codeBelt/generate-template-files

Is there a way to pass an input in one single commands?

Closed this issue · 18 comments

So we can call the command like this: node ./tools/generate.js --create-service "replace_string_1" "replace_string_2" --overwrite

Is there a way to do that?

👍

Currently there is no way to do this but I will look into it.

I'm really interested by this feature. I would like to use the generator in command line without user interactions. It would allow us to use the generator in a script to generate multiple files.
For example to create multiple stores, it would be interesting to have an array of store's name and use them in a loop to create all the files at once.

For the moment, is it possible to have a function "generareTemplateFile" that takes only one IConfigItem and dynamicReplacers as argument ?
With "process.argv" it will allow us to create our scripts.

I will try to work on it this weekend. Currently I am very busy at work. I will see what I can do.

Thank you ! I saw your code, I will try to do it myself and add a pull request if it is ok for you.

sure cool with me

Added Command Line Functionality to v2.4.0 and is now published https://www.npmjs.com/package/generate-template-files

Just want to add that the way this was implemented it added a major breaking change, because it's now reading the arguments directly you cannot use this pack in conjunction with your scripts if they take arguments. I believe the proper implementation would have been not too hook onto arguments at all and instead pass them as arguments to the function generateTemplateFiles

@CGeorges I agree now that you point that out that it was a breaking change. Can you explain/show how you see it working. Is it like something I have below?

I have not tested this code, it's just an example of what I think you are saying.

// myScript.js
const { generateTemplateFiles } = require('generate-template-files');
const yargs = require('yargs');

const nameValue = yargs.argv.name;
const outPutpath = yargs.argv.outputpath || './src/app/stores/__name__(lowerCase)';

const items = [
  {
    defaultCase: '(pascalCase)',
    entry: {
      folderPath: './tools/templates/angular/ngrx-store/',
    },
    dynamicReplacers: [
      {slot: '__name__', nameValue},
    ],
    output: {
      path: outPutpath,
      pathAndFileNameDefaultCase: '(kebabCase)',
    },
  }
]

generateTemplateFiles(items);

// Then you could have other script below that use other arguments?

This is what you would type in the terminal:

node myScript --name=something --outputpath=./src/here 

@codeBelt Yes, that should be perfect. I'm assuming we don't need any changes done to stringReplacers because dynamicReplacers can be used instead if developer wants to provide automatic fill. The only missing dynamic options are item selection, confirming path and force overwrite.

√ What do you want to generate? · Create embeddable onboarding fragment
√ Output path: · dist/fr/fr/onboarding-link.html
√ Overwrite files, continue? (y/N) · true

The above questions I get when passing certain arguments, then I just use dynamicReplacers instead.

Probably the current implementation could work as well, as long as it's looking for specific arguments with key and value like you mentioned --item=something. Right now running my script with npm run script fr fr it will try to replace an item fr which breaks.

@CGeorges I don think if you are using the command line you need to select whats options to generate. The array of items is what you to generate and you would figure that out before passing in to generateTemplateFiles.

In the example above for "confirming path" you could set that up yourself before passing to generateTemplateFiles. Example: --outputpath1=./src/here --outputpath2=./src/here

I guess for "force overwrite" I could add an optional property on the IConfigItem called forceOverwrite: true and you could supply that with arguments?

So it sounds like the way you are using it is to configure the IConfigItem programmatically and then you send it to generateTemplateFiles? Could you setup a Github repo so I can see how you are using generate-template-files.


I can see how the latest changes would break what you are doing. I guess I have to figure out how to do it both ways because I could people like @knona just wanting to run the below script and not have to handle process.argv themselves :

node ./tools/generate.js angular-ngrx-store __name__=some-name


I will have to think about this. Maybe I have a indicator (gtf) that lets me know to only run in command line mode. @CGeorges @dennbagas @knona thoughts?

node ./tools/generate.js --gtf=angular-ngrx-store __name__=some-name

@CGeorges I don think if you are using the command line you need to select whats options to generate. The array of items is what you to generate and you would figure that out before passing in to generateTemplateFiles.

Yes, but even if you pass just 1 item in the array, upon running the script it will still ask which item you want to generate, maybe remove the question if it's just 1 item could be the solution?

In the example above for "confirming path" you could set that up yourself before passing to generateTemplateFiles. Example: --outputpath1=./src/here --outputpath2=./src/here

Same as above, I provide a path but still being asked to confirm the path.

I guess for "force overwrite" I could add an optional property on the IConfigItem called forceOverwrite: true and you could supply that with arguments?

the argument forceOverwrite sounds like a great solution.

I will have to think about this. Maybe I have a indicator (gtf) that lets me know to only run in command line mode. @CGeorges @dennbagas @knona thoughts?

Limiting the current argv functionality to just 1 specific indicator would fix the breaking change, I totally love that!

@codeBelt @CGeorges
Only use the "gtf" indicator will not be enough if we add validation.
Indeed, in the new PR, we check that all string replacers are passed as argument in command line.
If you want to use some others arguments in command line, they will be checked and it won't work.

If we don't add validation, it's ok but I think it would be better to have both.

I have some ideas how to implement that.
In all cases, I think we should let the user instantiate the GenerateTemplateFiles class and use the "generate" public method.


My first idea which is easier

The generate method would take as argument the array of command line arguments. Instead of parse all command line arguments we could parse the array. yargs.parse(myArrayOfCommandLineArguments)


My second idea

The generate method would take as argument an object which describe the template to generate and the options.

interface MyParams {
  name: string; // the name of the template to generate
  stringReplacers: IReplacer[]; // the array of string replacers
  outputPath?: string; // the path which override the original path
  overwrite?: boolean; // describe if we should overwrite the files if they exist
}

We could provide to the user a function to parse command line arguments. He is free to use it to parse the arguments from command line and then set the result as argument of the generate method.

Pros:
Really flexible. It allow the user to use the generator as he wants.

Cons:
For basic usages, an ordinary user should set up more things and write a few more lines of code.
We could imagine that we have an other method "generateFromCommandLine" which has no argument and do the parsing.


What do you think about that ?

I like your idea on having another method like generateFromCommandLine.

// Prompt (Current way)
const { generateTemplateFiles } = require('generate-template-files');

// Command Line way
const { generateFromCommandLine } = require('generate-template-files');

This will keep the current keep @CGeorges happy on how he is doing things and having another method will allow us to control them independently.

I few other name idea in no particular order:

  • generateTemplateFilesWithoutPrompts
  • generateTemplateFilesCommandLine
  • generateTemplateFilesCli
  • generateFromCommandLine

Version 2.4.0 has the command line code that breaks existing usages so I have published another version 2.4.1 removing the command line code. Once I have figured out the new way of writing the command line version I will make a 3.0.0 release.

This issue is fixed here #44 . Please review and give any feedback.

@CGeorges @dennbagas @knona