diff options
author | 2023-10-10 00:07:41 -0700 | |
---|---|---|
committer | 2023-10-12 16:04:02 -0700 | |
commit | 07db922aad3b043a0b1826019e356b9e09c8d27b (patch) | |
tree | 3807f229efcabec7c1645abf212fd8167a08bfe1 | |
parent | bd2c8ca3d3d4c9ab6b89917395b13989bb08b051 (diff) | |
download | bun-07db922aad3b043a0b1826019e356b9e09c8d27b.tar.gz bun-07db922aad3b043a0b1826019e356b9e09c8d27b.tar.zst bun-07db922aad3b043a0b1826019e356b9e09c8d27b.zip |
WIP
-rw-r--r-- | src/cli.zig | 422 | ||||
-rw-r--r-- | src/cli/bunx_command.zig | 18 | ||||
-rw-r--r-- | src/cli/package_manager_command.zig | 40 | ||||
-rw-r--r-- | src/deps/zig-clap/clap.zig | 72 | ||||
-rw-r--r-- | src/install/install.zig | 148 |
5 files changed, 353 insertions, 347 deletions
diff --git a/src/cli.zig b/src/cli.zig index 5ec2146ea..807d8568f 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -55,46 +55,7 @@ pub const Cli = struct { MainPanicHandler.Singleton = &panicker; Command.start(allocator, log) catch |err| { switch (err) { - // error.MissingEntryPoint => { - // Output.prettyErrorln("<r><b>bun build <r><d>v" ++ Global.package_json_version_with_sha ++ "<r>", .{}); - // Output.prettyErrorln( - // \\<r><red>error: Missing entrypoints. What would you like to bundle?<r> - // \\ - // \\<b>Usage<r>: <b><green>bun build<r> [flags] [...entrypoints] - // \\ - // \\<b>Common Flags:<r> - // \\ <cyan>--outfile<r> Write the output to a specific file (default: stdout) - // \\ <cyan>--outdir<r> Write the output to a directory (required for splitting) - // \\ <cyan>--minify<r> Enable all minification flags - // \\ <cyan>--minify-whitespace<r> Remove unneeded whitespace - // \\ <cyan>--minify-syntax<r> Transform code to use less syntax - // \\ <cyan>--minify-identifiers<r> Shorten variable names - // \\ <cyan>--sourcemap<r> Generate sourcemaps - // \\ none | inline | external - // \\ <cyan>--target<r> The intended execution environment for the bundle. - // \\ browser | bun | node - // \\ <cyan>--splitting<r> Enable code splitting (requires --outdir) - // \\ <cyan>--watch<r> Run bundler in watch mode - // \\ - // \\<b>Examples:<r> - // \\ <d>Frontend web apps:<r> - // \\ <b><green>bun build<r> <blue>./src/index.ts<r> <cyan>--outfile=bundle.js<r> - // \\ <b><green>bun build<r> <cyan>--minify<r> <cyan>--splitting<r> <cyan>--outdir=out<r> <blue>./index.jsx ./lib/worker.ts<r> - // \\ - // \\ <d>Bundle code to be run in Bun (reduces server startup time)<r> - // \\ <b><green>bun build<r> <cyan>--target=bun<r> <blue>./server.ts<r> <cyan>--outfile=server.js<r> - // \\ - // \\ <d>Creating a standalone executable (see https://bun.sh/docs/bundler/executables)<r> - // \\ <b><green>bun build<r> <cyan>--compile<r> <blue>./cli.ts<r> <cyan>--outfile=my-app<r> - // \\ - // \\A full list of flags is available at <magenta>https://bun.sh/docs/bundler<r> - // \\ - // , .{}); - // Global.exit(1); - // }, else => { - // Always dump the logs - // std.debug.print("dump logs", .{}); if (Output.enable_ansi_colors_stderr) { log.printForLogLevelWithEnableAnsiColors(Output.errorWriter(), true) catch {}; } else { @@ -167,16 +128,15 @@ pub const Arguments = struct { const base_params_ = [_]ParamType{ clap.parseParam("-h, --help Display this menu and exit") catch unreachable, - // clap.parseParam("--all") catch unreachable, clap.parseParam("--cwd <STR> Absolute path to resolve files & entry points from. This just changes the process' cwd.") catch unreachable, - clap.parseParam("-c, --config <PATH>? Config file to load Bun from (e.g. -c bunfig.toml") catch unreachable, + clap.parseParam("-c, --config <PATH>? Specify path to Bun config file. Default <d>$cwd<r>/bunfig.toml") catch unreachable, clap.parseParam("<POS>...") catch unreachable, }; const transpiler_params_ = [_]ParamType{ clap.parseParam("--main-fields <STR>... Main fields to lookup in package.json. Defaults to --target dependent") catch unreachable, clap.parseParam("--extension-order <STR>... Defaults to: .tsx,.ts,.jsx,.js,.json ") catch unreachable, - clap.parseParam("--tsconfig-override <STR> Load tsconfig from path instead of cwd/tsconfig.json") catch unreachable, + clap.parseParam("--tsconfig-override <STR> Specify custom tsconfig.json. Default <d>$cwd<r>/tsconfig.json") catch unreachable, clap.parseParam("-d, --define <STR>... Substitute K:V while parsing, e.g. --define process.env.NODE_ENV:\"development\". Values are parsed as JSON.") catch unreachable, clap.parseParam("-e, --external <STR>... Exclude module from transpilation (can use * wildcards). ex: -e react") catch unreachable, clap.parseParam("-l, --loader <STR>... Parse files with .ext:loader, e.g. --loader .js:jsx. Valid loaders: js, jsx, ts, tsx, json, toml, text, file, wasm, napi") catch unreachable, @@ -187,26 +147,13 @@ pub const Arguments = struct { clap.parseParam("--jsx-runtime <STR> \"automatic\" (default) or \"classic\"") catch unreachable, }; const runtime_params_ = [_]ParamType{ - // clap.parseParam("--cwd <STR> Absolute path to resolve files & entry points from. This just changes the process' cwd.") catch unreachable, - // clap.parseParam("-c, --config <PATH>? Config file to load Bun from (e.g. -c bunfig.toml") catch unreachable, - clap.parseParam("-r, --preload <STR>... Import a module before other modules are loaded") catch unreachable, clap.parseParam("--hot Enable auto reload in the Bun runtime, test runner, or bundler") catch unreachable, clap.parseParam("--watch Automatically restart the process on file change") catch unreachable, - // clap.parseParam("--main-fields <STR>... Main fields to lookup in package.json. Defaults to --target dependent") catch unreachable, - // clap.parseParam("--no-summary Don't print a summary (when generating .bun)") catch unreachable, - - // clap.parseParam("-u, --origin <STR> Rewrite import URLs to start with --origin. Default: \"\"") catch unreachable, - // clap.parseParam("-p, --port <STR> Port to serve Bun's dev server on. Default: \"3000\"") catch unreachable, clap.parseParam("--smol Use less memory, but run garbage collection more often") catch unreachable, - // clap.parseParam("--minify Minify (experimental)") catch unreachable, - // clap.parseParam("--minify-syntax Minify syntax and inline data (experimental)") catch unreachable, - // clap.parseParam("--minify-whitespace Minify whitespace (experimental)") catch unreachable, - // clap.parseParam("--minify-identifiers Minify identifiers") catch unreachable, - - clap.parseParam("--inspect <STR>? Activate Bun's Debugger") catch unreachable, - clap.parseParam("--inspect-wait <STR>? Activate Bun's Debugger, wait for a connection before executing") catch unreachable, - clap.parseParam("--inspect-brk <STR>? Activate Bun's Debugger, set breakpoint on first line of code and wait") catch unreachable, + clap.parseParam("--inspect <STR>? Activate Bun's debugger") catch unreachable, + clap.parseParam("--inspect-wait <STR>? Activate Bun's debugger, wait for a connection before executing") catch unreachable, + clap.parseParam("--inspect-brk <STR>? Activate Bun's debugger, set breakpoint on first line of code and wait") catch unreachable, clap.parseParam("--if-present Exit if the entrypoint does not exist") catch unreachable, clap.parseParam("--no-install Disable auto install in the Bun runtime") catch unreachable, clap.parseParam("-i Automatically install dependencies and use global cache in Bun's runtime, equivalent to --install=fallback") catch unreachable, @@ -215,15 +162,7 @@ pub const Arguments = struct { clap.parseParam("--prefer-latest Use the latest matching versions of packages in the Bun runtime, always checking npm") catch unreachable, }; - // const runtime_params = [_]ParamType{ - // clap.parseParam("--silent Don't repeat the command for bun run") catch unreachable, - // }; - // const positional_params_ = [_]ParamType{ - // clap.parseParam("<POS>...") catch unreachable, - // }; - const auto_only_params = [_]ParamType{ - // clap.parseParam("-h, --help Display this menu and exit") catch unreachable, clap.parseParam("--all") catch unreachable, clap.parseParam("-v, --version Print version and exit") catch unreachable, clap.parseParam("--revision Print version with revision and exit") catch unreachable, @@ -238,6 +177,11 @@ pub const Arguments = struct { }; const run_params = run_only_params ++ runtime_params_ ++ transpiler_params_ ++ base_params_; + const bunx_commands = [_]ParamType{ + clap.parseParam("--silent Don't repeat the command for bun run") catch unreachable, + clap.parseParam("-b, --bun Force a script or package to use Bun's runtime instead of Node.js (via symlinking node)") catch unreachable, + }; + // these commands don't use clap // Command.Tag.BunxCommand // Command.Tag.InitCommand @@ -419,10 +363,8 @@ pub const Arguments = struct { } pub fn parse(allocator: std.mem.Allocator, ctx: *Command.Context, comptime cmd: Command.Tag) !Api.TransformOptions { - std.debug.print("starting parse\n", .{}); var diag = clap.Diagnostic{}; const params_to_parse = comptime cmd.params(); - const params_to_print = comptime cmd.params_to_print(); var args = clap.parse(clap.Help, params_to_parse, .{ .diagnostic = &diag, @@ -432,25 +374,17 @@ pub const Arguments = struct { else 0, }) catch |err| { - std.debug.print("error caught\n", .{}); // Report useful error and exit clap.help(Output.errorWriter(), params_to_parse) catch {}; Output.errorWriter().writeAll("\n") catch {}; diag.report(Output.errorWriter(), err) catch {}; - std.debug.print("done printing\n", .{}); Global.exit(1); }; - std.debug.print("past parsing\n", .{}); - // const print_all_help = args.flag("--all"); const print_help = args.flag("--help"); if (print_help) { - std.debug.print("printing help\n", .{}); - cmd.print_helptext(params_to_print); - // clap.help(Output.writer(), params_to_parse[0..params_to_parse.len]) catch {}; - // Output.prettyln("\n-------\n\n", .{}); + cmd.printHelp(); Output.flush(); - // HelpCommand.printWithReason(.explicit); Global.exit(0); } @@ -581,6 +515,7 @@ pub const Arguments = struct { // if (args.option("--port")) |port_str| { // opts.port = std.fmt.parseInt(u16, port_str, 10) catch return error.InvalidPort; // } + opts.serve = false; // TODO opts.main_fields = args.options("--main-fields"); // we never actually supported inject. @@ -592,7 +527,6 @@ pub const Arguments = struct { // opts.no_summary = args.flag("--no-summary"); if (cmd == .AutoCommand or cmd == .RunCommand or cmd == .TestCommand) { - std.debug.print("auto/run/test\n", .{}); const preloads = args.options("--preload"); if (args.flag("--hot")) { @@ -858,15 +792,11 @@ pub const Arguments = struct { if (cmd == .BuildCommand) { if (opts.entry_points.len == 0 and opts.framework == null) { Output.prettyErrorln("<r><b>bun build <r><d>v" ++ Global.package_json_version_with_sha ++ "<r>", .{}); - // Output.flush(); - // cmd.print_helptext(); - // Output.pretty("\n-------------\n", .{}); Output.prettyError("<r><red>error: Missing entrypoints. What would you like to bundle?<r>\n\n", .{}); Output.flush(); - Output.pretty("Usage:\n <d>$<r> <b><green>bun build<r> \\<entrypoint\\> [...\\<entrypoints\\>] [flags] \n", .{}); + Output.pretty("Usage:\n <d>$<r> <b><green>bun build<r> \\<entrypoint\\> [...\\<entrypoints\\>] <cyan>[flags]<r> \n", .{}); Output.pretty("\nTo see full documentation:\n <d>$<r> <b><green>bun build<r> --help\n", .{}); Output.flush(); - // return error.MissingEntryPoint; Global.exit(1); } } @@ -979,6 +909,7 @@ pub const HelpCommand = struct { \\ \\ <b><yellow>upgrade<r> Get the latest version of Bun \\ <b>bun --help<r> Show all supported flags and commands + \\ <b>bun [command] --help<r> Print helptext for a specific command \\ \\ Learn more about Bun: <magenta>https://bun.sh/docs<r> \\ Join our Discord community: <blue>https://bun.sh/discord<r> @@ -1148,11 +1079,8 @@ pub const Command = struct { ctx.allocator = allocator; if (comptime Command.Tag.uses_global_options.get(command)) { - std.debug.print("arguments.parse\n", .{}); ctx.args = try Arguments.parse(allocator, &ctx, command); - } else { - std.debug.print("doesnt use global options\n", .{}); - } + } else {} return ctx; } }; @@ -1358,12 +1286,11 @@ pub const Command = struct { switch (tag) { .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), + .InitCommand => return try InitCommand.exec(allocator, bun.argv()), .BuildCommand => { if (comptime bun.fast_debug_build_mode and bun.fast_debug_build_cmd != .BuildCommand) unreachable; const ctx = try Command.Context.create(allocator, log, .BuildCommand); - try BuildCommand.exec(ctx); }, .InstallCompletionsCommand => { @@ -1547,18 +1474,24 @@ pub const Command = struct { var args = try std.process.argsAlloc(allocator); if (args.len <= 2) { - Output.prettyErrorln( - \\<b><cyan>bun create<r>: create a new project from a template - \\ - \\<b>Usage<r>: <b><cyan>bun create<r> [template] [...args] - \\ <b><cyan>bun create<r> [username/repo] [name] - \\ - \\If given a GitHub repository name, Bun will download it and use it as a template, - \\otherwise it will run <b><magenta>bunx create-[template]<r> with the given arguments. - \\ - \\Learn more about creating new projects: <magenta>https://bun.sh/docs/templates<r> - \\ - , .{}); + Command.Tag.printHelp(.CreateCommand); + Global.exit(1); + return; + } + + // iterate over args + // if --help, print help and exit + const print_help = brk: { + for (bun.argv()) |arg_| { + const arg = bun.span(arg_); + if (strings.eqlComptime(arg, "--help")) { + break :brk true; + } + } + break :brk false; + }; + if (print_help) { + Command.Tag.printHelp(.CreateCommand); Global.exit(1); return; } @@ -1595,11 +1528,11 @@ pub const Command = struct { \\ \\To create a project using Create React App, run \\ - \\ bun create react-app + \\ <d>bun create react-app<r> \\ \\To create a React project using Vite, run \\ - \\ bun create vite + \\ <d>bun create vite<r> \\ \\Then select "React" from the list of frameworks. \\ @@ -1644,13 +1577,10 @@ pub const Command = struct { return; }, .AutoCommand => { - std.debug.print("running autocommand\n", .{}); if (comptime bun.fast_debug_build_mode and bun.fast_debug_build_cmd != .AutoCommand) unreachable; var ctx = Command.Context.create(allocator, log, .AutoCommand) catch |e| { - std.debug.print("error in context.create()\n", .{}); switch (e) { error.MissingEntryPoint => { - std.debug.print("missing entry point\n", .{}); HelpCommand.execWithReason(allocator, .explicit); return; }, @@ -1759,7 +1689,7 @@ pub const Command = struct { } // Output.prettyWarnln("<r><yellow>warn<r><d>:<r> failed to parse command\n", .{}); - // std.debug.print("fallback to help\n", .{}); + // Output.flush(); try HelpCommand.exec(allocator); }, @@ -1864,68 +1794,135 @@ pub const Command = struct { pub fn params(comptime cmd: Tag) []const Arguments.ParamType { return &comptime switch (cmd) { - Command.Tag.AutoCommand => Arguments.auto_params, - Command.Tag.RunCommand => Arguments.run_params, - Command.Tag.BuildCommand => Arguments.build_params, - Command.Tag.TestCommand => Arguments.test_params, - Command.Tag.BunxCommand => Arguments.run_params, + .AutoCommand => Arguments.auto_params, + .RunCommand => Arguments.run_params, + .BuildCommand => Arguments.build_params, + .TestCommand => Arguments.test_params, + .BunxCommand => Arguments.run_params, else => Arguments.base_params_ ++ Arguments.runtime_params_ ++ Arguments.transpiler_params_, }; } - pub fn params_to_print(comptime cmd: Tag) []const Arguments.ParamType { - return &comptime switch (cmd) { - Command.Tag.BuildCommand => Arguments.build_only_params, - Command.Tag.TestCommand => Arguments.test_only_params, - Command.Tag.InstallCommand => Install.PackageManager.install_params, - Command.Tag.AddCommand => Install.PackageManager.add_params, - Command.Tag.UpdateCommand => Install.PackageManager.update_params, - Command.Tag.RemoveCommand => Install.PackageManager.remove_params, - Command.Tag.LinkCommand => Install.PackageManager.link_params, - Command.Tag.UnlinkCommand => Install.PackageManager.unlink_params, - Command.Tag.AutoCommand => Arguments.auto_params, - Command.Tag.RunCommand => Arguments.run_params, - Command.Tag.BunxCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - Command.Tag.InitCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - Command.Tag.CreateCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - Command.Tag.DiscordCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - Command.Tag.GetCompletionsCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - Command.Tag.HelpCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - Command.Tag.InstallCompletionsCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - Command.Tag.PackageManagerCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - Command.Tag.UpgradeCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - Command.Tag.ReplCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - Command.Tag.ReservedCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, - }; - } - - // fn print_helptext_(intro: []u8, outro: []u8, params_list: []const Arguments.ParamType) void { - // Output.pretty("\n{s}", .{intro}); - // Output.flush(); - // Output.pretty("\n<b>Flags:<r>", .{}); - // Output.flush(); - // clap.simpleHelp(params_list); - // Output.pretty("\n\n{s}", .{outro}); - // Output.flush(); + // pub fn params_to_print(comptime cmd: Tag) []const Arguments.ParamType { + // return &comptime switch (cmd) { + // .BuildCommand => Arguments.build_only_params, + // .TestCommand => Arguments.test_only_params, + // .InstallCommand => Install.PackageManager.install_params, + // .AddCommand => Install.PackageManager.add_params, + // .UpdateCommand => Install.PackageManager.update_params, + // .RemoveCommand => Install.PackageManager.remove_params, + // .LinkCommand => Install.PackageManager.link_params, + // .UnlinkCommand => Install.PackageManager.unlink_params, + // .AutoCommand => Arguments.auto_params, + // .RunCommand => Arguments.run_params, + // .BunxCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // .InitCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // .CreateCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // .DiscordCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // .GetCompletionsCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // .HelpCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // .InstallCompletionsCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // .PackageManagerCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // .UpgradeCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // .ReplCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // .ReservedCommand => Arguments.runtime_params_ ++ Arguments.transpiler_params_, + // }; // } - pub fn print_helptext(cmd: Tag, params_list: []const Arguments.ParamType) void { + pub fn printHelp(comptime cmd: Tag) void { + // const params_list = comptime cmd.params_to_print(); switch (cmd) { + + // these commands do not use Context + // .DiscordCommand => return try DiscordCommand.exec(allocator), + // .HelpCommand => return try HelpCommand.exec(allocator), + // .ReservedCommand => return try ReservedCommand.exec(allocator), + + // these commands are implemented in install.zig + // Command.Tag.InstallCommand => {}, + // Command.Tag.AddCommand => {}, + // Command.Tag.RemoveCommand => {}, + // Command.Tag.UpdateCommand => {}, + // Command.Tag.PackageManagerCommand => {}, + // Command.Tag.LinkCommand => {}, + // Command.Tag.UnlinkCommand => {}, + + // fall back to HelpCommand.printWithReason Command.Tag.AutoCommand => { - Output.pretty("asdf", .{}); - Output.flush(); + HelpCommand.printWithReason(.explicit); }, Command.Tag.RunCommand => { - Output.pretty("asdf", .{}); + const intro_text = + \\<b>Usage<r>: + \\ Run a file or package.json script. + \\ <b><green>bun run<r> <cyan>[flags]<r> \<file\> + \\ <b><green>bun run<r> <cyan>[flags]<r> \<package.json script\> + ; + + const outro_text = + \\<b>Examples:<r> + \\ <d>Run a JavaScript or TypeScript file<r> + \\ <b><green>bun run<r> <blue>./index.js<r> + \\ <b><green>bun run<r> <blue>./index.tsx<r> + \\ + \\ <d>Run a package.json script<r> + \\ <b><green>bun run dev<r> + \\ <b><green>bun run lint<r> + \\ + \\Full documentation is available at <magenta>https://bun.sh/docs/cli/run<r> + ; + + Output.pretty(intro_text ++ "\n\n", .{}); + Output.flush(); + Output.pretty("<b>Flags:<r>", .{}); + Output.flush(); + clap.simpleHelp(&Arguments.run_params); + Output.pretty("\n\n" ++ outro_text, .{}); Output.flush(); }, - Command.Tag.BunxCommand => { - Output.pretty("asdf", .{}); + + .InitCommand => { + const intro_text = + \\<b>Usage<r>: <b><green>bun build<r> <cyan>[flags]<r> [...entrypoints] + \\ Initialize a Bun project in the current directory. + \\ Creates a package.json, tsconfig.json, and bunfig.toml if they don't exist. + \\ + \\<b>Flags<r>: + \\ <cyan>-y, --yes<r> Accept all default options + \\ <cyan>--minify<r> Enable all minification flags + \\ + \\<b>Examples:<r> + \\ <b><green>bun init<r> + \\ <b><green>bun init --yes<r> <blue>./src/index.ts<r> <cyan>--outfile=bundle.js<r> + \\ + ; + + Output.pretty(intro_text, .{}); Output.flush(); }, + + Command.Tag.BunxCommand => { + 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 <cyan>--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> + \\ + , .{}); + }, Command.Tag.BuildCommand => { const intro_text = - \\<b>Usage<r>: <b><green>bun build<r> [flags] [...entrypoints] + \\<b>Usage<r>: + \\ Transpile and bundle one more more files. + \\ <b><green>bun build<r> <cyan>[flags]<r> [...entrypoints] ; const outro_text = @@ -1944,19 +1941,17 @@ pub const Command = struct { \\ ; - Output.pretty(intro_text, .{}); - Output.pretty("\n\n", .{}); + Output.pretty(intro_text ++ "\n\n", .{}); Output.flush(); Output.pretty("<b>Flags:<r>", .{}); Output.flush(); - clap.simpleHelp(params_list); - Output.pretty("\n\n", .{}); - Output.pretty(outro_text, .{}); + clap.simpleHelp(&Arguments.build_only_params); + Output.pretty("\n\n" ++ outro_text, .{}); Output.flush(); }, Command.Tag.TestCommand => { const intro_text = - \\<b>Usage<r>: <b><green>bun test<r> [flags] [patterns...] + \\<b>Usage<r>: <b><green>bun test<r> <cyan>[flags]<r> [patterns...] \\ Run all matching test files and print the results to stdout ; const outro_text = @@ -1977,118 +1972,69 @@ pub const Command = struct { Output.flush(); Output.pretty("\n<b>Flags:<r>", .{}); Output.flush(); - clap.simpleHelp(params_list); + clap.simpleHelp(&Arguments.test_only_params); Output.pretty("\n\n", .{}); Output.pretty(outro_text, .{}); Output.flush(); }, - Command.Tag.InitCommand => { - const intro_text = - \\<b>Usage<r>: <b><green>bun init<r> [flags] - \\ Run all matching test files and print the results to stdout - ; - const outro_text = - \\<b>Examples:<r> - \\ <d>Run all test files <r> - \\ <b><green>bun test<r> + Command.Tag.CreateCommand => { + Output.prettyErrorln( + \\<b><cyan>bun create<r>: create a new project from a template \\ - \\ <d>Run all test files with "foo" or "bar" in the file name<r> - \\ <b><green>bun test foo bar<r> + \\<b>Usage<r>: <b><cyan>bun create<r> [template] [...args] + \\ <b><cyan>bun create<r> [username/repo] [name] \\ - \\ <d>Run all test files, only including tests whose names includes "baz"<r> - \\ <b><green>bun test<r> <cyan>--test-name-pattern<r> baz<r> + \\If given a GitHub repository name, Bun will download it and use it as a template, + \\otherwise it will run <b><magenta>bunx create-[template]<r> with the given arguments. \\ - \\Full documentation is available at <magenta>https://bun.sh/docs/cli/test<r> - ; - Output.pretty("\n", .{}); - Output.pretty(intro_text, .{}); - Output.flush(); - Output.pretty("\n<b>Flags:<r>", .{}); - Output.flush(); - clap.simpleHelp(params_list); - Output.pretty("\n\n", .{}); - Output.pretty(outro_text, .{}); - Output.flush(); - }, - Command.Tag.CreateCommand => { - Output.pretty("asdf", .{}); - Output.flush(); + \\Learn more about creating new projects: <magenta>https://bun.sh/docs/templates<r> + \\ + , .{}); }, Command.Tag.HelpCommand => { - Output.pretty("asdf", .{}); - Output.flush(); + HelpCommand.printWithReason(.explicit); }, Command.Tag.UpgradeCommand => { - Output.pretty("asdf", .{}); - Output.flush(); - }, - Command.Tag.ReplCommand => { - Output.pretty("asdf", .{}); - Output.flush(); - }, - Command.Tag.InstallCommand => { - Output.pretty("asdf", .{}); - Output.flush(); - }, - Command.Tag.AddCommand => { const intro_text = - \\<b>Usage<r>: <b><green>bun add<r> [flags] \<pkg\> [...\<pkg\>] - \\ Install a package and add it to your package.json + \\<b>Usage<r>: <b><green>bun upgrade<r> <cyan>[flags]<r> + \\ Upgrade Bun ; const outro_text = \\<b>Examples:<r> - \\ <d>Add a dependency from the npm registry<r> - \\ <b><green>bun add zod<r> - \\ <b><green>bun add zod@next<r> - \\ <b><green>bun add zod@3.0.0<r> + \\ <d>Instal the latest stable version<r> + \\ <b><green>bun upgrade<r> \\ - \\ <d>Add a dev, optional, or peer dependency <r> - \\ <b><green>bun add -d typescript<r> - \\ <b><green>bun add -o lodash<r> - \\ <b><green>bun add --peer esbuild<r> + \\ <d>Install the most recent canary version of Bun<r> + \\ <b><green>bun upgrade --canary<r> \\ - \\Full documentation is available at <magenta>https://bun.sh/docs/cli/install<r> + \\Full documentation is available at <magenta>https://bun.sh/docs/installation#upgrading<r> ; Output.pretty("\n", .{}); Output.pretty(intro_text, .{}); Output.flush(); Output.pretty("\n<b>Flags:<r>", .{}); Output.flush(); - clap.simpleHelp(params_list); + clap.simpleHelp(&Arguments.test_only_params); Output.pretty("\n\n", .{}); Output.pretty(outro_text, .{}); Output.flush(); }, - Command.Tag.RemoveCommand => { - Output.pretty("asdf", .{}); - Output.flush(); - }, - Command.Tag.UpdateCommand => { - Output.pretty("asdf", .{}); - Output.flush(); - }, - Command.Tag.LinkCommand => { - Output.pretty("asdf", .{}); - Output.flush(); - }, - Command.Tag.UnlinkCommand => { - Output.pretty("asdf", .{}); - Output.flush(); - }, - Command.Tag.PackageManagerCommand => { - Output.pretty("asdf", .{}); - Output.flush(); - }, - Command.Tag.DiscordCommand => { - Output.pretty("asdf", .{}); + Command.Tag.ReplCommand => { + const intro_text = + \\<b>Usage<r>: <b><green>bun repl<r> <cyan>[flags]<r> + \\ Open a Bun REPL + ; + + Output.pretty(intro_text, .{}); Output.flush(); }, + Command.Tag.GetCompletionsCommand => { - Output.pretty("asdf", .{}); + Output.pretty("<b>Usage<r>: <b><green>bun getcompletes<r>", .{}); Output.flush(); }, Command.Tag.InstallCompletionsCommand => { - Output.pretty("asdf", .{}); + Output.pretty("<b>Usage<r>: <b><green>bun completions<r>", .{}); Output.flush(); }, else => { diff --git a/src/cli/bunx_command.zig b/src/cli/bunx_command.zig index e7f35d10d..84155b502 100644 --- a/src/cli/bunx_command.zig +++ b/src/cli/bunx_command.zig @@ -9,7 +9,7 @@ const stringZ = bun.stringZ; const default_allocator = bun.default_allocator; const C = bun.C; const std = @import("std"); - +const Command = @import("../cli.zig").Command; const Run = @import("./run_command.zig").RunCommand; pub const BunxCommand = struct { @@ -142,21 +142,7 @@ 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> - \\ - , .{}); + Command.Tag.printHelp(.BunxCommand); Global.exit(1); } diff --git a/src/cli/package_manager_command.zig b/src/cli/package_manager_command.zig index 00326bc97..f51504a03 100644 --- a/src/cli/package_manager_command.zig +++ b/src/cli/package_manager_command.zig @@ -44,7 +44,7 @@ const ByName = struct { }; pub const PackageManagerCommand = struct { - pub fn printHelp(_: std.mem.Allocator) void {} + // pub fn printHelp(_: std.mem.Allocator) void {} pub fn printHash(ctx: Command.Context, lockfile_: []const u8) !void { @setCold(true); var lockfile_buffer: [bun.MAX_PATH_BYTES]u8 = undefined; @@ -83,6 +83,26 @@ pub const PackageManagerCommand = struct { return subcommand; } + pub fn printHelp() void { + Output.prettyln( + \\<b><blue>bun pm<r>: Package manager utilities + \\ + \\ bun pm <b>bin<r> print the path to bin folder + \\ bun pm <b>-g bin<r> print the <b>global<r> path to bin folder + \\ bun pm <b>ls<r> list the dependency tree according to the current lockfile + \\ bun pm <b>ls<r> <cyan>--all<r> list the entire dependency tree according to the current lockfile + \\ bun pm <b>hash<r> generate & print the hash of the current lockfile + \\ bun pm <b>hash-string<r> print the string used to hash the lockfile + \\ bun pm <b>hash-print<r> print the hash stored in the current lockfile + \\ bun pm <b>cache<r> print the path to the cache folder + \\ bun pm <b>cache rm<r> clear the cache + \\ bun pm <b>migrate<r> migrate another package manager's lockfile without installing anything + \\ + \\Learn more about these at <magenta>https://bun.sh/docs/install/utilities<r> + \\ + , .{}); + } + pub fn exec(ctx: Command.Context) !void { var args = try std.process.argsAlloc(ctx.allocator); args = args[1..]; @@ -272,23 +292,7 @@ pub const PackageManagerCommand = struct { Global.exit(0); } - Output.prettyln( - \\<b><blue>bun pm<r>: package manager related commands - \\ - \\ bun pm <b>bin<r> print the path to bin folder - \\ bun pm <b>-g bin<r> print the <b>global<r> path to bin folder - \\ bun pm <b>ls<r> list the dependency tree according to the current lockfile - \\ bun pm <b>ls --all<r> list the entire dependency tree according to the current lockfile - \\ bun pm <b>hash<r> generate & print the hash of the current lockfile - \\ bun pm <b>hash-string<r> print the string used to hash the lockfile - \\ bun pm <b>hash-print<r> print the hash stored in the current lockfile - \\ bun pm <b>cache<r> print the path to the cache folder - \\ bun pm <b>cache rm<r> clear the cache - \\ bun pm <b>migrate<r> migrate another package manager's lockfile without installing anything - \\ - \\Learn more about these at <magenta>https://bun.sh/docs/install/utilities<r> - \\ - , .{}); + printHelp(); if (subcommand.len > 0) { Output.prettyErrorln("\n<red>error<r>: \"{s}\" unknown command\n", .{subcommand}); diff --git a/src/deps/zig-clap/clap.zig b/src/deps/zig-clap/clap.zig index bba58d445..3dd9d5a53 100644 --- a/src/deps/zig-clap/clap.zig +++ b/src/deps/zig-clap/clap.zig @@ -210,7 +210,6 @@ pub const Diagnostic = struct { /// Default diagnostics reporter when all you want is English with no colors. /// Use this as a reference for implementing your own if needed. pub fn report(diag: Diagnostic, stream: anytype, err: anyerror) !void { - std.debug.print("starting diag report", .{}); const Arg = struct { prefix: []const u8, name: []const u8, @@ -222,7 +221,6 @@ pub const Diagnostic = struct { else Arg{ .prefix = "", .name = diag.arg }; - std.debug.print("switching in diag.report", .{}); Output.pretty("Invalid argument '{s}{s}'\n", .{ a.prefix, a.name }); Output.pretty("{}", .{err}); Output.flush(); @@ -440,12 +438,7 @@ pub fn helpEx( ); } -pub fn simplePrintParam( - param: Param(Help), - // comptime Error: type, - // context: anytype, - // valueText: fn (@TypeOf(context), Param(Id)) Error![]const u8, -) !void { +pub fn simplePrintParam(param: Param(Help)) !void { Output.pretty("\n", .{}); if (param.names.short) |s| { Output.pretty("<cyan>-{c}<r>", .{s}); @@ -470,53 +463,12 @@ pub fn simplePrintParam( // } } pub fn simpleHelp( - // stream: anytype, params: []const Param(Help), - // helpText: *const fn (Param(Help)) []const u8, - // valueText: *const fn (Param(Help)) []const u8, ) void { - // _ = stream; - // const Context = struct { - // helpText: *const fn (Param(Help)) []const u8, - // valueText: *const fn (Param(Help)) []const u8, - - // pub fn help(c: @This(), p: Param(Id)) error{}![]const u8 { - // return c.helpText(p); - // } - - // pub fn value(c: @This(), p: Param(Id)) error{}![]const u8 { - // return c.valueText(p); - // } - // }; - - // return helpFull( - // stream, - // Id, - // params, - // error{}, - // Context{ - // .helpText = helpText, - // .valueText = valueText, - // }, - // Context.help, - // Context.value, - // ); - const max_spacing = blk: { var res: usize = 2; for (params) |param| { - // param.names.long.?.len orelse 0; - // var flags_len = brk: { - // if (param.names.long) |l| { - // break :brk l.len; - // } - // break :brk 0; - // }; var flags_len = if (param.names.long) |l| l.len else 0; - // if(param.names.short) flags_len += 4; - // var cs = io.countingWriter(io.null_writer); - // var flag_text = getValueSimple(param); - // try printParam(cs.writer(), Help, param, error{}, context, valueText); if (res < flags_len) res = flags_len; } @@ -528,15 +480,12 @@ pub fn simpleHelp( if (param.names.short == null and param.names.long == null) continue; + const desc_text = getHelpSimple(param); + if (desc_text.len == 0) continue; + // create a string with spaces_len spaces const default_allocator = @import("root").bun.default_allocator; - // var spaces_before = default_allocator.alloc(u8, num_spaces_after) catch unreachable; - // defer default_allocator.free(spaces_before); - // for (0..spaces_before) |i| { - // spaces_before[i] = ' '; - // } - const flags_len = if (param.names.long) |l| l.len else 0; const num_spaces_after = max_spacing - flags_len; var spaces_after = default_allocator.alloc(u8, num_spaces_after) catch unreachable; @@ -546,18 +495,7 @@ pub fn simpleHelp( } simplePrintParam(param) catch unreachable; - Output.pretty(" ", .{}); - const desc_text = getHelpSimple(param); - Output.pretty("{s} {s}", .{ spaces_after, desc_text }); - // print space spaces_len times - - // if (help_text.len > 0) { - // var cs = io.countingWriter(stream); - // try stream.print("\t", .{}); - // try printParam(cs.writer(), Help, param, error{}, context, valueText); - // try stream.writeByteNTimes(' ', max_spacing - @as(usize, @intCast(cs.bytes_written))); - // try stream.print("\t{s}\n", .{getHelpSimple(param)}); - // } + Output.pretty(" {s} {s}", .{ spaces_after, desc_text }); } } diff --git a/src/install/install.zig b/src/install/install.zig index 9b2dc4502..73e471ec5 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -48,6 +48,7 @@ const Bitset = bun.bit_set.DynamicBitSetUnmanaged; const z_allocator = @import("../memory_allocator.zig").z_allocator; const Syscall = bun.sys; const RunCommand = @import("../cli/run_command.zig").RunCommand; +const PackageManagerCommand = @import("../cli/package_manager_command.zig").PackageManagerCommand; threadlocal var initialized_store = false; const Futex = @import("../futex.zig"); @@ -6035,7 +6036,7 @@ pub const PackageManager = struct { "Possible values: \"hardlink\" (default), \"symlink\", \"copyfile\""; const install_params_ = [_]ParamType{ - clap.parseParam("-c, --config <STR>? Load config (bunfig.toml)") catch unreachable, + clap.parseParam("-c, --config <STR>? Specify path to config file (bunfig.toml)") catch unreachable, clap.parseParam("-y, --yarn Write a yarn.lock file (yarn v1)") catch unreachable, clap.parseParam("-p, --production Don't install devDependencies") catch unreachable, clap.parseParam("--no-save Don't save a lockfile") catch unreachable, @@ -6055,10 +6056,8 @@ pub const PackageManager = struct { clap.parseParam("--cwd <STR> Set a specific cwd") catch unreachable, clap.parseParam("--backend <STR> Platform-specific optimizations for installing dependencies. " ++ platform_specific_backend_label) catch unreachable, clap.parseParam("--link-native-bins <STR>... Link \"bin\" from a matching platform-specific \"optionalDependencies\" instead. Default: esbuild, turbo") catch unreachable, - // clap.parseParam("--omit <STR>... Skip installing dependencies of a certain type. \"dev\", \"optional\", or \"peer\"") catch unreachable, // clap.parseParam("--no-dedupe Disable automatic downgrading of dependencies that would otherwise cause unnecessary duplicate package versions ($BUN_CONFIG_NO_DEDUPLICATE)") catch unreachable, - clap.parseParam("--help Print this help menu") catch unreachable, }; @@ -6149,6 +6148,141 @@ pub const PackageManager = struct { } }; + pub fn printHelp(comptime subcommand: Subcommand) void { + switch (subcommand) { + // fall back to HelpCommand.printWithReason + Subcommand.install => { + const intro_text = + \\<b>Usage<r>: <b><green>bun install<r> <cyan>[flags]<r> [...\<pkg\>] + \\ Install the dependencies listed in package.json + ; + const outro_text = + \\<b>Examples:<r> + \\ <d>Install the dependencies for the current project<r> + \\ <b><green>bun install<r> + \\ + \\ <d>Skip devDependencies<r> + \\ <b><green>bun install --production<r> + \\ + \\Full documentation is available at <magenta>https://bun.sh/docs/cli/install<r> + ; + Output.pretty("\n" ++ intro_text, .{}); + Output.flush(); + Output.pretty("\n<b>Flags:<r>", .{}); + Output.flush(); + clap.simpleHelp(&PackageManager.add_params); + Output.pretty("\n\n" ++ outro_text, .{}); + Output.flush(); + }, + Subcommand.update => { + const intro_text = + \\<b>Usage<r>: <b><green>bun update<r> <cyan>[flags]<r> + \\ Update all dependencies to most recent versions within the version range in package.json + ; + const outro_text = + \\<b>Examples:<r> + \\ <d>Update all dependencies:<r> + \\ <b><green>bun update<r> + \\ + \\Full documentation is available at <magenta>https://bun.sh/docs/cli/install#bun-update<r> + ; + Output.pretty("\n" ++ intro_text, .{}); + Output.flush(); + Output.pretty("\n<b>Flags:<r>", .{}); + Output.flush(); + clap.simpleHelp(&PackageManager.add_params); + Output.pretty("\n\n" ++ outro_text, .{}); + Output.flush(); + }, + Subcommand.pm => { + PackageManagerCommand.printHelp(); + }, + Subcommand.add => { + const intro_text = + \\<b>Usage<r>: <b><green>bun add<r> <cyan>[flags]<r> \<pkg\> [...\<pkg\>] + ; + const outro_text = + \\<b>Examples:<r> + \\ <d>Add a dependency from the npm registry<r> + \\ <b><green>bun add zod<r> + \\ <b><green>bun add zod@next<r> + \\ <b><green>bun add zod@3.0.0<r> + \\ + \\ <d>Add a dev, optional, or peer dependency <r> + \\ <b><green>bun add -d typescript<r> + \\ <b><green>bun add -o lodash<r> + \\ <b><green>bun add --peer esbuild<r> + \\ + \\Full documentation is available at <magenta>https://bun.sh/docs/cli/install<r> + ; + Output.pretty("\n" ++ intro_text, .{}); + Output.flush(); + Output.pretty("\n\n<b>Flags:<r>", .{}); + Output.flush(); + clap.simpleHelp(&PackageManager.add_params); + Output.pretty("\n\n" ++ outro_text, .{}); + Output.flush(); + }, + Subcommand.remove => { + const intro_text = + \\<b>Usage<r>: <b><green>bun remove<r> <cyan>[flags]<r> \<pkg\> [...\<pkg\>] + \\ Remove a package from package.json and uninstall from node_modules + ; + const outro_text = + \\<b>Examples:<r> + \\ <d>Add a dependency from the npm registry<r> + \\ <b><green>bun remove ts-node<r> + \\ + \\Full documentation is available at <magenta>https://bun.sh/docs/cli/install#bun-remove<r> + ; + Output.pretty("\n" ++ intro_text, .{}); + Output.flush(); + Output.pretty("\n<b>Flags:<r>", .{}); + Output.flush(); + clap.simpleHelp(&PackageManager.remove_params); + Output.pretty("\n\n" ++ outro_text, .{}); + Output.flush(); + }, + Subcommand.link => { + const intro_text = + \\<b>Usage<r>: <b><green>bun link<r> <cyan>[flags]<r> [\<package\>] + ; + const outro_text = + \\<b>Examples:<r> + \\ <d>Register the current directory as a linkable package.<r> + \\ <d>Directory should contain a package.json.<r> + \\ <b><green>bun link<r> + \\ + \\ <d>Add a previously-registered linkable package as a dependency of the current project.<r> + \\ <b><green>bun link \<package\><r> + \\ + \\Full documentation is available at <magenta>https://bun.sh/docs/cli/install#bun-link<r> + ; + Output.pretty("\n" ++ intro_text, .{}); + Output.flush(); + Output.pretty("\n<b>Flags:<r>", .{}); + Output.flush(); + clap.simpleHelp(&PackageManager.link_params); + Output.pretty("\n\n" ++ outro_text, .{}); + Output.flush(); + }, + Subcommand.unlink => { + const intro_text = + \\<b>Usage<r>: <b><green>bun unlink<r> <cyan>[flags]<r> + \\ + \\<b>Examples:<r> + \\ <d>Unregister the current directory as a linkable package.<r> + \\ <b><green>bun unlink<r> + \\ + \\Full documentation is available at <magenta>https://bun.sh/docs/cli/install#bun-link<r> + ; + + Output.pretty("\n" ++ intro_text, .{}); + Output.flush(); + }, + } + } + pub fn parse(allocator: std.mem.Allocator, comptime subcommand: Subcommand) !CommandLineArguments { comptime var params: []const ParamType = &switch (subcommand) { .install => install_params, @@ -6173,11 +6307,9 @@ pub const PackageManager = struct { }; if (args.flag("--help")) { - Output.prettyln("\n<b><magenta>bun<r> (package manager) flags:<r>\n\n", .{}); - Output.flush(); - - clap.help(Output.writer(), params) catch {}; - + // Output.prettyln("\n<b><magenta>bun<r> (package manager) flags:<r>\n\n", .{}); + // Output.flush(); + printHelp(subcommand); Global.exit(0); } |