Skip to content

Commit 2bb5f73

Browse files
better CLI usage
1 parent c1e059c commit 2bb5f73

7 files changed

+151
-165
lines changed

index.test.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict'
2+
3+
const { test } = require('ava')
4+
const execa = require('execa')
5+
6+
test('--help', async (t) => {
7+
const { stdout } = await execa('./index.js', [ '--help' ])
8+
t.true(stdout.length > 0)
9+
t.true(/create-react-library/.test(stdout))
10+
})

lib/get-library-defaults.js lib/get-default-library-params.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ const config = require('./config')
99

1010
module.exports = async () => {
1111
const defaults = {
12+
name: '',
13+
description: '',
1214
author: config.get('author'),
13-
manager: config.get('manager', 'npm'),
14-
license: config.get('license', 'MIT')
15+
repo: (info) => `${info.author}/${info.name}`,
16+
license: config.get('license', 'MIT'),
17+
manager: config.get('manager', 'npm')
1518
}
1619

1720
try {
@@ -38,7 +41,7 @@ module.exports = async () => {
3841
defaults.manager = 'yarn'
3942
}
4043

41-
config.set('manager', defaults.manager)
44+
config.set('manager', defaults.manager || 'npm')
4245
}
4346
} catch (err) { }
4447

lib/index.js

+53-24
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,76 @@
11
#!/usr/bin/env node
22
'use strict'
33

4-
const meow = require('meow')
4+
const program = require('commander')
5+
const { version } = require('../package')
56

6-
const getLibraryDefaults = require('./get-library-defaults')
7+
const getDefaultLibraryParams = require('./get-default-library-params')
78
const createLibrary = require('./create-library')
8-
const promptLibraryInfo = require('./prompt-library-info')
9+
const promptLibraryParams = require('./prompt-library-params')
910

1011
module.exports = async () => {
11-
const defaults = await getLibraryDefaults()
12-
const info = await promptLibraryInfo(defaults)
13-
await createLibrary(info)
12+
const defaults = await getDefaultLibraryParams()
1413

15-
return info
16-
}
14+
program
15+
.name('create-react-library')
16+
.version(version)
17+
.usage('[options] [package-name]')
18+
.option('-d, --desc <string>', 'package description')
19+
.option('-a, --author <string>', 'author\'s github handle', defaults.author)
20+
.option('-l, --license <string>', 'package license', defaults.license)
21+
.option('-r, --repo <string>', 'package repo path')
22+
.option('-m, --manager <npm|yarn>', 'package manager to use', /^(npm|yarn)$/, defaults.manager)
23+
.option('-s, --skip-prompts', 'skip all prompts (must provide package-name via cli)')
24+
.parse(process.argv)
1725

18-
meow(`
19-
Usage
20-
$ create-react-library
21-
`)
26+
const opts = {
27+
description: program.desc,
28+
author: program.author,
29+
license: program.license,
30+
repo: program.repo,
31+
manager: program.manager,
32+
skipPrompts: program.skipPrompts
33+
}
2234

23-
module.exports()
24-
.then((info) => {
25-
console.log(`
35+
Object.keys(opts).forEach((key) => {
36+
if (!opts[key] && defaults[key]) {
37+
opts[key] = defaults[key]
38+
}
39+
})
40+
41+
if (program.args.length === 1) {
42+
opts.name = program.args[0]
43+
} else if (program.args.length > 1) {
44+
console.error('invalid arguments')
45+
program.help()
46+
process.exit(1)
47+
}
2648

27-
Your module has been created at ${info.dest}.
49+
const params = await promptLibraryParams(opts)
50+
const lib = await createLibrary(params)
51+
52+
console.log(`
53+
54+
Your module has been created at ${lib.dest}.
2855
2956
To get started, in one tab, run:
30-
$ cd ${info.name} && ${info.manager} start
57+
$ cd ${lib.name} && ${lib.manager} start
3158
3259
And in another tab, run the create-react-app devserver:
33-
$ cd ${info.name}/example && ${info.manager} start
60+
$ cd ${lib.name}/example && ${lib.manager} start
3461
`)
3562

36-
if (info.manager === 'npm') {
37-
console.log(`
63+
if (lib.manager === 'npm') {
64+
console.log(`
3865
39-
Because you're using npm, you'll need to publish a dummy version of ${info.name} first before you can "npm link" your package into the example app.
66+
Because you're using npm, you'll need to publish a dummy version of ${lib.name} first before you can "npm link" your package into the example app.
4067
`)
41-
}
68+
}
4269

43-
process.exit(0)
44-
})
70+
return lib
71+
}
72+
73+
module.exports()
4574
.catch((err) => {
4675
console.error(err)
4776
process.exit(1)

lib/prompt-library-info.js

-56
This file was deleted.

lib/prompt-library-params.js

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
'use strict'
2+
3+
const inquirer = require('inquirer')
4+
const validateNpmName = require('validate-npm-package-name')
5+
6+
const config = require('./config')
7+
8+
module.exports = async (opts) => {
9+
if (opts.name && !validateNpmName(opts.name).validForNewPackages) {
10+
throw new Error(`invalid package name "${opts.name}"`)
11+
}
12+
13+
if (opts.skipPrompts) {
14+
if (!opts.name) {
15+
throw new Error('invalid input; you must pass a package name with --skip-prompts')
16+
}
17+
18+
Object.keys(opts).forEach((key) => {
19+
const value = opts[key]
20+
if (typeof value === 'function') {
21+
opts[key] = value(opts)
22+
}
23+
})
24+
25+
return opts
26+
} else {
27+
const info = await inquirer.prompt([
28+
{
29+
type: 'input',
30+
name: 'name',
31+
message: 'Package Name',
32+
validate: (name) => {
33+
return name && validateNpmName(name).validForNewPackages
34+
},
35+
default: opts.name
36+
},
37+
{
38+
type: 'input',
39+
name: 'description',
40+
message: 'Package Description',
41+
default: opts.description
42+
},
43+
{
44+
type: 'input',
45+
name: 'author',
46+
message: 'Author\'s GitHub Handle',
47+
default: opts.author
48+
},
49+
{
50+
type: 'input',
51+
name: 'repo',
52+
message: 'GitHub Repo Path',
53+
default: opts.repo
54+
},
55+
{
56+
type: 'input',
57+
name: 'license',
58+
message: 'License',
59+
default: opts.license
60+
},
61+
{
62+
type: 'list',
63+
name: 'manager',
64+
message: 'Package Manager',
65+
choices: [ 'npm', 'yarn' ],
66+
default: opts.manager
67+
}
68+
])
69+
70+
config.set('author', info.author)
71+
config.set('license', info.license)
72+
config.set('manager', info.manager)
73+
74+
return info
75+
}
76+
}

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"publish"
2929
],
3030
"dependencies": {
31+
"commander": "^2.15.1",
3132
"conf": "^1.4.0",
3233
"cp-file": "^5.0.0",
3334
"execa": "^0.10.0",
@@ -37,7 +38,6 @@
3738
"handlebars": "^4.0.11",
3839
"inquirer": "^5.2.0",
3940
"make-dir": "^1.2.0",
40-
"meow": "^5.0.0",
4141
"node-compat-require": "^1.0.3",
4242
"ora": "^2.1.0",
4343
"p-each-series": "^1.0.0",

0 commit comments

Comments
 (0)