diff options
-rw-r--r-- | src/cli/bunx_command.zig | 57 | ||||
-rw-r--r-- | test/cli/install/bunx.test.ts | 20 |
2 files changed, 51 insertions, 26 deletions
diff --git a/src/cli/bunx_command.zig b/src/cli/bunx_command.zig index 6fa022cae..05d7d70df 100644 --- a/src/cli/bunx_command.zig +++ b/src/cli/bunx_command.zig @@ -159,7 +159,8 @@ pub const BunxCommand = struct { Global.exit(1); } - pub fn exec(ctx: bun.CLI.Command.Context, argv: [][*:0]const u8) !void { + pub fn exec(ctx_: bun.CLI.Command.Context, argv: [][*:0]const u8) !void { + var ctx = ctx_; var requests_buf = bun.PackageManager.UpdateRequest.Array.init(0) catch unreachable; var run_in_bun = ctx.debug.run_in_bun; @@ -220,6 +221,9 @@ pub const BunxCommand = struct { Global.exit(1); } + // Don't log stuff + ctx.debug.silent = true; + var update_request = update_requests[0]; // if you type "tsc" and TypeScript is not installed: @@ -280,15 +284,22 @@ pub const BunxCommand = struct { const passthrough = passthrough_list.items; if (update_request.version.literal.isEmpty() or update_request.version.tag != .dist_tag) { + var destination_: ?[:0]const u8 = null; + + // Only use the system-installed version if there is no version specified + if (update_request.version.literal.isEmpty()) { + destination_ = bun.which( + &path_buf, + PATH_FOR_BIN_DIRS, + this_bundler.fs.top_level_dir, + initial_bin_name, + ); + } + // Similar to "npx": // // 1. Try the bin in the current node_modules and then we try the bin in the global cache - if (bun.which( - &path_buf, - PATH_FOR_BIN_DIRS, - this_bundler.fs.top_level_dir, - initial_bin_name, - ) orelse bun.which( + if (destination_ orelse bun.which( &path_buf, bunx_cache_dir, this_bundler.fs.top_level_dir, @@ -312,12 +323,17 @@ pub const BunxCommand = struct { if (!strings.eqlLong(package_name_for_bin, initial_bin_name, true)) { absolute_in_cache_dir = std.fmt.bufPrint(&absolute_in_cache_dir_buf, "{s}/node_modules/.bin/{s}", .{ bunx_cache_dir, package_name_for_bin }) catch unreachable; - if (bun.which( - &path_buf, - PATH_FOR_BIN_DIRS, - this_bundler.fs.top_level_dir, - package_name_for_bin, - ) orelse bun.which( + // Only use the system-installed version if there is no version specified + if (update_request.version.literal.isEmpty()) { + destination_ = bun.which( + &path_buf, + PATH_FOR_BIN_DIRS, + this_bundler.fs.top_level_dir, + package_name_for_bin, + ); + } + + if (destination_ orelse bun.which( &path_buf, bunx_cache_dir, this_bundler.fs.top_level_dir, @@ -408,14 +424,10 @@ pub const BunxCommand = struct { // Similar to "npx": // - // 1. Try the bin in the current node_modules and then we try the bin in the global cache + // 1. Try the bin in the global cache + // Do not try $PATH because we already checked it above if we should if (bun.which( &path_buf, - PATH_FOR_BIN_DIRS, - this_bundler.fs.top_level_dir, - initial_bin_name, - ) orelse bun.which( - &path_buf, bunx_cache_dir, this_bundler.fs.top_level_dir, absolute_in_cache_dir, @@ -434,18 +446,11 @@ pub const BunxCommand = struct { // 2. The "bin" is possibly not the same as the package name, so we load the package.json to figure out what "bin" to use if (getBinNameFromTempDirectory(&this_bundler, bunx_cache_dir, update_request.name)) |package_name_for_bin| { - - // if we check the bin name and its actually the same, we don't need to check $PATH here again if (!strings.eqlLong(package_name_for_bin, initial_bin_name, true)) { absolute_in_cache_dir = std.fmt.bufPrint(&absolute_in_cache_dir_buf, "{s}/node_modules/.bin/{s}", .{ bunx_cache_dir, package_name_for_bin }) catch unreachable; if (bun.which( &path_buf, - PATH_FOR_BIN_DIRS, - this_bundler.fs.top_level_dir, - package_name_for_bin, - ) orelse bun.which( - &path_buf, bunx_cache_dir, this_bundler.fs.top_level_dir, absolute_in_cache_dir, diff --git a/test/cli/install/bunx.test.ts b/test/cli/install/bunx.test.ts index 70d7aac29..c353aa123 100644 --- a/test/cli/install/bunx.test.ts +++ b/test/cli/install/bunx.test.ts @@ -15,6 +15,26 @@ afterEach(async () => { await rm(x_dir, { force: true, recursive: true }); }); +it("should choose the tagged versions instead of the PATH versions when a tag is specified", async () => { + const processes = Array.from({ length: 3 }, (_, i) => { + return spawn({ + cmd: [bunExe(), "x", "semver@7.5." + i, "--help"], + cwd: x_dir, + stdout: "pipe", + stdin: "ignore", + stderr: "inherit", + env, + }); + }); + + const results = await Promise.all(processes.map(p => p.exited)); + expect(results).toEqual([0, 0, 0]); + const outputs = (await Promise.all(processes.map(p => new Response(p.stdout).text()))).map(a => + a.substring(0, a.indexOf("\n")), + ); + expect(outputs).toEqual(["SemVer 7.5.0", "SemVer 7.5.1", "SemVer 7.5.2"]); +}); + it("should install and run default (latest) version", async () => { const { stdout, stderr, exited } = spawn({ cmd: [bunExe(), "x", "uglify-js", "--compress"], |