Skip to content

Commit 0cff2b4

Browse files
authoredOct 29, 2020
Prefer local install (#572)
1 parent b519201 commit 0cff2b4

File tree

4 files changed

+160
-142
lines changed

4 files changed

+160
-142
lines changed
 

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"github-url-from-git": "^1.5.0",
4343
"has-yarn": "^2.1.0",
4444
"hosted-git-info": "^3.0.0",
45+
"import-local": "^3.0.2",
4546
"inquirer": "^7.0.0",
4647
"is-installed-globally": "^0.3.1",
4748
"is-scoped": "^2.1.0",

‎readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Run `np` without arguments to launch the interactive UI that guides you through
8080

8181
## Config
8282

83-
`np` can be configured both locally and globally. When using the global `np` binary, you can configure any of the CLI flags in either a `.np-config.js` or `.np-config.json` file in the home directory. When using the local `np` binary, for example, in a `npm run` script, you can configure `np` by setting the flags in either a top-level `np` field in `package.json` or in a `.np-config.js` or `.np-config.json` file in the project directory.
83+
`np` can be configured both locally and globally. When using the global `np` binary, you can configure any of the CLI flags in either a `.np-config.js` or `.np-config.json` file in the home directory. When using the local `np` binary, for example, in a `npm run` script, you can configure `np` by setting the flags in either a top-level `np` field in `package.json` or in a `.np-config.js` or `.np-config.json` file in the project directory. If it exists, the local installation will always take precedence. This ensures any local config matches the version of `np` it was designed for.
8484

8585
Currently, these are the flags you can configure:
8686

‎source/cli-implementation.js

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#!/usr/bin/env node
2+
'use strict';
3+
// eslint-disable-next-line import/no-unassigned-import
4+
require('symbol-observable'); // Important: This needs to be first to prevent weird Observable incompatibilities
5+
const logSymbols = require('log-symbols');
6+
const meow = require('meow');
7+
const updateNotifier = require('update-notifier');
8+
const hasYarn = require('has-yarn');
9+
const config = require('./config');
10+
const {isPackageNameAvailable} = require('./npm/util');
11+
const version = require('./version');
12+
const util = require('./util');
13+
const ui = require('./ui');
14+
const np = require('.');
15+
16+
const cli = meow(`
17+
Usage
18+
$ np <version>
19+
20+
Version can be:
21+
${version.SEMVER_INCREMENTS.join(' | ')} | 1.2.3
22+
23+
Options
24+
--any-branch Allow publishing from any branch
25+
--branch Name of the release branch (default: master)
26+
--no-cleanup Skips cleanup of node_modules
27+
--no-tests Skips tests
28+
--yolo Skips cleanup and testing
29+
--no-publish Skips publishing
30+
--preview Show tasks without actually executing them
31+
--tag Publish under a given dist-tag
32+
--no-yarn Don't use Yarn
33+
--contents Subdirectory to publish
34+
--no-release-draft Skips opening a GitHub release draft
35+
--test-script Name of npm run script to run tests before publishing (default: test)
36+
--no-2fa Don't enable 2FA on new packages (not recommended)
37+
38+
Examples
39+
$ np
40+
$ np patch
41+
$ np 1.0.2
42+
$ np 1.0.2-beta.3 --tag=beta
43+
$ np 1.0.2-beta.3 --tag=beta --contents=dist
44+
`, {
45+
booleanDefault: undefined,
46+
flags: {
47+
anyBranch: {
48+
type: 'boolean'
49+
},
50+
branch: {
51+
type: 'string'
52+
},
53+
cleanup: {
54+
type: 'boolean'
55+
},
56+
tests: {
57+
type: 'boolean'
58+
},
59+
yolo: {
60+
type: 'boolean'
61+
},
62+
publish: {
63+
type: 'boolean'
64+
},
65+
releaseDraft: {
66+
type: 'boolean'
67+
},
68+
tag: {
69+
type: 'string'
70+
},
71+
yarn: {
72+
type: 'boolean'
73+
},
74+
contents: {
75+
type: 'string'
76+
},
77+
preview: {
78+
type: 'boolean'
79+
},
80+
testScript: {
81+
type: 'string'
82+
},
83+
'2fa': {
84+
type: 'boolean'
85+
}
86+
}
87+
});
88+
89+
updateNotifier({pkg: cli.pkg}).notify();
90+
91+
(async () => {
92+
const pkg = util.readPkg();
93+
94+
const defaultFlags = {
95+
cleanup: true,
96+
tests: true,
97+
publish: true,
98+
releaseDraft: true,
99+
yarn: hasYarn(),
100+
'2fa': true
101+
};
102+
103+
const localConfig = await config();
104+
105+
const flags = {
106+
...defaultFlags,
107+
...localConfig,
108+
...cli.flags
109+
};
110+
111+
// Workaround for unintended auto-casing behavior from `meow`.
112+
if ('2Fa' in flags) {
113+
flags['2fa'] = flags['2Fa'];
114+
}
115+
116+
const runPublish = flags.publish && !pkg.private;
117+
118+
const availability = flags.publish ? await isPackageNameAvailable(pkg) : {
119+
isAvailable: false,
120+
isUnknown: false
121+
};
122+
123+
const version = cli.input.length > 0 ? cli.input[0] : false;
124+
125+
const options = await ui({
126+
...flags,
127+
availability,
128+
version,
129+
runPublish
130+
}, pkg);
131+
132+
if (!options.confirm) {
133+
process.exit(0);
134+
}
135+
136+
console.log(); // Prints a newline for readability
137+
const newPkg = await np(options.version, options);
138+
139+
if (options.preview) {
140+
return;
141+
}
142+
143+
console.log(`\n ${newPkg.name} ${newPkg.version} published 🎉`);
144+
})().catch(error => {
145+
console.error(`\n${logSymbols.error} ${error.message}`);
146+
process.exit(1);
147+
});

‎source/cli.js

+11-141
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,17 @@
11
#!/usr/bin/env node
22
'use strict';
3-
// eslint-disable-next-line import/no-unassigned-import
4-
require('symbol-observable'); // Important: This needs to be first to prevent weird Observable incompatibilities
5-
const logSymbols = require('log-symbols');
6-
const meow = require('meow');
7-
const updateNotifier = require('update-notifier');
8-
const hasYarn = require('has-yarn');
9-
const config = require('./config');
10-
const {isPackageNameAvailable} = require('./npm/util');
11-
const version = require('./version');
12-
const util = require('./util');
13-
const ui = require('./ui');
14-
const np = require('.');
3+
const util = require('util');
4+
const importLocal = require('import-local');
5+
const isInstalledGlobally = require('is-installed-globally');
156

16-
const cli = meow(`
17-
Usage
18-
$ np <version>
7+
const debuglog = util.debuglog('np');
198

20-
Version can be:
21-
${version.SEMVER_INCREMENTS.join(' | ')} | 1.2.3
22-
23-
Options
24-
--any-branch Allow publishing from any branch
25-
--branch Name of the release branch (default: master)
26-
--no-cleanup Skips cleanup of node_modules
27-
--no-tests Skips tests
28-
--yolo Skips cleanup and testing
29-
--no-publish Skips publishing
30-
--preview Show tasks without actually executing them
31-
--tag Publish under a given dist-tag
32-
--no-yarn Don't use Yarn
33-
--contents Subdirectory to publish
34-
--no-release-draft Skips opening a GitHub release draft
35-
--test-script Name of npm run script to run tests before publishing (default: test)
36-
--no-2fa Don't enable 2FA on new packages (not recommended)
37-
38-
Examples
39-
$ np
40-
$ np patch
41-
$ np 1.0.2
42-
$ np 1.0.2-beta.3 --tag=beta
43-
$ np 1.0.2-beta.3 --tag=beta --contents=dist
44-
`, {
45-
booleanDefault: undefined,
46-
flags: {
47-
anyBranch: {
48-
type: 'boolean'
49-
},
50-
branch: {
51-
type: 'string'
52-
},
53-
cleanup: {
54-
type: 'boolean'
55-
},
56-
tests: {
57-
type: 'boolean'
58-
},
59-
yolo: {
60-
type: 'boolean'
61-
},
62-
publish: {
63-
type: 'boolean'
64-
},
65-
releaseDraft: {
66-
type: 'boolean'
67-
},
68-
tag: {
69-
type: 'string'
70-
},
71-
yarn: {
72-
type: 'boolean'
73-
},
74-
contents: {
75-
type: 'string'
76-
},
77-
preview: {
78-
type: 'boolean'
79-
},
80-
testScript: {
81-
type: 'string'
82-
},
83-
'2fa': {
84-
type: 'boolean'
85-
}
86-
}
87-
});
88-
89-
updateNotifier({pkg: cli.pkg}).notify();
90-
91-
(async () => {
92-
const pkg = util.readPkg();
93-
94-
const defaultFlags = {
95-
cleanup: true,
96-
tests: true,
97-
publish: true,
98-
releaseDraft: true,
99-
yarn: hasYarn(),
100-
'2fa': true
101-
};
102-
103-
const localConfig = await config();
104-
105-
const flags = {
106-
...defaultFlags,
107-
...localConfig,
108-
...cli.flags
109-
};
110-
111-
// Workaround for unintended auto-casing behavior from `meow`.
112-
if ('2Fa' in flags) {
113-
flags['2fa'] = flags['2Fa'];
114-
}
115-
116-
const runPublish = flags.publish && !pkg.private;
117-
118-
const availability = flags.publish ? await isPackageNameAvailable(pkg) : {
119-
isAvailable: false,
120-
isUnknown: false
121-
};
122-
123-
const version = cli.input.length > 0 ? cli.input[0] : false;
124-
125-
const options = await ui({
126-
...flags,
127-
availability,
128-
version,
129-
runPublish
130-
}, pkg);
131-
132-
if (!options.confirm) {
133-
process.exit(0);
134-
}
135-
136-
console.log(); // Prints a newline for readability
137-
const newPkg = await np(options.version, options);
138-
139-
if (options.preview) {
140-
return;
9+
// Prefer the local installation
10+
if (!importLocal(__filename)) {
11+
if (isInstalledGlobally) {
12+
debuglog('Using global install of np.');
14113
}
14214

143-
console.log(`\n ${newPkg.name} ${newPkg.version} published 🎉`);
144-
})().catch(error => {
145-
console.error(`\n${logSymbols.error} ${error.message}`);
146-
process.exit(1);
147-
});
15+
// eslint-disable-next-line import/no-unassigned-import
16+
require('./cli-implementation');
17+
}

0 commit comments

Comments
 (0)
Please sign in to comment.