plopjs / plop Goto Github PK
View Code? Open in Web Editor NEWConsistency Made Simple
Home Page: http://plopjs.com
License: MIT License
Consistency Made Simple
Home Page: http://plopjs.com
License: MIT License
I just met plop. And I am in love with it.
Why I choose Plop over Yeoman?
Because it is composable, I can set a project by calling some third party plops (#20) and also add my owns, right on this way:
module.exports = function (plop) {
require('plop-generator-react')(plop);
require('plop-generator-redux')(plop);
// Custom generators here...
};
So my proposal is: why not creating a website for Plop? And may be list the community created Plops?
Cheers :).
Maybe this is possible but after looking at the docs and some of the code I don't think so. I want to be able to navigate to a folder and generate some files there rather than having the path
be relative to the plopfile.js
file, I'd rather have the path
be relative to where the command is executed. Right now, I can accomplish this by generating the path
like this:
function getPath(subPath) {
const plopPath = process.cwd().substring(plop.getPlopfilePath().length + 1)
return path.join(plopPath, subPath)
}
But I'd much rather not have to do that and do this instead:
{
type: 'add',
path: '{{name}}.js',
usePWDForPath: true,
// ...etc
}
An important note here is that the templateFile
should remain as it is and should not be relative to the PWD
.
What do you think?
Hey there ploppers (ok, that's terrible), I'd like to add a list of companies that are using plop to the plopjs.com website. So if your company uses plop and would like to be included on the list, please leave a comment below (or email) with your company's name and website address.
Thanks all!
how would you suggest creating a global plopfile that can be used across projects?
Please document choices of a prompt in github pages.
Related issue: #64
I wanted to use plop with es6 but i couldn't,
Liftoff is exactly what you need for this project.
I was wondering: what terminal emulator is running in your screenshot gif in the readme?
Thanks
It's possible get the templates from a git repository?
Example: https://gist.github.com/despairblue/82a7bd6a16eccdbb7856493fb4d79c0a
Running node_modules/.bin/plop
doesn't create a file or return an error code. When adding prompts
everything works again.
I have a select that purpose a folder list.
In the next step, I need to validated to ask him to type a folder name.
I will have to read the value of the folder list choice in order to write the validate function.
Is that possible ? to read the user input ? I've looked everywhere in the documentation it's like missing.
Just a quick line to say thank you for creating plop. Why haven't I heard about it before?
I'm using it to create assets for a HAPI server, and although it took a couple of hours to get it in place, it's going to save so much time.
I'd like to be able to run a plopfile add action and overwrite the existing files. I've tried setting abortOnFail
to false without any luck. I imagine I can delete the existing files in my custom action, but am curious if there is already a built-in way to do this. I couldn't find docs for abortOnFail
.
Edit: this is specifically for use with the add function.
I was looking for a way to supply my own paths and things of that nature, but --help and the readme were not helping. But they're in there, just undocumented https://github.com/amwmedia/plop/blob/master/plop.js#L24
Something that came up when I was plopping files:
It being so late, haha, I was trying to reference the pascalCase helper within handlebars with a literal PascalCase.
Instead of throwing the error Missing helper "PascalCase"
from the message prop within the error object instead the only error output printed in the console was [FAILED] undefined undefined undefined
Maybe we include the error message in the fail by default and use a falsy to check for a line.type to determine if we should output the additional props?
It may be useful to reach deeper than the 1st level of the package object.
I suggest plop should come bundled with pkg
anyone can override like this:
const get = require('lodash.get');
const pkg = require('./package.json');
plop.addHelper('pkg', propertyPath => get(pkg, propertyPath));
It may be taken right from lodash like I suggested above or it can be replicated in this project if you don't want more dependencies.
The starting prompt says: "[PLOP] Please choose a generator. (Use arrow keys)" each time when I run plop, is it possible to customize it to some other message?
In the prompts, I have
{
type: 'list',
name: 'type',
message: 'Type of the saga',
choices: [{
name: 'non-blockingly watcher',
value: 'nonBlockinglyWatcher'
}]
}
and in the actions
{
type: 'add',
path: 'common/sagas/assets/index.js',
templateFile: 'generators/sagas/{{ type }}/index.js'
}
But when I run the generator, I get an ENOENT
:
? [SAGA] Type of the saga non-blockingly watcher
[FAILED] add PROJECT/common/sagas/assets/index.js ENOENT:
no such file or directory, open 'PROJECT/generators/sagas/{{ type }}/index.js'
i.e. {{ type }}
will not be replaced.
Hey, I just tried plop with inquirer-recursive and each time plop comes to prompt with recursive question it fails with error given below.
I resolved the issue by updating [email protected] to [email protected]. At the moment inquirer-recursive works properly and nothing have broke so it's not an issue for me, but some other people may be misguided by https://github.com/amwmedia/plop/blob/master/inquirer-prompts.md.
I will suggest to:
plop: 1.7.3
OS: Windows 10
Node: 6.5.0
Receivied error:
[ERROR] inquirer.prompt(...).then is not a function TypeError: inquirer.prompt(...).then is not a function
at Prompt.askForLoop (@project_folder@\node_modules\inquirer-recursive\index.js:27:8)
at Prompt._run (@project_folder@\node_modules\inquirer-recursive\index.js:46:10)
at Prompt.run (@project_folder@\node_modules\inquirer\lib\prompts\base.js:55:8)
at @Roaming_folder@\nvm\v6.5.0\node_modules\plop\node_modules\inquirer\lib\ui\prompt.js:79:45
at tryCatcher (@Roaming_folder@\nvm\v6.5.0\node_modules\plop\node_modules\rx\dist\rx.js:63:31)
at Defer.subscribeCore (@Roaming_folder@\nvm\v6.5.0\node_modules\plop\node_modules\rx\dist\rx.js:2536:37)
at Defer.tryCatcher (@Roaming_folder@\nvm\v6.5.0\node_modules\plop\node_modules\rx\dist\rx.js:63:31)
at setDisposable (@Roaming_folder@\nvm\v6.5.0\node_modules\plop\node_modules\rx\dist\rx.js:2082:46)
at Defer.Rx.ObservableBase.ObservableBase._subscribe (@Roaming_folder@\nvm\v6.5.0\node_modules\plop\node_modules\rx\dist\rx.js:2097:9)
at Defer.Rx.Observable.observableProto.subscribe.observableProto.forEach (@Roaming_folder@\nvm\v6.5.0\node_modules\plop\node_modules\rx\dist\rx.js:2034:19)
Hi !
I need to allow arguments to be passed to a plop command (to make it easier to automate certain tasks).
For a generator like this:
plop.setGenerator('CreateUser', {
description: 'create a json user file',
prompts: [
{
type: 'input',
name: 'name',
message: 'Please enter a name'
},
{
type: 'input',
name: 'phoneNumber',
message: 'Please enter a name'
}
],
actions: []
});
It would be cool if we could execute this command plop CreateUser --name="PAG" --phoneNumber="0836656565"
I did a test to implement this behavior and it works great.
Are you guys interested in this feature?
ie ( 'plop component myComp' ), given that I have a generator named 'component', I would like to skip the prompt for name if the their is a name argument passed in. I am able to access the argument via this.process.argv[3], but it seems I can't use 'prompts' property as a function, so I am unable to add any conditional logic here as I can with actions. Is there an easier way to do this?
Really digging this repo @amwmedia The final paragraph of the README is spot on. Some thoughts:
Since I'm installing this globally, there are a few things that could be really handy...
plop help
or plop --help
plog init
to generate a simple plopfile.js
in a directory. I'd envision this with some boilerplate like the addHelper
and setGenerator
.If you have any opinions on how that would be implemented, I'd be happy to submit a pull request. Really excited to start using this though. Cheers!
Hello!
Partially, there is no documentation for the fields a prompt or action can have.
I only found that information by reading the example plop file.
Please document the validate
property of prompts.
I'm going to be soon introducing the ability to plop an entire project codebase and I want to throw out the approach I'm currently considering for feedback. My plan is to enable a syntax something like the following.
$ plop --project http://github.com/some/repo --destination ./some-repo
or shorthand
$ plop -p http://github.com/some/repo -d ./some-repo
--destination
was not provided)plopinit.js
. This would use standard plopfile syntax to setup helpers, partials, and generators to be used for initialization{{
and each instance found would be replaced with an escaped version \{{
. This replacement would also search for another set of tokens (thinking {{# #}}
or {{% %}}
). These would be replaced with standard curly braces./cc @nicoespeon @kentcdodds @mxstbr @calcaide @Kevin-Wolf
Looking for questions or input
While building these things, I'm finding that it would be really nice to be able to run some tests rather than having to test in manually. Do you think we could develop a good way to do that? Even if it's just some examples that would be handy. But being able to assert files were created and their contents without actually creating them would be really helpful.
I think that it'd make this utility more powerful if both inquirer and handlebars integration were extracted to plugins to make this utility pluggable. That would allow me to provide my own template compiler and data gatherer. It would also allow for customizing these things without having to make plop expose APIs for these things explicitly. Thoughts?
Alright, so first off, I'm pretty stoked to be taking Plop for a spin. It seems super promising and can't wait to roll it into my workflow.
It seem as though node-plop is breaking the CLI tool at the moment. Plop is installed both as a global and a dev dependency for my project. However, Plop fails when I try invoking it. I've tested my own plopfile as well as pulled the one from the example dir and also found another in a gist which was tried. All of them yield the same issue.
Here is the stack trace for the issue:
~\AppData\Roaming\npm\node_modules\plop\node_modules\node-plop\lib\modules\node-plop.js:29
function nodePlop(plopfilePath = '', plopCfg = {}) {
^
SyntaxError: Unexpected token =
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:373:25)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (~\AppData\Roaming\npm\node_modules\plop\node_modules\node-plop\lib\index.js:5:17)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
I'm on a team that uses a somewhat complex plopfile and I'd like to have a quick way to verify that it is working the way we want. I would love to be able to require('plop')
and automatically generate some components with defaults.
The interface for my script might look something like this:
var plop = require('plop');
var path = require('path');
var exampleDir = path.resolve(__dirname, 'example');
plop.runGenerator('widget', {
// Use the same variables as the prompts require
path: path.resolve(exampleDir, 'widgets'),
name: 'my-widget',
animal: 'dog'
});
plop.runGenerator('complexWidget', {
path: path.resolve(exampleDir, 'complex', 'widgets'),
name: 'my-complex-widget',
animal: 'hippo'
});
@kentcdodds this might be a good way to verify your plopfile settings, as an alternative to #7.
I haven't found it in the example file or in the readme so I'm not sure if that is already possible. If not, I would like to file a feature request here ;)
I am using plop to create a json configuration which can contain a selector
property with an array as value which is freely expandable and can hold 1-n items. In my case it's a css selector. I have now created an action to add a new css selector:
{
type: 'prompt',
name: 'selector',
message: 'Enter a css selector to add:',
}
What I am now looking for is to jump back to prompts[0]
in case prompts[1]
is answered with yes:
{
type: 'confirm',
name: 'addMore',
message: 'Add another css selector?',
}
So what I would like to have is something like this:
[PLOP] Please choose a generator. cssconfig
[TEST] Enter a css selector to add: .foo
[TEST] Add another css selector? Yes
[TEST] Enter a css selector to add: .bar
[TEST] Add another css selector? Yes
[TEST] Enter a css selector to add: .foobar
[TEST] Add another css selector? No
[SUCCESS] add W:\test.js
The generated file should then contain something like:
{
"selector": [".foo", ".bar", ".foobar"]
[...]
}
Sure, in my example I could just allow to write several selectors comma separated but I can think of other usecases where you might want to have further actions based on previous selections.
So is it possible? If not, can it be (more or less) easily added as feature? (Probably it's more a inquirer issue than plop, isn't it?)
Hi,
Love this framework.
I am wondering how I can show a prompt ONLY if the value of a previous prompt was "true"?
Is this possible?
Is there an easy way to pass custom json objects to actions?
The scenario: I'd like to define a metadata json structure and pass it to generators to populate files (and templates) accordingly.
I'd also need to let data flow (specifically, array items) from one generator to another.
Do you think it makes sense to just use the generator and start asking questions instead of picking one, if there is only one to pick?
This is a feature request, to generate multiple files in one action. Something like generate src/modules/{{lowerCase name}}/*.js
from templates in plop-templates/modules/*.js
using the asterisk / glob (*).
e.g plop-templates
folder
plop-templates/modules/index.js
plop-templates/modules/parser.js
plop-templates/modules/utils.js
plop-templates/modules/helpers.js
plop-templates/modules/others.js
plop-templates/modules/anothers.js
And then in plopfile.js
:
...
prompts: [
{
type: 'input',
name: 'name',
message: 'What is the module name?',
},
],
actions: [
{
type: 'add',
path: 'src/modules/{{lowerCase name}}/*.js', // <--- here are the globs
templateFile: 'plop-templates/modules/*.js', // <--- globs
}
]
...
and command plop module foo
will generate:
src/modules/foo/index.js
src/modules/foo/parser.js
src/modules/foo/utils.js
src/modules/foo/helpers.js
src/modules/foo/others.js
src/modules/foo/anothers.js
Your great works are much appreciated. Cheers โ
I just discovered Plop and was amazed by how easy it is to use! Kudos to you sir!
I would like to ask if there are plans to add support for a built-in pluralize
helper so that I can emulate what Rails does when I run the rails generate scaffold
command, to generate certain file/folder names contain the plural version of the input I pass into my plop generator.
If you are open to that idea I can make a PR for it ๐
I'm new to plop.
I followed the advice of putting the plopfile.js file at the root of my project.
When I ran plop the first time, I ran it from a subdirectory of the project. I expected it to create the files relative to the current subdirectory. It didn't. It created them at the root of the project.
Is there an easy way to get plop to generate the files in the current subdirectory without asking for it? I finally used plop.addHelper('cwd', (p) => process.cwd());
and then prefixed all of my path strings with {{cwd}}/
.
Let's say I have the following generators:
I want the module
generator to internally call model
, view
and controller
generators.
Is there an API method to achieve this?
Cheers.
Notice you have written your own helper library fs-promise
but such a lib already exists.
Why not extend the existing one!?
Is it possible to modify the data
or answers
object after prompts?
Here is the general idea:
data
object that is passed to my jade templates so that I can do something like: for each schema type, add an input field to the view
.render() {
return (
<div style={{ height: '100%', width: '100%' }} />
);
}
It gives error: Expecting 'CLOSE_RAW_BLOCK', 'CLOSE', 'CLOSE_UNESCAPED', 'STRING', 'NUMBER', 'BOOLEAN', 'OPEN_SEXPR', ' CLOSE_SEXPR', 'ID', 'DATA', got 'INVALID'
In general, this is a piece of my template which is react.js file, so that double quotes are useful to react. In this case, how would I parse that?
Is it possible to use statements (foreach, if, etc.) in templates?
If not:
Hi, I'm having a trouble to use arrow keys to navigate. I've tried cmd and git bash, as well as the webstorm terminal.
I'm testing it as a part of the react-boilerplate. This is the pre-anniversary win10.
If I want to give the user, for example, to choose which css preprocessor he preferred sass/less/stylus ( for the file extension ) and I need to save this somewhere for not asking him again every time, There is a way to do that?
I am using plop kind of a time now, it saves a lot of times, so thanks for it!
Now I have tried to autoload generators, when scaffolding a project, but I couldnt figure out how to do it. Is it possible, did I missed something? I want to run it on my postinstall
, so a command like plop page --name=index
would make sense.
@amwmedia As you said in issue #20 (if I understood well) plop is using node-plop internally, right?
Supossing that, I can see that plop is not requesting node-plop, in fact, the files are duplicated, please correct me if I am worng. That confuses me a bit, actually, that's why I didn't realise that plop is using node-plop.
In case that my assumption is correct, what do you think about using node-plop as a module?
According to the Inquirer docs, message can take either a String or a Function:
message: (String|Function) The question to print. If defined as a function,
the first parameter will be the current inquirer session answers.
So, I would expect the following question object to print the previous answers in the prompt:
{
type: 'confirm',
name: 'confirmCreateComponent',
message: function (answers) {
return (
`Are you sure you would like to create the following component?
name: <${answers.ComponentName} />
type: ${answers.componentType}
location: ${path.join(__dirname, answers.dir)}
`
);
},
Instead, it prints the function body in the prompt:
? [COMPONENT] function (answers) {
return (
`Are you sure you would like to create the following component?
name: <${answers.ComponentName} />
type: ${answers.componentType}
location: ${path.join(__dirname, answers.dir)}
`
);
} (Y/n)
Am I misunderstanding the docs?
I tried to run it from local node_modules/.bin
Then I installed it as global dependency, generated a new plopfile plop -i
and run it. Nothing
Here is the screenshot http://d.pr/i/13ELg2
On macOS I have no problems.
Add the ability to pass in a 'when' into the action object so that it only triggers if the condition passes similar to the 'when' in prompts
My proposition is to add a modify action for JSON files, where you will provide callback instead of pattern and template. In callback you would get JSON.parse
d object and you should also return POJsO which will be JSON.stringify
d and written to file.
Looks like there is some mismatch in plop
, inquirer
, around the use of promises:
Offending code:
plop/node_modules/inquirer/lib/ui/prompt.js:79:50
PromptUI.prototype.fetchAnswer = function (question) {
var Prompt = this.prompts[question.type];
var prompt = new Prompt(question, this.rl, this.answers);
return rx.Observable.defer(function () {
// This next lines fails as prompt.run() doesn't seem to return a promise
return rx.Observable.fromPromise(prompt.run().then(function (answer) {
return {name: question.name, answer: answer};
}));
});
};
Log:
(Use "/" key to search this directory)[ERROR] Cannot read property 'then' of undefined TypeError: Cannot read property 'then' of undefined
at /Users/ppodil/Projects/react-mobx-seed/node_modules/plop/node_modules/inquirer/lib/ui/prompt.js:79:50
at tryCatcher (/Users/ppodil/Projects/react-mobx-seed/node_modules/rx/dist/rx.js:63:31)
at Defer.subscribeCore (/Users/ppodil/Projects/react-mobx-seed/node_modules/rx/dist/rx.js:2536:37)
at Defer.tryCatcher (/Users/ppodil/Projects/react-mobx-seed/node_modules/rx/dist/rx.js:63:31)
at setDisposable (/Users/ppodil/Projects/react-mobx-seed/node_modules/rx/dist/rx.js:2082:46)
at Defer.Rx.ObservableBase.ObservableBase._subscribe (/Users/ppodil/Projects/react-mobx-seed/node_modules/rx/dist/rx.js:2097:9)
at Defer.Rx.Observable.observableProto.subscribe.observableProto.forEach (/Users/ppodil/Projects/react-mobx-seed/node_modules/rx/dist/rx.js:2034:19)
at MergeObserver.handleSubscribe (/Users/ppodil/Projects/react-mobx-seed/node_modules/rx/dist/rx.js:3525:28)
at MergeObserver.next (/Users/ppodil/Projects/react-mobx-seed/node_modules/rx/dist/rx.js:3531:14)
at MergeObserver.Rx.internals.AbstractObserver.AbstractObserver.onNext (/Users/ppodil/Projects/react-mobx-seed/node_modules/rx/dist/rx.js:1762:31)
I have a use case for this capability. I've tried requiring handlebars myself and adding the partial that way but that doesn't appear to register it with the instance being used by plop somehow because I get an error that my partial could not be found.
Is it possible to force the replacement of existing files?
That's required when running the generator after changes (example: template updated)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.