Skip to content

Commit 008a836

Browse files
jdaltonzkat
authored andcommitted
init: use npx for extended initializers (#20303)
PR-URL: npm/npm#20303 Credit: @jdalton Reviewed-By: @zkat
1 parent ad7a596 commit 008a836

File tree

4 files changed

+111
-11
lines changed

4 files changed

+111
-11
lines changed

doc/cli/npm-init.md

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,38 @@ npm-init(1) -- Interactively create a package.json file
33

44
## SYNOPSIS
55

6-
npm init [-f|--force|-y|--yes]
6+
npm init [--force|-f|--yes|-y]
7+
npm init <@scope> (same as `npx <@scope>/create`)
8+
npm init [<@scope>/]<pkg> (same as `npx [<@scope>/]create-<pkg>`)
79

810
## DESCRIPTION
911

10-
This will ask you a bunch of questions, and then write a package.json for you.
12+
* `npm init [--force|-f|--yes|-y]`:
1113

12-
It attempts to make reasonable guesses about what you want things to be set to,
13-
and then writes a package.json file with the options you've selected.
14+
This will ask you a bunch of questions, and then write a package.json for
15+
you.
1416

15-
If you already have a package.json file, it'll read that first, and default to
16-
the options in there.
17+
It attempts to make reasonable guesses about what you want things to be set
18+
to, and then writes a package.json file with the options you've selected.
1719

18-
It is strictly additive, so it does not delete options from your package.json
19-
without a really good reason to do so.
20+
If you already have a package.json file, it'll read that first, and default
21+
to the options in there.
2022

21-
If you invoke it with `-f`, `--force`, `-y`, or `--yes`, it will use only
22-
defaults and not prompt you for any options.
23+
It is strictly additive, so it does not delete options from your
24+
package.json without a really good reason to do so.
25+
26+
If you invoke it with `--force`, `-f`, `--yes`, or `-y`, it will use only
27+
defaults and not prompt you for any options.
28+
29+
* `npm init <@scope>` (same as `npx <@scope>/create`):
30+
31+
Run `<@scope>/create` as the package initializer instead of
32+
[`npm-init`](https://www.npmjs.com/package/init-package-json).
33+
34+
* `npm init [<@scope>/]<pkg>` (same as `npx [<@scope>/]create-<pkg>`):
35+
36+
Run `[<@scope>/]create-<pkg>` as the package initializer instead of
37+
[`npm-init`](https://www.npmjs.com/package/init-package-json).
2338

2439
## CONFIGURATION
2540

lib/config/cmd-list.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var shorthands = {
44
'rb': 'rebuild',
55
'list': 'ls',
66
'ln': 'link',
7+
'create': 'init',
78
'i': 'install',
89
'it': 'install-test',
910
'cit': 'install-ci-test',
@@ -24,6 +25,7 @@ var affordances = {
2425
'll': 'ls',
2526
'verison': 'version',
2627
'ic': 'ci',
28+
'innit': 'init',
2729
'isntall': 'install',
2830
'dist-tags': 'dist-tag',
2931
'apihelp': 'help',

lib/init.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,37 @@
22

33
module.exports = init
44

5+
var path = require('path')
56
var log = require('npmlog')
67
var npm = require('./npm.js')
8+
var npx = require('libnpx')
79
var initJson = require('init-package-json')
810
var output = require('./utils/output.js')
911
var noProgressTillDone = require('./utils/no-progress-while-running').tillDone
12+
var usage = require('./utils/usage')
1013

11-
init.usage = 'npm init [--force|-f|--yes|-y]'
14+
init.usage = usage(
15+
'init',
16+
'\nnpm init [--force|-f|--yes|-y]' +
17+
'\nnpm init <@scope> (same as `npx <@scope>/create`)' +
18+
'\nnpm init [<@scope>/]<pkg> (same as `npx [<@scope>/]create-<pkg>`)'
19+
)
1220

1321
function init (args, cb) {
22+
if (args.length) {
23+
var NPM_PATH = path.resolve(__dirname, '../bin/npm-cli.js')
24+
var initerName = args[0]
25+
var packageName = /^@[^/]+$/.test(initerName)
26+
? initerName + '/create'
27+
: initerName.replace(/^(@[^/]+\/)?/, '$1create-')
28+
29+
var npxArgs = [process.argv0, '[fake arg]', '--always-spawn', packageName, ...process.argv.slice(4)]
30+
var parsed = npx.parseArgs(npxArgs, NPM_PATH)
31+
32+
return npx(parsed)
33+
.then(() => cb())
34+
.catch(cb)
35+
}
1436
var dir = process.cwd()
1537
log.pause()
1638
var initFile = npm.config.get('init-module')

test/tap/init-create.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* eslint-disable standard/no-callback-literal */
2+
var test = require('tap').test
3+
var requireInject = require('require-inject')
4+
5+
var npm = require('../../lib/npm.js')
6+
7+
test('npm init <pkg-name>', function (t) {
8+
var initJsonMock = function () {
9+
t.ok(false, 'should not run initJson()')
10+
}
11+
initJsonMock.yes = function () {
12+
t.ok(false, 'should not run initJson.yes()')
13+
return false
14+
}
15+
var libnpxMock = function () {
16+
return Promise.resolve()
17+
}
18+
libnpxMock.parseArgs = function (argv, defaultNpm) {
19+
t.ok(argv[0].includes('node'), 'node is the first arg')
20+
t.equals(argv[2], '--always-spawn', 'set npx opts.alwaysSpawn')
21+
t.equals(argv[3], 'create-pkg-name', 'expands pkg-name')
22+
t.ok(defaultNpm.endsWith('npm-cli.js'), 'passes npx bin path')
23+
}
24+
25+
npm.load({ loglevel: 'silent' }, function () {
26+
var init = requireInject('../../lib/init', {
27+
'init-package-json': initJsonMock,
28+
'libnpx': libnpxMock
29+
})
30+
31+
init(['pkg-name'], function () {})
32+
33+
t.end()
34+
})
35+
})
36+
37+
test('npm init with scoped packages', function (t) {
38+
var libnpxMock = function () {
39+
return Promise.resolve()
40+
}
41+
42+
npm.load({ loglevel: 'silent' }, function () {
43+
var init = requireInject('../../lib/init', {
44+
'libnpx': libnpxMock
45+
})
46+
47+
libnpxMock.parseArgs = function (argv) {
48+
t.equals(argv[3], '@scope/create', 'expands @scope')
49+
}
50+
51+
init(['@scope'], function () {})
52+
53+
libnpxMock.parseArgs = function (argv) {
54+
t.equals(argv[3], '@scope/create-pkg-name', 'expands @scope/pkg-name')
55+
}
56+
57+
init(['@scope/pkg-name'], function () {})
58+
59+
t.end()
60+
})
61+
})

0 commit comments

Comments
 (0)