Skip to content

Commit

Permalink
fix(core): handle duplicated dependencies correctly
Browse files Browse the repository at this point in the history
This fixes a problematic behavior when identical dependencies with and
without range specifiers, such as ^, ~, or x. For example, if we have
`jsr:@std/testing@^0.210.0` and `jsr:@std/testing@0.210.0/bdd` at the
same time, both are updated to the latest version, or neither is
updated, which should not happen.
  • Loading branch information
hasundue committed May 14, 2024
1 parent 8bb9a32 commit b11a913
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 7 deletions.
14 changes: 7 additions & 7 deletions core/dependency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ export async function resolveLatestVersion(
dependency: Dependency,
options?: { cache?: boolean },
): Promise<UpdatedDependency | undefined> {
const constraint = dependency.version
? SemVer.tryParseRange(dependency.version)
: undefined;
// Do not update inequality ranges.
if (constraint && constraint.flat().length > 1) {
return;
}
using cache = options?.cache
? new LatestVersionCache(dependency.name)
: undefined;
Expand All @@ -177,13 +184,6 @@ export async function resolveLatestVersion(
// The dependency is already found to be up to date or unable to resolve.
return;
}
const constraint = dependency.version
? SemVer.tryParseRange(dependency.version)
: undefined;
// Do not update inequality ranges.
if (constraint && constraint.flat().length > 1) {
return;
}
const result = await _resolveLatestVersion(dependency);
cache?.set(dependency.name, result ?? null);
return result;
Expand Down
17 changes: 17 additions & 0 deletions core/import_map_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,23 @@ describe("resolve()", () => {
);
});

it("resolve a jsr specifier with a caret", async () => {
const dir = "../test/cases/import_map_duplicated_imports";
const importMap = await readFromJson(
new URL(`${dir}/deno.json`, import.meta.url),
);
assertExists(importMap);
const referrer = new URL(`${dir}/mod.ts`, import.meta.url);
assertEquals(
importMap.resolve("@std/testing", referrer),
{
resolved: "jsr:@std/testing@^0.210.0",
key: "@std/testing",
value: "jsr:@std/testing@^0.210.0",
},
);
});

it("resolve a jsr specifier with path", async () => {
const dir = "../test/cases/jsr_with_path_in_import_map";
const importMap = await readFromJson(
Expand Down
6 changes: 6 additions & 0 deletions test/cases/import_map_duplicated_imports/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"imports": {
"@std/testing": "jsr:@std/testing@^0.210.0",
"@std/testing/bdd": "jsr:@std/testing@0.210.0/bdd"
}
}
1 change: 1 addition & 0 deletions test/cases/import_map_duplicated_imports/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { describe } from "@std/testing/bdd";
97 changes: 97 additions & 0 deletions test/snapshots/file_test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,103 @@ snapshot[`write - import_map/mod.ts 2`] = `
]
`;

snapshot[`write - import_map_duplicated_imports/deno.json 1`] = `
[
{
dependencies: [
{
code: {
span: undefined,
specifier: "jsr:@std/testing@0.210.0/bdd",
},
from: {
name: "@std/testing",
path: "/bdd",
protocol: "jsr:",
version: "0.210.0",
},
map: {
key: "@std/testing/bdd",
resolved: "jsr:@std/testing@0.210.0/bdd",
},
to: {
name: "@std/testing",
path: "/bdd",
protocol: "jsr:",
version: "123.456.789",
},
},
],
kind: "import_map",
},
]
`;

snapshot[`write - import_map_duplicated_imports/deno.json 2`] = `
[
'{
"imports": {
"@std/testing": "jsr:@std/testing@^0.210.0",
"@std/testing/bdd": "jsr:@std/testing@123.456.789/bdd"
}
}
',
]
`;

snapshot[`write - import_map_duplicated_imports/mod.ts 1`] = `
[
{
dependencies: [
{
code: {
span: {
end: {
character: 43,
line: 0,
},
start: {
character: 25,
line: 0,
},
},
specifier: "@std/testing/bdd",
},
from: {
name: "@std/testing",
path: "/bdd",
protocol: "jsr:",
version: "0.210.0",
},
map: {
key: "@std/testing/bdd",
resolved: "jsr:@std/testing@0.210.0/bdd",
},
to: {
name: "@std/testing",
path: "/bdd",
protocol: "jsr:",
version: "123.456.789",
},
},
],
kind: "import_map",
},
]
`;

snapshot[`write - import_map_duplicated_imports/mod.ts 2`] = `
[
'{
"imports": {
"@std/testing": "jsr:@std/testing@^0.210.0",
"@std/testing/bdd": "jsr:@std/testing@123.456.789/bdd"
}
}
',
]
`;

snapshot[`write - npm.ts 1`] = `
[
{
Expand Down
55 changes: 55 additions & 0 deletions test/snapshots/update_test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,61 @@ snapshot[`collect - import_map - mod.ts 1`] = `
]
`;

snapshot[`collect - import_map_duplicated_imports - deno.json 1`] = `
[
{
code: {
span: undefined,
specifier: "jsr:@std/testing@0.210.0/bdd",
},
from: {
name: "@std/testing",
path: "/bdd",
protocol: "jsr:",
version: "0.210.0",
},
to: {
name: "@std/testing",
path: "/bdd",
protocol: "jsr:",
version: "123.456.789",
},
},
]
`;

snapshot[`collect - import_map_duplicated_imports - mod.ts 1`] = `
[
{
code: {
span: {
end: {
character: 43,
line: 0,
},
start: {
character: 25,
line: 0,
},
},
specifier: "@std/testing/bdd",
},
from: {
name: "@std/testing",
path: "/bdd",
protocol: "jsr:",
version: "0.210.0",
},
to: {
name: "@std/testing",
path: "/bdd",
protocol: "jsr:",
version: "123.456.789",
},
},
]
`;

snapshot[`collect - npm.ts 1`] = `
[
{
Expand Down

0 comments on commit b11a913

Please sign in to comment.