Skip to content

Commit

Permalink
Merge pull request #219 from plopjs/inline-bypass-arr
Browse files Browse the repository at this point in the history
Allow merging of plop args and generator args, improved docs
  • Loading branch information
crutchcorn authored May 19, 2020
2 parents d89d874 + 25aca53 commit 66f5884
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 14 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ node_modules/
example/folder/
example/change-me.txt
.idea
.vscode
.vscode
.DS_STORE
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -460,3 +460,76 @@ function MyConfirmPluginConstructor() {
### Adding Bypass Support to Your Plopfile
If the 3rd party prompt plugin you are using does not support bypass by default, you can add the `bypass` function above to your prompt's config object and plop will use it for handling bypass data for that prompt.

## Wrapping Plop

Plop provides a lot of powerful functionality "for free". This utility is so powerful, in fact, that you can even wrap `plop`
into your own CLI project. To do so, you only need a `plopfile.js`, a `package.json`, and a template to reference.

Your `index.js` file should look like the following:

```javascript
#!/usr/bin/env node
const path = require('path');
const args = process.argv.slice(2);
const {Plop, run} = require('plop');
const argv = require('minimist')(args);

Plop.launch({
cwd: argv.cwd,
// In order for `plop` to always pick up the `plopfile.js` despite the CWD, you must use `__dirname`
configPath: path.join(__dirname, 'plopfile.js'),
require: argv.require,
completion: argv.completion
// This will merge the `plop` argv and the generator argv.
// This means that you don't need to use `--` anymore
}, env => run(env, undefined, true));
```

> Be aware that if you choose to use the `env => run(env, undefined, true))`, you may run into command merging issues
> when using generator arg passing.
>
> If you'd like to opt-out of this behavior and act like plop does (requiring `--` before passing named arguments to generators)
> simply replace the `env =>` arrow function with `run`:
>
>```javascript
>Plop.launch({}, run);
>```
And your `package.json` should look like the following:
```json
{
"name": "create-your-name-app",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "plop",
},
"bin": {
"create-your-name-app": "./index.js"
},
"preferGlobal": true,
"dependencies": {
"plop": "^2.6.0"
}
}
```
### Adding General CLI Actions

Many CLI utilities handle some actions for you, such as running `git init` or `npm install` once the template is generated.

While we'd like to provide these actions, we also want to keep the core actions limited in scope. As such, we maintain a collection of libraries built to add these actions to Plop in [our Awesome Plop list](https://github.com/plopjs/awesome-plop). There, you'll be able to find options for those actions, or even build your own and add it to the list!

### Further Customization

While `plop` provides a great level of customization for CLI utility wrappers, there may be usecases where you simply
want more control over the CLI experience while also utilizing the template generation code.

Luckily, [`node-plop`](https://github.com/plopjs/node-plop/) may be for you! It's what the `plop` CLI itself is built
upon and can be easily extended for other usage in the CLI. However, be warned, documentation is not quite as fleshed out
for integration with `node-plop`. That is to say `Thar be dragons`.

> We note lackluster documentation on `node-plop` integration not as a point of pride, but rather a word of warning.
> If you'd like to contribute documentation to the project, please do so! We always welcome and encourage contributions!
24 changes: 14 additions & 10 deletions src/input-processing.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ module.exports = {getBypassAndGenerator, handleArgFlags};
/**
* Parses the user input to identify the generator to run and any bypass data
* @param plop - The plop context
* @param passArgsBeforeDashes - Should we pass args before `--` to the generator API
*/
function getBypassAndGenerator(plop) {
// See if there are args to pass to generator
const eoaIndex = args.indexOf('--');
const {plopArgV, eoaArg} = (eoaIndex === -1
? {plopArgV: []}
: {
plopArgV: minimist(args.slice(eoaIndex + 1, args.length)),
eoaArg: args[eoaIndex + 1]
}
);
function getBypassAndGenerator(plop, passArgsBeforeDashes) {
// See if there are args to pass to generator
const eoaIndex = args.indexOf('--');
const {plopArgV, eoaArg} = (
passArgsBeforeDashes ?
{plopArgV: argv} :
eoaIndex === -1
? {plopArgV: []}
: {
plopArgV: minimist(args.slice(eoaIndex + 1, args.length)),
eoaArg: args[eoaIndex + 1]
}
);

// locate the generator name based on input and take the rest of the
// user's input as prompt bypass data to be passed into the generator
Expand Down
18 changes: 15 additions & 3 deletions src/plop.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,19 @@ const Plop = new Liftoff({
v8flags: v8flags
});

function run(env) {
/**
* The function to pass as the second argument to `Plop.launch`
* @param env - This is passed implicitly
* @param _ - Passed implicitly. Not needed, but allows for `passArgsBeforeDashes` to be explicitly passed
* @param passArgsBeforeDashes - An opt-in `true` boolean that will allow merging of plop CLI API and generator API
* @example
* Plop.launch({}, env => run(env, undefined, true))
*
* !!!!!! WARNING !!!!!!
* One of the reasons we default generator arguments as anything past `--` is a few reasons:
* Primarily that there may be name-spacing issues when combining the arg order and named arg passing
*/
function run(env, _, passArgsBeforeDashes) {
const plopfilePath = env.configPath;

// handle basic argument flags like --help, --version, etc
Expand All @@ -36,7 +48,7 @@ function run(env) {

const generators = plop.getGeneratorList();
const generatorNames = generators.map(v => v.name);
const {generatorName, bypassArr, plopArgV} = getBypassAndGenerator(plop);
const {generatorName, bypassArr, plopArgV} = getBypassAndGenerator(plop, passArgsBeforeDashes);

// look up a generator and run it with calculated bypass data
const runGeneratorByName = name => {
Expand Down Expand Up @@ -112,4 +124,4 @@ function doThePlop(generator, bypassArr) {
module.exports = {
Plop,
run
}
}

0 comments on commit 66f5884

Please sign in to comment.