Skip to content

Commit

Permalink
fix(core): handle npm workspaces
Browse files Browse the repository at this point in the history
  • Loading branch information
meeroslav committed Dec 9, 2022
1 parent e6dbcad commit d2e663b
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 68 deletions.
38 changes: 0 additions & 38 deletions packages/nx/src/lock-file/__fixtures__/npm.lock.ts
Expand Up @@ -22642,41 +22642,3 @@ export const lockFileV1YargsAndDevkitOnly = `{
}
}
`;

/**
* V1
* dependencies:
* "workspace-a": {
"version": "file:workspace-a",
"requires": {
"@nrwl/devkit": "15.0.13",
"postgres": "charsleysa/postgres#fix-errors-compiled",
"yargs": "17.6.2"
}
},
*/

/**
* V1
* packages:
* "node_modules/workspace-a": {
"resolved": "workspace-a",
"link": true
},
"workspace-a": {
"dependencies": {
"@nrwl/devkit": "15.0.13",
"postgres": "charsleysa/postgres#fix-errors-compiled",
"yargs": "17.6.2"
}
},
* dependencies:
"workspace-a": {
"version": "file:workspace-a",
"requires": {
"@nrwl/devkit": "15.0.13",
"postgres": "charsleysa/postgres#fix-errors-compiled",
"yargs": "17.6.2"
}
},
*/
56 changes: 35 additions & 21 deletions packages/nx/src/lock-file/npm.spec.ts
Expand Up @@ -121,7 +121,9 @@ describe('npm LockFile utility', () => {
});

it('should match the original file on stringification', () => {
expect(stringifyNpmLockFile(parsedLockFile)).toEqual(lockFileV3);
expect(JSON.parse(stringifyNpmLockFile(parsedLockFile))).toEqual(
JSON.parse(lockFileV3)
);
});

it('should prune the lock file', () => {
Expand All @@ -139,18 +141,22 @@ describe('npm LockFile utility', () => {

it('should correctly prune lockfile with single package', () => {
expect(
stringifyNpmLockFile(
pruneNpmLockFile(parsedLockFile, TypeScriptOnlyPackage)
JSON.parse(
stringifyNpmLockFile(
pruneNpmLockFile(parsedLockFile, TypeScriptOnlyPackage)
)
)
).toEqual(lockFileV3JustTypescript);
).toEqual(JSON.parse(lockFileV3JustTypescript));
});

it('should correctly prune lockfile with multiple packages', () => {
expect(
stringifyNpmLockFile(
pruneNpmLockFile(parsedLockFile, YargsAndDevkitPackage)
JSON.parse(
stringifyNpmLockFile(
pruneNpmLockFile(parsedLockFile, YargsAndDevkitPackage)
)
)
).toEqual(lockFileV3YargsAndDevkitOnly);
).toEqual(JSON.parse(lockFileV3YargsAndDevkitOnly));
});
});

Expand Down Expand Up @@ -189,8 +195,8 @@ describe('npm LockFile utility', () => {
const parsedWorkspaceLockFile = parseNpmLockFile(
npmLockFileWithWorkspaces
);
expect(stringifyNpmLockFile(parsedWorkspaceLockFile)).toEqual(
npmLockFileWithWorkspaces
expect(JSON.parse(stringifyNpmLockFile(parsedWorkspaceLockFile))).toEqual(
JSON.parse(npmLockFileWithWorkspaces)
);
});

Expand Down Expand Up @@ -244,7 +250,9 @@ describe('npm LockFile utility', () => {
});

it('should match the original file on stringification', () => {
expect(stringifyNpmLockFile(parsedLockFile)).toEqual(lockFileV2);
expect(JSON.parse(stringifyNpmLockFile(parsedLockFile))).toEqual(
JSON.parse(lockFileV2)
);
});

it('should prune the lock file', () => {
Expand All @@ -262,16 +270,18 @@ describe('npm LockFile utility', () => {

it('should correctly prune lockfile with single package', () => {
expect(
stringifyNpmLockFile(
pruneNpmLockFile(parsedLockFile, TypeScriptOnlyPackage)
JSON.parse(
stringifyNpmLockFile(
pruneNpmLockFile(parsedLockFile, TypeScriptOnlyPackage)
)
)
).toEqual(lockFileV2JustTypescript);
).toEqual(JSON.parse(lockFileV2JustTypescript));
});

it('should correctly prune lockfile with multiple packages', () => {
const pruned = pruneNpmLockFile(parsedLockFile, YargsAndDevkitPackage);
expect(stringifyNpmLockFile(pruned)).toEqual(
lockFileV2YargsAndDevkitOnly
expect(JSON.parse(stringifyNpmLockFile(pruned))).toEqual(
JSON.parse(lockFileV2YargsAndDevkitOnly)
);
});
});
Expand Down Expand Up @@ -345,7 +355,9 @@ describe('npm LockFile utility', () => {
});

it('should match the original file on stringification', () => {
expect(stringifyNpmLockFile(parsedLockFile)).toEqual(lockFileV1);
expect(JSON.parse(stringifyNpmLockFile(parsedLockFile))).toEqual(
JSON.parse(lockFileV1)
);
});

describe('pruning', () => {
Expand Down Expand Up @@ -378,16 +390,18 @@ describe('npm LockFile utility', () => {

it('should correctly prune lockfile with single package', () => {
expect(
stringifyNpmLockFile(
pruneNpmLockFile(parsedLockFile, TypeScriptOnlyPackage)
JSON.parse(
stringifyNpmLockFile(
pruneNpmLockFile(parsedLockFile, TypeScriptOnlyPackage)
)
)
).toEqual(lockFileV1JustTypescript);
).toEqual(JSON.parse(lockFileV1JustTypescript));
});

it('should correctly prune lockfile with multiple packages', () => {
const pruned = pruneNpmLockFile(parsedLockFile, YargsAndDevkitPackage);
expect(stringifyNpmLockFile(pruned)).toEqual(
lockFileV1YargsAndDevkitOnly
expect(JSON.parse(stringifyNpmLockFile(pruned))).toEqual(
JSON.parse(lockFileV1YargsAndDevkitOnly)
);
});
});
Expand Down
48 changes: 39 additions & 9 deletions packages/nx/src/lock-file/npm.ts
Expand Up @@ -7,7 +7,7 @@ import { workspaceRoot } from '../utils/workspace-root';
import { LockFileData, PackageDependency } from './utils/lock-file-type';
import { TransitiveLookupFunctionInput } from './utils/mapping';
import { hashString, generatePrunnedHash } from './utils/hashing';
import { PackageJsonDeps } from './utils/pruning';
import type { PackageJsonDeps } from './utils/pruning';

type PackageMeta = {
path: string;
Expand Down Expand Up @@ -110,13 +110,32 @@ function mapPackages(
packagePath
);

let dependency;
if (lockfileVersion === 2) {
const path = packagePath.split(/\/?node_modules\//).slice(1);

path.forEach((proj) => {
if (!dependency) {
dependency = dependencies[proj];
} else {
dependency = dependency.dependencies[proj];
}
});
// if versions are same, no need to track it further
if (dependency && value.version === dependency.version) {
dependency = undefined;
}
}

mapPackageDependency(
mappedPackages,
packageName,
newKey,
packagePath,
value,
lockfileVersion
lockfileVersion,
undefined,
dependency
);
}
});
Expand Down Expand Up @@ -151,7 +170,8 @@ function mapPackageDependency(
packagePath: string,
value: NpmDependency | Omit<PackageDependency, 'packageMeta'>,
lockfileVersion: number,
isRootVersion?: boolean
isRootVersion?: boolean,
dependencyValue?: NpmDependency
) {
const { dev, peer, optional } = value;
const packageMeta = {
Expand All @@ -177,10 +197,17 @@ function mapPackageDependency(

mappedPackages[packageName][key] = {
...(value as Omit<PackageDependency, 'packageMeta'>),
...(!value.integrity && {
actualVersion: value.version,
version: value.resolved,
}),
...(!value.integrity &&
value.version && {
actualVersion: value.version,
version: value.resolved,
}),
...(value.integrity &&
dependencyValue && {
actualVersion: value.version,
version: dependencyValue.version,
}),
...(dependencyValue && { dependencyValue }),
packageMeta: [],
rootVersion,
};
Expand Down Expand Up @@ -297,6 +324,7 @@ function unmapPackage(packages: Dependencies, dependency: PackageDependency) {
dev,
peer,
optional,
dependencyValue,
...value
} = dependency;
// we need to decompose value, to achieve particular field ordering
Expand All @@ -321,7 +349,8 @@ function unmapDependencies(
packageName: string,
{ packageMeta, ...value }: PackageDependency & { packageMeta: PackageMeta[] }
): void {
const { version, resolved, integrity, devOptional } = value;
const { version, resolved, integrity, devOptional, dependencyValue, from } =
value;

for (let i = 0; i < packageMeta.length; i++) {
const { path, dev, optional, peer } = packageMeta[i];
Expand All @@ -334,10 +363,11 @@ function unmapDependencies(
);

// sorting fields to match package-lock structure
innerDeps[packageName] = {
innerDeps[packageName] = dependencyValue || {
version,
resolved,
integrity,
from,
dev,
devOptional,
optional,
Expand Down

0 comments on commit d2e663b

Please sign in to comment.