diff options
author | 2023-03-04 02:49:32 +0100 | |
---|---|---|
committer | 2023-03-03 17:49:32 -0800 | |
commit | 7c367ff687554c39baf1d27218c9c8bc7129650b (patch) | |
tree | 41ac0661ffa2d5fc3a6de7591551d5e3b64185bc | |
parent | 0f8f484e21e3ebafaf62370421f6296eaca262fe (diff) | |
download | bun-7c367ff687554c39baf1d27218c9c8bc7129650b.tar.gz bun-7c367ff687554c39baf1d27218c9c8bc7129650b.tar.zst bun-7c367ff687554c39baf1d27218c9c8bc7129650b.zip |
fix(bunx): Show usage when calling bunx without arguments (#2295)
* Make sure to return a helpful error message if no args are passed to bunx
* Add tests for bunx without args
-rw-r--r-- | src/cli/bunx_command.zig | 43 | ||||
-rw-r--r-- | test/bun.js/install/bunx.test.ts | 19 |
2 files changed, 45 insertions, 17 deletions
diff --git a/src/cli/bunx_command.zig b/src/cli/bunx_command.zig index ef1fc3c17..ef23757df 100644 --- a/src/cli/bunx_command.zig +++ b/src/cli/bunx_command.zig @@ -118,6 +118,25 @@ pub const BunxCommand = struct { }; } + fn exit_with_usage() noreturn { + Output.prettyErrorln( + \\usage<r><d>:<r> <cyan>bunx <r><d>[<r><blue>--bun<r><d>]<r><cyan> package<r><d>[@version] [...flags or arguments to pass through]<r> + \\ + \\bunx runs an npm package executable, automatically installing into a global shared cache if not installed in node_modules. + \\ + \\example<d>:<r> + \\ + \\ <cyan>bunx bun-repl<r> + \\ <cyan>bunx prettier foo.js<r> + \\ + \\The <blue>--bun<r> flag forces the package to run in Bun's JavaScript runtime, even when it tries to use Node.js. + \\ + \\ <cyan>bunx <r><blue>--bun<r><cyan> tsc --version<r> + \\ + , .{}); + Global.exit(1); + } + pub fn exec(ctx: bun.CLI.Command.Context) !void { var requests_buf = bun.PackageManager.UpdateRequest.Array.init(0) catch unreachable; var run_in_bun = ctx.debug.run_in_bun; @@ -158,7 +177,10 @@ pub const BunxCommand = struct { } } - const passthrough = passthrough_list.items; + // check if package_name_for_update_request is empty string or " " + if (package_name_for_update_request[0].len == 0) { + exit_with_usage(); + } var update_requests = bun.PackageManager.UpdateRequest.parse( ctx.allocator, @@ -169,22 +191,7 @@ pub const BunxCommand = struct { ); if (update_requests.len == 0) { - Output.prettyErrorln( - \\usage<r><d>:<r> <cyan>bunx <r><d>[<r><blue>--bun<r><d>]<r><cyan> package<r><d>[@version] [...flags or arguments to pass through]<r> - \\ - \\bunx runs an npm package executable, automatically installing into a global shared cache if not installed in node_modules. - \\ - \\example<d>:<r> - \\ - \\ <cyan>bunx bun-repl<r> - \\ <cyan>bunx prettier foo.js<r> - \\ - \\The <blue>--bun<r> flag forces the package to run in Bun's JavaScript runtime, even when it tries to use Node.js. - \\ - \\ <cyan>bunx <r><blue>--bun<r><cyan> tsc --version<r> - \\ - , .{}); - Global.exit(1); + exit_with_usage(); } // this shouldn't happen @@ -248,6 +255,8 @@ pub const BunxCommand = struct { var absolute_in_cache_dir_buf: [bun.MAX_PATH_BYTES]u8 = undefined; var 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; + const passthrough = passthrough_list.items; + // Similar to "npx": // // 1. Try the bin in the current node_modules and then we try the bin in the global cache diff --git a/test/bun.js/install/bunx.test.ts b/test/bun.js/install/bunx.test.ts index 76cd944a1..941f006bb 100644 --- a/test/bun.js/install/bunx.test.ts +++ b/test/bun.js/install/bunx.test.ts @@ -53,6 +53,25 @@ it("should install and run specified version", async () => { expect(await exited).toBe(0); }); +it("should output usage if no arguments are passed", async () => { + const { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "x"], + cwd: x_dir, + stdout: null, + stdin: "pipe", + stderr: "pipe", + env, + }); + + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err).toContain("usage: "); + expect(stdout).toBeDefined(); + const out = await new Response(stdout).text(); + expect(out).toHaveLength(0); + expect(await exited).toBe(1); +}); + it("should download dependency to run local file", async () => { await writeFile( join(x_dir, "test.js"), |