Skip to content

Commit 8be411b

Browse files
authored
Template CLI (#2)
1 parent 0b0d5df commit 8be411b

21 files changed

+529
-2
lines changed

.storybook/config.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { addParameters, configure, setAddon } from '@storybook/react'
22
import { configureViewport, INITIAL_VIEWPORTS } from '@storybook/addon-viewport'
3-
import { withBackgrounds } from '@storybook/addon-backgrounds'
43
import JSXAddon from 'storybook-addon-jsx'
54
import '@storybook/addon-console'
65

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
1515
- ESLint and prettier setup
1616
- babel setup
1717
- styled-components setup
18+
- templating cli (thx to commander, shelljs and inquirer)

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ storybook.
1919
integration
2020
- [jest](https://github.com/facebook/jest) 🃏 and [enzyme](https://github.com/airbnb/enzyme)
2121
for testing
22+
- [built-in cli]: create new component packages within seconds (`yarn commander --help`)
2223

2324
## Getting started
2425

package.json

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"bootstrap": "lerna bootstrap",
1515
"build": "lerna run build --stream --parallel",
1616
"build-storybook": "build-storybook -c .storybook -o dist/storybook",
17+
"commander": "node ./scripts/commander",
1718
"clean": "lerna clean",
1819
"clean-dist": "lerna run prebuild --stream --parallel",
1920
"lint": "yarn lint-css && yarn lint-js && yarn lint-md",
@@ -81,6 +82,8 @@
8182
"babel-jest": "^24.3.1",
8283
"babel-loader": "^8.0.5",
8384
"babel-plugin-styled-components": "^1.10.0",
85+
"chalk": "^2.4.2",
86+
"commander": "^2.19.0",
8487
"enzyme": "^3.9.0",
8588
"enzyme-adapter-react-16": "^1.10.0",
8689
"enzyme-to-json": "^3.3.5",
@@ -93,6 +96,7 @@
9396
"eslint-plugin-prettier": "^3.0.1",
9497
"eslint-plugin-react": "^7.12.4",
9598
"husky": "^1.3.1",
99+
"inquirer": "^6.2.2",
96100
"jest": "^24.3.1",
97101
"jest-environment-jsdom": "^24.3.1",
98102
"jest-environment-jsdom-global": "^1.1.1",
@@ -105,6 +109,7 @@
105109
"remark-lint": "^6.0.4",
106110
"remark-preset-lint-recommended": "^3.0.2",
107111
"rimraf": "^2.6.3",
112+
"shelljs": "^0.8.3",
108113
"storybook-addon-jsx": "^6.0.0",
109114
"storybook-readme": "^4.0.5",
110115
"stylelint": "^9.10.1",

scripts/commander.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env node
2+
/* eslint-disable import/no-extraneous-dependencies */
3+
/**
4+
* Docs
5+
* - https://www.npmjs.com/package/commander
6+
*
7+
* Inspired by
8+
* - https://github.com/sitepoint-editors/node-scaffolding-tool/blob/master/lib/create.js
9+
* - https://www.sitepoint.com/scaffolding-tool-caporal-js/
10+
*
11+
* Alternative to commander
12+
* - https://github.com/mattallty/Caporal.js
13+
*
14+
* Prompt Handler
15+
* - https://www.npmjs.com/package/inquirer
16+
*/
17+
const program = require('commander')
18+
19+
const pkg = require('../package.json')
20+
21+
const create = require('./create')
22+
23+
program
24+
.version(pkg.version)
25+
.command('create')
26+
.description('create new package from template')
27+
.action(create)
28+
.parse(process.argv)
29+
30+
if (!process.argv.slice(2).length) {
31+
program.outputHelp()
32+
}
33+
34+
// do this at the end of the file
35+
program.parse(process.argv)

scripts/create.js

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/* eslint-disable import/no-extraneous-dependencies */
2+
const fs = require('fs')
3+
const path = require('path')
4+
5+
const chalk = require('chalk')
6+
const inquirer = require('inquirer')
7+
const shell = require('shelljs')
8+
9+
const logger = {
10+
log: msg => console.log(msg), // eslint-disable-line no-console
11+
success: msg => console.log(chalk.green(msg)), // eslint-disable-line no-console
12+
}
13+
14+
const templateBase = path.resolve(__dirname, '../templates')
15+
16+
module.exports = () => {
17+
// ask for the user's input
18+
logger.log('Please fill the following values…')
19+
20+
// scan the templates folder for variants
21+
inquirer
22+
.prompt([
23+
{
24+
type: 'list',
25+
name: 'template',
26+
message: 'Which template do you want to use',
27+
choices: shell.ls(templateBase),
28+
},
29+
])
30+
.then(({ template }) => {
31+
const templatePath = `${templateBase}/${template}`
32+
33+
// prompt variables
34+
const variables = require(`${templatePath}/_variables`) // eslint-disable-line
35+
36+
inquirer.prompt(variables).then(answers => {
37+
const { name } = answers
38+
const targetPath = path.resolve(__dirname, `../packages/${name}/`)
39+
40+
// Remove Apache-2.0 licence file if another is selected
41+
if (answers.licence !== 'Apache-2.0') {
42+
shell.rm(`${templatePath}/LICENCE`)
43+
}
44+
45+
// copy template
46+
if (fs.existsSync(templatePath)) {
47+
logger.log('Copying files…')
48+
shell.mkdir('-p', targetPath)
49+
shell.cp('-R', `${templatePath}/*`, targetPath)
50+
logger.success('✔ The files have been copied!')
51+
}
52+
53+
// Remove variables file from the target directory
54+
if (fs.existsSync(`${targetPath}/_variables.js`)) {
55+
shell.rm(`${targetPath}/_variables.js`)
56+
}
57+
58+
// Replace variable values in all files
59+
shell.ls('-Rl', targetPath).forEach(entry => {
60+
if (entry.isFile()) {
61+
// Replace '[VARIABLE]` with the corresponding variable value from the prompt
62+
variables.forEach(variable => {
63+
shell.sed(
64+
'-i',
65+
`\\[${variable.name.toUpperCase()}\\]`,
66+
answers[variable.name],
67+
`${targetPath}/${entry.name}`,
68+
)
69+
})
70+
71+
// Insert current year in files
72+
shell.sed(
73+
'-i',
74+
'\\[YEAR\\]',
75+
new Date().getFullYear(),
76+
`${targetPath}/${entry.name}`,
77+
)
78+
}
79+
})
80+
81+
logger.log(chalk.green('✔ Success!'))
82+
})
83+
})
84+
}

templates/component/.eslintrc.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const rules = require('../../.eslintrc.js')
2+
3+
module.exports = rules

templates/component/.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
dist
3+
node_modules
4+
*.log
5+
tmp

templates/component/.stylelintrc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": [
3+
"../../.stylelintrc"
4+
]
5+
}

0 commit comments

Comments
 (0)