Giter Site home page Giter Site logo

preset's Introduction


Logo of the Preset tool

Preset


Status   version   docs

npx apply <your-username/your-preset>


An elegant, ecosystem-agnostic preset mechanism.
It was made to automate the repetitive task of doing the same modifications each time a project is created.

Learn more



·

Built with ❤︎ by Enzo Innocenzi

preset's People

Contributors

avarun42 avatar innocenzi avatar jrson83 avatar nhedger avatar thdxr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

preset's Issues

feat: support Git tags

Add support for Git tags in order to handle versioning. Not sure about the syntax though. I'm thinking either a flag (--tag v0.1.4), or directly in the URL/shorthand:

# handle syntax
npx use-preset user/repo@tag:subdirectory

# url syntax
npx use-preset https://github.com/user/repo@tag:subdirectory

[Feature request] Allow actions to be grouped together

For very big presets it would be nice if actions could be grouped together, on one hand this would allow naming of multiple commands together so the cli output can be less cluttered and on the other and would allow multiples of the same if statement to be condensed into one.

In use it could look something like this:

// Before: 
.command('git', ['init', '--quiet'])
    .if(({ prompts }) => Boolean(prompts.git))
    .chain()
.command('git', ['add', 'README.md'])
    .if(({ prompts }) => Boolean(prompts.git))
    .chain()
.command('git', ['commit', '-m', '"Add README.md"', '--quiet'])
    .if(({ prompts }) => Boolean(prompts.git))
    .chain()
 .command('git', ['checkout', '-b', 'develop', '--quiet'])
    .if(({ prompts }) => Boolean(prompts.git))
    .chain()

// After:
.command()
    .title('Initialising local git repo')
    .if(({ prompts }) => Boolean(prompts.git)
    .run('git', ['init', '--quiet'])
    .run('git', ['add', 'README.md'])
    .run('git', ['commit', '-m', '"Add README.md"', '--quiet'])
    .run('git', ['checkout', '-b', 'develop', '--quiet'])

Currently this isn't possible, only the last run action in the command will actually be executed.

why double indentation in the edit API?

I'm just reading about Preset and I really appreciate the philosophy. I've used Yeoman in the past and this makes much more sense to me.

I'd like to understand how you're thinking about indentation. If I'm understanding the documentation correctly, the options are either to double the previous line's indentation or to use a fixed indentation that isn't based on the previous line. I'd like to be able to add or subtract a single tab or number of spaces from the previous line. (Ideally, the library would detect tabs vs spaces if it's consistent in the file.)

[Question] Copy conflict strategy "ask" in non-interaction mode

I make GitHub Workflow to check my preset
https://github.com/oanhnn/preset-laravel/runs/1189176191

npx: installed 102 in 5.03s
[STARTED] Resolve
[SUCCESS] Resolve
[STARTED] Parse
[SUCCESS] Parse
[STARTED] Task without title.
[TITLE] Apply laravel
[STARTED] Copy some default config files
[STARTED] Validate
[SUCCESS] Validate
[STARTED] Execute
[DATA] ? .editorconfig already exists. Do you want to replace it? ‣  / 
[DATA] ? .editorconfig already exists. Do you want to replace it? ‣ no / yes

But it has a problem: in non-interaction mode (CI), Copy conflict strategy "ask" still show question and exit.
How it doesn't ask and get the initial value?

withoutAsking usage

Hello @innocenzi

To install node dependencies without confirmation i had to write my preset like this:

  .installDependencies()
    .for('node')
    .withoutAsking(false)
    .title('Install npm dependencies')
    .chain();

is the correct behavior? i was expecting to say withoutAsking = true

feat: fluent preset builder

Instead of building presets with the object syntax, allow for an alternative fluent one.

Preset.make('preset-name')
  .applyPreset('external/preset')
  .copyTemplates()
  .execute(() => {
    // custom action
  })
  // etc etc

Not sure about the exact API yet. Ideally, it would support everything the object syntax does, hooks included.

feat: post-install instructions

Inspired from cliui, a post-install instruction would be nice to have for preset makers to give additional information about their installation.

It wouldn't be of the form of an action, but a preset property, just like the preset name.

// Object-based
module.exports = {
  name: 'some preset',
  instructions: [
    'Run "npm run dev" to start development'
  ]
}

// Fluent
module.exports = Preset.make('some preset')
  .instruct([
    'Run "npm run dev" to start development'
  ])

feat: `.preset` configuration

The idea is to implement a resolver, similar to the community resolver, which reads a ~/.preset file to find custom repositories.

Not sure of the format of that configuration file, but it should be able to map a keyword:repository to a custom Git repository.

Conflict with built-in command?

I was trying to use Tailwind with SvelteKit when came across this project svelte-add/tailwindcss.

But when I tried running npx apply svelte-add/postcss, it does nothing except echoing:

npx apply svelte-add/postcss

After a few minutes trying, I realised that this could possibly mean that npx apply was actually running a built in command (instead of running preset/cli). So I tried man apply. And lo!

man apply

I don't remember installing it. I also have checked with brew ls in case it was installed as a package dependency of other clis that I actually use, and the result is negative.

I'm running:

  • macOS Catalina 10.15.7
  • node v14.15.4
  • npm/npx v6.14.10
  • yarn 1.22.4

Oh by the way, in npx introductory blog post:

Calling npx <command> when <command> isn’t already in your $PATH will automatically install a package with that name from the npm registry for you, and invoke it.

In other words, if <command> (in this case apply) is already in my $PATH, then by default npx will run that.

So this is the expected behaviour on npx part.

`edit` action

An action that would look for specific files and edit their content. Ideally, support for this feature should be added:

  • Add or remove a line before or after a specific line
    • Specific line can be found by line content or line number
  • Replace content in every matching files
    • Should support regular expressions

feat: guess the name of the repository with prefix `preset-`

If I create the repository call user/preset-a, I hope will use apply user/a or apply user/preset-a both can to run the preset..

I think this feature will allow me to create repo with preset- without having to type the prefix preset-.

Is this feature possible?

`preset` action

An action that would apply another preset on the same directory. This would be useful for combining presets, in order for users to apply modifications on top of existing presets.

feat: edit dependencies action

New actions for ecosystem-specific dependency management. Currently, edit-json works fine for editing package.json and composer.json files, but it could help some syntactic sugar, and maybe new features (eg. sorting, see #45).

Global configuration file

Allow for custom aliases to avoid having to type the whole organization/repository resolvable for presets that are used often.

Also allows for default package manager for installPackages.

Improve extract from template file to target file

Summary

When extract from template file to target file, it don't existed yet, preset make incorrect target path.

Steps to reproduce

Make preset with preset.ts

Preset.extract()
    .from('abc/.eslintignore')
    .to('.eslintignore')
    .withDots(true)
    .whenConflict(Preset.isInteractive() ? 'ask' : 'override')

Make template file templates/abc/.eslintignore

Run

mkdir ci-test
apply /path/to/preset ci-test

Expect behavior?

The preset copy templates/abc/.eslintignore to ci-test/.eslintignore

What is the current bug behavior?

The preset copy templates/abc/.eslintignore to ci-test/.eslintignore/abc/.eslintignore

Why not set .to('') ? Because it will make ci-test/abc/.eslintignore

docs: comment fluent API

Right now, the fluent API is made with a Preset object and multiple pending objects, but none are commented. They should be properly commented to reduce the round-trips to the actual documentation for users that do not know the API that well yet.

`stub` action

An action that would copy files, the same way as the copy action, but with additional support for replacing its content.

It can be useful for template files which contents should be determined by user input or with data fetched from the target directory (eg. classes with namespaces, custom names, etc).

feat: support dependencies (`install` mode)

Currently, the presets are evaluated with eval so there is no need to install their dependencies, since most of the time they don't have any. This is a design choice that was made because application speed was in mind.

That said, there are times where dependencies may be useful, and as such, support for installing them should be added.

It means that the new importer should look for pnpm or yarn and fallback to npm, install dependencies after a clone, and then require the preset.

This can be done with the recently added installDependencies utility method.

  • After cloning, execute the above function
  • require() the preset file

A preset maker would chose the installation mode with a mode property on the preset object.

module.exports = {
  name: 'Some preset',
  mode: 'install'
}

feat: use monorepo preset

It would be nice to use a preset located in a monorepo with the GitHub URL syntax

npx use-preset username/repository/tree/branch/package

Alternatives:

# Omit "tree"
npx use-preset username/repository/branch/package
# Branchname will default to master | main
npx use-preset username/repository/package

change: improve console feedback

Just like the previous rewrite, I didn't focus on the console output. I previously used taskr2 but the console logging was way too tied to the logic, so I eventually removed it.

Now that the logging is event-based, I'm considering improving it while keeping it simple, with something like ora. But this one appears to not work properly, so not sure when I'll dive into that.

`install-dependencies` action

An action that makes it easier to install dependencies, in order to avoid using the after hook and installDependencies context function.

This should install dependencies for the selected ecosystem. For node, it would look for yarn first, then npm.

module.exports = {
  actions: () => [{
    type: 'install-dependencies',
    mode: 'install', // and 'update'
    for: 'node' // and 'php', and maybe other ecosystems
  }]
}

Preset.editJson().merge() produces duplicated code when you add values within an array

Le'ts say I want to edit the package.json and and want to configure jest. Then I have the following code:

  Preset.editJson('package.json').merge({
    jest: {
      roots: ['<rootDir>/src'],
      setupFilesAfterEnv: ['<rootDir>/jest/jest.setup.js'],
      collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}', '!src/**/*.d.ts'],
      testMatch: ['<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}', '<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}'],
      testEnvironment: 'jsdom',
      transform: {
        '^.+\\.(js|jsx|mjs|cjs|ts|tsx)$': '<rootDir>/node_modules/babel-jest',
        '.+\\.(svg|css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
      },
      transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$', '^.+\\.module\\.(css|sass|scss)$'],
      moduleNameMapper: {
        '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
      },
      watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],
      resetMocks: true,
    },
  });

I run my preset once: everything as expected.
I run it several times. Then there are two cases:

  1. ✅ Code is automatically merged and not duplicated.
    For example the "testEnvironment": "jsdom", or the "resetMocks": true: this will not be added again to the package json
  2. ❌ Code like the
      roots: ['<rootDir>/src'],
      watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],

This will be added several times to the package json

Conclusion:
It looks like that his happens with array values only.
I would expect that that also checked and not added again when they are already existing.

`run` action

A simple action that would allow to run shell commands.

Should be used with care because cross-platform is important. Because of that, an os property should be added to the context object.

Can't seem to be able to catch errors.

I'm not sure how catching errors is supposed to work. editJson errors on JSONC (JSON with comments), which is common in files like tsconfig, or settings.json.

Is there a recommended way to handle errors and provide error messages?

Improve logging and console feedback

I'd like to improve the console feedback when doing resource-heavy manipulations, such as installing dependency. Right now, it can be done from the context without any feedback (the console will hang).

An option would be to include Listr and integrate it. If this is done, it can be used throughout the whole CLI for better overall feedback.

Additionally, some of the logger icons takes too much space on windows, which renders pretty bad. The Logger and Prompt classes should be rewritten properly in the future.

feat: warn user when cli is outdated

The CLI should be used with npx use-preset, but this is sometimes frustrating because it's a bit slower. Because of that, chances are that use-preset is installed globally.

For this reason, when running a preset, the tool should asynchronously check for a new version. If one is found, use should be alerted.

feat: per-action hooks

Currently, global execution hooks are available, but per-action hooks should be added to the base action contract.

[Feature request] Support functional in parameter of addAfter/addBefore method

I want add an environment variable base existed environment variable in .env file.
I was try with replace().with(), but it don't work. (See below comments)

module.exports = Preset.make('Update ENV')
  .edit('.env')
  .replace(/^APP_URL=http:\/\/(.*)$/)
  .with((str, domain) => {
    return ['APP_URL=http://' + domain, 'APP_DOMAIN=' + domain].join('\n')
  })
  .chain()

I think addAfter/addBefore method should support functional like replace().with().

module.exports = Preset.make('Update ENV')
  .edit('.env')
  .search(/^APP_URL=http:\/\/(.*)$/)
    .addAfter((str, domain) => 'APP_DOMAIN=' + domain)
    .end()
  .chain()

Init new preset without git to use it as a local code generator

I would like to have an option to create an preset without git. This would make it possible to use the code generator for local code generation. This I could use for example when I want to generate a new menu entry and a page. This I don't want to have in a separate repository. It should just live in my project.

I would suggest to have an optional argument to the init command

npx apply <preset-name> --init --local

or even have the git as an optional command:

npx apply <preset-name> --init --add-git

feat: delete temporary files

The git and gist resolvers clone repositories into temporary folders. However, they are not automatically deleted. They should be.

feat: support `use-preset` back

I managed to get apply, but little did I know this was an existing command name on macOS. For this reason, instead of requiring users to use --ignore-existing, I'm thinking about maintaining both apply and use-preset. That would require a change in the importer as well.

`edit-json` action

An action that would provide support for easily working with JSON files. Merging objects or removing paths should be easily done.

For instance, its API could look like this:

{
  merge: {
    dependencies: {
      vue: '^2'
    }
  },
  remove: [
    'dependencies.axios'
  ]
}

How does Multiselect ArrayType work?

I've been struggling to figure out how to implement the MultiSelect Prompt.

Screenshot 2021-06-21 at 5 59 12 PM

code
import { Preset } from 'apply';

Preset.setName('Config');
Preset.prompt()
	.add('configs', {
		type: 'ArrayPrompt',
		name: 'configs',
		message: 'What configs would you like?',
		choices: ['stylelint', 'settings.json']
	});

I've read through the docs multiple times, but can't seem to understand how it's meant to work.

Any advice would be greatly appreciated!

When trying to publish:vendor by execute, nothing happens

Hello, I'm trying to make a preset for Laravel that will publish the vendor.

After installing the desired package, I try execute:

Preset.execute('php')
    .withArguments([
        'artisan',
        'vendor:publish',
        '--provider="NunoMaduro\\PhpInsights\\Application\\Adapters\\Laravel\\InsightsServiceProvider"',
    ])

However, the vendor is not published, and there are no errors.

change: use `https` by default

Apparently a lot of people don't have SSH set up so instead of requiring them to use --no-ssh, I'll just update the resolvers to use https by default unless --ssh (or an URL) is passed.

Downside: private presets will require --ssh.

Alternative: detect if SSH is configured before cloning.

Alternative: keep stuff as-is but improve error message and provide steps to solve it (links to the docs for setting up SSH w/ GitHub, and hint about the --no-ssh flag)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.