seng-generator
Advanced tools
Comparing version 0.5.0 to 0.6.0
{ | ||
"name": "seng-generator", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"description": "A CLI generator to create code based on templates", | ||
@@ -44,2 +44,3 @@ "preferGlobal": true, | ||
"istextorbinary": "^2.1.0", | ||
"lodash": "^4.17.4", | ||
"metalsmith": "^2.3.0", | ||
@@ -46,0 +47,0 @@ "open": "0.0.5", |
@@ -41,3 +41,3 @@ # seng generator | ||
**available variables:** | ||
**default available variables:** | ||
@@ -52,2 +52,68 @@ * ```name```: Name in it's original format | ||
#### Custom Variables | ||
Seng-generator also supports custom variables. Custom variables can be used to create more complex templates, because | ||
you can use all the [handlebars features](http://handlebarsjs.com/) like conditional statements and | ||
loops. | ||
The variables should be declared in the `.senggenerator` file in the root of the specific template folder in an array | ||
called `variables`. | ||
Example `.senggenerator` file with a custom variable: | ||
```json | ||
{ | ||
"destination": "./src/common/components", | ||
"variables": [{ | ||
"name": "debug", | ||
"type": "confirm", | ||
"message": "Do you want to add debug logs?", | ||
"isBoolean": true, | ||
"default": false | ||
}] | ||
} | ||
``` | ||
The options of a variable reflect the [inquirer options](https://github.com/SBoudrias/Inquirer.js#question) | ||
with a few additions. The options are declared as json so javascript functions can't be used. | ||
Extra options: | ||
* ```isArray```: (boolean) Whether input should be converted to an array. The input should be a comma seperated list | ||
```value1,value2,value3```. | ||
* ```isNumber```: (boolean) Whether input should be converted to a number. | ||
* ```isBoolean```: (boolean) Whether input should be converted to a boolean. | ||
It's possible to combine the ```isArray``` with ```isNumber``` or ```isBoolean```. | ||
Once they are declared you can use them in your templates: | ||
```handlebars | ||
{{#if debug}} | ||
console.log('{{name_pc}}', props); | ||
{{/if}} | ||
{{#if names}} | ||
<ul> | ||
{{#each names}} | ||
<li>{{this}}</li> | ||
{{/each}} | ||
</ul> | ||
{{/if}} | ||
{{functionName}} | ||
``` | ||
Once the template is ready for use with seng-generator there are a few ways to set the custom variables: | ||
* `sg wizard`: The questions from the variable config will be added to the default wizard questions. The wizard | ||
allows spaces. | ||
* `sg <type> <name> -w`: Will show a wizard just for the custom variables defined in the config. The wizard also allows | ||
spaces. | ||
* `sg <type> <name> -v variable1=true,variable2=showMessage,variable3=[name1,name2,name3]`: This is the fastest way | ||
to set custom variables. It has one downside and that is that it doesn't allow spaces. So if you need spaces use the | ||
wizard. If a variable has a default value in the variable config you can also skip it. If you skip a variable that | ||
doesn't have a default value a warning will be displayed. Always use brackets when declaring an array. | ||
The variable settings per template can be displayed by running `sg settings`. | ||
## Settings | ||
@@ -93,2 +159,7 @@ | ||
Options: | ||
* ```-f, --force```: Force creation. By default it's impossible override files when they already exist in the | ||
destination path. This option forces the creation of code and will override files if necessary. | ||
Examples: | ||
@@ -127,3 +198,9 @@ ```console | ||
* ```-s, --sub-directory <subdirectory>```: Set subdirectory. This path is added to the destination path. | ||
* ```-f, --force```: Force creation. By default it's impossible to create code if the destination path doesn't exist. This option forces the creation of code and will generates the destination folders if they don't exist. | ||
* ```-f, --force```: Force creation. By default it's impossible to create code if the destination path doesn't exist | ||
or when the files already exists in the destination path. This option forces the creation of code and will generates the destination folders if they don't exist. | ||
* ```-v, --variables```: Set custom variables the quick way. The custom variables should be declared in the template | ||
.senggenerator file. Variables should be comma separated and it's impossible to use spaces (use `sg wizard` or `-w` if you | ||
need spaces). It's also possible to use arrays they should be declared as a comma separated list surrounded by brackets. `-v | ||
variable1=true,variable2=[car,house,snow]` | ||
* ```-w, --wizard```: Use wizard to input custom variables. | ||
@@ -140,3 +217,4 @@ Examples: | ||
Set or display settings. Without any options it will show the settings. By default it will set the settings locally in a .senggenerator file. | ||
You can also set global settings by using the global option. | ||
You can also set global settings by using the global option. It also displays the custom variable settings so you can | ||
see which variables can be used in every template. | ||
@@ -143,0 +221,0 @@ ```console |
@@ -12,2 +12,3 @@ const path = require('path'); | ||
const isTextOrBinary = require('istextorbinary'); | ||
const _ = require('lodash'); | ||
@@ -19,3 +20,3 @@ module.exports = function generate(type, options, settings) { | ||
if(!templatePath) { | ||
if (!templatePath) { | ||
console.error(chalk.red(`Template folder that contains template ${type} doesn't exist`)); | ||
@@ -36,3 +37,3 @@ return Promise.reject(); | ||
metalsmith(fullTemplatePath) | ||
.metadata(Object.assign({}, getNames(options.name))) | ||
.metadata(getVariables(type, options, settings)) | ||
.source('.') | ||
@@ -44,11 +45,12 @@ .destination(path.resolve(options.destination)) | ||
.use(renderTemplates) | ||
.build(function (err) { | ||
.use(!options.force ? checkExists : (files, metalsmith, done) => done()) | ||
.build((err) => { | ||
if (err) { | ||
console.error(chalk.red(err)); | ||
reject(); | ||
} | ||
else { | ||
} else { | ||
resolve(); | ||
} | ||
}); | ||
}).catch((error) => { | ||
}); | ||
@@ -58,3 +60,2 @@ }; | ||
function getNames(name) { | ||
return { | ||
@@ -108,3 +109,3 @@ name, | ||
function run(file, done) { | ||
if(isTextOrBinary.isBinarySync(path.basename(file), files[file].contents)) { | ||
if (isTextOrBinary.isBinarySync(path.basename(file), files[file].contents)) { | ||
done(); | ||
@@ -124,5 +125,26 @@ return; | ||
function checkExists(files, metalsmith, done) { | ||
const keys = Object.keys(files); | ||
const destination = metalsmith.destination(); | ||
let fileExists = null; | ||
keys.forEach((key) => { | ||
const filePath = path.join(destination, key); | ||
if (pathExists(filePath)) { | ||
fileExists = filePath; | ||
} | ||
}); | ||
if (fileExists) { | ||
done(`${fileExists} already exists. Use force (-f) if you want to override the existing file.`); | ||
} else { | ||
done(); | ||
} | ||
} | ||
function replaceVars(value, object) { | ||
return value.replace(/\$?\{([@#$%&\w\.]*)(\((.*?)\))?\}/gi, (match, name) => { | ||
const props = name.split("."); | ||
const props = name.split('.'); | ||
const prop = props.shift(); | ||
@@ -138,1 +160,54 @@ let o = object; | ||
function getVariables(type, options, settings) { | ||
let userVariables = options.variables || {}; | ||
let variables = {}; | ||
let variableSettings = {}; | ||
if (settings.templates[type]) { | ||
variableSettings = (settings.templates[type].variables || []).reduce((result, variable) => { | ||
result[variable.name] = variable; | ||
return result; | ||
}, {}); | ||
variables = (settings.templates[type].variables || []).reduce((result, variable) => { | ||
if (typeof variable.default === 'undefined' && typeof userVariables[variable.name] === 'undefined') { | ||
console.log(chalk.yellow(`Warning: custom variable '${variable.name}' is not supplied and has no default value`)); | ||
console.log(); | ||
} | ||
result[variable.name] = variable.default || ''; | ||
return result; | ||
}, {}); | ||
} | ||
userVariables = Object.keys(userVariables).reduce((result, key) => { | ||
let value = userVariables[key]; | ||
if (variableSettings[key]) { | ||
if (variableSettings[key].isArray) { | ||
value = value.split(','); | ||
value = value.map((item) => item.trim()); | ||
if (variableSettings[key].isBoolean) { | ||
value = value.map((item) => item == 'true' || item == 1); | ||
} else if (variableSettings[key].isNumber) { | ||
value = value.map((item) => parseFloat(item)); | ||
} | ||
} else if (variableSettings[key].isBoolean) { | ||
value = value == 'true' || value == 1; | ||
} else if (variableSettings[key].isNumber) { | ||
value = parseFloat(value); | ||
} | ||
} else { | ||
console.log(chalk.yellow(`Warning: variable '${key}' is not declared in the template .senggenerator file`)); | ||
console.log(); | ||
} | ||
result[key] = value; | ||
return result; | ||
}, {}); | ||
return _.merge(variables, userVariables, getNames(options.name)); | ||
} | ||
@@ -7,2 +7,3 @@ const settingsFile = '.senggenerator'; | ||
const chalk = require('chalk'); | ||
const _ = require('lodash'); | ||
@@ -59,2 +60,10 @@ const defaultSettings = { | ||
if (settings.variables) { | ||
const defaultVariable = { | ||
type: 'input' | ||
}; | ||
settings.variables = settings.variables.map((variable) => _.merge({}, defaultVariable, variable)); | ||
} | ||
return settings; | ||
@@ -61,0 +70,0 @@ } |
@@ -6,4 +6,5 @@ const Settings = require('./settings'); | ||
const chalk = require('chalk'); | ||
const _ = require('lodash'); | ||
module.exports = function wizard(type, name) { | ||
module.exports = function wizard(type, name, force) { | ||
let settingOverrides = {}; | ||
@@ -16,3 +17,16 @@ | ||
inquirer.prompt(questions).then((answers) => { | ||
generate(answers.type || type, answers, settings).then(()=> { | ||
let templateSettings = Settings.getTemplateSettings(settings.templatePath)[answers.type || type]; | ||
if (templateSettings.variables) { | ||
return inquirer.prompt(templateSettings.variables).then((variables) => { | ||
answers.variables = variables; | ||
return answers; | ||
}); | ||
} | ||
return answers; | ||
}).then((options) => { | ||
options = _.merge(options, { force: force }); | ||
return generate(options.type || type, options, settings).then(() => { | ||
console.log(); | ||
@@ -19,0 +33,0 @@ console.log(chalk.green('Done!')); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
29896
406
241
17
+ Addedlodash@^4.17.4