aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alex Lam S.L <alexlamsl@gmail.com> 2023-05-26 07:58:30 +0300
committerGravatar GitHub <noreply@github.com> 2023-05-25 21:58:30 -0700
commit4c566f56c1412201f9de50804960cb0b79b7af4a (patch)
tree0a390ff4183ac0da88c4feb0c552d4eb7aeee08e
parentb395836080a8e4da6a04d6d6f6c3aa68d0f33dd7 (diff)
downloadbun-4c566f56c1412201f9de50804960cb0b79b7af4a.tar.gz
bun-4c566f56c1412201f9de50804960cb0b79b7af4a.tar.zst
bun-4c566f56c1412201f9de50804960cb0b79b7af4a.zip
[install] fix `.bin` linking (#3067)
- causes intermittent `bun install` failures on `bun-types`
-rw-r--r--src/install/install.zig6
-rw-r--r--test/cli/install/bun-install.test.ts159
-rw-r--r--test/cli/install/dummy.registry.ts2
3 files changed, 161 insertions, 6 deletions
diff --git a/src/install/install.zig b/src/install/install.zig
index 40c14d30f..209f2eb96 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -6591,10 +6591,10 @@ pub const PackageManager = struct {
const bin = this.bins[package_id];
if (bin.tag != .none) {
if (!this.has_created_bin) {
+ if (!this.options.global) {
+ this.root_node_modules_folder.dir.makeDirZ(".bin") catch {};
+ }
Bin.Linker.umask = C.umask(0);
- if (!this.options.global)
- this.node_modules_folder.dir.makeDirZ(".bin") catch {};
-
this.has_created_bin = true;
}
diff --git a/test/cli/install/bun-install.test.ts b/test/cli/install/bun-install.test.ts
index 91c15c178..8dd3d3cba 100644
--- a/test/cli/install/bun-install.test.ts
+++ b/test/cli/install/bun-install.test.ts
@@ -4081,7 +4081,7 @@ it("should ignore invalid workspaces from parent directory", async () => {
expect(await exited).toBe(0);
expect(urls.sort()).toEqual([`${root_url}/bar`, `${root_url}/bar-0.0.2.tgz`]);
expect(requested).toBe(2);
- expect(await readdirSorted(join(package_dir))).toEqual(["bunfig.toml", "moo", "package.json"]);
+ expect(await readdirSorted(package_dir)).toEqual(["bunfig.toml", "moo", "package.json"]);
expect(await file(join(package_dir, "package.json")).text()).toEqual(foo_package);
expect(await readdirSorted(join(package_dir, "moo"))).toEqual([
"bun.lockb",
@@ -4137,7 +4137,7 @@ it("should handle --cwd", async () => {
expect(await exited).toBe(0);
expect(urls.sort()).toEqual([`${root_url}/bar`, `${root_url}/bar-0.0.2.tgz`]);
expect(requested).toBe(2);
- expect(await readdirSorted(join(package_dir))).toEqual(["bunfig.toml", "moo", "package.json"]);
+ expect(await readdirSorted(package_dir)).toEqual(["bunfig.toml", "moo", "package.json"]);
expect(await file(join(package_dir, "package.json")).text()).toEqual(foo_package);
expect(await readdirSorted(join(package_dir, "moo"))).toEqual([
"bun.lockb",
@@ -4153,3 +4153,158 @@ it("should handle --cwd", async () => {
version: "0.0.2",
});
});
+
+it("should perform bin-linking across multiple dependencies", async () => {
+ const foo_package = JSON.stringify({
+ name: "foo",
+ devDependencies: {
+ "conditional-type-checks": "1.0.6",
+ "prettier": "2.8.8",
+ "tsd": "0.22.0",
+ "typescript": "5.0.4",
+ },
+ });
+ await writeFile(join(package_dir, "package.json"), foo_package);
+ await writeFile(
+ join(package_dir, "bunfig.toml"),
+ `
+[install]
+cache = false
+`,
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "install"],
+ cwd: package_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env,
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toContain("Saved lockfile");
+ expect(err).not.toContain("error:");
+ expect(stdout).toBeDefined();
+ const out = await new Response(stdout).text();
+ expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
+ " + conditional-type-checks@1.0.6",
+ " + prettier@2.8.8",
+ " + tsd@0.22.0",
+ " + typescript@5.0.4",
+ "",
+ " 119 packages installed",
+ ]);
+ expect(await exited).toBe(0);
+ expect(await readdirSorted(package_dir)).toEqual(["bun.lockb", "bunfig.toml", "node_modules", "package.json"]);
+ expect(await file(join(package_dir, "package.json")).text()).toEqual(foo_package);
+ expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
+ ".bin",
+ ".cache",
+ "@babel",
+ "@nodelib",
+ "@tsd",
+ "@types",
+ "ansi-escapes",
+ "ansi-regex",
+ "ansi-styles",
+ "array-union",
+ "arrify",
+ "braces",
+ "camelcase",
+ "camelcase-keys",
+ "chalk",
+ "color-convert",
+ "color-name",
+ "conditional-type-checks",
+ "decamelize",
+ "decamelize-keys",
+ "dir-glob",
+ "emoji-regex",
+ "error-ex",
+ "escape-string-regexp",
+ "eslint-formatter-pretty",
+ "eslint-rule-docs",
+ "fast-glob",
+ "fastq",
+ "fill-range",
+ "find-up",
+ "function-bind",
+ "glob-parent",
+ "globby",
+ "hard-rejection",
+ "has",
+ "has-flag",
+ "hosted-git-info",
+ "ignore",
+ "indent-string",
+ "irregular-plurals",
+ "is-arrayish",
+ "is-core-module",
+ "is-extglob",
+ "is-fullwidth-code-point",
+ "is-glob",
+ "is-number",
+ "is-plain-obj",
+ "is-unicode-supported",
+ "js-tokens",
+ "json-parse-even-better-errors",
+ "kind-of",
+ "lines-and-columns",
+ "locate-path",
+ "log-symbols",
+ "lru-cache",
+ "map-obj",
+ "meow",
+ "merge2",
+ "micromatch",
+ "min-indent",
+ "minimist-options",
+ "normalize-package-data",
+ "p-limit",
+ "p-locate",
+ "p-try",
+ "parse-json",
+ "path-exists",
+ "path-parse",
+ "path-type",
+ "picomatch",
+ "plur",
+ "prettier",
+ "queue-microtask",
+ "quick-lru",
+ "read-pkg",
+ "read-pkg-up",
+ "redent",
+ "resolve",
+ "reusify",
+ "run-parallel",
+ "semver",
+ "slash",
+ "spdx-correct",
+ "spdx-exceptions",
+ "spdx-expression-parse",
+ "spdx-license-ids",
+ "string-width",
+ "strip-ansi",
+ "strip-indent",
+ "supports-color",
+ "supports-hyperlinks",
+ "supports-preserve-symlinks-flag",
+ "to-regex-range",
+ "trim-newlines",
+ "tsd",
+ "type-fest",
+ "typescript",
+ "validate-npm-package-license",
+ "yallist",
+ "yargs-parser",
+ ]);
+ expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([
+ "prettier",
+ "resolve",
+ "semver",
+ "tsc",
+ "tsd",
+ "tsserver",
+ ]);
+}, 10000);
diff --git a/test/cli/install/dummy.registry.ts b/test/cli/install/dummy.registry.ts
index d4436ab73..69af0c381 100644
--- a/test/cli/install/dummy.registry.ts
+++ b/test/cli/install/dummy.registry.ts
@@ -8,7 +8,7 @@ import { mkdtempSync, realpathSync } from "fs";
let expect: typeof import("bun:test")["expect"];
-import { mkdtemp, readdir, realpath, rm, writeFile } from "fs/promises";
+import { readdir, rm, writeFile } from "fs/promises";
import { tmpdir } from "os";
import { basename, join } from "path";