diff options
author | 2023-03-04 13:56:25 +0100 | |
---|---|---|
committer | 2023-03-04 14:56:25 +0200 | |
commit | 8e1d2a5af9909dc44865e8aed1c251cf2ffe6189 (patch) | |
tree | 9233bcc3fe3145b16d98fcf5e92e9166fb2e7bab | |
parent | 362684505177e8edf8f8231bfe2f824c8ab28090 (diff) | |
download | bun-8e1d2a5af9909dc44865e8aed1c251cf2ffe6189.tar.gz bun-8e1d2a5af9909dc44865e8aed1c251cf2ffe6189.tar.zst bun-8e1d2a5af9909dc44865e8aed1c251cf2ffe6189.zip |
fix(bunx): can't resolve executable for scoped packages (#2293)
Fixes #2292
-rw-r--r-- | src/cli/bunx_command.zig | 4 | ||||
-rw-r--r-- | test/bun.js/install/bunx.test.ts | 41 |
2 files changed, 43 insertions, 2 deletions
diff --git a/src/cli/bunx_command.zig b/src/cli/bunx_command.zig index ef23757df..6aba8379e 100644 --- a/src/cli/bunx_command.zig +++ b/src/cli/bunx_command.zig @@ -211,6 +211,8 @@ pub const BunxCommand = struct { const initial_bin_name = if (strings.eqlComptime(update_request.name, "typescript")) "tsc" + else if (strings.lastIndexOfChar(update_request.name, '/')) |index| + update_request.name[index + 1 ..] else update_request.name; @@ -374,7 +376,7 @@ pub const BunxCommand = struct { }, } - absolute_in_cache_dir = std.fmt.bufPrint(&absolute_in_cache_dir_buf, "{s}/node_modules/.bin/{s}", .{ bunx_cache_dir, update_request.name }) catch unreachable; + absolute_in_cache_dir = std.fmt.bufPrint(&absolute_in_cache_dir_buf, "{s}/node_modules/.bin/{s}", .{ bunx_cache_dir, initial_bin_name }) catch unreachable; // Similar to "npx": // diff --git a/test/bun.js/install/bunx.test.ts b/test/bun.js/install/bunx.test.ts index 941f006bb..e43dd673d 100644 --- a/test/bun.js/install/bunx.test.ts +++ b/test/bun.js/install/bunx.test.ts @@ -3,7 +3,7 @@ import { afterEach, beforeEach, expect, it } from "bun:test"; import { bunExe } from "bunExe"; import { bunEnv as env } from "bunEnv"; import { realpathSync } from "fs"; -import { mkdtemp, rm, writeFile } from "fs/promises"; +import { mkdtemp, realpath, rm, writeFile } from "fs/promises"; import { tmpdir } from "os"; import { join } from "path"; import { readdirSorted } from "./dummy.registry"; @@ -72,6 +72,45 @@ it("should output usage if no arguments are passed", async () => { expect(await exited).toBe(1); }); +it("should work for @scoped packages", async () => { + await rm(join(await realpath(tmpdir()), "@withfig"), { force: true, recursive: true }); + // without cache + const withoutCache = spawn({ + cmd: [bunExe(), "x", "@withfig/autocomplete-tools", "--help"], + cwd: x_dir, + stdout: null, + stdin: "pipe", + stderr: "pipe", + env, + }); + + expect(withoutCache.stderr).toBeDefined(); + let err = await new Response(withoutCache.stderr).text(); + expect(err).not.toContain("error"); + expect(withoutCache.stdout).toBeDefined(); + let out = await new Response(withoutCache.stdout).text(); + expect(out.trim()).toContain("Usage: @withfig/autocomplete-tool"); + expect(await withoutCache.exited).toBe(0); + + // cached + const cached = spawn({ + cmd: [bunExe(), "x", "@withfig/autocomplete-tools", "--help"], + cwd: x_dir, + stdout: null, + stdin: "pipe", + stderr: "pipe", + env, + }); + + expect(cached.stderr).toBeDefined(); + err = await new Response(cached.stderr).text(); + expect(err).not.toContain("error"); + expect(cached.stdout).toBeDefined(); + out = await new Response(cached.stdout).text(); + expect(out.trim()).toContain("Usage: @withfig/autocomplete-tool"); + expect(await cached.exited).toBe(0); +}); + it("should download dependency to run local file", async () => { await writeFile( join(x_dir, "test.js"), |