Skip to content

Commit

Permalink
feat: check resolutions for inconsistencies (#348)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmish authored Mar 27, 2022
1 parent 07e78f3 commit ef2aa44
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 9 deletions.
39 changes: 33 additions & 6 deletions lib/dependency-versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ function recordDependencyVersionsForPackageJson(
);
}
}

if (package_.packageJson.resolutions) {
for (const [dependency, dependencyVersion] of Object.entries(
package_.packageJson.resolutions
)) {
recordDependencyVersion(
dependenciesToVersionsSeen,
dependency,
dependencyVersion,
package_
);
}
}
}

function recordDependencyVersion(
Expand Down Expand Up @@ -235,7 +248,7 @@ export function filterOutIgnoredDependencies(
function writeDependencyVersion(
packageJsonPath: string,
packageJsonEndsInNewline: boolean,
isDependency: boolean, // true for dependency, false for dev-dependency.
type: 'dependencies' | 'devDependencies' | 'resolutions',
dependencyName: string,
newVersion: string
) {
Expand All @@ -245,9 +258,7 @@ function writeDependencyVersion(
});

packageJsonEditor.set(
`${
isDependency ? 'dependencies' : 'devDependencies'
}.${dependencyName.replace(
`${type}.${dependencyName.replace(
/\./g, // Escape dots to avoid creating unwanted nested properties.
'\\.'
)}`,
Expand Down Expand Up @@ -314,7 +325,7 @@ export function fixMismatchingVersions(
writeDependencyVersion(
package_.pathPackageJson,
package_.packageJsonEndsInNewline,
false,
'devDependencies',
mismatchingVersion.dependency,
fixedVersion
);
Expand All @@ -330,7 +341,23 @@ export function fixMismatchingVersions(
writeDependencyVersion(
package_.pathPackageJson,
package_.packageJsonEndsInNewline,
true,
'dependencies',
mismatchingVersion.dependency,
fixedVersion
);
isFixed = true;
}

if (
package_.packageJson.resolutions &&
package_.packageJson.resolutions[mismatchingVersion.dependency] &&
package_.packageJson.resolutions[mismatchingVersion.dependency] !==
fixedVersion
) {
writeDependencyVersion(
package_.pathPackageJson,
package_.packageJsonEndsInNewline,
'resolutions',
mismatchingVersion.dependency,
fixedVersion
);
Expand Down
4 changes: 1 addition & 3 deletions test/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,16 @@ export const FIXTURE_PATH_INCREASABLE_RANGE = join(
FIXTURE_PATH,
'increasable-range'
);

export const FIXTURE_PATH_VALID_WITH_PACKAGES = join(
FIXTURE_PATH,
'valid-with-packages'
);

export const FIXTURE_PATH_WORKSPACE_PACKAGE_NOT_AN_ARRAY = join(
FIXTURE_PATH,
'workspace-packages-not-an-array'
);

export const FIXTURE_PATH_NESTED_WORKSPACES = join(
FIXTURE_PATH,
'nested-workspaces'
);
export const FIXTURE_PATH_RESOLUTIONS = join(FIXTURE_PATH, 'resolutions');
12 changes: 12 additions & 0 deletions test/fixtures/resolutions/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"workspaces": [
"*"
],
"devDependencies": {
"foo": "^1.2.0"
},
"resolutions": {
"foo": "^2.0.0",
"bar": "^1.0.0"
}
}
7 changes: 7 additions & 0 deletions test/fixtures/resolutions/package1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "package1",
"dependencies": {
"foo": "1.3.0",
"bar": "^1.0.0"
}
}
138 changes: 138 additions & 0 deletions test/lib/dependency-versions-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
FIXTURE_PATH_NO_DEPENDENCIES,
FIXTURE_PATH_PACKAGE_MISSING_PACKAGE_JSON,
FIXTURE_PATH_INCONSISTENT_LOCAL_PACKAGE_VERSION,
FIXTURE_PATH_RESOLUTIONS,
} from '../fixtures/index.js';
import mockFs from 'mock-fs';
import { readFileSync } from 'node:fs';
Expand Down Expand Up @@ -170,6 +171,43 @@ describe('Utils | dependency-versions', function () {
},
]);
});

it('has mismatches with resolutions', function () {
const dependencyVersions = calculateVersionsForEachDependency(
getPackagesHelper(FIXTURE_PATH_RESOLUTIONS)
);
expect(calculateMismatchingVersions(dependencyVersions)).toStrictEqual([
{
dependency: 'foo',
versions: [
{
version: '^1.2.0',
packages: [
expect.objectContaining({
path: FIXTURE_PATH_RESOLUTIONS,
}),
],
},
{
version: '1.3.0',
packages: [
expect.objectContaining({
path: join(FIXTURE_PATH_RESOLUTIONS, 'package1'),
}),
],
},
{
version: '^2.0.0',
packages: [
expect.objectContaining({
path: FIXTURE_PATH_RESOLUTIONS,
}),
],
},
],
},
]);
});
});

describe('#filterOutIgnoredDependencies', function () {
Expand Down Expand Up @@ -685,6 +723,106 @@ describe('Utils | dependency-versions', function () {
});
});

describe('resolutions', function () {
beforeEach(function () {
// Create a mock workspace filesystem for temporary usage in this test because changes will be written to some files.
mockFs({
'package.json': JSON.stringify({
workspaces: ['*'],
devDependencies: {
foo: '^1.2.0',
},
resolutions: {
foo: '^1.0.0',
bar: '^1.0.0',
},
}),
package1: {
'package.json': JSON.stringify({
name: 'package1',
dependencies: {
foo: '^2.0.0',
bar: '^1.0.0',
},
}),
},
});
});

afterEach(function () {
mockFs.restore();
});

it('fixes the fixable inconsistencies', function () {
const packages = getPackagesHelper('.');
const mismatchingVersions = calculateMismatchingVersions(
calculateVersionsForEachDependency(packages)
);
const { fixed, notFixed } = fixMismatchingVersions(
packages,
mismatchingVersions
);

// Read in package.json files.
const packageJsonRootContents = readFileSync('package.json', 'utf8');
const packageJson1Contents = readFileSync(
'package1/package.json',
'utf8'
);
const packageJsonRoot: PackageJson = JSON.parse(
packageJsonRootContents
);
const packageJson1: PackageJson = JSON.parse(packageJson1Contents);

expect(
packageJsonRoot.devDependencies &&
packageJsonRoot.devDependencies['foo']
).toStrictEqual('^2.0.0');

expect(
packageJsonRoot.resolutions && packageJsonRoot.resolutions['foo']
).toStrictEqual('^2.0.0');

expect(
packageJson1.dependencies && packageJson1.dependencies['foo']
).toStrictEqual('^2.0.0');

expect(notFixed).toStrictEqual([]);

expect(fixed).toStrictEqual([
{
dependency: 'foo',
versions: [
{
version: '^1.0.0',
packages: [
expect.objectContaining({
path: '.',
}),
],
},
{
version: '^1.2.0',
packages: [
expect.objectContaining({
path: '.',
}),
],
},
{
version: '^2.0.0',
packages: [
expect.objectContaining({
path: 'package1',
}),
],
},
],
},
]);
});
});

describe('increasable range', function () {
beforeEach(function () {
// Create a mock workspace filesystem for temporary usage in this test because changes will be written to some files.
Expand Down

0 comments on commit ef2aa44

Please sign in to comment.