Skip to content

Commit 66feb3f

Browse files
Jarred-Sumnerpaperclover
authored andcommitted
Always get latest version when @tag is explicitly passed (oven-sh#5346)
1 parent 36576ab commit 66feb3f

File tree

1 file changed

+65
-57
lines changed

1 file changed

+65
-57
lines changed

src/cli/bunx_command.zig

+65-57
Original file line numberDiff line numberDiff line change
@@ -279,65 +279,67 @@ pub const BunxCommand = struct {
279279

280280
const passthrough = passthrough_list.items;
281281

282-
// Similar to "npx":
283-
//
284-
// 1. Try the bin in the current node_modules and then we try the bin in the global cache
285-
if (bun.which(
286-
&path_buf,
287-
PATH_FOR_BIN_DIRS,
288-
this_bundler.fs.top_level_dir,
289-
initial_bin_name,
290-
) orelse bun.which(
291-
&path_buf,
292-
bunx_cache_dir,
293-
this_bundler.fs.top_level_dir,
294-
absolute_in_cache_dir,
295-
)) |destination| {
296-
const out = bun.asByteSlice(destination);
297-
_ = try Run.runBinary(
298-
ctx,
299-
try this_bundler.fs.dirname_store.append(@TypeOf(out), out),
282+
if (update_request.version.literal.isEmpty() or update_request.version.tag != .dist_tag) {
283+
// Similar to "npx":
284+
//
285+
// 1. Try the bin in the current node_modules and then we try the bin in the global cache
286+
if (bun.which(
287+
&path_buf,
288+
PATH_FOR_BIN_DIRS,
300289
this_bundler.fs.top_level_dir,
301-
this_bundler.env,
302-
passthrough,
303-
);
304-
// we are done!
305-
Global.exit(0);
306-
}
290+
initial_bin_name,
291+
) orelse bun.which(
292+
&path_buf,
293+
bunx_cache_dir,
294+
this_bundler.fs.top_level_dir,
295+
absolute_in_cache_dir,
296+
)) |destination| {
297+
const out = bun.asByteSlice(destination);
298+
_ = try Run.runBinary(
299+
ctx,
300+
try this_bundler.fs.dirname_store.append(@TypeOf(out), out),
301+
this_bundler.fs.top_level_dir,
302+
this_bundler.env,
303+
passthrough,
304+
);
305+
// we are done!
306+
Global.exit(0);
307+
}
307308

308-
// 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
309-
if (getBinName(&this_bundler, bun.fdcast(root_dir_info.getFileDescriptor()), bunx_cache_dir, initial_bin_name)) |package_name_for_bin| {
310-
// if we check the bin name and its actually the same, we don't need to check $PATH here again
311-
if (!strings.eqlLong(package_name_for_bin, initial_bin_name, true)) {
312-
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;
309+
// 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
310+
if (getBinName(&this_bundler, bun.fdcast(root_dir_info.getFileDescriptor()), bunx_cache_dir, initial_bin_name)) |package_name_for_bin| {
311+
// if we check the bin name and its actually the same, we don't need to check $PATH here again
312+
if (!strings.eqlLong(package_name_for_bin, initial_bin_name, true)) {
313+
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;
313314

314-
if (bun.which(
315-
&path_buf,
316-
PATH_FOR_BIN_DIRS,
317-
this_bundler.fs.top_level_dir,
318-
package_name_for_bin,
319-
) orelse bun.which(
320-
&path_buf,
321-
bunx_cache_dir,
322-
this_bundler.fs.top_level_dir,
323-
absolute_in_cache_dir,
324-
)) |destination| {
325-
const out = bun.asByteSlice(destination);
326-
_ = try Run.runBinary(
327-
ctx,
328-
try this_bundler.fs.dirname_store.append(@TypeOf(out), out),
315+
if (bun.which(
316+
&path_buf,
317+
PATH_FOR_BIN_DIRS,
329318
this_bundler.fs.top_level_dir,
330-
this_bundler.env,
331-
passthrough,
332-
);
333-
// we are done!
334-
Global.exit(0);
319+
package_name_for_bin,
320+
) orelse bun.which(
321+
&path_buf,
322+
bunx_cache_dir,
323+
this_bundler.fs.top_level_dir,
324+
absolute_in_cache_dir,
325+
)) |destination| {
326+
const out = bun.asByteSlice(destination);
327+
_ = try Run.runBinary(
328+
ctx,
329+
try this_bundler.fs.dirname_store.append(@TypeOf(out), out),
330+
this_bundler.fs.top_level_dir,
331+
this_bundler.env,
332+
passthrough,
333+
);
334+
// we are done!
335+
Global.exit(0);
336+
}
337+
}
338+
} else |err| {
339+
if (err == error.NoBinFound) {
340+
Output.prettyErrorln("<r><red>error<r><d>:<r> could not determine executable to run for package <r><b>{s}<r>", .{update_request.name});
341+
Global.exit(1);
335342
}
336-
}
337-
} else |err| {
338-
if (err == error.NoBinFound) {
339-
Output.prettyErrorln("<r><red>error<r><d>:<r> could not determine executable to run for package <r><b>{s}<r>", .{update_request.name});
340-
Global.exit(1);
341343
}
342344
}
343345

@@ -353,22 +355,28 @@ pub const BunxCommand = struct {
353355

354356
create_package_json: {
355357
// create package.json, but only if it doesn't exist
356-
var package_json = bunx_install_dir.createFileZ("package.json", .{ .truncate = false }) catch break :create_package_json;
358+
var package_json = bunx_install_dir.createFileZ("package.json", .{ .truncate = true }) catch break :create_package_json;
357359
defer package_json.close();
358360
package_json.writeAll("{}\n") catch {};
359361
}
360362

361363
var args_buf = [_]string{
362-
try std.fs.selfExePathAlloc(ctx.allocator), "add", "--no-summary", try std.fmt.allocPrint(
364+
try std.fs.selfExePathAlloc(ctx.allocator), "add", "--no-summary",
365+
try std.fmt.allocPrint(
363366
ctx.allocator,
364367
"{s}@{s}",
365368
.{
366369
update_request.name,
367370
display_version,
368371
},
369372
),
373+
// disable the manifest cache when a tag is specified
374+
// so that @latest is fetched from the registry
375+
"--no-cache",
370376
};
371-
var child_process = std.ChildProcess.init(&args_buf, default_allocator);
377+
const argv_to_use: []const string = args_buf[0 .. args_buf.len - @as(usize, @intFromBool(update_request.version.tag != .dist_tag))];
378+
379+
var child_process = std.ChildProcess.init(argv_to_use, default_allocator);
372380
child_process.cwd = bunx_install_dir_path;
373381
child_process.cwd_dir = bunx_install_dir;
374382
const env_map = try this_bundler.env.map.cloneToEnvMap(ctx.allocator);

0 commit comments

Comments
 (0)