Skip to content

Commit

Permalink
fix(@angular-devkit/schematics): filters out non-NPM dependencies (an…
Browse files Browse the repository at this point in the history
…gular#13059)

Non-NPM dependencies in package.json are now filtered out of `ng update`. Dependencies which are linked as tarball or Git references will now be skipped during the update process.
  • Loading branch information
dgp1130 committed Nov 13, 2019
1 parent 7e7248d commit 431add6
Showing 1 changed file with 34 additions and 6 deletions.
40 changes: 34 additions & 6 deletions packages/schematics/update/update/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,29 @@ function _formatVersion(version: string | undefined) {
return version;
}

/**
* @param depString Dependency from `package.json`. Could be a semver, local tarball reference,
* link to a GitHub repo, etc.
* @return Whether or not the given string is a simple semantic version, and thus represents a
* package hosted on NPM, either as a public or private package.
*/
function isSimpleSemVer(depString: string): boolean {
// Any tarball is clearly not a simple semantic version. We need to manually exclude this
// case because semver.coerce() has special logic to extract the version number from the name
// of a tarball generated with `npm pack`. By NPM specification, the name *must* end in ".tar",
// ".tar.gz", or ".tgz", so we can simply exclude these extensions.
// See: https://docs.npmjs.com/cli/install.
if (depString.endsWith('.tar') || depString.endsWith('.tar.gz') || depString.endsWith('.tgz')) {
return false;
}

const version = semver.coerce(depString);
if (!version) {
return false;
}

return !!semver.valid(version);
}

export default function(options: UpdateSchema): Rule {
if (!options.packages) {
Expand All @@ -850,11 +873,16 @@ export default function(options: UpdateSchema): Rule {

return (tree: Tree, context: SchematicContext) => {
const logger = context.logger;
const allDependencies = _getAllDependencies(tree);
const packages = _buildPackageList(options, allDependencies, logger);
const allDeps = _getAllDependencies(tree);

// Filter out non-NPM dependencies by checking if they link to a semver.
const npmDeps = new Map(Array.from(allDeps.entries())
.filter(([_, source]) => isSimpleSemVer(source)));

const packages = _buildPackageList(options, npmDeps, logger);
const usingYarn = options.packageManager === 'yarn';

return observableFrom([...allDependencies.keys()]).pipe(
return observableFrom([...npmDeps.keys()]).pipe(
// Grab all package.json from the npm repository. This requires a lot of HTTP calls so we
// try to parallelize as many as possible.
mergeMap(depName => getNpmPackageJson(
Expand Down Expand Up @@ -899,8 +927,8 @@ export default function(options: UpdateSchema): Rule {
do {
lastPackagesSize = packages.size;
npmPackageJsonMap.forEach((npmPackageJson) => {
_addPackageGroup(tree, packages, allDependencies, npmPackageJson, logger);
_addPeerDependencies(tree, packages, allDependencies, npmPackageJson, npmPackageJsonMap, logger);
_addPackageGroup(tree, packages, npmDeps, npmPackageJson, logger);
_addPeerDependencies(tree, packages, npmDeps, npmPackageJson, npmPackageJsonMap, logger);
});
} while (packages.size > lastPackagesSize);

Expand All @@ -909,7 +937,7 @@ export default function(options: UpdateSchema): Rule {
npmPackageJsonMap.forEach((npmPackageJson) => {
packageInfoMap.set(
npmPackageJson.name,
_buildPackageInfo(tree, packages, allDependencies, npmPackageJson, logger),
_buildPackageInfo(tree, packages, npmDeps, npmPackageJson, logger),
);
});

Expand Down

0 comments on commit 431add6

Please sign in to comment.