From 4b63ced72dc1b304e737d9ea055c8b6e75f46119 Mon Sep 17 00:00:00 2001 From: dave caruso Date: Thu, 7 Sep 2023 09:04:21 -0700 Subject: fix(cli): final touches for 1.0 (#4538) * better * cli * remove submodule --------- Co-authored-by: Jarred Sumner --- .vscode/launch.json | 2 +- src/cli.zig | 74 ++++++++++++++++++++++++++++++++++++++++++------ src/cli/bunx_command.zig | 2 +- src/cli/init_command.zig | 44 ++++++++++++++-------------- 4 files changed, 88 insertions(+), 34 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c5da97788..862c583a5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "request": "launch", "name": "bun test [file]", "program": "bun-debug", - "args": ["create", "--help"], + "args": ["test", "${file}"], // The cwd here must be the same as in CI. Or you will cause test failures that only happen in CI. "cwd": "${workspaceFolder}/test", "env": { diff --git a/src/cli.zig b/src/cli.zig index 2326f346a..303063574 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -888,7 +888,7 @@ pub const HelpCommand = struct { \\ run ./my-script.ts Run JavaScript with Bun, a package.json script, or a bin \\ test Run unit tests with Bun \\ x {s:<16} Install and execute a package bin (bunx) - // \\ repl Start a REPL session with Bun + \\ repl Start a REPL session with Bun \\ \\ init Start an empty Bun project from a blank template \\ create {s:<16} Create a new project from a template (bun c) @@ -929,7 +929,7 @@ pub const HelpCommand = struct { switch (reason) { .explicit => Output.pretty( - "Bun: a fast JavaScript runtime, package manager, bundler and test runner.\n\n" ++ fmt, + "Bun: a fast JavaScript runtime, package manager, bundler and test runner. (" ++ Global.package_json_version ++ ")\n\n" ++ fmt, args, ), .invalid_command => Output.prettyError( @@ -950,6 +950,21 @@ pub const HelpCommand = struct { } }; +pub const ReservedCommand = struct { + pub fn exec(_: std.mem.Allocator) !void { + @setCold(true); + const command_name = bun.argv()[1]; + Output.prettyError( + \\Uh-oh. bun {s} is a subcommand reserved for future use by Bun. + \\ + \\If you were trying to run a package.json script called {s}, use bun run {s}. + \\ + , .{ command_name, command_name, command_name }); + Output.flush(); + std.process.exit(1); + } +}; + const AddCompletions = @import("./cli/add_completions.zig"); pub const Command = struct { @@ -1116,8 +1131,11 @@ pub const Command = struct { RootCommandMatcher.case("link") => .LinkCommand, RootCommandMatcher.case("unlink") => .UnlinkCommand, RootCommandMatcher.case("x") => .BunxCommand, + RootCommandMatcher.case("repl") => .ReplCommand, - RootCommandMatcher.case("i"), RootCommandMatcher.case("install") => brk: { + RootCommandMatcher.case("i"), + RootCommandMatcher.case("install"), + => brk: { for (args_iter.buf) |arg| { const span = std.mem.span(arg); if (span.len > 0 and (strings.eqlComptime(span, "-g") or strings.eqlComptime(span, "--global"))) { @@ -1129,17 +1147,41 @@ pub const Command = struct { }, RootCommandMatcher.case("c"), RootCommandMatcher.case("create") => .CreateCommand, - RootCommandMatcher.case(TestCommand.name) => .TestCommand, + RootCommandMatcher.case("test") => .TestCommand, RootCommandMatcher.case("pm") => .PackageManagerCommand, RootCommandMatcher.case("add"), RootCommandMatcher.case("a") => .AddCommand, + RootCommandMatcher.case("update") => .UpdateCommand, - RootCommandMatcher.case("r"), RootCommandMatcher.case("remove"), RootCommandMatcher.case("rm"), RootCommandMatcher.case("uninstall") => .RemoveCommand, - RootCommandMatcher.case("run") => .RunCommand, + RootCommandMatcher.case("r"), + RootCommandMatcher.case("remove"), + RootCommandMatcher.case("rm"), + RootCommandMatcher.case("uninstall"), + => .RemoveCommand, + RootCommandMatcher.case("run") => .RunCommand, RootCommandMatcher.case("help") => .HelpCommand, + + // These are reserved for future use by Bun, so that someone + // doing `bun deploy` to run a script doesn't accidentally break + // when we add our actual command + RootCommandMatcher.case("deploy") => .ReservedCommand, + RootCommandMatcher.case("cloud") => .ReservedCommand, + RootCommandMatcher.case("info") => .ReservedCommand, + RootCommandMatcher.case("config") => .ReservedCommand, + RootCommandMatcher.case("use") => .ReservedCommand, + RootCommandMatcher.case("auth") => .ReservedCommand, + RootCommandMatcher.case("login") => .ReservedCommand, + RootCommandMatcher.case("logout") => .ReservedCommand, + RootCommandMatcher.case("whoami") => .ReservedCommand, + RootCommandMatcher.case("publish") => .ReservedCommand, + RootCommandMatcher.case("prune") => .ReservedCommand, + RootCommandMatcher.case("outdated") => .ReservedCommand, + RootCommandMatcher.case("list") => .ReservedCommand, + RootCommandMatcher.case("why") => .ReservedCommand, + else => .AutoCommand, }; } @@ -1158,6 +1200,7 @@ pub const Command = struct { "discord", "pm", "x", + "repl", }; const reject_list = default_completions_list ++ [_]string{ @@ -1236,6 +1279,7 @@ pub const Command = struct { .DiscordCommand => return try DiscordCommand.exec(allocator), .HelpCommand => return try HelpCommand.exec(allocator), .InitCommand => return try InitCommand.exec(allocator, bun.argv()), + .ReservedCommand => return try ReservedCommand.exec(allocator), else => {}, } @@ -1279,6 +1323,16 @@ pub const Command = struct { try BunxCommand.exec(ctx, bun.argv()[1..]); return; }, + .ReplCommand => { + // TODO: Put this in native code. + if (comptime bun.fast_debug_build_mode and bun.fast_debug_build_cmd != .BunxCommand) unreachable; + var ctx = try Command.Context.create(allocator, log, .BunxCommand); + ctx.debug.run_in_bun = true; // force the same version of bun used. fixes bun-debug for example + var args = bun.argv()[1..]; + args[0] = @constCast("bun-repl"); + try BunxCommand.exec(ctx, args); + return; + }, .RemoveCommand => { if (comptime bun.fast_debug_build_mode and bun.fast_debug_build_cmd != .RemoveCommand) unreachable; const ctx = try Command.Context.create(allocator, log, .RemoveCommand); @@ -1403,10 +1457,11 @@ pub const Command = struct { }, .CreateCommand => { if (comptime bun.fast_debug_build_mode and bun.fast_debug_build_cmd != .CreateCommand) unreachable; + // These are templates from the legacy `bun create` + // most of them aren't useful but these few are kinda nice. const HardcodedNonBunXList = bun.ComptimeStringMap(void, .{ .{"elysia"}, .{"elysia-buchta"}, - .{"bun-bakery"}, .{"stric"}, }); @@ -1416,7 +1471,6 @@ pub const Command = struct { var args = try std.process.argsAlloc(allocator); if (args.len <= 2) { - // Help Output.prettyErrorln( \\bun create: create a new project from a template \\ @@ -1445,7 +1499,7 @@ pub const Command = struct { var slice = std.mem.trim(u8, bun.asByteSlice(remainder[remainder_i]), " \t\n;"); if (slice.len > 0 and !strings.hasPrefixComptime(slice, "--")) { if (positional_i == 0) { - template_name_start = remainder_i; + template_name_start = remainder_i + 2; } positionals[positional_i] = slice; positional_i += 1; @@ -1698,6 +1752,8 @@ pub const Command = struct { UnlinkCommand, UpdateCommand, UpgradeCommand, + ReplCommand, + ReservedCommand, pub fn params(comptime cmd: Tag) []const Arguments.ParamType { return &comptime switch (cmd) { diff --git a/src/cli/bunx_command.zig b/src/cli/bunx_command.zig index 0a161d102..f721eb98b 100644 --- a/src/cli/bunx_command.zig +++ b/src/cli/bunx_command.zig @@ -163,7 +163,7 @@ pub const BunxCommand = struct { var requests_buf = bun.PackageManager.UpdateRequest.Array.init(0) catch unreachable; var run_in_bun = ctx.debug.run_in_bun; - var passthrough_list = try std.ArrayList(string).initCapacity(ctx.allocator, bun.argv().len -| 1); + var passthrough_list = try std.ArrayList(string).initCapacity(ctx.allocator, argv.len); var package_name_for_update_request = [1]string{""}; { var found_subcommand_name = false; diff --git a/src/cli/init_command.zig b/src/cli/init_command.zig index 0606500ac..ed9a00477 100644 --- a/src/cli/init_command.zig +++ b/src/cli/init_command.zig @@ -221,23 +221,27 @@ pub const InitCommand = struct { }; if (!auto_yes) { - Output.prettyln("bun init helps you get started with a minimal project and tries to guess sensible defaults.\nPress ^C anytime to quit\n\n", .{}); - Output.flush(); + if (!did_load_package_json) { + Output.prettyln("bun init helps you get started with a minimal project and tries to guess sensible defaults. Press ^C anytime to quit\n\n", .{}); + Output.flush(); - fields.name = try normalizePackageName(alloc, try prompt( - alloc, - "package name ", - fields.name, - Output.enable_ansi_colors_stdout, - )); - fields.entry_point = try prompt( - alloc, - "entry point ", - fields.entry_point, - Output.enable_ansi_colors_stdout, - ); - try Output.writer().writeAll("\n"); - Output.flush(); + fields.name = try normalizePackageName(alloc, try prompt( + alloc, + "package name ", + fields.name, + Output.enable_ansi_colors_stdout, + )); + fields.entry_point = try prompt( + alloc, + "entry point ", + fields.entry_point, + Output.enable_ansi_colors_stdout, + ); + try Output.writer().writeAll("\n"); + Output.flush(); + } else { + Output.prettyln("A package.json was found here. Would you like to configure", .{}); + } } const Steps = struct { @@ -249,13 +253,7 @@ pub const InitCommand = struct { var steps = Steps{}; - steps.write_gitignore = brk: { - if (exists(".gitignore")) { - break :brk false; - } - - break :brk true; - }; + steps.write_gitignore = !exists(".gitignore"); steps.write_readme = !exists("README.md") and !exists("README") and !exists("README.txt") and !exists("README.mdx"); -- cgit v1.2.3