mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
fix(install): resolve dist-tag dependencies to local workspace packages
When a workspace package has the same name as an npm package and a dependency uses a dist-tag specifier (e.g. "latest" or ""), bun install would incorrectly fetch from the npm registry instead of symlinking to the local workspace. This extends the workspace resolution logic in both the lockfile package resolver and the enqueue step to handle dist-tag versions the same way as other version specifiers, preferring local workspace packages when `link_workspace_packages` is enabled.
This commit is contained in:
@@ -1611,6 +1611,31 @@ fn getOrPutResolvedPackage(
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (version.tag == .dist_tag) {
|
||||
if (this.options.link_workspace_packages) {
|
||||
const workspace_path = if (this.lockfile.workspace_paths.count() > 0)
|
||||
this.lockfile.workspace_paths.get(name_hash)
|
||||
else
|
||||
null;
|
||||
if (workspace_path != null) {
|
||||
const root_package = this.lockfile.rootPackage() orelse break :resolve_from_workspace;
|
||||
const root_dependencies = root_package.dependencies.get(this.lockfile.buffers.dependencies.items);
|
||||
const root_resolutions = root_package.resolutions.get(this.lockfile.buffers.resolutions.items);
|
||||
|
||||
for (root_dependencies, root_resolutions) |root_dep, workspace_package_id| {
|
||||
if (workspace_package_id != invalid_package_id and
|
||||
root_dep.version.tag == .workspace and
|
||||
root_dep.name_hash == name_hash)
|
||||
{
|
||||
successFn(this, dependency_id, workspace_package_id);
|
||||
return .{
|
||||
.package = this.lockfile.packages.get(workspace_package_id),
|
||||
.is_first_time = false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1121,6 +1121,24 @@ pub fn Package(comptime SemverIntType: type) type {
|
||||
}
|
||||
}
|
||||
},
|
||||
.dist_tag => {
|
||||
if (workspace_path != null and pm.options.link_workspace_packages) {
|
||||
const path = workspace_path.?.sliced(buf);
|
||||
if (Dependency.parseWithTag(
|
||||
allocator,
|
||||
external_alias.value,
|
||||
external_alias.hash,
|
||||
path.slice,
|
||||
.workspace,
|
||||
&path,
|
||||
log,
|
||||
pm,
|
||||
)) |dep| {
|
||||
dependency_version.tag = dep.tag;
|
||||
dependency_version.value = dep.value;
|
||||
}
|
||||
}
|
||||
},
|
||||
.workspace => workspace: {
|
||||
if (workspace_path) |path| {
|
||||
if (workspace_range) |range| {
|
||||
|
||||
@@ -738,6 +738,252 @@ exports[`dependency on workspace without version in package.json: version: *-pre
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`dependency on workspace without version in package.json: version: latest 1`] = `
|
||||
"{
|
||||
"format": "v3",
|
||||
"meta_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"package_index": {
|
||||
"no-deps": 2,
|
||||
"foo": 0,
|
||||
"bar": 1
|
||||
},
|
||||
"trees": [
|
||||
{
|
||||
"id": 0,
|
||||
"path": "node_modules",
|
||||
"depth": 0,
|
||||
"dependencies": {
|
||||
"bar": {
|
||||
"id": 0,
|
||||
"package_id": 1
|
||||
},
|
||||
"no-deps": {
|
||||
"id": 1,
|
||||
"package_id": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "bar",
|
||||
"literal": "",
|
||||
"workspace": "packages/bar",
|
||||
"package_id": 1,
|
||||
"behavior": {
|
||||
"workspace": true
|
||||
},
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "no-deps",
|
||||
"literal": "",
|
||||
"workspace": "packages/mono",
|
||||
"package_id": 2,
|
||||
"behavior": {
|
||||
"workspace": true
|
||||
},
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "no-deps",
|
||||
"literal": "latest",
|
||||
"workspace": "packages/mono",
|
||||
"package_id": 2,
|
||||
"behavior": {
|
||||
"prod": true
|
||||
},
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"packages": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "foo",
|
||||
"name_hash": "14841791273925386894",
|
||||
"resolution": {
|
||||
"tag": "root",
|
||||
"value": "",
|
||||
"resolved": ""
|
||||
},
|
||||
"dependencies": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "local",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "bar",
|
||||
"name_hash": "11592711315645265694",
|
||||
"resolution": {
|
||||
"tag": "workspace",
|
||||
"value": "workspace:packages/bar",
|
||||
"resolved": "workspace:packages/bar"
|
||||
},
|
||||
"dependencies": [
|
||||
2
|
||||
],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "no-deps",
|
||||
"name_hash": "5128161233225832376",
|
||||
"resolution": {
|
||||
"tag": "workspace",
|
||||
"value": "workspace:packages/mono",
|
||||
"resolved": "workspace:packages/mono"
|
||||
},
|
||||
"dependencies": [],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
}
|
||||
],
|
||||
"workspace_paths": {
|
||||
"11592711315645265694": "packages/bar",
|
||||
"5128161233225832376": "packages/mono"
|
||||
},
|
||||
"workspace_versions": {
|
||||
"11592711315645265694": "1.0.0"
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`dependency on workspace without version in package.json: version: 1`] = `
|
||||
"{
|
||||
"format": "v3",
|
||||
"meta_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"package_index": {
|
||||
"no-deps": 2,
|
||||
"foo": 0,
|
||||
"bar": 1
|
||||
},
|
||||
"trees": [
|
||||
{
|
||||
"id": 0,
|
||||
"path": "node_modules",
|
||||
"depth": 0,
|
||||
"dependencies": {
|
||||
"bar": {
|
||||
"id": 0,
|
||||
"package_id": 1
|
||||
},
|
||||
"no-deps": {
|
||||
"id": 1,
|
||||
"package_id": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "bar",
|
||||
"literal": "",
|
||||
"workspace": "packages/bar",
|
||||
"package_id": 1,
|
||||
"behavior": {
|
||||
"workspace": true
|
||||
},
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "no-deps",
|
||||
"literal": "",
|
||||
"workspace": "packages/mono",
|
||||
"package_id": 2,
|
||||
"behavior": {
|
||||
"workspace": true
|
||||
},
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "no-deps",
|
||||
"literal": "",
|
||||
"workspace": "packages/mono",
|
||||
"package_id": 2,
|
||||
"behavior": {
|
||||
"prod": true
|
||||
},
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"packages": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "foo",
|
||||
"name_hash": "14841791273925386894",
|
||||
"resolution": {
|
||||
"tag": "root",
|
||||
"value": "",
|
||||
"resolved": ""
|
||||
},
|
||||
"dependencies": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "local",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "bar",
|
||||
"name_hash": "11592711315645265694",
|
||||
"resolution": {
|
||||
"tag": "workspace",
|
||||
"value": "workspace:packages/bar",
|
||||
"resolved": "workspace:packages/bar"
|
||||
},
|
||||
"dependencies": [
|
||||
2
|
||||
],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "no-deps",
|
||||
"name_hash": "5128161233225832376",
|
||||
"resolution": {
|
||||
"tag": "workspace",
|
||||
"value": "workspace:packages/mono",
|
||||
"resolved": "workspace:packages/mono"
|
||||
},
|
||||
"dependencies": [],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
}
|
||||
],
|
||||
"workspace_paths": {
|
||||
"11592711315645265694": "packages/bar",
|
||||
"5128161233225832376": "packages/mono"
|
||||
},
|
||||
"workspace_versions": {
|
||||
"11592711315645265694": "1.0.0"
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`dependency on workspace without version in package.json: version: 1 1`] = `
|
||||
"{
|
||||
"format": "v3",
|
||||
@@ -1674,327 +1920,12 @@ exports[`dependency on workspace without version in package.json: version: *+bui
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`dependency on workspace without version in package.json: version: latest 1`] = `
|
||||
"{
|
||||
"format": "v3",
|
||||
"meta_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"package_index": {
|
||||
"no-deps": [
|
||||
2,
|
||||
3
|
||||
],
|
||||
"foo": 0,
|
||||
"bar": 1
|
||||
},
|
||||
"trees": [
|
||||
{
|
||||
"id": 0,
|
||||
"path": "node_modules",
|
||||
"depth": 0,
|
||||
"dependencies": {
|
||||
"bar": {
|
||||
"id": 0,
|
||||
"package_id": 1
|
||||
},
|
||||
"no-deps": {
|
||||
"id": 1,
|
||||
"package_id": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"path": "node_modules/bar/node_modules",
|
||||
"depth": 1,
|
||||
"dependencies": {
|
||||
"no-deps": {
|
||||
"id": 2,
|
||||
"package_id": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "bar",
|
||||
"literal": "",
|
||||
"workspace": "packages/bar",
|
||||
"package_id": 1,
|
||||
"behavior": {
|
||||
"workspace": true
|
||||
},
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "no-deps",
|
||||
"literal": "",
|
||||
"workspace": "packages/mono",
|
||||
"package_id": 2,
|
||||
"behavior": {
|
||||
"workspace": true
|
||||
},
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "no-deps",
|
||||
"literal": "latest",
|
||||
"dist_tag": {
|
||||
"name": "no-deps",
|
||||
"tag": "no-deps"
|
||||
},
|
||||
"package_id": 3,
|
||||
"behavior": {
|
||||
"prod": true
|
||||
},
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"packages": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "foo",
|
||||
"name_hash": "14841791273925386894",
|
||||
"resolution": {
|
||||
"tag": "root",
|
||||
"value": "",
|
||||
"resolved": ""
|
||||
},
|
||||
"dependencies": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "local",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "bar",
|
||||
"name_hash": "11592711315645265694",
|
||||
"resolution": {
|
||||
"tag": "workspace",
|
||||
"value": "workspace:packages/bar",
|
||||
"resolved": "workspace:packages/bar"
|
||||
},
|
||||
"dependencies": [
|
||||
2
|
||||
],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "no-deps",
|
||||
"name_hash": "5128161233225832376",
|
||||
"resolution": {
|
||||
"tag": "workspace",
|
||||
"value": "workspace:packages/mono",
|
||||
"resolved": "workspace:packages/mono"
|
||||
},
|
||||
"dependencies": [],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "no-deps",
|
||||
"name_hash": "5128161233225832376",
|
||||
"resolution": {
|
||||
"tag": "npm",
|
||||
"value": "2.0.0",
|
||||
"resolved": "http://localhost:1234/no-deps/-/no-deps-2.0.0.tgz"
|
||||
},
|
||||
"dependencies": [],
|
||||
"integrity": "sha512-W3duJKZPcMIG5rA1io5cSK/bhW9rWFz+jFxZsKS/3suK4qHDkQNxUTEXee9/hTaAoDCeHWQqogukWYKzfr6X4g==",
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
}
|
||||
],
|
||||
"workspace_paths": {
|
||||
"11592711315645265694": "packages/bar",
|
||||
"5128161233225832376": "packages/mono"
|
||||
},
|
||||
"workspace_versions": {
|
||||
"11592711315645265694": "1.0.0"
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`dependency on workspace without version in package.json: version: 1`] = `
|
||||
"{
|
||||
"format": "v3",
|
||||
"meta_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"package_index": {
|
||||
"no-deps": [
|
||||
2,
|
||||
3
|
||||
],
|
||||
"foo": 0,
|
||||
"bar": 1
|
||||
},
|
||||
"trees": [
|
||||
{
|
||||
"id": 0,
|
||||
"path": "node_modules",
|
||||
"depth": 0,
|
||||
"dependencies": {
|
||||
"bar": {
|
||||
"id": 0,
|
||||
"package_id": 1
|
||||
},
|
||||
"no-deps": {
|
||||
"id": 1,
|
||||
"package_id": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"path": "node_modules/bar/node_modules",
|
||||
"depth": 1,
|
||||
"dependencies": {
|
||||
"no-deps": {
|
||||
"id": 2,
|
||||
"package_id": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "bar",
|
||||
"literal": "",
|
||||
"workspace": "packages/bar",
|
||||
"package_id": 1,
|
||||
"behavior": {
|
||||
"workspace": true
|
||||
},
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "no-deps",
|
||||
"literal": "",
|
||||
"workspace": "packages/mono",
|
||||
"package_id": 2,
|
||||
"behavior": {
|
||||
"workspace": true
|
||||
},
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "no-deps",
|
||||
"literal": "",
|
||||
"dist_tag": {
|
||||
"name": "no-deps",
|
||||
"tag": "no-deps"
|
||||
},
|
||||
"package_id": 3,
|
||||
"behavior": {
|
||||
"prod": true
|
||||
},
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"packages": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "foo",
|
||||
"name_hash": "14841791273925386894",
|
||||
"resolution": {
|
||||
"tag": "root",
|
||||
"value": "",
|
||||
"resolved": ""
|
||||
},
|
||||
"dependencies": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "local",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "bar",
|
||||
"name_hash": "11592711315645265694",
|
||||
"resolution": {
|
||||
"tag": "workspace",
|
||||
"value": "workspace:packages/bar",
|
||||
"resolved": "workspace:packages/bar"
|
||||
},
|
||||
"dependencies": [
|
||||
2
|
||||
],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "no-deps",
|
||||
"name_hash": "5128161233225832376",
|
||||
"resolution": {
|
||||
"tag": "workspace",
|
||||
"value": "workspace:packages/mono",
|
||||
"resolved": "workspace:packages/mono"
|
||||
},
|
||||
"dependencies": [],
|
||||
"integrity": null,
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "no-deps",
|
||||
"name_hash": "5128161233225832376",
|
||||
"resolution": {
|
||||
"tag": "npm",
|
||||
"value": "2.0.0",
|
||||
"resolved": "http://localhost:1234/no-deps/-/no-deps-2.0.0.tgz"
|
||||
},
|
||||
"dependencies": [],
|
||||
"integrity": "sha512-W3duJKZPcMIG5rA1io5cSK/bhW9rWFz+jFxZsKS/3suK4qHDkQNxUTEXee9/hTaAoDCeHWQqogukWYKzfr6X4g==",
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
}
|
||||
],
|
||||
"workspace_paths": {
|
||||
"11592711315645265694": "packages/bar",
|
||||
"5128161233225832376": "packages/mono"
|
||||
},
|
||||
"workspace_versions": {
|
||||
"11592711315645265694": "1.0.0"
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`dependency on same name as workspace and dist-tag: with version 1`] = `
|
||||
"{
|
||||
"format": "v3",
|
||||
"meta_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"package_index": {
|
||||
"no-deps": [
|
||||
2,
|
||||
3
|
||||
],
|
||||
"no-deps": 2,
|
||||
"foo": 0,
|
||||
"bar": 1
|
||||
},
|
||||
@@ -2013,17 +1944,6 @@ exports[`dependency on same name as workspace and dist-tag: with version 1`] = `
|
||||
"package_id": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"path": "node_modules/bar/node_modules",
|
||||
"depth": 1,
|
||||
"dependencies": {
|
||||
"no-deps": {
|
||||
"id": 2,
|
||||
"package_id": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
@@ -2050,11 +1970,8 @@ exports[`dependency on same name as workspace and dist-tag: with version 1`] = `
|
||||
{
|
||||
"name": "no-deps",
|
||||
"literal": "latest",
|
||||
"dist_tag": {
|
||||
"name": "no-deps",
|
||||
"tag": "no-deps"
|
||||
},
|
||||
"package_id": 3,
|
||||
"workspace": "packages/mono",
|
||||
"package_id": 2,
|
||||
"behavior": {
|
||||
"prod": true
|
||||
},
|
||||
@@ -2114,22 +2031,6 @@ exports[`dependency on same name as workspace and dist-tag: with version 1`] = `
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "no-deps",
|
||||
"name_hash": "5128161233225832376",
|
||||
"resolution": {
|
||||
"tag": "npm",
|
||||
"value": "2.0.0",
|
||||
"resolved": "http://localhost:1234/no-deps/-/no-deps-2.0.0.tgz"
|
||||
},
|
||||
"dependencies": [],
|
||||
"integrity": "sha512-W3duJKZPcMIG5rA1io5cSK/bhW9rWFz+jFxZsKS/3suK4qHDkQNxUTEXee9/hTaAoDCeHWQqogukWYKzfr6X4g==",
|
||||
"man_dir": "",
|
||||
"origin": "npm",
|
||||
"bin": null,
|
||||
"scripts": {}
|
||||
}
|
||||
],
|
||||
"workspace_paths": {
|
||||
|
||||
@@ -66,17 +66,10 @@ test("dependency on workspace without version in package.json", async () => {
|
||||
"kjwoehcojrgjoj", // dist-tag does not exist, should choose local workspace
|
||||
"*.1.*",
|
||||
"*-pre",
|
||||
"latest", // dist-tag exists, should choose local workspace
|
||||
"", // empty string is treated as "latest" dist tag, should choose local workspace
|
||||
];
|
||||
const shouldNotWork: string[] = [
|
||||
"1",
|
||||
"1.*",
|
||||
"1.1.*",
|
||||
"1.1.0",
|
||||
"*-pre+build",
|
||||
"*+build",
|
||||
"latest", // dist-tag exists, should choose package from npm
|
||||
"",
|
||||
];
|
||||
const shouldNotWork: string[] = ["1", "1.*", "1.1.*", "1.1.0", "*-pre+build", "*+build"];
|
||||
|
||||
for (const version of shouldWork) {
|
||||
writeFileSync(
|
||||
@@ -213,7 +206,7 @@ test("dependency on same name as workspace and dist-tag", async () => {
|
||||
expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
|
||||
expect.stringContaining("bun install v1."),
|
||||
"",
|
||||
"3 packages installed",
|
||||
"2 packages installed",
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user