aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cli/bunx_command.zig57
-rw-r--r--test/cli/install/bunx.test.ts20
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"],