Skip to content

Commit

Permalink
feat: upgrade npm-package-arg to v8 (#344)
Browse files Browse the repository at this point in the history
* feat: upgrade npm-package-arg to v8

Co-authored-by: 天玎 <tianding.wk@antgroup.com>
  • Loading branch information
gemwuu and 天玎 authored Jun 30, 2021
1 parent babe0b5 commit 6cc5548
Show file tree
Hide file tree
Showing 18 changed files with 116 additions and 93 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ env:
- CC=clang CXX=clang++ npm_config_clang=1 npm_registry=https://registry.npmjs.org
language: node_js
node_js:
- '13'
- '14'
- '12'
- '10'
- '8'
before_script:
- echo -e "Host *\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
script:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ Usage:
npmuninstall <pkg>
npmuninstall <pkg>@<version>
npmuninstall <pkg>@<version> [<pkg>@<version>]
npminstall <alias>@npm:<name>
```

#### npmlink
Expand Down Expand Up @@ -162,6 +163,7 @@ const npminstall = require('npminstall');
- [x] support `ignore-scripts`
- [x] uninstall
- [x] resolutions
- [x] [npm alias](https://github.com/npm/rfcs/blob/latest/implemented/0001-package-aliases.md)

## Different with NPM

Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ environment:
npm_registry: https://registry.npmjs.org

matrix:
- nodejs_version: "8"
- nodejs_version: "10"
- nodejs_version: "12"
- nodejs_version: "14"

# Install scripts. (runs after repo cloning)
install:
Expand Down
10 changes: 7 additions & 3 deletions bin/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const utils = require('../lib/utils');
const globalConfig = require('../lib/config');
const installLocal = require('..').installLocal;
const installGlobal = require('..').installGlobal;
const {
LOCAL_TYPES,
REMOTE_TYPES,
} = require('../lib/npa_types');

const orignalArgv = process.argv.slice(2);
const argv = parseArgs(orignalArgv, {
Expand Down Expand Up @@ -139,7 +143,7 @@ if (process.env.NPMINSTALL_BY_UPDATE) {
}

for (const name of argv._) {
const p = npa(String(name));
const p = npa(String(name), argv.root);
pkgs.push({ name: p.name, version: p.rawSpec, type: p.type });
}

Expand Down Expand Up @@ -433,14 +437,14 @@ async function updateDependencies(root, pkgs, propName, saveExact, remoteNames)
const pkg = await utils.readJSON(pkgFile);
const deps = pkg[propName] = pkg[propName] || {};
for (const item of pkgs) {
if ([ 'remote', 'hosted', 'git' ].indexOf(item.type) >= 0) {
if (REMOTE_TYPES.includes(item.type)) {
// if install from remote or git and don't specified name
// get package's name from `remoteNames`
item.name
? deps[item.name] = item.version
: deps[remoteNames[item.version]] = item.version;
} else {
const pkgDir = item.type === 'local' ? item.version : path.join(root, 'node_modules', item.name);
const pkgDir = LOCAL_TYPES.includes(item.type) ? item.version : path.join(root, 'node_modules', item.name);
const itemPkg = await utils.readJSON(path.join(pkgDir, 'package.json'));
deps[itemPkg.name] = `${savePrefix}${itemPkg.version}`;
}
Expand Down
5 changes: 3 additions & 2 deletions bin/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const fs = require('mz/fs');
const parseArgs = require('minimist');
const utils = require('../lib/utils');
const bin = require('../lib/bin');
const { REGISTRY_TYPES } = require('../lib/npa_types');

const orignalArgv = process.argv.slice(2);
const argv = parseArgs(orignalArgv, {
Expand Down Expand Up @@ -105,7 +106,7 @@ const folders = argv._.map(name => utils.formatPath(name));
let pkg;
debug('link %s', folder);
// try to parse it as a package, if it is a path(./module/path), pkgInfo.name will be null
const pkgInfo = npa(folder);
const pkgInfo = npa(folder, root);
if (pkgInfo.name) {
debug('link source %s is a npm module', folder);
folder = path.join(globalModuleDir, pkgInfo.name);
Expand All @@ -118,7 +119,7 @@ const folders = argv._.map(name => utils.formatPath(name));

const pkgNotExist = !pkg.name;
const specIsTag = pkgInfo.type === 'tag' && !!pkgInfo.rawSpec;
const specNotSemver = [ 'tag', 'range', 'version' ].indexOf(pkgInfo.type) === -1;
const specNotSemver = !REGISTRY_TYPES.includes(pkgInfo.type);
const specNotSatisfies = (pkgInfo.type === 'range' || pkgInfo.type === 'version') && !semver.satisfies(pkg.version, pkgInfo.spec);

if (pkgNotExist || specIsTag || specNotSemver || specNotSatisfies) {
Expand Down
48 changes: 22 additions & 26 deletions lib/download/git.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,59 @@
'use strict';

const path = require('path');
const urlutil = require('url');
const uuid = require('uuid');
const chalk = require('chalk');
const runscript = require('runscript');
const ngu = require('normalize-git-url');
const utils = require('../utils');

module.exports = async (pkg, options) => {
const {
name,
raw,
hosted,
displayName,
} = pkg;

options.gitPackages++;
options.console.warn(chalk.yellow(`[${pkg.displayName}] install ${pkg.name || ''} from git ${pkg.spec}, may be very slow, please keep patience`));
const gitInfo = parseGitInfo(pkg);
options.console.warn(chalk.yellow(`[${displayName}] install ${name || ''} from git ${raw}, may be very slow, please keep patience`));
const url = hosted.https();
const branchOrCommit = hosted.committish || 'master';
const cloneDir = path.join(options.storeDir, '.tmp', uuid());
await utils.mkdirp(cloneDir);
try {
const hostname = urlutil.parse(gitInfo.url).hostname;
let commit;

if (hostname === 'github.com') {
if (hosted.type === 'github') {
try {
// try download tarball first
// github.com can download tarball via branch, too
await downloadAndExtract(gitInfo.url, gitInfo.branch, cloneDir, options);
commit = gitInfo.branch;
await downloadAndExtract(url, branchOrCommit, cloneDir, options);
commit = branchOrCommit;
} catch (err) {
options.console.warn(chalk.yellow(`download tarball failed: ${err.message}, try to clone repository now.`));
await clone(gitInfo.url, gitInfo.branch, cloneDir, options);
await clone(url, branchOrCommit, cloneDir, options);
commit = await getLastCommitHash(cloneDir);
}
} else {
await clone(gitInfo.url, gitInfo.branch, cloneDir, options);
await clone(url, branchOrCommit, cloneDir, options);
commit = await getLastCommitHash(cloneDir);
}

const resolved = gitInfo.url + '#' + commit;
const resolved = `${url}#${commit}`;
await utils.addMetaToJSONFile(path.join(cloneDir, 'package.json'), {
_from: pkg.raw,
_from: raw,
_resolved: resolved,
});
const res = await utils.copyInstall(cloneDir, options);
if (pkg.name && pkg.name !== res.package.name) {
options.console.warn(chalk.yellow(`[${pkg.displayName}] Package name unmatched: expected ${pkg.name} but found ${res.package.name}`));
res.package.name = pkg.name;
if (name && name !== res.package.name) {
options.console.warn(chalk.yellow(`[${displayName}] Package name unmatched: expected ${name} but found ${res.package.name}`));
res.package.name = name;
}
// record package name
options.remoteNames[pkg.raw] = res.package.name;
options.remoteNames[raw] = res.package.name;
return res;
} catch (err) {
throw new Error(`[${pkg.displayName}] ${err.message}`);
throw new Error(`[${displayName}] ${err.message}`);
} finally {
// clean up
try {
Expand All @@ -59,15 +64,6 @@ module.exports = async (pkg, options) => {
}
};

function parseGitInfo(pkg) {
// https://github.com/npm/npm-package-arg#result-object
// type can be git and hosted
// hosted support github, gitlab and bitbucket
return pkg.type === 'git'
? ngu(pkg.rawSpec)
: ngu(pkg.hosted.httpsUrl);
}

async function clone(url, branch, target, options) {
const cloneScript = `git clone ${url} ${target}`;
options.console.warn(chalk.yellow(cloneScript));
Expand Down
7 changes: 5 additions & 2 deletions lib/download/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ const npm = require('./npm');
const local = require('./local');
const remote = require('./remote');
const git = require('./git');
const { LOCAL_TYPES } = require('../npa_types');

module.exports = async (pkg, options) => {
if (pkg.type === 'local') {
if (LOCAL_TYPES.includes(pkg.type)) {
return await local(pkg, options);
}
if (pkg.type === 'remote') {
return await remote(pkg, options);
}
if (pkg.type === 'git' || pkg.type === 'hosted') {
if (pkg.type === 'git') {
return await git(pkg, options);
}

// type is `tag | version | range`
return await npm(pkg, options);
};
17 changes: 6 additions & 11 deletions lib/download/local.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,12 @@ const uuid = require('uuid');
const utils = require('../utils');

module.exports = async (pkg, options) => {
const {
fetchSpec,
displayName,
} = pkg;
options.localPackages++;
let filepath = pkg.spec;
if (!path.isAbsolute(filepath)) {
filepath = path.join(options.root, filepath);
} else {
// npa resolve './file/path' from process.cwd()
// but we want to resolve from `options.root`
if (pkg.rawSpec[0] === '.') {
filepath = path.join(options.root, pkg.rawSpec);
}
}
let filepath = fetchSpec;

try {
filepath = await fs.realpath(filepath);
Expand All @@ -29,7 +24,7 @@ module.exports = async (pkg, options) => {
? await localFolder(filepath, pkg, options)
: await localTarball(filepath, pkg, options);
} catch (err) {
throw new Error(`[${pkg.displayName}] resolved target ${filepath} error: ${err.message}`);
throw new Error(`[${displayName}] resolved target ${filepath} error: ${err.message}`);
}
};

Expand Down
5 changes: 3 additions & 2 deletions lib/download/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,13 @@ async function resolve(pkg, options) {
if (err) throw err;
}

let spec = pkg.spec;
let spec = pkg.fetchSpec;
if (spec === '*') {
spec = 'latest';
}

const distTags = packageMeta['dist-tags'];

let realPkgVersion = utils.findMaxSatisfyingVersion(spec, distTags, packageMeta.allVersions);
let fixDependencies;

Expand Down Expand Up @@ -103,7 +104,7 @@ async function resolve(pkg, options) {
}

debug('[%s@%s] spec: %s, real version: %s, dist-tags: %j',
pkg.name, pkg.rawSpec, pkg.spec, realPkg.version, distTags);
pkg.name, pkg.rawSpec, pkg.fetchSpec, realPkg.version, distTags);

// cache resolve result
dependenciesTree[pkg.raw] = realPkg;
Expand Down
21 changes: 14 additions & 7 deletions lib/download/remote.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,34 @@ const chalk = require('chalk');
const utils = require('../utils');

module.exports = async (pkg, options) => {
const {
name,
raw,
fetchSpec,
displayName,
} = pkg;

options.remotePackages++;
const remoteUrl = pkg.spec;
options.console.warn(chalk.yellow(`[${pkg.displayName}] install ${pkg.name || ''} from remote ${remoteUrl}, may be very slow, please keep patience`));
const remoteUrl = fetchSpec;
options.console.warn(chalk.yellow(`[${displayName}] install ${name || ''} from remote ${remoteUrl}, may be very slow, please keep patience`));
const readstream = await utils.getTarballStream(remoteUrl, options);
const ungzipDir = path.join(options.storeDir, '.tmp', uuid());
await utils.mkdirp(ungzipDir);
try {
await utils.unpack(readstream, ungzipDir, pkg);
await utils.addMetaToJSONFile(path.join(ungzipDir, 'package.json'), {
_from: pkg.name ? `${pkg.name}@${remoteUrl}` : remoteUrl,
_from: name ? `${name}@${remoteUrl}` : remoteUrl,
_resolved: remoteUrl,
});
const res = await utils.copyInstall(ungzipDir, options);
if (pkg.name && pkg.name !== res.package.name) {
throw new Error(`Invalid Package, expected ${pkg.name} but found ${res.package.name}`);
if (name && name !== res.package.name) {
throw new Error(`Invalid Package, expected ${name} but found ${res.package.name}`);
}
// record package name
options.remoteNames[pkg.raw] = res.package.name;
options.remoteNames[raw] = res.package.name;
return res;
} catch (err) {
throw new Error(`[${pkg.displayName}] ${err.message}`);
throw new Error(`[${displayName}] ${err.message}`);
} finally {
// clean up
try {
Expand Down
2 changes: 1 addition & 1 deletion lib/format_install_options.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ module.exports = function formatInstallOptions(options) {
// production mode: log all message to console
// other: only show today message to console
options.onlyShowTodayUpdateToConsole = !options.production;
// record all the packages' name which install from remote/git/hosted
// record all the packages' name which install from remote/git
options.remoteNames = {};

options.pkgs = options.pkgs || [];
Expand Down
2 changes: 1 addition & 1 deletion lib/global_install.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ module.exports = async options => {
}));

console.info(chalk.gray(`Downloading ${name} to ${tmpDir}`));
const p = npa(pkg.name ? `${pkg.name}@${pkg.version}` : pkg.version);
const p = npa(pkg.name ? `${pkg.name}@${pkg.version}` : pkg.version, options.root);
const result = await download(p, installOptions);

// read the real package.json and get the pakcage's name
Expand Down
Loading

0 comments on commit 6cc5548

Please sign in to comment.