aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Justin Whear <justin.whear@gmail.com> 2023-02-28 13:49:05 -0800
committerGravatar GitHub <noreply@github.com> 2023-02-28 13:49:05 -0800
commit7b9a17f9d7106ffd8e553a5192aba60d14ea5e9c (patch)
tree0aebdc62db0e8bfbf0db537537cb1c8ac6844772
parentbd91aa8c25a05768cae5a0df482bb8f50c599c20 (diff)
downloadbun-7b9a17f9d7106ffd8e553a5192aba60d14ea5e9c.tar.gz
bun-7b9a17f9d7106ffd8e553a5192aba60d14ea5e9c.tar.zst
bun-7b9a17f9d7106ffd8e553a5192aba60d14ea5e9c.zip
Update clap (#2238)
* remove vendored clap * Update to latest zig-clap Major changes: * Instead of vendoring zig-clap and adding changes, this uses Hejsil/zig-clap directly as a submodule * `cli.zig` and related files have been updated to use new API (no more `flag()` or `option()`) * A workaround for the Run and Auto commands has been implemented that allows us to use the official upstream Minor change: * `-i` now has the long option `--install-fallback`; I didn't spend much time thinking about this name, so suggestions weclome. * deinit jsBundleArgs
-rw-r--r--.gitmodules3
-rw-r--r--misctools/fetch.zig16
-rw-r--r--misctools/http_bench.zig22
-rw-r--r--src/cli.zig292
-rw-r--r--src/cli/create_command.zig44
m---------src/deps/zig-clap0
-rw-r--r--src/deps/zig-clap/.gitignore1
-rw-r--r--src/deps/zig-clap/LICENSE24
-rw-r--r--src/deps/zig-clap/build.zig55
-rw-r--r--src/deps/zig-clap/clap.zig546
-rw-r--r--src/deps/zig-clap/clap/args.zig337
-rw-r--r--src/deps/zig-clap/clap/comptime.zig194
-rw-r--r--src/deps/zig-clap/clap/streaming.zig430
-rw-r--r--src/deps/zig-clap/gyro.zzz14
-rw-r--r--src/deps/zig-clap/zig.mod5
-rw-r--r--src/install/install.zig147
16 files changed, 290 insertions, 1840 deletions
diff --git a/.gitmodules b/.gitmodules
index c22446cbd..a86b743b7 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -65,3 +65,6 @@ fetchRecurseSubmodules = false
[submodule "src/deps/c-ares"]
path = src/deps/c-ares
url = https://github.com/c-ares/c-ares.git
+[submodule "src/deps/zig-clap"]
+ path = src/deps/zig-clap
+ url = https://github.com/Hejsil/zig-clap.git
diff --git a/misctools/fetch.zig b/misctools/fetch.zig
index cdefd29d4..85f21c3b7 100644
--- a/misctools/fetch.zig
+++ b/misctools/fetch.zig
@@ -78,7 +78,7 @@ pub const Arguments = struct {
pub fn parse(allocator: std.mem.Allocator) !Arguments {
var diag = clap.Diagnostic{};
- var args = clap.parse(clap.Help, &params, .{
+ var res = clap.parse(clap.Help, &params, clap.parsers.default, .{
.diagnostic = &diag,
.allocator = allocator,
}) catch |err| {
@@ -87,7 +87,7 @@ pub const Arguments = struct {
return err;
};
- var positionals = args.positionals();
+ var positionals = res.positionals;
var raw_args: std.ArrayListUnmanaged(string) = undefined;
if (positionals.len > 0) {
@@ -96,16 +96,16 @@ pub const Arguments = struct {
raw_args = .{};
}
- if (args.flag("--version")) {
+ if (res.args.version) {
try Output.writer().writeAll(VERSION);
Global.exit(0);
}
var method = Method.GET;
var url: URL = .{};
- var body_string: string = args.option("--body") orelse "";
+ var body_string: string = res.args.body orelse "";
- if (args.option("--file")) |file_path| {
+ if (res.args.file) |file_path| {
if (file_path.len > 0) {
var cwd = try std.process.getCwd(&cwd_buf);
var parts = [_]string{file_path};
@@ -154,12 +154,12 @@ pub const Arguments = struct {
return Arguments{
.url = url,
.method = method,
- .verbose = args.flag("--verbose"),
+ .verbose = res.args.verbose,
.headers = .{},
.headers_buf = "",
.body = body_string,
- .turbo = args.flag("--turbo"),
- .quiet = args.flag("--quiet"),
+ .turbo = res.args.turbo,
+ .quiet = res.args.quiet,
};
}
};
diff --git a/misctools/http_bench.zig b/misctools/http_bench.zig
index 5e12f0157..d4d27b56e 100644
--- a/misctools/http_bench.zig
+++ b/misctools/http_bench.zig
@@ -82,7 +82,7 @@ pub const Arguments = struct {
pub fn parse(allocator: std.mem.Allocator) !Arguments {
var diag = clap.Diagnostic{};
- var args = clap.parse(clap.Help, &params, .{
+ var res = clap.parse(clap.Help, &params, clap.parsers.default, .{
.diagnostic = &diag,
.allocator = allocator,
}) catch |err| {
@@ -91,7 +91,7 @@ pub const Arguments = struct {
return err;
};
- var positionals = args.positionals();
+ var positionals = res.positionals;
var raw_args: std.ArrayListUnmanaged(string) = undefined;
if (positionals.len > 0) {
@@ -100,16 +100,16 @@ pub const Arguments = struct {
raw_args = .{};
}
- if (args.flag("--version")) {
+ if (res.args.version) {
try Output.writer().writeAll(VERSION);
Global.exit(0);
}
var method = Method.GET;
var url: URL = .{};
- var body_string: string = args.option("--body") orelse "";
+ var body_string: string = res.args.body orelse "";
- if (args.option("--file")) |file_path| {
+ if (res.args.file) |file_path| {
if (file_path.len > 0) {
var cwd = try std.process.getCwd(&cwd_buf);
var parts = [_]string{file_path};
@@ -158,18 +158,18 @@ pub const Arguments = struct {
return Arguments{
.url = url,
.method = method,
- .verbose = args.flag("--verbose"),
+ .verbose = res.args.verbose,
.headers = .{},
.headers_buf = "",
.body = body_string,
- // .keep_alive = !args.flag("--no-keep-alive"),
- .concurrency = std.fmt.parseInt(u16, args.option("--max-concurrency") orelse "32", 10) catch 32,
- .turbo = args.flag("--turbo"),
- .timeout = std.fmt.parseInt(usize, args.option("--timeout") orelse "0", 10) catch |err| {
+ // .keep_alive = !res.args.@"--no-keep-alive",
+ .concurrency = std.fmt.parseInt(u16, res.args.@"max-concurrency" orelse "32", 10) catch 32,
+ .turbo = res.args.turbo,
+ .timeout = std.fmt.parseInt(usize, res.args.timeout orelse "0", 10) catch |err| {
Output.prettyErrorln("<r><red>{s}<r> parsing timeout", .{@errorName(err)});
Global.exit(1);
},
- .count = std.fmt.parseInt(usize, args.option("--count") orelse "10", 10) catch |err| {
+ .count = std.fmt.parseInt(usize, res.args.count orelse "10", 10) catch |err| {
Output.prettyErrorln("<r><red>{s}<r> parsing count", .{@errorName(err)});
Global.exit(1);
},
diff --git a/src/cli.zig b/src/cli.zig
index e05bd113d..e44c75d43 100644
--- a/src/cli.zig
+++ b/src/cli.zig
@@ -160,59 +160,70 @@ pub const Arguments = struct {
}
}
- pub const ParamType = clap.Param(clap.Help);
-
- const public_params = [_]ParamType{
- clap.parseParam("--use <STR> Choose a framework, e.g. \"--use next\". It checks first for a package named \"bun-framework-packagename\" and then \"packagename\".") catch unreachable,
- clap.parseParam("-b, --bun Force a script or package to use Bun.js instead of Node.js (via symlinking node)") catch unreachable,
- clap.parseParam("--bunfile <STR> Use a .bun file (default: node_modules.bun)") catch unreachable,
- clap.parseParam("--server-bunfile <STR> Use a .server.bun file (default: node_modules.server.bun)") 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("--disable-react-fast-refresh Disable React Fast Refresh") catch unreachable,
- clap.parseParam("--disable-hmr Disable Hot Module Reloading (disables fast refresh too) in bun dev") catch unreachable,
- clap.parseParam("--extension-order <STR>... defaults to: .tsx,.ts,.jsx,.js,.json ") catch unreachable,
- clap.parseParam("--jsx-factory <STR> Changes the function called when compiling JSX elements using the classic JSX runtime") catch unreachable,
- clap.parseParam("--jsx-fragment <STR> Changes the function called when compiling JSX fragments") catch unreachable,
- clap.parseParam("--jsx-import-source <STR> Declares the module specifier to be used for importing the jsx and jsxs factory functions. Default: \"react\"") catch unreachable,
- clap.parseParam("--jsx-production Use jsx instead of jsxDEV (default) for the automatic runtime") catch unreachable,
- clap.parseParam("--jsx-runtime <STR> \"automatic\" (default) or \"classic\"") catch unreachable,
- clap.parseParam("-r, --preload <STR>... Import a module before other modules are loaded") catch unreachable,
- clap.parseParam("--main-fields <STR>... Main fields to lookup in package.json. Defaults to --platform dependent") catch unreachable,
- clap.parseParam("--no-summary Don't print a summary (when generating .bun") catch unreachable,
- clap.parseParam("-v, --version Print version and exit") catch unreachable,
- clap.parseParam("--platform <STR> \"bun\" or \"browser\" or \"node\", used when building or bundling") catch unreachable,
- // clap.parseParam("--production [not implemented] generate production code") catch unreachable,
- clap.parseParam("--public-dir <STR> Top-level directory for .html files, fonts or anything external. Defaults to \"<cwd>/public\", to match create-react-app and Next.js") catch unreachable,
- clap.parseParam("--tsconfig-override <STR> Load tsconfig from path instead of cwd/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("-h, --help Display this help and exit. ") catch unreachable,
- clap.parseParam("-l, --loader <STR>... Parse files with .ext:loader, e.g. --loader .js:jsx. Valid loaders: jsx, js, json, tsx, ts, css") 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("--hot Enable auto reload in bun's JavaScript runtime") catch unreachable,
- clap.parseParam("--no-install Disable auto install in bun's JavaScript runtime") catch unreachable,
- clap.parseParam("-i Automatically install dependencies and use global cache in bun's runtime, equivalent to --install=fallback") catch unreachable,
- clap.parseParam("--install <STR> Install dependencies automatically when no node_modules are present, default: \"auto\". \"force\" to ignore node_modules, fallback to install any missing") catch unreachable,
- clap.parseParam("--prefer-offline Skip staleness checks for packages in bun's JavaScript runtime and resolve from disk") catch unreachable,
- clap.parseParam("--prefer-latest Use the latest matching versions of packages in bun's JavaScript runtime, always checking npm") catch unreachable,
- clap.parseParam("--silent Don't repeat the command for bun run") catch unreachable,
- clap.parseParam("<POS>... ") catch unreachable,
+ pub const parser = .{
+ .STR = clap.parsers.string,
+ .PATH = clap.parsers.string,
+ .POS = clap.parsers.string,
};
- const debug_params = [_]ParamType{
- clap.parseParam("--dump-environment-variables Dump environment variables from .env and process as JSON and quit. Useful for debugging") catch unreachable,
- clap.parseParam("--dump-limits Dump system limits. Useful for debugging") catch unreachable,
- clap.parseParam("--disable-bun.js Disable bun.js from loading in the dev server") catch unreachable,
+ pub const ParamType = clap.Param(clap.Help);
+
+ const public_params = clap.parseParamsComptime(
+ \\--use <STR> Choose a framework, e.g. "--use next". It checks first for a package named "bun-framework-packagename" and then "packagename".
+ \\-b, --bun Force a script or package to use Bun.js instead of Node.js (via symlinking node)
+ \\--bunfile <STR> Use a .bun file (default: node_modules.bun)
+ \\--server-bunfile <STR> Use a .server.bun file (default: node_modules.server.bun)
+ \\--cwd <STR> Absolute path to resolve files & entry points from. This just changes the process' cwd.
+ \\-c, --config <PATH> Config file to load bun from (e.g. -c bunfig.toml)
+ \\--disable-react-fast-refresh Disable React Fast Refresh
+ \\--disable-hmr Disable Hot Module Reloading (disables fast refresh too) in bun dev
+ \\--extension-order <STR>... defaults to: .tsx,.ts,.jsx,.js,.json
+ \\--jsx-factory <STR> Changes the function called when compiling JSX elements using the classic JSX runtime
+ \\--jsx-fragment <STR> Changes the function called when compiling JSX fragments
+ \\--jsx-import-source <STR> Declares the module specifier to be used for importing the jsx and jsxs factory functions. Default: "react"
+ \\--jsx-production Use jsx instead of jsxDEV (default) for the automatic runtime
+ \\--jsx-runtime <STR> "automatic" (default) or "classic"
+ \\-r, --preload <STR>... Import a module before other modules are loaded") catch unreachable,
+ \\--main-fields <STR>... Main fields to lookup in package.json. Defaults to --platform dependent
+ \\--no-summary Don't print a summary (when generating .bun
+ \\-v, --version Print version and exit
+ \\--platform <STR> "bun" or "browser" or "node", used when building or bundling
+ \\--public-dir <STR> Top-level directory for .html files, fonts or anything external. Defaults to "<cwd>/public", to match create-react-app and Next.js
+ \\--tsconfig-override <STR> Load tsconfig from path instead of cwd/tsconfig.json
+ \\-d, --define <STR>... Substitute K:V while parsing, e.g. --define process.env.NODE_ENV:"development". Values are parsed as JSON.
+ \\-e, --external <STR>... Exclude module from transpilation (can use * wildcards). ex: -e react
+ \\-h, --help Display this help and exit.
+ \\-l, --loader <STR>... Parse files with .ext:loader, e.g. --loader .js:jsx. Valid loaders: jsx, js, json, tsx, ts, css
+ \\-u, --origin <STR> Rewrite import URLs to start with --origin. Default: ""
+ \\-p, --port <STR> Port to serve bun's dev server on. Default: "3000"
+ \\--hot Enable auto reload in bun's JavaScript runtime
+ \\--no-install Disable auto install in bun's JavaScript runtime
+ \\-i, --install-fallback Automatically install dependencies and use global cache in bun's runtime, equivalent to --install=fallback
+ \\--install <STR> Install dependencies automatically when no node_modules are present, default: "auto". "force" to ignore node_modules, fallback to install any missing
+ \\--prefer-offline Skip staleness checks for packages in bun's JavaScript runtime and resolve from disk
+ \\--prefer-latest Use the latest matching versions of packages in bun's JavaScript runtime, always checking npm
+ \\--silent Don't repeat the command for bun run
+ \\<POS>...
+ );
+
+ const debug_params = clap.parseParamsComptime(
+ \\--dump-environment-variables Dump environment variables from .env and process as JSON and quit. Useful for debugging
+ \\--dump-limits Dump system limits. Useful for debugging
+ )
+ // clap can't handle parsing the '.'
+ ++ .{
+ clap.Param(clap.Help){
+ .id = .{ .val = "disable-bun.js", .desc = "Disable bun.js from loading in the dev server" },
+ .names = .{ .long = "disable-bun.js" },
+ }
};
pub const params = public_params ++ debug_params;
- const build_only_params = [_]ParamType{
- clap.parseParam("--sourcemap <STR>? Build with sourcemaps - 'inline', 'external', or 'none'") catch unreachable,
- clap.parseParam("--outdir <STR> Default to \"dist\" if multiple files") catch unreachable,
- };
+ const build_only_params = clap.parseParamsComptime(
+ \\--sourcemap <STR> Build with sourcemaps - "inline", "external", or "none"
+ \\--outdir <STR> Default to "dist" if multiple files
+ );
const build_params_public = public_params ++ build_only_params;
pub const build_params = build_params_public ++ debug_params;
@@ -322,40 +333,78 @@ pub const Arguments = struct {
try loadConfigPath(allocator, auto_loaded, config_path, ctx, comptime cmd);
}
- pub fn loadConfigWithCmdArgs(
- comptime cmd: Command.Tag,
- allocator: std.mem.Allocator,
- args: clap.Args(clap.Help, cmd.params()),
- ctx: *Command.Context,
- ) !void {
- return try loadConfig(allocator, args.option("--config"), ctx, comptime cmd);
- }
-
pub fn parse(allocator: std.mem.Allocator, ctx: *Command.Context, comptime cmd: Command.Tag) !Api.TransformOptions {
var diag = clap.Diagnostic{};
- const params_to_use = comptime cmd.params();
- var args = clap.parse(clap.Help, params_to_use, .{
- .diagnostic = &diag,
- .allocator = allocator,
- .stop_after_positional_at = if (cmd == .RunCommand) 2 else if (cmd == .AutoCommand)
- 1
- else
- 0,
- }) catch |err| {
+ return parseImpl(allocator, ctx, cmd, &diag) catch |err| {
// Report useful error and exit
- clap.help(Output.errorWriter(), params_to_use) catch {};
+ clap.help(Output.errorWriter(), clap.Help, cmd.params(), .{}) catch {};
Output.errorWriter().writeAll("\n") catch {};
diag.report(Output.errorWriter(), err) catch {};
Global.exit(1);
};
+ }
- if (args.flag("--version")) {
+ // This implementation is separated into a function so that we can use try at
+ // various key points knowing that the public parse fn will catch and handle
+ // those errors for us.
+ fn parseImpl(allocator: std.mem.Allocator, ctx: *Command.Context, comptime cmd: Command.Tag, diag: *clap.Diagnostic) !Api.TransformOptions {
+ const params_to_use = comptime cmd.params();
+
+ // We'll need to work around clap a bit to support this pattern:
+ // bun run --bun-arg app.js --app-arg
+ //
+ // 1) Collect all args into a slice so that we can iterate them multiple times.
+ // 2) Count positionals until we hit the second one (in the example above,
+ // could vary based on command).
+ // 3) Call clap.parse with only the slice up to and including that positional.
+ // 4) All remaining args become passthroughs
+ const full_args = try std.process.argsAlloc(allocator);
+ //NOTE: we won't free full_args because we'll make slices available to
+ // the running script and they need to remain available for the entire run
+ const args = full_args[1..]; // skip exe path
+
+ // 2: Find our parse stopping point
+ const passthrough_after_nth_positional = comptime if (cmd == .RunCommand) 2
+ else if (cmd == .AutoCommand) 1
+ else 0;
+ var it = clap.args.SliceIterator{ .args = args[0..] };
+ var streaming_clap = clap.streaming.Clap(clap.Help, clap.args.SliceIterator){
+ .params = params_to_use,
+ .iter = &it,
+ .diagnostic = diag,
+ };
+ var args_to_parse: usize = 0;
+ if (comptime passthrough_after_nth_positional > 0) {
+ var num_positionals_seen: usize = 0;
+ while (try streaming_clap.next()) |arg| : (args_to_parse += 1) {
+ if (arg.param.names.longest().kind == .positional) {
+ num_positionals_seen += 1;
+
+ if (num_positionals_seen == passthrough_after_nth_positional) {
+ args_to_parse += 1;
+ break;
+ }
+ }
+ }
+ } else
+ args_to_parse = args.len;
+
+ // 3: parse but only up to args_to_parse
+ it = clap.args.SliceIterator{ .args = args[0..args_to_parse] };
+ var res = try clap.parseEx(clap.Help, params_to_use, Arguments.parser, &it, .{
+ .diagnostic = diag,
+ .allocator = allocator,
+ });
+ //defer res.deinit();
+
+
+ if (res.args.version) {
printVersionAndExit();
}
var cwd: []u8 = undefined;
- if (args.option("--cwd")) |cwd_| {
+ if (res.args.cwd) |cwd_| {
cwd = brk: {
var outbuf: [bun.MAX_PATH_BYTES]u8 = undefined;
const out = std.os.realpath(cwd_, &outbuf) catch |err| {
@@ -369,15 +418,17 @@ pub const Arguments = struct {
}
ctx.args.absolute_working_dir = cwd;
- ctx.positionals = args.positionals();
+ ctx.positionals = res.positionals;
+ // All remaining args should be passed through
+ ctx.passthrough = args[args_to_parse..];
if (comptime Command.Tag.loads_config.get(cmd)) {
- try loadConfigWithCmdArgs(cmd, allocator, args, ctx);
+ try loadConfig(allocator, res.args.config, ctx, cmd);
}
var opts: Api.TransformOptions = ctx.args;
- var defines_tuple = try DefineColonList.resolve(allocator, args.options("--define"));
+ var defines_tuple = try DefineColonList.resolve(allocator, res.args.define);
if (defines_tuple.keys.len > 0) {
opts.define = .{
@@ -386,7 +437,7 @@ pub const Arguments = struct {
};
}
- var loader_tuple = try LoaderColonList.resolve(allocator, args.options("--loader"));
+ var loader_tuple = try LoaderColonList.resolve(allocator, res.args.loader);
if (loader_tuple.keys.len > 0) {
opts.loaders = .{
@@ -395,40 +446,39 @@ pub const Arguments = struct {
};
}
- if (args.options("--external").len > 0) {
- var externals = try allocator.alloc([]u8, args.options("--external").len);
- for (args.options("--external"), 0..) |external, i| {
+ if (res.args.external.len > 0) {
+ var externals = try allocator.alloc([]u8, res.args.external.len);
+ for (res.args.external, 0..) |external, i| {
externals[i] = constStrToU8(external);
}
opts.external = externals;
}
- opts.tsconfig_override = if (args.option("--tsconfig-override")) |ts|
+ opts.tsconfig_override = if (res.args.@"tsconfig-override") |ts|
(Arguments.readFile(allocator, cwd, ts) catch |err| fileReadError(err, Output.errorStream(), ts, "tsconfig.json"))
else
null;
- if (args.option("--origin")) |origin| {
+ if (res.args.origin) |origin| {
opts.origin = origin;
}
- if (args.option("--port")) |port_str| {
+ if (res.args.port) |port_str| {
opts.port = std.fmt.parseInt(u16, port_str, 10) catch return error.InvalidPort;
}
opts.serve = cmd == .DevCommand;
- opts.main_fields = args.options("--main-fields");
+ opts.main_fields = res.args.@"main-fields";
opts.generate_node_module_bundle = cmd == .BunCommand;
// we never actually supported inject.
- // opts.inject = args.options("--inject");
- opts.extension_order = args.options("--extension-order");
- ctx.debug.hot_reload = args.flag("--hot");
- ctx.passthrough = args.remaining();
+ // opts.inject = res.args.inject;
+ opts.extension_order = res.args.@"extension-order";
+ ctx.debug.hot_reload = res.args.hot;
- opts.no_summary = args.flag("--no-summary");
- opts.disable_hmr = args.flag("--disable-hmr");
+ opts.no_summary = res.args.@"no-summary";
+ opts.disable_hmr = res.args.@"disable-hmr";
if (cmd != .DevCommand) {
- const preloads = args.options("--preload");
+ const preloads = res.args.preload;
if (ctx.preloads.len > 0 and preloads.len > 0) {
var all = std.ArrayList(string).initCapacity(ctx.allocator, ctx.preloads.len + preloads.len) catch unreachable;
all.appendSliceAssumeCapacity(ctx.preloads);
@@ -439,37 +489,36 @@ pub const Arguments = struct {
}
}
- ctx.debug.silent = args.flag("--silent");
+ ctx.debug.silent = res.args.@"silent";
if (opts.port != null and opts.origin == null) {
opts.origin = try std.fmt.allocPrint(allocator, "http://localhost:{d}/", .{opts.port.?});
}
- const print_help = args.flag("--help");
- if (print_help) {
+ if (res.args.help) {
const params_len = if (cmd == .BuildCommand) build_params_public.len else public_params.len;
- clap.help(Output.writer(), params_to_use[0..params_len]) catch {};
+ clap.help(Output.writer(), clap.Help, params_to_use[0..params_len], .{}) catch {};
Output.prettyln("\n-------\n\n", .{});
Output.flush();
HelpCommand.printWithReason(.explicit);
Global.exit(0);
}
- ctx.debug.dump_environment_variables = args.flag("--dump-environment-variables");
- ctx.debug.fallback_only = ctx.debug.fallback_only or args.flag("--disable-bun.js");
- ctx.debug.dump_limits = args.flag("--dump-limits");
+ ctx.debug.dump_environment_variables = res.args.@"dump-environment-variables";
+ ctx.debug.fallback_only = ctx.debug.fallback_only or res.args.@"disable-bun.js";
+ ctx.debug.dump_limits = res.args.@"dump-limits";
- ctx.debug.offline_mode_setting = if (args.flag("--prefer-offline"))
+ ctx.debug.offline_mode_setting = if (res.args.@"prefer-offline")
Bunfig.OfflineMode.offline
- else if (args.flag("--prefer-latest"))
+ else if (res.args.@"prefer-latest")
Bunfig.OfflineMode.latest
else
Bunfig.OfflineMode.online;
- if (args.flag("--no-install")) {
+ if (res.args.@"no-install") {
ctx.debug.global_cache = .disable;
- } else if (args.flag("-i")) {
+ } else if (res.args.@"install-fallback") {
ctx.debug.global_cache = .fallback;
- } else if (args.option("--install")) |enum_value| {
+ } else if (res.args.install) |enum_value| {
// -i=auto --install=force, --install=disable
if (options.GlobalCache.Map.get(enum_value)) |result| {
ctx.debug.global_cache = result;
@@ -482,18 +531,18 @@ pub const Arguments = struct {
}
}
- // var output_dir = args.option("--outdir");
+ // var output_dir = res.args.outdir;
var output_dir: ?string = null;
const production = false;
- if (cmd == .BuildCommand) {
- if (args.option("--outdir")) |outdir| {
+ if (comptime cmd == .BuildCommand) {
+ if (res.args.outdir) |outdir| {
if (outdir.len > 0) {
output_dir = outdir;
}
}
- if (args.option("--sourcemap")) |setting| {
+ if (res.args.sourcemap) |setting| {
if (setting.len == 0 or strings.eqlComptime(setting, "inline")) {
opts.source_map = Api.SourceMapMode.inline_into_file;
} else if (strings.eqlComptime(setting, "none")) {
@@ -565,24 +614,24 @@ pub const Arguments = struct {
opts.entry_points = entry_points;
}
- var jsx_factory = args.option("--jsx-factory");
- var jsx_fragment = args.option("--jsx-fragment");
- var jsx_import_source = args.option("--jsx-import-source");
- var jsx_runtime = args.option("--jsx-runtime");
- var jsx_production = args.flag("--jsx-production");
+ var jsx_factory = res.args.@"jsx-factory";
+ var jsx_fragment = res.args.@"jsx-fragment";
+ var jsx_import_source = res.args.@"jsx-import-source";
+ var jsx_runtime = res.args.@"jsx-runtime";
+ var jsx_production = res.args.@"jsx-production";
const react_fast_refresh = switch (comptime cmd) {
- .BunCommand, .DevCommand => !(args.flag("--disable-react-fast-refresh") or jsx_production),
+ .BunCommand, .DevCommand => !(res.args.@"disable-react-fast-refresh" or jsx_production),
else => true,
};
if (comptime Command.Tag.cares_about_bun_file.get(cmd)) {
- opts.node_modules_bundle_path = args.option("--bunfile") orelse opts.node_modules_bundle_path orelse brk: {
+ opts.node_modules_bundle_path = res.args.bunfile orelse opts.node_modules_bundle_path orelse brk: {
const node_modules_bundle_path_absolute = resolve_path.joinAbs(cwd, .auto, "node_modules.bun");
break :brk std.fs.realpathAlloc(allocator, node_modules_bundle_path_absolute) catch null;
};
- opts.node_modules_bundle_path_server = args.option("--server-bunfile") orelse opts.node_modules_bundle_path_server orelse brk: {
+ opts.node_modules_bundle_path_server = res.args.@"server-bunfile" orelse opts.node_modules_bundle_path_server orelse brk: {
const node_modules_bundle_path_absolute = resolve_path.joinAbs(cwd, .auto, "node_modules.server.bun");
break :brk std.fs.realpathAlloc(allocator, node_modules_bundle_path_absolute) catch null;
@@ -591,7 +640,7 @@ pub const Arguments = struct {
switch (comptime cmd) {
.AutoCommand, .DevCommand, .BuildCommand, .BunCommand => {
- if (args.option("--public-dir")) |public_dir| {
+ if (res.args.@"public-dir") |public_dir| {
if (public_dir.len > 0) {
opts.router = Api.RouteConfig{ .extensions = &.{}, .dir = &.{}, .static_dir = public_dir };
}
@@ -606,7 +655,7 @@ pub const Arguments = struct {
switch (comptime cmd) {
.BuildCommand => {
- // if (args.option("--resolve")) |_resolve| {
+ // if (res.args.resolve) |_resolve| {
// switch (ResolveMatcher.match(_resolve)) {
// ResolveMatcher.case("disable") => {
// opts.resolve = Api.ResolveMode.disable;
@@ -634,19 +683,19 @@ pub const Arguments = struct {
const PlatformMatcher = strings.ExactSizeMatcher(8);
- if (args.option("--platform")) |_platform| {
+ if (res.args.platform) |_platform| {
opts.platform = opts.platform orelse switch (PlatformMatcher.match(_platform)) {
PlatformMatcher.case("browser") => Api.Platform.browser,
PlatformMatcher.case("node") => Api.Platform.node,
PlatformMatcher.case("macro") => if (cmd == .BuildCommand) Api.Platform.bun_macro else Api.Platform.bun,
PlatformMatcher.case("bun") => Api.Platform.bun,
- else => invalidPlatform(&diag, _platform),
+ else => invalidPlatform(diag, _platform),
};
ctx.debug.run_in_bun = opts.platform.? == .bun;
}
- ctx.debug.run_in_bun = args.flag("--bun") or ctx.debug.run_in_bun;
+ ctx.debug.run_in_bun = res.args.bun or ctx.debug.run_in_bun;
if (jsx_factory != null or
jsx_fragment != null or
@@ -678,7 +727,7 @@ pub const Arguments = struct {
}
}
- if (args.option("--use")) |entry| {
+ if (res.args.use) |entry| {
opts.framework = Api.FrameworkConfig{
.package = entry,
.development = !production,
@@ -819,16 +868,17 @@ pub const PrintBundleCommand = struct {
var stdout = std.io.getStdOut();
var input = try std.fs.openFileAbsolute(try std.os.realpath(entry_point, &out_buffer), .{ .mode = .read_only });
- const params = comptime [_]Arguments.ParamType{
- clap.parseParam("--summary Peek inside the .bun") catch unreachable,
- };
+ const params = comptime clap.parseParamsComptime(
+ \\--summary Peek inside the .bun"
+ );
- var jsBundleArgs = clap.parse(clap.Help, &params, .{ .allocator = ctx.allocator }) catch {
+ var jsBundleArgs = clap.parse(clap.Help, &params, Arguments.parser, .{ .allocator = ctx.allocator }) catch {
try NodeModuleBundle.printBundle(std.fs.File, input, @TypeOf(stdout), stdout);
return;
};
+ defer jsBundleArgs.deinit();
- if (jsBundleArgs.flag("--summary")) {
+ if (jsBundleArgs.args.summary) {
NodeModuleBundle.printSummaryFromDisk(std.fs.File, input, @TypeOf(stdout), stdout, ctx.allocator) catch {};
return;
}
diff --git a/src/cli/create_command.zig b/src/cli/create_command.zig
index 0c76a9c01..c21ccf21d 100644
--- a/src/cli/create_command.zig
+++ b/src/cli/create_command.zig
@@ -25,6 +25,7 @@ const Api = @import("../api/schema.zig").Api;
const resolve_path = @import("../resolver/resolve_path.zig");
const configureTransformOptionsForBun = @import("../bun.js/config.zig").configureTransformOptionsForBun;
const Command = @import("../cli.zig").Command;
+const BunArguments = @import("../cli.zig").Arguments;
const bundler = bun.bundler;
const NodeModuleBundle = @import("../node_module_bundle.zig").NodeModuleBundle;
const fs = @import("../fs.zig");
@@ -187,35 +188,34 @@ const CreateOptions = struct {
verbose: bool = false,
open: bool = false,
- const params = [_]clap.Param(clap.Help){
- clap.parseParam("--help Print this menu") catch unreachable,
- clap.parseParam("--force Overwrite existing files") catch unreachable,
- clap.parseParam("--no-install Don't install node_modules") catch unreachable,
- clap.parseParam("--no-git Don't create a git repository") catch unreachable,
- clap.parseParam("--verbose Too many logs") catch unreachable,
- clap.parseParam("--no-package-json Disable package.json transforms") catch unreachable,
- clap.parseParam("--open On finish, start bun & open in-browser") catch unreachable,
- clap.parseParam("<POS>... ") catch unreachable,
- };
+ const params = clap.parseParamsComptime(
+ \\--help Print this menu
+ \\--force Overwrite existing files
+ \\--no-install Don't install node_modules
+ \\--no-git Don't create a git repository
+ \\--verbose Too many logs
+ \\--no-package-json Disable package.json transforms
+ \\--open On finish, start bun & open in-browser
+ \\<POS>...
+ );
pub fn parse(ctx: Command.Context, comptime print_flags_only: bool) !CreateOptions {
var diag = clap.Diagnostic{};
-
- var args = clap.parse(clap.Help, &params, .{ .diagnostic = &diag, .allocator = ctx.allocator }) catch |err| {
+ var res = clap.parse(clap.Help, &params, BunArguments.parser, .{ .diagnostic = &diag, .allocator = ctx.allocator }) catch |err| {
// Report useful error and exit
diag.report(Output.errorWriter(), err) catch {};
return err;
};
- if (args.flag("--help") or comptime print_flags_only) {
+ if (res.args.help or comptime print_flags_only) {
if (comptime print_flags_only) {
- clap.help(Output.writer(), params[1..]) catch {};
+ clap.help(Output.writer(), clap.Help, params[1..], .{}) catch {};
return undefined;
}
Output.prettyln("<r><b>bun create<r>\n\n flags:\n", .{});
Output.flush();
- clap.help(Output.writer(), params[1..]) catch {};
+ clap.help(Output.writer(), clap.Help, params[1..], .{}) catch {};
Output.pretty("\n", .{});
Output.prettyln("<r> environment variables:\n\n", .{});
Output.prettyln(" GITHUB_ACCESS_TOKEN<r> Downloading code from GitHub with a higher rate limit", .{});
@@ -226,19 +226,19 @@ const CreateOptions = struct {
Global.exit(0);
}
- var opts = CreateOptions{ .positionals = args.positionals() };
+ var opts = CreateOptions{ .positionals = res.positionals };
if (opts.positionals.len >= 1 and (strings.eqlComptime(opts.positionals[0], "c") or strings.eqlComptime(opts.positionals[0], "create"))) {
opts.positionals = opts.positionals[1..];
}
- opts.skip_package_json = args.flag("--no-package-json");
+ opts.skip_package_json = res.args.@"no-package-json";
- opts.verbose = args.flag("--verbose");
- opts.open = args.flag("--open");
- opts.skip_install = args.flag("--no-install");
- opts.skip_git = args.flag("--no-git");
- opts.overwrite = args.flag("--force");
+ opts.verbose = res.args.verbose;
+ opts.open = res.args.open;
+ opts.skip_install = res.args.@"no-install";
+ opts.skip_git = res.args.@"no-git";
+ opts.overwrite = res.args.force;
return opts;
}
diff --git a/src/deps/zig-clap b/src/deps/zig-clap
new file mode 160000
+Subproject 9c3ac846121a03934c7460cc54989059b1f66b2
diff --git a/src/deps/zig-clap/.gitignore b/src/deps/zig-clap/.gitignore
deleted file mode 100644
index 2040c29db..000000000
--- a/src/deps/zig-clap/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-zig-cache
diff --git a/src/deps/zig-clap/LICENSE b/src/deps/zig-clap/LICENSE
deleted file mode 100644
index cf1ab25da..000000000
--- a/src/deps/zig-clap/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-This is free and unencumbered software released into the public domain.
-
-Anyone is free to copy, modify, publish, use, compile, sell, or
-distribute this software, either in source code form or as a compiled
-binary, for any purpose, commercial or non-commercial, and by any
-means.
-
-In jurisdictions that recognize copyright laws, the author or authors
-of this software dedicate any and all copyright interest in the
-software to the public domain. We make this dedication for the benefit
-of the public at large and to the detriment of our heirs and
-successors. We intend this dedication to be an overt act of
-relinquishment in perpetuity of all present and future rights to this
-software under copyright law.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-For more information, please refer to <http://unlicense.org>
diff --git a/src/deps/zig-clap/build.zig b/src/deps/zig-clap/build.zig
deleted file mode 100644
index 5ab66da8a..000000000
--- a/src/deps/zig-clap/build.zig
+++ /dev/null
@@ -1,55 +0,0 @@
-const builtin = @import("builtin");
-const std = @import("std");
-
-const Builder = std.build.Builder;
-const Mode = std.builtin.Mode;
-
-pub fn build(b: *Builder) void {
- const mode = b.standardReleaseOptions();
- const target = b.standardTargetOptions(.{});
-
- const test_all_step = b.step("test", "Run all tests in all modes.");
- inline for ([_]Mode{ Mode.Debug, Mode.ReleaseFast, Mode.ReleaseSafe, Mode.ReleaseSmall }) |test_mode| {
- const mode_str = comptime modeToString(test_mode);
-
- const tests = b.addTest("clap.zig");
- tests.setBuildMode(test_mode);
- tests.setTarget(target);
- tests.setNamePrefix(mode_str ++ " ");
-
- const test_step = b.step("test-" ++ mode_str, "Run all tests in " ++ mode_str ++ ".");
- test_step.dependOn(&tests.step);
- test_all_step.dependOn(test_step);
- }
-
- const example_step = b.step("examples", "Build examples");
- inline for ([_][]const u8{
- "simple",
- "simple-ex",
- //"simple-error",
- "streaming-clap",
- "help",
- "usage",
- }) |example_name| {
- const example = b.addExecutable(example_name, "example/" ++ example_name ++ ".zig");
- example.addPackagePath("clap", "clap.zig");
- example.setBuildMode(mode);
- example.setTarget(target);
- example.install();
- example_step.dependOn(&example.step);
- }
-
- const all_step = b.step("all", "Build everything and runs all tests");
- all_step.dependOn(test_all_step);
-
- b.default_step.dependOn(all_step);
-}
-
-fn modeToString(mode: Mode) []const u8 {
- return switch (mode) {
- Mode.Debug => "debug",
- Mode.ReleaseFast => "release-fast",
- Mode.ReleaseSafe => "release-safe",
- Mode.ReleaseSmall => "release-small",
- };
-}
diff --git a/src/deps/zig-clap/clap.zig b/src/deps/zig-clap/clap.zig
deleted file mode 100644
index a21a1cb1a..000000000
--- a/src/deps/zig-clap/clap.zig
+++ /dev/null
@@ -1,546 +0,0 @@
-const std = @import("std");
-
-const debug = std.debug;
-const heap = std.heap;
-const io = std.io;
-const mem = std.mem;
-const testing = std.testing;
-
-pub const args = @import("clap/args.zig");
-
-test "clap" {
- testing.refAllDecls(@This());
-}
-
-pub const ComptimeClap = @import("clap/comptime.zig").ComptimeClap;
-pub const StreamingClap = @import("clap/streaming.zig").StreamingClap;
-
-/// The names a ::Param can have.
-pub const Names = struct {
- /// '-' prefix
- short: ?u8 = null,
-
- /// '--' prefix
- long: ?[]const u8 = null,
-};
-
-/// Whether a param takes no value (a flag), one value, or can be specified multiple times.
-pub const Values = enum {
- none,
- one,
- many,
- one_optional,
-};
-
-/// Represents a parameter for the command line.
-/// Parameters come in three kinds:
-/// * Short ("-a"): Should be used for the most commonly used parameters in your program.
-/// * They can take a value three different ways.
-/// * "-a value"
-/// * "-a=value"
-/// * "-avalue"
-/// * They chain if they don't take values: "-abc".
-/// * The last given parameter can take a value in the same way that a single parameter can:
-/// * "-abc value"
-/// * "-abc=value"
-/// * "-abcvalue"
-/// * Long ("--long-param"): Should be used for less common parameters, or when no single character
-/// can describe the paramter.
-/// * They can take a value two different ways.
-/// * "--long-param value"
-/// * "--long-param=value"
-/// * Positional: Should be used as the primary parameter of the program, like a filename or
-/// an expression to parse.
-/// * Positional parameters have both names.long and names.short == null.
-/// * Positional parameters must take a value.
-pub fn Param(comptime Id: type) type {
- return struct {
- id: Id = std.mem.zeroes(Id),
- names: Names = std.mem.zeroes(Names),
- takes_value: Values = .none,
- };
-}
-
-/// Takes a string and parses it to a Param(Help).
-/// This is the reverse of 'help' but for at single parameter only.
-pub fn parseParam(line: []const u8) !Param(Help) {
- @setEvalBranchQuota(999999);
-
- var found_comma = false;
- var it = mem.tokenize(u8, line, " \t");
- var param_str = it.next() orelse return error.NoParamFound;
-
- const short_name = if (!mem.startsWith(u8, param_str, "--") and
- mem.startsWith(u8, param_str, "-"))
- blk: {
- found_comma = param_str[param_str.len - 1] == ',';
- if (found_comma)
- param_str = param_str[0 .. param_str.len - 1];
-
- if (param_str.len != 2)
- return error.InvalidShortParam;
-
- const short_name = param_str[1];
- if (!found_comma) {
- var res = parseParamRest(it.rest());
- res.names.short = short_name;
- return res;
- }
-
- param_str = it.next() orelse return error.NoParamFound;
- break :blk short_name;
- } else null;
-
- _ = if (mem.startsWith(u8, param_str, "--")) {
- if (param_str[param_str.len - 1] == ',')
- return error.TrailingComma;
- } else if (found_comma) {
- return error.TrailingComma;
- } else if (short_name == null) {
- return parseParamRest(mem.trimLeft(u8, line, " \t"));
- } else null;
-
- var res = parseParamRest(it.rest());
- res.names.long = param_str[2..];
- res.names.short = short_name;
- return res;
-}
-
-fn parseParamRest(line: []const u8) Param(Help) {
- if (mem.startsWith(u8, line, "<")) blk: {
- const len = mem.indexOfScalar(u8, line, '>') orelse break :blk;
- const takes_many = mem.startsWith(u8, line[len + 1 ..], "...");
- const takes_one_optional = mem.startsWith(u8, line[len + 1 ..], "?");
- const help_start = len + 1 + @as(usize, 3) * @boolToInt(takes_many) + (@as(usize, 1) * @boolToInt(takes_one_optional));
- return .{
- .takes_value = if (takes_many) Values.many else if (takes_one_optional) Values.one_optional else Values.one,
- .id = .{
- .msg = mem.trim(u8, line[help_start..], " \t"),
- .value = line[1..len],
- },
- };
- }
-
- return .{ .id = .{ .msg = mem.trim(u8, line, " \t") } };
-}
-
-fn expectParam(expect: Param(Help), actual: Param(Help)) void {
- testing.expectEqualStrings(expect.id.msg, actual.id.msg);
- testing.expectEqualStrings(expect.id.value, actual.id.value);
- testing.expectEqual(expect.names.short, actual.names.short);
- testing.expectEqual(expect.takes_value, actual.takes_value);
- if (expect.names.long) |long| {
- testing.expectEqualStrings(long, actual.names.long.?);
- } else {
- testing.expectEqual(@as(?[]const u8, null), actual.names.long);
- }
-}
-
-test "parseParam" {
- expectParam(Param(Help){
- .id = .{ .msg = "Help text", .value = "value" },
- .names = .{ .short = 's', .long = "long" },
- .takes_value = .one,
- }, try parseParam("-s, --long <value> Help text"));
-
- expectParam(Param(Help){
- .id = .{ .msg = "Help text", .value = "value" },
- .names = .{ .short = 's', .long = "long" },
- .takes_value = .many,
- }, try parseParam("-s, --long <value>... Help text"));
-
- expectParam(Param(Help){
- .id = .{ .msg = "Help text", .value = "value" },
- .names = .{ .long = "long" },
- .takes_value = .one,
- }, try parseParam("--long <value> Help text"));
-
- expectParam(Param(Help){
- .id = .{ .msg = "Help text", .value = "value" },
- .names = .{ .short = 's' },
- .takes_value = .one,
- }, try parseParam("-s <value> Help text"));
-
- expectParam(Param(Help){
- .id = .{ .msg = "Help text" },
- .names = .{ .short = 's', .long = "long" },
- }, try parseParam("-s, --long Help text"));
-
- expectParam(Param(Help){
- .id = .{ .msg = "Help text" },
- .names = .{ .short = 's' },
- }, try parseParam("-s Help text"));
-
- expectParam(Param(Help){
- .id = .{ .msg = "Help text" },
- .names = .{ .long = "long" },
- }, try parseParam("--long Help text"));
-
- expectParam(Param(Help){
- .id = .{ .msg = "Help text", .value = "A | B" },
- .names = .{ .long = "long" },
- .takes_value = .one,
- }, try parseParam("--long <A | B> Help text"));
-
- expectParam(Param(Help){
- .id = .{ .msg = "Help text", .value = "A" },
- .names = .{},
- .takes_value = .one,
- }, try parseParam("<A> Help text"));
-
- expectParam(Param(Help){
- .id = .{ .msg = "Help text", .value = "A" },
- .names = .{},
- .takes_value = .many,
- }, try parseParam("<A>... Help text"));
-
- testing.expectError(error.TrailingComma, parseParam("--long, Help"));
- testing.expectError(error.TrailingComma, parseParam("-s, Help"));
- testing.expectError(error.InvalidShortParam, parseParam("-ss Help"));
- testing.expectError(error.InvalidShortParam, parseParam("-ss <value> Help"));
- testing.expectError(error.InvalidShortParam, parseParam("- Help"));
-}
-
-/// Optional diagnostics used for reporting useful errors
-pub const Diagnostic = struct {
- arg: []const u8 = "",
- name: Names = Names{},
-
- /// 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 {
- const Arg = struct {
- prefix: []const u8,
- name: []const u8,
- };
- const a = if (diag.name.short) |*c|
- Arg{ .prefix = "-", .name = @as(*const [1]u8, c)[0..] }
- else if (diag.name.long) |l|
- Arg{ .prefix = "--", .name = l }
- else
- Arg{ .prefix = "", .name = diag.arg };
-
- switch (err) {
- error.DoesntTakeValue => try stream.print("The argument '{s}{s}' does not take a value\n", .{ a.prefix, a.name }),
- error.MissingValue => try stream.print("The argument '{s}{s}' requires a value but none was supplied\n", .{ a.prefix, a.name }),
- error.InvalidArgument => if (a.prefix.len > 0 and a.name.len > 0)
- try stream.print("Invalid argument '{s}{s}'\n", .{ a.prefix, a.name })
- else
- try stream.print("Failed to parse argument due to unexpected single dash\n", .{}),
- else => try stream.print("Error while parsing arguments: {s}\n", .{@errorName(err)}),
- }
- }
-};
-
-fn testDiag(diag: Diagnostic, err: anyerror, expected: []const u8) void {
- var buf: [1024]u8 = undefined;
- var slice_stream = io.fixedBufferStream(&buf);
- diag.report(slice_stream.writer(), err) catch unreachable;
- testing.expectEqualStrings(expected, slice_stream.getWritten());
-}
-
-pub fn Args(comptime Id: type, comptime params: []const Param(Id)) type {
- return struct {
- arena: std.heap.ArenaAllocator,
- clap: ComptimeClap(Id, params),
- exe_arg: ?[]const u8,
-
- pub fn deinit(a: *@This()) void {
- a.arena.deinit();
- }
-
- pub fn flag(a: @This(), comptime name: []const u8) bool {
- return a.clap.flag(name);
- }
-
- pub fn option(a: @This(), comptime name: []const u8) ?[]const u8 {
- return a.clap.option(name);
- }
-
- pub fn options(a: @This(), comptime name: []const u8) []const []const u8 {
- return a.clap.options(name);
- }
-
- pub fn positionals(a: @This()) []const []const u8 {
- return a.clap.positionals();
- }
-
- pub fn remaining(a: @This()) []const []const u8 {
- return a.clap.remaining();
- }
-
- pub fn hasFlag(comptime name: []const u8) bool {
- return ComptimeClap(Id, params).hasFlag(name);
- }
- };
-}
-
-/// Options that can be set to customize the behavior of parsing.
-pub const ParseOptions = struct {
- /// The allocator used for all memory allocations. Defaults to the `heap.page_allocator`.
- /// Note: You should probably override this allocator if you are calling `parseEx`. Unlike
- /// `parse`, `parseEx` does not wrap the allocator so the heap allocator can be
- /// quite expensive. (TODO: Can we pick a better default? For `parse`, this allocator
- /// is fine, as it wraps it in an arena)
- allocator: mem.Allocator = heap.page_allocator,
- diagnostic: ?*Diagnostic = null,
- stop_after_positional_at: usize = 0,
-};
-
-/// Same as `parseEx` but uses the `args.OsIterator` by default.
-pub fn parse(
- comptime Id: type,
- comptime params: []const Param(Id),
- opt: ParseOptions,
-) !Args(Id, params) {
- var iter = args.OsIterator.init(opt.allocator);
- var res = Args(Id, params){
- .arena = iter.arena,
- .exe_arg = iter.exe_arg,
- .clap = undefined,
- };
-
- // Let's reuse the arena from the `OSIterator` since we already have
- // it.
- res.clap = try parseEx(Id, params, &iter, .{
- .allocator = res.arena.allocator(),
- .diagnostic = opt.diagnostic,
- .stop_after_positional_at = opt.stop_after_positional_at,
- });
- return res;
-}
-
-/// Parses the command line arguments passed into the program based on an
-/// array of `Param`s.
-pub fn parseEx(
- comptime Id: type,
- comptime params: []const Param(Id),
- iter: anytype,
- opt: ParseOptions,
-) !ComptimeClap(Id, params) {
- const Clap = ComptimeClap(Id, params);
- return try Clap.parse(iter, opt);
-}
-
-/// Will print a help message in the following format:
-/// -s, --long <valueText> helpText
-/// -s, helpText
-/// -s <valueText> helpText
-/// --long helpText
-/// --long <valueText> helpText
-pub fn helpFull(
- stream: anytype,
- comptime Id: type,
- params: []const Param(Id),
- comptime Error: type,
- context: anytype,
- helpText: fn (@TypeOf(context), Param(Id)) Error![]const u8,
- valueText: fn (@TypeOf(context), Param(Id)) Error![]const u8,
-) !void {
- const max_spacing = blk: {
- var res: usize = 0;
- for (params) |param| {
- var cs = io.countingWriter(io.null_writer);
- try printParam(cs.writer(), Id, param, Error, context, valueText);
- if (res < cs.bytes_written)
- res = @intCast(usize, cs.bytes_written);
- }
-
- break :blk res;
- };
-
- for (params) |param| {
- if (param.names.short == null and param.names.long == null)
- continue;
-
- var cs = io.countingWriter(stream);
- try stream.print("\t", .{});
- try printParam(cs.writer(), Id, param, Error, context, valueText);
- try stream.writeByteNTimes(' ', max_spacing - @intCast(usize, cs.bytes_written));
- try stream.print("\t{s}\n", .{try helpText(context, param)});
- }
-}
-
-fn printParam(
- stream: anytype,
- comptime Id: type,
- param: Param(Id),
- comptime Error: type,
- context: anytype,
- valueText: fn (@TypeOf(context), Param(Id)) Error![]const u8,
-) !void {
- if (param.names.short) |s| {
- try stream.print("-{c}", .{s});
- } else {
- try stream.print(" ", .{});
- }
- if (param.names.long) |l| {
- if (param.names.short) |_| {
- try stream.print(", ", .{});
- } else {
- try stream.print(" ", .{});
- }
-
- try stream.print("--{s}", .{l});
- }
-
- switch (param.takes_value) {
- .none => {},
- .one => try stream.print(" <{s}>", .{try valueText(context, param)}),
- .one_optional => try stream.print(" <{s}>?", .{try valueText(context, param)}),
- .many => try stream.print(" <{s}>...", .{try valueText(context, param)}),
- }
-}
-
-/// A wrapper around helpFull for simple helpText and valueText functions that
-/// cant return an error or take a context.
-pub fn helpEx(
- stream: anytype,
- comptime Id: type,
- params: []const Param(Id),
- helpText: *const fn (Param(Id)) []const u8,
- valueText: *const fn (Param(Id)) []const u8,
-) !void {
- const Context = struct {
- helpText: *const fn (Param(Id)) []const u8,
- valueText: *const fn (Param(Id)) []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,
- );
-}
-
-pub const Help = struct {
- msg: []const u8 = "",
- value: []const u8 = "",
-};
-
-/// A wrapper around helpEx that takes a Param(Help).
-pub fn help(stream: anytype, params: []const Param(Help)) !void {
- try helpEx(stream, Help, params, getHelpSimple, getValueSimple);
-}
-
-fn getHelpSimple(param: Param(Help)) []const u8 {
- return param.id.msg;
-}
-
-fn getValueSimple(param: Param(Help)) []const u8 {
- return param.id.value;
-}
-
-/// Will print a usage message in the following format:
-/// [-abc] [--longa] [-d <valueText>] [--longb <valueText>] <valueText>
-///
-/// First all none value taking parameters, which have a short name are
-/// printed, then non positional parameters and finally the positinal.
-pub fn usageFull(
- stream: anytype,
- comptime Id: type,
- params: []const Param(Id),
- comptime Error: type,
- context: anytype,
- valueText: fn (@TypeOf(context), Param(Id)) Error![]const u8,
-) !void {
- var cos = io.countingWriter(stream);
- const cs = cos.writer();
- for (params) |param| {
- const name = param.names.short orelse continue;
- if (param.takes_value != .none)
- continue;
-
- if (cos.bytes_written == 0)
- try stream.writeAll("[-");
- try cs.writeByte(name);
- }
- if (cos.bytes_written != 0)
- try cs.writeByte(']');
-
- var positional: ?Param(Id) = null;
- for (params) |param| {
- if (param.takes_value == .none and param.names.short != null)
- continue;
-
- const prefix = if (param.names.short) |_| "-" else "--";
-
- // Seems the zig compiler is being a little wierd. I doesn't allow me to write
- // @as(*const [1]u8, s) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
- const name = if (param.names.short) |*s| @ptrCast([*]const u8, s)[0..1] else param.names.long orelse {
- positional = param;
- continue;
- };
- if (cos.bytes_written != 0)
- try cs.writeByte(' ');
-
- try cs.print("[{s}{s}", .{ prefix, name });
- switch (param.takes_value) {
- .none => {},
- .one => try cs.print(" <{s}>", .{try valueText(context, param)}),
- .one_optional => try cs.print(" <{s}>?", .{try valueText(context, param)}),
- .many => try cs.print(" <{s}>...", .{try valueText(context, param)}),
- }
-
- try cs.writeByte(']');
- }
-
- if (positional) |p| {
- if (cos.bytes_written != 0)
- try cs.writeByte(' ');
- try cs.print("<{s}>", .{try valueText(context, p)});
- }
-}
-
-/// A wrapper around usageFull for a simple valueText functions that
-/// cant return an error or take a context.
-pub fn usageEx(
- stream: anytype,
- comptime Id: type,
- params: []const Param(Id),
- valueText: fn (Param(Id)) []const u8,
-) !void {
- const Context = struct {
- valueText: fn (Param(Id)) []const u8,
-
- pub fn value(c: @This(), p: Param(Id)) error{}![]const u8 {
- return c.valueText(p);
- }
- };
-
- return usageFull(
- stream,
- Id,
- params,
- error{},
- Context{ .valueText = valueText },
- Context.value,
- );
-}
-
-/// A wrapper around usageEx that takes a Param(Help).
-pub fn usage(stream: anytype, params: []const Param(Help)) !void {
- try usageEx(stream, Help, params, getValueSimple);
-}
-
-fn testUsage(expected: []const u8, params: []const Param(Help)) !void {
- var buf: [1024]u8 = undefined;
- var fbs = io.fixedBufferStream(&buf);
- try usage(fbs.writer(), params);
- testing.expectEqualStrings(expected, fbs.getWritten());
-}
diff --git a/src/deps/zig-clap/clap/args.zig b/src/deps/zig-clap/clap/args.zig
deleted file mode 100644
index a1fa3773a..000000000
--- a/src/deps/zig-clap/clap/args.zig
+++ /dev/null
@@ -1,337 +0,0 @@
-const std = @import("std");
-
-const builtin = @import("builtin");
-const debug = std.debug;
-const heap = std.heap;
-const mem = std.mem;
-const process = std.process;
-const testing = std.testing;
-
-/// An example of what methods should be implemented on an arg iterator.
-pub const ExampleArgIterator = struct {
- const Error = error{};
-
- pub fn next(_: *ExampleArgIterator) Error!?[]const u8 {
- return "2";
- }
-};
-
-/// An argument iterator which iterates over a slice of arguments.
-/// This implementation does not allocate.
-pub const SliceIterator = struct {
- const Error = error{};
-
- args: []const []const u8,
- index: usize = 0,
-
- pub fn next(iter: *SliceIterator) Error!?[]const u8 {
- if (iter.args.len <= iter.index)
- return null;
-
- defer iter.index += 1;
- return iter.args[iter.index];
- }
-};
-
-test "SliceIterator" {
- const args = &[_][]const u8{ "A", "BB", "CCC" };
- var iter = SliceIterator{ .args = args };
-
- for (args) |a| {
- const b = try iter.next();
- debug.assert(mem.eql(u8, a, b.?));
- }
-}
-
-/// An argument iterator which wraps the ArgIterator in ::std.
-/// On windows, this iterator allocates.
-pub const OsIterator = struct {
- const Error = process.ArgIterator.InitError;
-
- arena: heap.ArenaAllocator,
- args: process.ArgIterator,
-
- /// The executable path (this is the first argument passed to the program)
- /// TODO: Is it the right choice for this to be null? Maybe `init` should
- /// return an error when we have no exe.
- exe_arg: ?[:0]const u8,
-
- pub fn init(allocator: mem.Allocator) OsIterator {
- var res = OsIterator{
- .arena = heap.ArenaAllocator.init(allocator),
- .args = process.args(),
- .exe_arg = undefined,
- };
- res.exe_arg = res.next();
- return res;
- }
-
- pub fn deinit(iter: *OsIterator) void {
- iter.arena.deinit();
- }
-
- pub fn next(iter: *OsIterator) ?[:0]const u8 {
- return iter.args.next();
- }
-};
-
-/// An argument iterator that takes a string and parses it into arguments, simulating
-/// how shells split arguments.
-pub const ShellIterator = struct {
- const Error = error{
- DanglingEscape,
- QuoteNotClosed,
- } || mem.Allocator.Error;
-
- arena: heap.ArenaAllocator,
- str: []const u8,
-
- pub fn init(allocator: mem.Allocator, str: []const u8) ShellIterator {
- return .{
- .arena = heap.ArenaAllocator.init(allocator),
- .str = str,
- };
- }
-
- pub fn deinit(iter: *ShellIterator) void {
- iter.arena.deinit();
- }
-
- pub fn next(iter: *ShellIterator) Error!?[]const u8 {
- // Whenever possible, this iterator will return slices into `str` instead of
- // allocating. Sometimes this is not possible, for example, escaped characters
- // have be be unescape, so we need to allocate in this case.
- var list = std.ArrayList(u8).init(&iter.arena.allocator);
- var start: usize = 0;
- var state: enum {
- skip_whitespace,
- no_quote,
- no_quote_escape,
- single_quote,
- double_quote,
- double_quote_escape,
- after_quote,
- } = .skip_whitespace;
-
- for (iter.str, 0..) |c, i| {
- switch (state) {
- // The state that skips the initial whitespace.
- .skip_whitespace => switch (c) {
- ' ', '\t', '\n' => {},
- '\'' => {
- start = i + 1;
- state = .single_quote;
- },
- '"' => {
- start = i + 1;
- state = .double_quote;
- },
- '\\' => {
- start = i + 1;
- state = .no_quote_escape;
- },
- else => {
- start = i;
- state = .no_quote;
- },
- },
-
- // The state that parses the none quoted part of a argument.
- .no_quote => switch (c) {
- // We're done parsing a none quoted argument when we hit a
- // whitespace.
- ' ', '\t', '\n' => {
- defer iter.str = iter.str[i..];
- return iter.result(start, i, &list);
- },
-
- // Slicing is not possible if a quote starts while parsing none
- // quoted args.
- // Example:
- // ab'cd' -> abcd
- '\'' => {
- try list.appendSlice(iter.str[start..i]);
- start = i + 1;
- state = .single_quote;
- },
- '"' => {
- try list.appendSlice(iter.str[start..i]);
- start = i + 1;
- state = .double_quote;
- },
-
- // Slicing is not possible if we need to escape a character.
- // Example:
- // ab\"d -> ab"d
- '\\' => {
- try list.appendSlice(iter.str[start..i]);
- start = i + 1;
- state = .no_quote_escape;
- },
- else => {},
- },
-
- // We're in this state after having parsed the quoted part of an
- // argument. This state works mostly the same as .no_quote, but
- // is aware, that the last character seen was a quote, which should
- // not be part of the argument. This is why you will see `i - 1` here
- // instead of just `i` when `iter.str` is sliced.
- .after_quote => switch (c) {
- ' ', '\t', '\n' => {
- defer iter.str = iter.str[i..];
- return iter.result(start, i - 1, &list);
- },
- '\'' => {
- try list.appendSlice(iter.str[start .. i - 1]);
- start = i + 1;
- state = .single_quote;
- },
- '"' => {
- try list.appendSlice(iter.str[start .. i - 1]);
- start = i + 1;
- state = .double_quote;
- },
- '\\' => {
- try list.appendSlice(iter.str[start .. i - 1]);
- start = i + 1;
- state = .no_quote_escape;
- },
- else => {
- try list.appendSlice(iter.str[start .. i - 1]);
- start = i;
- state = .no_quote;
- },
- },
-
- // The states that parse the quoted part of arguments. The only differnece
- // between single and double quoted arguments is that single quoted
- // arguments ignore escape sequences, while double quoted arguments
- // does escaping.
- .single_quote => switch (c) {
- '\'' => state = .after_quote,
- else => {},
- },
- .double_quote => switch (c) {
- '"' => state = .after_quote,
- '\\' => {
- try list.appendSlice(iter.str[start..i]);
- start = i + 1;
- state = .double_quote_escape;
- },
- else => {},
- },
-
- // The state we end up when after the escape character (`\`). All these
- // states do is transition back into the previous state.
- // TODO: Are there any escape sequences that does transform the second
- // character into something else? For example, in Zig, `\n` is
- // transformed into the line feed ascii character.
- .no_quote_escape => switch (c) {
- else => state = .no_quote,
- },
- .double_quote_escape => switch (c) {
- else => state = .double_quote,
- },
- }
- }
-
- defer iter.str = iter.str[iter.str.len..];
- switch (state) {
- .skip_whitespace => return null,
- .no_quote => return iter.result(start, iter.str.len, &list),
- .after_quote => return iter.result(start, iter.str.len - 1, &list),
- .no_quote_escape => return Error.DanglingEscape,
- .single_quote,
- .double_quote,
- .double_quote_escape,
- => return Error.QuoteNotClosed,
- }
- }
-
- fn result(iter: *ShellIterator, start: usize, end: usize, list: *std.ArrayList(u8)) Error!?[]const u8 {
- const res = iter.str[start..end];
-
- // If we already have something in `list` that means that we could not
- // parse the argument without allocation. We therefor need to just append
- // the rest we have to the list and return that.
- if (list.items.len != 0) {
- try list.appendSlice(res);
- return try list.toOwnedSlice();
- }
- return res;
- }
-};
-
-fn testShellIteratorOk(str: []const u8, allocations: usize, expect: []const []const u8) void {
- var allocator = testing.FailingAllocator.init(testing.allocator, allocations);
- var it = ShellIterator.init(&allocator.allocator, str);
- defer it.deinit();
-
- for (expect) |e| {
- if (it.next()) |actual| {
- testing.expect(actual != null);
- testing.expectEqualStrings(e, actual.?);
- } else |err| testing.expectEqual(@as(anyerror![]const u8, e), err);
- }
-
- if (it.next()) |actual| {
- testing.expectEqual(@as(?[]const u8, null), actual);
- testing.expectEqual(allocations, allocator.allocations);
- } else |err| testing.expectEqual(@as(anyerror!void, {}), err);
-}
-
-fn testShellIteratorErr(str: []const u8, expect: anyerror) void {
- var it = ShellIterator.init(testing.allocator, str);
- defer it.deinit();
-
- while (it.next() catch |err| {
- testing.expectError(expect, @as(anyerror!void, err));
- return;
- }) |_| {}
-
- testing.expectError(expect, @as(anyerror!void, {}));
-}
-
-test "ShellIterator" {
- testShellIteratorOk("a", 0, &[_][]const u8{"a"});
- testShellIteratorOk("'a'", 0, &[_][]const u8{"a"});
- testShellIteratorOk("\"a\"", 0, &[_][]const u8{"a"});
- testShellIteratorOk("a b", 0, &[_][]const u8{ "a", "b" });
- testShellIteratorOk("'a' b", 0, &[_][]const u8{ "a", "b" });
- testShellIteratorOk("\"a\" b", 0, &[_][]const u8{ "a", "b" });
- testShellIteratorOk("a 'b'", 0, &[_][]const u8{ "a", "b" });
- testShellIteratorOk("a \"b\"", 0, &[_][]const u8{ "a", "b" });
- testShellIteratorOk("'a b'", 0, &[_][]const u8{"a b"});
- testShellIteratorOk("\"a b\"", 0, &[_][]const u8{"a b"});
- testShellIteratorOk("\"a\"\"b\"", 1, &[_][]const u8{"ab"});
- testShellIteratorOk("'a''b'", 1, &[_][]const u8{"ab"});
- testShellIteratorOk("'a'b", 1, &[_][]const u8{"ab"});
- testShellIteratorOk("a'b'", 1, &[_][]const u8{"ab"});
- testShellIteratorOk("a\\ b", 1, &[_][]const u8{"a b"});
- testShellIteratorOk("\"a\\ b\"", 1, &[_][]const u8{"a b"});
- testShellIteratorOk("'a\\ b'", 0, &[_][]const u8{"a\\ b"});
- testShellIteratorOk(" a b ", 0, &[_][]const u8{ "a", "b" });
- testShellIteratorOk("\\ \\ ", 0, &[_][]const u8{ " ", " " });
-
- testShellIteratorOk(
- \\printf 'run\nuninstall\n'
- , 0, &[_][]const u8{ "printf", "run\\nuninstall\\n" });
- testShellIteratorOk(
- \\setsid -f steam "steam://$action/$id"
- , 0, &[_][]const u8{ "setsid", "-f", "steam", "steam://$action/$id" });
- testShellIteratorOk(
- \\xargs -I% rg --no-heading --no-line-number --only-matching
- \\ --case-sensitive --multiline --text --byte-offset '(?-u)%' $@
- \\
- , 0, &[_][]const u8{
- "xargs", "-I%", "rg", "--no-heading",
- "--no-line-number", "--only-matching", "--case-sensitive", "--multiline",
- "--text", "--byte-offset", "(?-u)%", "$@",
- });
-
- testShellIteratorErr("'a", error.QuoteNotClosed);
- testShellIteratorErr("'a\\", error.QuoteNotClosed);
- testShellIteratorErr("\"a", error.QuoteNotClosed);
- testShellIteratorErr("\"a\\", error.QuoteNotClosed);
- testShellIteratorErr("a\\", error.DanglingEscape);
-}
diff --git a/src/deps/zig-clap/clap/comptime.zig b/src/deps/zig-clap/clap/comptime.zig
deleted file mode 100644
index 3dcd4f7d7..000000000
--- a/src/deps/zig-clap/clap/comptime.zig
+++ /dev/null
@@ -1,194 +0,0 @@
-const clap = @import("../clap.zig");
-const std = @import("std");
-
-const debug = std.debug;
-const heap = std.heap;
-const mem = std.mem;
-const testing = std.testing;
-
-/// Deprecated: Use `parseEx` instead
-pub fn ComptimeClap(
- comptime Id: type,
- comptime params: []const clap.Param(Id),
-) type {
- var _flags: usize = 0;
- var _single_options: usize = 0;
- var _multi_options: usize = 0;
- var _converted_params: []const clap.Param(usize) = &[_]clap.Param(usize){};
- for (params) |param| {
- var index: usize = 0;
- if (param.names.long != null or param.names.short != null) {
- const ptr = switch (param.takes_value) {
- .none => &_flags,
- .one_optional, .one => &_single_options,
- .many => &_multi_options,
- };
- index = ptr.*;
- ptr.* += 1;
- }
-
- const converted = clap.Param(usize){
- .id = index,
- .names = param.names,
- .takes_value = param.takes_value,
- };
- _converted_params = _converted_params ++ [_]clap.Param(usize){converted};
- }
- const flags = _flags;
- const single_options = _single_options;
- const multi_options = _multi_options;
- const converted_params = _converted_params;
-
- return struct {
- single_options: [single_options]?[]const u8,
- multi_options: [multi_options][]const []const u8,
- flags: [flags]bool,
- pos: []const []const u8,
- passthrough_positionals: []const []const u8,
- allocator: mem.Allocator,
-
- pub fn parse(iter: anytype, opt: clap.ParseOptions) !@This() {
- const allocator = opt.allocator;
- var multis = [_]std.ArrayList([]const u8){undefined} ** multi_options;
- for (&multis) |*multi| {
- multi.* = std.ArrayList([]const u8).init(allocator);
- }
-
- var pos = std.ArrayList([]const u8).init(allocator);
- var passthrough_positionals = std.ArrayList([]const u8).init(allocator);
-
- var res = @This(){
- .single_options = [_]?[]const u8{null} ** single_options,
- .multi_options = [_][]const []const u8{undefined} ** multi_options,
- .flags = [_]bool{false} ** flags,
- .pos = undefined,
- .allocator = allocator,
- .passthrough_positionals = undefined,
- };
-
- var stream = clap.StreamingClap(usize, @typeInfo(@TypeOf(iter)).Pointer.child){
- .params = converted_params,
- .iter = iter,
- };
-
- while (try stream.next()) |arg| {
- const param = arg.param;
- if (param.names.long == null and param.names.short == null) {
- try pos.append(arg.value.?);
- if (opt.stop_after_positional_at > 0 and pos.items.len >= opt.stop_after_positional_at) {
- const bun = @import("bun");
- if (comptime bun.Environment.isWindows) @compileError(
- "TODO: implement stop_after_positional_at on windows",
- );
-
- var remaining_ = std.os.argv[@min(std.os.argv.len, stream.iter.args.inner.index)..];
- const first: []const u8 = if (remaining_.len > 0) bun.span(remaining_[0]) else "";
- if (first.len > 0 and std.mem.eql(u8, first, "--")) {
- remaining_ = remaining_[1..];
- }
-
- try passthrough_positionals.ensureTotalCapacityPrecise(remaining_.len);
- for (remaining_) |arg_| {
- // use bun.span due to the optimization for long strings
- passthrough_positionals.appendAssumeCapacity(bun.span(arg_));
- }
- break;
- }
- } else if (param.takes_value == .one or param.takes_value == .one_optional) {
- debug.assert(res.single_options.len != 0);
- if (res.single_options.len != 0)
- res.single_options[param.id] = arg.value orelse "";
- } else if (param.takes_value == .many) {
- debug.assert(multis.len != 0);
- if (multis.len != 0)
- try multis[param.id].append(arg.value.?);
- } else {
- debug.assert(res.flags.len != 0);
- if (res.flags.len != 0)
- res.flags[param.id] = true;
- }
- }
-
- for (&multis, 0..) |*multi, i|
- res.multi_options[i] = try multi.toOwnedSlice();
- res.pos = try pos.toOwnedSlice();
- res.passthrough_positionals = try passthrough_positionals.toOwnedSlice();
- return res;
- }
-
- pub fn deinit(parser: @This()) void {
- for (parser.multi_options) |o|
- parser.allocator.free(o);
- parser.allocator.free(parser.pos);
- }
-
- pub fn flag(parser: @This(), comptime name: []const u8) bool {
- const param = comptime findParam(name);
- if (param.takes_value != .none and param.takes_value != .one_optional)
- @compileError(name ++ " is an option and not a flag.");
-
- return parser.flags[param.id];
- }
-
- pub fn option(parser: @This(), comptime name: []const u8) ?[]const u8 {
- const param = comptime findParam(name);
- if (param.takes_value == .none)
- @compileError(name ++ " is a flag and not an option.");
- if (param.takes_value == .many)
- @compileError(name ++ " takes many options, not one.");
- return parser.single_options[param.id];
- }
-
- pub fn options(parser: @This(), comptime name: []const u8) []const []const u8 {
- const param = comptime findParam(name);
- if (param.takes_value == .none)
- @compileError(name ++ " is a flag and not an option.");
- if (param.takes_value == .one or param.takes_value == .one_optional)
- @compileError(name ++ " takes one option, not multiple.");
-
- return parser.multi_options[param.id];
- }
-
- pub fn positionals(parser: @This()) []const []const u8 {
- return parser.pos;
- }
-
- pub fn remaining(parser: @This()) []const []const u8 {
- return parser.passthrough_positionals;
- }
-
- pub fn hasFlag(comptime name: []const u8) bool {
- comptime {
- for (converted_params) |param| {
- if (param.names.short) |s| {
- if (mem.eql(u8, name, "-" ++ [_]u8{s}))
- return true;
- }
- if (param.names.long) |l| {
- if (mem.eql(u8, name, "--" ++ l))
- return true;
- }
- }
-
- return false;
- }
- }
-
- fn findParam(comptime name: []const u8) clap.Param(usize) {
- comptime {
- for (converted_params) |param| {
- if (param.names.short) |s| {
- if (mem.eql(u8, name, "-" ++ [_]u8{s}))
- return param;
- }
- if (param.names.long) |l| {
- if (mem.eql(u8, name, "--" ++ l))
- return param;
- }
- }
-
- @compileError(name ++ " is not a parameter.");
- }
- }
- };
-}
diff --git a/src/deps/zig-clap/clap/streaming.zig b/src/deps/zig-clap/clap/streaming.zig
deleted file mode 100644
index e3948e33b..000000000
--- a/src/deps/zig-clap/clap/streaming.zig
+++ /dev/null
@@ -1,430 +0,0 @@
-const builtin = @import("builtin");
-const clap = @import("../clap.zig");
-const std = @import("std");
-
-const args = clap.args;
-const debug = std.debug;
-const heap = std.heap;
-const io = std.io;
-const mem = std.mem;
-const os = std.os;
-const testing = std.testing;
-
-/// The result returned from StreamingClap.next
-pub fn Arg(comptime Id: type) type {
- return struct {
- const Self = @This();
-
- param: *const clap.Param(Id),
- value: ?[]const u8 = null,
- };
-}
-
-/// A command line argument parser which, given an ArgIterator, will parse arguments according
-/// to the params. StreamingClap parses in an iterating manner, so you have to use a loop together with
-/// StreamingClap.next to parse all the arguments of your program.
-pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
- return struct {
- const State = union(enum) {
- normal,
- chaining: Chaining,
- rest_are_positional,
-
- const Chaining = struct {
- arg: []const u8,
- index: usize,
- };
- };
-
- params: []const clap.Param(Id),
- iter: *ArgIterator,
- state: State = .normal,
- positional: ?*const clap.Param(Id) = null,
- diagnostic: ?*clap.Diagnostic = null,
-
- /// Get the next Arg that matches a Param.
- pub fn next(parser: *@This()) !?Arg(Id) {
- switch (parser.state) {
- .normal => return try parser.normal(),
- .chaining => |state| return try parser.chainging(state),
- .rest_are_positional => {
- const param = parser.positionalParam() orelse unreachable;
- const value = parser.iter.next() orelse return null;
- return Arg(Id){ .param = param, .value = value };
- },
- }
- }
-
- fn normal(parser: *@This()) !?Arg(Id) {
- const ArgType = Arg(Id);
- const arg_info = (try parser.parseNextArg()) orelse return null;
- const arg = arg_info.arg;
-
- switch (arg_info.kind) {
- .long => {
- const eql_index = mem.indexOfScalar(u8, arg, '=');
- const name = if (eql_index) |i| arg[0..i] else arg;
- const maybe_value = if (eql_index) |i| arg[i + 1 ..] else null;
-
- for (parser.params) |*param| {
- const match = param.names.long orelse continue;
-
- if (!mem.eql(u8, name, match))
- continue;
- if (param.takes_value == .none) {
- if (maybe_value != null)
- return parser.err(arg, .{ .long = name }, error.DoesntTakeValue);
-
- return ArgType{ .param = param };
- }
-
- const value = blk: {
- if (maybe_value) |v|
- break :blk v;
-
- break :blk parser.iter.next() orelse brk2: {
- if (param.takes_value != .one_optional)
- return parser.err(arg, .{ .long = name }, error.MissingValue);
-
- break :brk2 "";
- };
- };
-
- return ArgType{ .param = param, .value = value };
- }
-
- return null;
- },
- .short => return try parser.chainging(.{
- .arg = arg,
- .index = 0,
- }),
- .positional => if (parser.positionalParam()) |param| {
- // If we find a positional with the value `--` then we
- // interpret the rest of the arguments as positional
- // arguments.
- if (mem.eql(u8, arg, "--")) {
- parser.state = .rest_are_positional;
- const value = parser.iter.next() orelse return null;
- return Arg(Id){ .param = param, .value = value };
- }
-
- return Arg(Id){ .param = param, .value = arg };
- } else {
- return parser.err(arg, .{}, error.InvalidArgument);
- },
- }
- }
-
- fn chainging(parser: *@This(), state: State.Chaining) !?Arg(Id) {
- const arg = state.arg;
- const index = state.index;
- const next_index = index + 1;
-
- for (parser.params) |*param| {
- const short = param.names.short orelse continue;
- if (short != arg[index])
- continue;
-
- // Before we return, we have to set the new state of the clap
- defer {
- if (arg.len <= next_index or param.takes_value != .none) {
- parser.state = .normal;
- } else {
- parser.state = .{
- .chaining = .{
- .arg = arg,
- .index = next_index,
- },
- };
- }
- }
-
- const next_is_eql = if (next_index < arg.len) arg[next_index] == '=' else false;
- if (param.takes_value == .none or param.takes_value == .one_optional) {
- if (next_is_eql and param.takes_value == .none)
- return parser.err(arg, .{ .short = short }, error.DoesntTakeValue);
- return Arg(Id){ .param = param };
- }
-
- if (arg.len <= next_index) {
- const value = parser.iter.next() orelse
- return parser.err(arg, .{ .short = short }, error.MissingValue);
-
- return Arg(Id){ .param = param, .value = value };
- }
-
- if (next_is_eql)
- return Arg(Id){ .param = param, .value = arg[next_index + 1 ..] };
-
- return Arg(Id){ .param = param, .value = arg[next_index..] };
- }
-
- return parser.err(arg, .{ .short = arg[index] }, error.InvalidArgument);
- }
-
- fn positionalParam(parser: *@This()) ?*const clap.Param(Id) {
- if (parser.positional) |p|
- return p;
-
- for (parser.params) |*param| {
- if (param.names.long) |_|
- continue;
- if (param.names.short) |_|
- continue;
-
- parser.positional = param;
- return param;
- }
-
- return null;
- }
-
- const ArgInfo = struct {
- arg: []const u8,
- kind: enum {
- long,
- short,
- positional,
- },
- };
-
- fn parseNextArg(parser: *@This()) !?ArgInfo {
- const full_arg = parser.iter.next() orelse return null;
- if (mem.eql(u8, full_arg, "--") or mem.eql(u8, full_arg, "-"))
- return ArgInfo{ .arg = full_arg, .kind = .positional };
- if (mem.startsWith(u8, full_arg, "--"))
- return ArgInfo{ .arg = full_arg[2..], .kind = .long };
- if (mem.startsWith(u8, full_arg, "-"))
- return ArgInfo{ .arg = full_arg[1..], .kind = .short };
-
- return ArgInfo{ .arg = full_arg, .kind = .positional };
- }
-
- fn err(parser: @This(), arg: []const u8, names: clap.Names, _err: anytype) @TypeOf(_err) {
- if (parser.diagnostic) |d|
- d.* = .{ .arg = arg, .name = names };
- return _err;
- }
- };
-}
-
-fn testNoErr(params: []const clap.Param(u8), args_strings: []const []const u8, results: []const Arg(u8)) void {
- var iter = args.SliceIterator{ .args = args_strings };
- var c = StreamingClap(u8, args.SliceIterator){
- .params = params,
- .iter = &iter,
- };
-
- for (results) |res| {
- const arg = (c.next() catch unreachable) orelse unreachable;
- testing.expectEqual(res.param, arg.param);
- const expected_value = res.value orelse {
- testing.expectEqual(@as(@TypeOf(arg.value), null), arg.value);
- continue;
- };
- const actual_value = arg.value orelse unreachable;
- testing.expectEqualSlices(u8, expected_value, actual_value);
- }
-
- if (c.next() catch unreachable) |_|
- unreachable;
-}
-
-fn testErr(params: []const clap.Param(u8), args_strings: []const []const u8, expected: []const u8) void {
- var diag = clap.Diagnostic{};
- var iter = args.SliceIterator{ .args = args_strings };
- var c = StreamingClap(u8, args.SliceIterator){
- .params = params,
- .iter = &iter,
- .diagnostic = &diag,
- };
- while (c.next() catch |err| {
- var buf: [1024]u8 = undefined;
- var fbs = io.fixedBufferStream(&buf);
- diag.report(fbs.writer(), err) catch unreachable;
- testing.expectEqualStrings(expected, fbs.getWritten());
- return;
- }) |_| {}
-
- testing.expect(false);
-}
-
-test "short params" {
- const params = [_]clap.Param(u8){
- .{ .id = 0, .names = .{ .short = 'a' } },
- .{ .id = 1, .names = .{ .short = 'b' } },
- .{
- .id = 2,
- .names = .{ .short = 'c' },
- .takes_value = .one,
- },
- .{
- .id = 3,
- .names = .{ .short = 'd' },
- .takes_value = .many,
- },
- };
-
- const a = &params[0];
- const b = &params[1];
- const c = &params[2];
- const d = &params[3];
-
- testNoErr(
- &params,
- &[_][]const u8{
- "-a", "-b", "-ab", "-ba",
- "-c", "0", "-c=0", "-ac",
- "0", "-ac=0", "-d=0",
- },
- &[_]Arg(u8){
- .{ .param = a },
- .{ .param = b },
- .{ .param = a },
- .{ .param = b },
- .{ .param = b },
- .{ .param = a },
- .{ .param = c, .value = "0" },
- .{ .param = c, .value = "0" },
- .{ .param = a },
- .{ .param = c, .value = "0" },
- .{ .param = a },
- .{ .param = c, .value = "0" },
- .{ .param = d, .value = "0" },
- },
- );
-}
-
-test "long params" {
- const params = [_]clap.Param(u8){
- .{ .id = 0, .names = .{ .long = "aa" } },
- .{ .id = 1, .names = .{ .long = "bb" } },
- .{
- .id = 2,
- .names = .{ .long = "cc" },
- .takes_value = .one,
- },
- .{
- .id = 3,
- .names = .{ .long = "dd" },
- .takes_value = .many,
- },
- };
-
- const aa = &params[0];
- const bb = &params[1];
- const cc = &params[2];
- const dd = &params[3];
-
- testNoErr(
- &params,
- &[_][]const u8{
- "--aa", "--bb",
- "--cc", "0",
- "--cc=0", "--dd=0",
- },
- &[_]Arg(u8){
- .{ .param = aa },
- .{ .param = bb },
- .{ .param = cc, .value = "0" },
- .{ .param = cc, .value = "0" },
- .{ .param = dd, .value = "0" },
- },
- );
-}
-
-test "positional params" {
- const params = [_]clap.Param(u8){.{
- .id = 0,
- .takes_value = .one,
- }};
-
- testNoErr(
- &params,
- &[_][]const u8{ "aa", "bb" },
- &[_]Arg(u8){
- .{ .param = &params[0], .value = "aa" },
- .{ .param = &params[0], .value = "bb" },
- },
- );
-}
-
-test "all params" {
- const params = [_]clap.Param(u8){
- .{
- .id = 0,
- .names = .{ .short = 'a', .long = "aa" },
- },
- .{
- .id = 1,
- .names = .{ .short = 'b', .long = "bb" },
- },
- .{
- .id = 2,
- .names = .{ .short = 'c', .long = "cc" },
- .takes_value = .one,
- },
- .{ .id = 3, .takes_value = .one },
- };
-
- const aa = &params[0];
- const bb = &params[1];
- const cc = &params[2];
- const positional = &params[3];
-
- testNoErr(
- &params,
- &[_][]const u8{
- "-a", "-b", "-ab", "-ba",
- "-c", "0", "-c=0", "-ac",
- "0", "-ac=0", "--aa", "--bb",
- "--cc", "0", "--cc=0", "something",
- "-", "--", "--cc=0", "-a",
- },
- &[_]Arg(u8){
- .{ .param = aa },
- .{ .param = bb },
- .{ .param = aa },
- .{ .param = bb },
- .{ .param = bb },
- .{ .param = aa },
- .{ .param = cc, .value = "0" },
- .{ .param = cc, .value = "0" },
- .{ .param = aa },
- .{ .param = cc, .value = "0" },
- .{ .param = aa },
- .{ .param = cc, .value = "0" },
- .{ .param = aa },
- .{ .param = bb },
- .{ .param = cc, .value = "0" },
- .{ .param = cc, .value = "0" },
- .{ .param = positional, .value = "something" },
- .{ .param = positional, .value = "-" },
- .{ .param = positional, .value = "--cc=0" },
- .{ .param = positional, .value = "-a" },
- },
- );
-}
-
-test "errors" {
- const params = [_]clap.Param(u8){
- .{
- .id = 0,
- .names = .{ .short = 'a', .long = "aa" },
- },
- .{
- .id = 1,
- .names = .{ .short = 'c', .long = "cc" },
- .takes_value = .one,
- },
- };
- testErr(&params, &[_][]const u8{"q"}, "Invalid argument 'q'\n");
- testErr(&params, &[_][]const u8{"-q"}, "Invalid argument '-q'\n");
- testErr(&params, &[_][]const u8{"--q"}, "Invalid argument '--q'\n");
- testErr(&params, &[_][]const u8{"--q=1"}, "Invalid argument '--q'\n");
- testErr(&params, &[_][]const u8{"-a=1"}, "The argument '-a' does not take a value\n");
- testErr(&params, &[_][]const u8{"--aa=1"}, "The argument '--aa' does not take a value\n");
- testErr(&params, &[_][]const u8{"-c"}, "The argument '-c' requires a value but none was supplied\n");
- testErr(&params, &[_][]const u8{"--cc"}, "The argument '--cc' requires a value but none was supplied\n");
-}
diff --git a/src/deps/zig-clap/gyro.zzz b/src/deps/zig-clap/gyro.zzz
deleted file mode 100644
index 3853db049..000000000
--- a/src/deps/zig-clap/gyro.zzz
+++ /dev/null
@@ -1,14 +0,0 @@
-pkgs:
- clap:
- version: 0.3.0
- license: Unlicense
- description: Simple command line argument parsing library
- source_url: "https://github.com/Hejsil/zig-clap"
- root: clap.zig
- files:
- README.md
- LICENSE
- build.zig
- clap/*.zig
- example/*.zig
-
diff --git a/src/deps/zig-clap/zig.mod b/src/deps/zig-clap/zig.mod
deleted file mode 100644
index 00c1a690d..000000000
--- a/src/deps/zig-clap/zig.mod
+++ /dev/null
@@ -1,5 +0,0 @@
-id: aoe2l16htluewam6bfwvv0khsbbno8g8jd7suonifg74u7kd
-name: clap
-main: clap.zig
-license: Unlicense
-dependencies:
diff --git a/src/install/install.zig b/src/install/install.zig
index 0c280ccaa..5399a6fd3 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -5271,56 +5271,58 @@ pub const PackageManager = struct {
else
"Possible values: \"hardlink\" (default), \"symlink\", \"copyfile\"";
- pub const install_params_ = [_]ParamType{
- clap.parseParam("-c, --config <STR>? Load config (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,
- clap.parseParam("--dry-run Don't install anything") catch unreachable,
- clap.parseParam("--lockfile <PATH> Store & load a lockfile at a specific filepath") catch unreachable,
- clap.parseParam("-f, --force Always request the latest versions from the registry & reinstall all dependencies") catch unreachable,
- clap.parseParam("--cache-dir <PATH> Store & load cached data from a specific directory path") catch unreachable,
- clap.parseParam("--no-cache Ignore manifest cache entirely") catch unreachable,
- clap.parseParam("--silent Don't log anything") catch unreachable,
- clap.parseParam("--verbose Excessively verbose logging") catch unreachable,
- clap.parseParam("--no-progress Disable the progress bar") catch unreachable,
- clap.parseParam("--no-summary Don't print a summary") catch unreachable,
- clap.parseParam("--no-verify Skip verifying integrity of newly downloaded packages") catch unreachable,
- clap.parseParam("--ignore-scripts Skip lifecycle scripts in the project's package.json (dependency scripts are never run)") catch unreachable,
- clap.parseParam("-g, --global Install globally") catch unreachable,
- 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,
+ pub const install_params_ = clap.parseParamsComptime(
+ \\-c, --config <STR>? Load config (bunfig.toml)
+ \\-y, --yarn Write a yarn.lock file (yarn v1)
+ \\-p, --production Don't install devDependencies
+ \\--no-save Don't save a lockfile
+ \\--dry-run Don't install anything
+ \\--lockfile <PATH> Store & load a lockfile at a specific filepath
+ \\-f, --force Always request the latest versions from the registry & reinstall all dependencies
+ \\--cache-dir <PATH> Store & load cached data from a specific directory path
+ \\--no-cache Ignore manifest cache entirely
+ \\--silent Don't log anything
+ \\--verbose Excessively verbose logging
+ \\--no-progress Disable the progress bar
+ \\--no-summary Don't print a summary
+ \\--no-verify Skip verifying integrity of newly downloaded packages
+ \\--ignore-scripts Skip lifecycle scripts in the project's package.json (dependency scripts are never run)
+ \\-g, --global Install globally
+ \\--cwd <STR> Set a specific cwd
+ \\--backend <STR> Platform-specific optimizations for installing dependencies.
+ \\
+ ++ platform_specific_backend_label ++
+ \\
+ \\--link-native-bins <STR>... Link "bin" from a matching platform-specific "optionalDependencies" instead. Default: esbuild, turbo
+ \\--help Print this help menu
+ );
+ // 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,
- };
- pub const install_params = install_params_ ++ [_]ParamType{
- clap.parseParam("<POS> ... ") catch unreachable,
- };
+ pub const install_params = install_params_ ++ clap.parseParamsComptime(
+ \\<STR> ...
+ );
- pub const add_params = install_params_ ++ [_]ParamType{
- clap.parseParam("-d, --development Add dependency to \"devDependencies\"") catch unreachable,
- clap.parseParam("--optional Add dependency to \"optionalDependencies\"") catch unreachable,
- clap.parseParam("<POS> ... \"name\" or \"name@version\" of packages to install") catch unreachable,
- };
+ pub const add_params = install_params_ ++ clap.parseParamsComptime(
+ \\-d, --development Add dependency to "devDependencies"
+ \\--optional Add dependency to "optionalDependencies"
+ \\<STR> ... "name" or "name@version" of packages to install
+ );
- pub const remove_params = install_params_ ++ [_]ParamType{
- clap.parseParam("<POS> ... \"name\" of packages to remove from package.json") catch unreachable,
- };
+ pub const remove_params = install_params_ ++ clap.parseParamsComptime(
+ \\<STR> ... "name" of packages to remove from package.json
+ );
- pub const link_params = install_params_ ++ [_]ParamType{
- clap.parseParam("--save Save to package.json") catch unreachable,
- clap.parseParam("<POS> ... \"name\" install package as a link") catch unreachable,
- };
+ pub const link_params = install_params_ ++ clap.parseParamsComptime(
+ \\--save Save to package.json
+ \\<STR> ... "name" install package as a link
+ );
- pub const unlink_params = install_params_ ++ [_]ParamType{
- clap.parseParam("--save Save to package.json") catch unreachable,
- clap.parseParam("<POS> ... \"name\" uninstall package as a link") catch unreachable,
- };
+ pub const unlink_params = install_params_ ++ clap.parseParamsComptime(
+ \\--save Save to package.json
+ \\<STR> ... "name" uninstall package as a link
+ );
pub const CommandLineArguments = struct {
registry: string = "",
@@ -5377,62 +5379,63 @@ pub const PackageManager = struct {
) !CommandLineArguments {
var diag = clap.Diagnostic{};
- var args = clap.parse(clap.Help, params, .{
+ var res = clap.parse(clap.Help, params, BunArguments.parser, .{
.diagnostic = &diag,
.allocator = allocator,
}) catch |err| {
- clap.help(Output.errorWriter(), params) catch {};
+ clap.help(Output.errorWriter(), clap.Help, params, .{}) catch {};
Output.errorWriter().writeAll("\n") catch {};
diag.report(Output.errorWriter(), err) catch {};
return err;
};
- if (args.flag("--help")) {
+ if (res.args.help) {
Output.prettyln("\n<b><magenta>bun<r> (package manager) flags:<r>\n\n", .{});
Output.flush();
- clap.help(Output.writer(), params) catch {};
+ clap.help(Output.writer(), clap.Help, params, .{}) catch {};
Global.exit(0);
}
var cli = CommandLineArguments{};
- cli.yarn = args.flag("--yarn");
- cli.production = args.flag("--production");
- cli.no_save = args.flag("--no-save");
- cli.no_progress = args.flag("--no-progress");
- cli.dry_run = args.flag("--dry-run");
- cli.global = args.flag("--global");
- cli.force = args.flag("--force");
- cli.no_verify = args.flag("--no-verify");
- // cli.no_dedupe = args.flag("--no-dedupe");
- cli.no_cache = args.flag("--no-cache");
- cli.silent = args.flag("--silent");
- cli.verbose = args.flag("--verbose");
- cli.ignore_scripts = args.flag("--ignore-scripts");
- cli.no_summary = args.flag("--no-summary");
- if (comptime @TypeOf(args).hasFlag("--save")) {
+ cli.yarn = res.args.yarn;
+ cli.production = res.args.production;
+ cli.no_save = res.args.@"no-save";
+ cli.no_progress = res.args.@"no-progress";
+ cli.dry_run = res.args.@"dry-run";
+ cli.global = res.args.global;
+ cli.force = res.args.force;
+ cli.no_verify = res.args.@"no-verify";
+ // cli.no_dedupe = res.args.no_dedupe;
+ cli.no_cache = res.args.@"no-cache";
+ cli.silent = res.args.silent;
+ cli.verbose = res.args.verbose;
+ cli.ignore_scripts = res.args.@"ignore-scripts";
+ cli.no_summary = res.args.@"no-summary";
+
+ if (comptime @hasDecl(@TypeOf(res.args), "save")) {
cli.no_save = true;
- if (args.flag("--save")) {
+ if (res.args.save) {
cli.no_save = false;
}
}
- if (args.option("--config")) |opt| {
+ if (res.args.config) |opt| {
cli.config = opt;
}
try BunArguments.loadConfig(allocator, cli.config, ctx, .InstallCommand);
- cli.link_native_bins = args.options("--link-native-bins");
+ cli.link_native_bins = res.args.@"link-native-bins";
if (comptime params.len == add_params.len) {
- cli.development = args.flag("--development");
- cli.optional = args.flag("--optional");
+ cli.development = res.args.development;
+ cli.optional = res.args.optional;
}
- // for (args.options("--omit")) |omit| {
+ // for (res.args.omit) |omit| {
// if (strings.eqlComptime(omit, "dev")) {
// cli.omit.dev = true;
// } else if (strings.eqlComptime(omit, "optional")) {
@@ -5445,11 +5448,11 @@ pub const PackageManager = struct {
// }
// }
- if (args.option("--lockfile")) |lockfile| {
+ if (res.args.lockfile) |lockfile| {
cli.lockfile = lockfile;
}
- if (args.option("--cwd")) |cwd_| {
+ if (res.args.cwd) |cwd_| {
var buf: [bun.MAX_PATH_BYTES]u8 = undefined;
var buf2: [bun.MAX_PATH_BYTES]u8 = undefined;
var final_path: [:0]u8 = undefined;
@@ -5468,7 +5471,7 @@ pub const PackageManager = struct {
}
const specified_backend: ?PackageInstall.Method = brk: {
- if (args.option("--backend")) |backend_| {
+ if (res.args.backend) |backend_| {
break :brk PackageInstall.Method.map.get(backend_);
}
break :brk null;
@@ -5480,7 +5483,7 @@ pub const PackageManager = struct {
}
}
- cli.positionals = args.positionals();
+ cli.positionals = res.positionals;
return cli;
}