aboutsummaryrefslogtreecommitdiff
path: root/src/cli.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli.zig')
-rw-r--r--src/cli.zig274
1 files changed, 185 insertions, 89 deletions
diff --git a/src/cli.zig b/src/cli.zig
index 8974704db..a223324a8 100644
--- a/src/cli.zig
+++ b/src/cli.zig
@@ -52,8 +52,11 @@ const ShellCompletions = @import("./cli/shell_completions.zig");
const TestCommand = @import("./cli/test_command.zig").TestCommand;
const UpgradeCommand = @import("./cli/upgrade_command.zig").UpgradeCommand;
+const MacroMap = @import("./resolver/package_json.zig").MacroMap;
+
const Reporter = @import("./report.zig");
var start_time: i128 = undefined;
+const Bunfig = @import("./bunfig.zig").Bunfig;
pub const Cli = struct {
var wait_group: sync.WaitGroup = undefined;
@@ -160,6 +163,7 @@ pub const Arguments = struct {
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.json") 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)") catch unreachable,
clap.parseParam("--extension-order <STR>... defaults to: .tsx,.ts,.jsx,.js,.json ") catch unreachable,
@@ -181,7 +185,7 @@ pub const Arguments = struct {
clap.parseParam("-i, --inject <STR>... Inject module at the top of every file") 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("-p, --port <STR> Port to serve bun's dev server on. Default: \"3000\"") catch unreachable,
clap.parseParam("--silent Don't repeat the command for bun run") catch unreachable,
clap.parseParam("<POS>... ") catch unreachable,
};
@@ -225,40 +229,112 @@ pub const Arguments = struct {
cwd = try std.process.getCwdAlloc(allocator);
}
+ var opts: Api.TransformOptions = ctx.args;
+ opts.absolute_working_dir = cwd;
+
+ if (comptime Command.Tag.loads_config.get(cmd)) {
+ if (args.option("--config")) |config_path__| {
+ var config_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ var config_path_ = config_path__;
+ if (config_path_.len == 0) {
+ config_path_ = "bunfig.json";
+ }
+ var config_path: [:0]u8 = undefined;
+ if (config_path_[0] == '/') {
+ @memcpy(&config_buf, config_path_.ptr, config_path_.len);
+ config_buf[config_path_.len] = 0;
+ config_path = config_buf[0..config_path_.len :0];
+ } else {
+ var parts = [_]string{ cwd, config_path_ };
+ config_path_ = resolve_path.joinAbsStringBuf(
+ cwd,
+ &config_buf,
+ &parts,
+ .auto,
+ );
+ config_buf[config_path_.len] = 0;
+ config_path = config_buf[0..config_path_.len :0];
+ }
+
+ var config_file = std.fs.openFileAbsoluteZ(config_path, .{ .read = true }) catch |err| {
+ Output.prettyErrorln("<r><red>error<r>: {s} opening config \"{s}\"", .{
+ @errorName(err),
+ std.mem.span(config_path),
+ });
+ Output.flush();
+ std.os.exit(1);
+ };
+ var contents = config_file.readToEndAlloc(allocator, std.math.maxInt(usize)) catch |err| {
+ Output.prettyErrorln("<r><red>error<r>: {s} reading config \"{s}\"", .{
+ @errorName(err),
+ std.mem.span(config_path),
+ });
+ Output.flush();
+ std.os.exit(1);
+ };
+
+ js_ast.Stmt.Data.Store.create(allocator);
+ js_ast.Expr.Data.Store.create(allocator);
+ defer {
+ js_ast.Stmt.Data.Store.reset();
+ js_ast.Expr.Data.Store.reset();
+ }
+ var original_level = ctx.log.level;
+ defer {
+ ctx.log.level = original_level;
+ }
+ ctx.log.level = logger.Log.Level.warn;
+ try Bunfig.parse(allocator, logger.Source.initPathString(std.mem.span(config_path), contents), ctx, cmd);
+ opts = ctx.args;
+ }
+ }
+
var defines_tuple = try DefineColonList.resolve(allocator, args.options("--define"));
+
+ if (defines_tuple.keys.len > 0) {
+ opts.define = .{
+ .keys = defines_tuple.keys,
+ .values = defines_tuple.values,
+ };
+ }
+
var loader_tuple = try LoaderColonList.resolve(allocator, args.options("--loader"));
- var externals = std.mem.zeroes([][]u8);
+
+ if (loader_tuple.keys.len > 0) {
+ opts.loaders = .{
+ .extensions = loader_tuple.keys,
+ .loaders = loader_tuple.values,
+ };
+ }
+
if (args.options("--external").len > 0) {
- externals = try allocator.alloc([]u8, args.options("--external").len);
+ var externals = try allocator.alloc([]u8, args.options("--external").len);
for (args.options("--external")) |external, i| {
externals[i] = constStrToU8(external);
}
+ opts.external = externals;
}
- var opts = Api.TransformOptions{
- .tsconfig_override = if (args.option("--tsconfig-override")) |ts| (Arguments.readFile(allocator, cwd, ts) catch |err| fileReadError(err, Output.errorStream(), ts, "tsconfig.json")) else null,
- .external = externals,
- .absolute_working_dir = cwd,
- .origin = args.option("--origin"),
- .define = .{
- .keys = defines_tuple.keys,
- .values = defines_tuple.values,
- },
- .loaders = .{
- .extensions = loader_tuple.keys,
- .loaders = loader_tuple.values,
- },
- .port = if (args.option("--port")) |port_str| std.fmt.parseInt(u16, port_str, 10) catch return error.InvalidPort else null,
-
- .serve = cmd == .DevCommand or (FeatureFlags.dev_only and cmd == .AutoCommand),
- .main_fields = args.options("--main-fields"),
- .generate_node_module_bundle = cmd == .BunCommand,
- .inject = args.options("--inject"),
- .extension_order = args.options("--extension-order"),
- .entry_points = undefined,
- .no_summary = args.flag("--no-summary"),
- .disable_hmr = args.flag("--disable-hmr"),
- };
+ opts.tsconfig_override = if (args.option("--tsconfig-override")) |ts|
+ (Arguments.readFile(allocator, cwd, ts) catch |err| fileReadError(err, Output.errorStream(), ts, "tsconfig.json"))
+ else
+ null;
+
+ if (args.option("--origin")) |origin| {
+ opts.origin = origin;
+ }
+
+ if (args.option("--port")) |port_str| {
+ opts.port = std.fmt.parseInt(u16, port_str, 10) catch return error.InvalidPort;
+ }
+ opts.serve = cmd == .DevCommand or (FeatureFlags.dev_only and cmd == .AutoCommand);
+ opts.main_fields = args.options("--main-fields");
+ opts.generate_node_module_bundle = cmd == .BunCommand;
+ opts.inject = args.options("--inject");
+ opts.extension_order = args.options("--extension-order");
+
+ opts.no_summary = args.flag("--no-summary");
+ opts.disable_hmr = args.flag("--disable-hmr");
ctx.positionals = args.positionals();
ctx.debug.silent = args.flag("--silent");
@@ -277,70 +353,70 @@ pub const Arguments = struct {
}
ctx.debug.dump_environment_variables = args.flag("--dump-environment-variables");
- ctx.debug.fallback_only = args.flag("--disable-bun.js");
+ ctx.debug.fallback_only = ctx.debug.fallback_only or args.flag("--disable-bun.js");
ctx.debug.dump_limits = args.flag("--dump-limits");
// var output_dir = args.option("--outdir");
var output_dir: ?string = null;
+ const production = false;
+
+ if (opts.entry_points.len == 0) {
+ var entry_points = args.positionals();
+
+ switch (comptime cmd) {
+ .BunCommand => {
+ if (entry_points.len > 0 and (strings.eqlComptime(
+ entry_points[0],
+ "bun",
+ ))) {
+ entry_points = entry_points[1..];
+ }
+ },
+ .DevCommand => {
+ if (entry_points.len > 0 and (strings.eqlComptime(
+ entry_points[0],
+ "dev",
+ ) or strings.eqlComptime(
+ entry_points[0],
+ "d",
+ ))) {
+ entry_points = entry_points[1..];
+ }
+ },
+ .BuildCommand => {
+ if (entry_points.len > 0 and (strings.eqlComptime(
+ entry_points[0],
+ "build",
+ ) or strings.eqlComptime(
+ entry_points[0],
+ "b",
+ ))) {
+ entry_points = entry_points[1..];
+ }
- var entry_points = args.positionals();
-
- switch (comptime cmd) {
- .BunCommand => {
- if (entry_points.len > 0 and (strings.eqlComptime(
- entry_points[0],
- "bun",
- ))) {
- entry_points = entry_points[1..];
- }
- },
- .DevCommand => {
- if (entry_points.len > 0 and (strings.eqlComptime(
- entry_points[0],
- "dev",
- ) or strings.eqlComptime(
- entry_points[0],
- "d",
- ))) {
- entry_points = entry_points[1..];
- }
- },
- .BuildCommand => {
- if (entry_points.len > 0 and (strings.eqlComptime(
- entry_points[0],
- "build",
- ) or strings.eqlComptime(
- entry_points[0],
- "b",
- ))) {
- entry_points = entry_points[1..];
- }
- },
- .RunCommand => {
- if (entry_points.len > 0 and (strings.eqlComptime(
- entry_points[0],
- "run",
- ) or strings.eqlComptime(
- entry_points[0],
- "r",
- ))) {
- entry_points = entry_points[1..];
- }
- },
- else => {},
- }
-
- const production = false; //args.flag("--production");
- if (comptime cmd == .BuildCommand) {
- var write = entry_points.len > 1 or output_dir != null;
- if (write and output_dir == null) {
- var _paths = [_]string{ cwd, "out" };
- output_dir = try std.fs.path.resolve(allocator, &_paths);
+ var write = entry_points.len > 1 or output_dir != null;
+ if (write and output_dir == null) {
+ var _paths = [_]string{ cwd, "out" };
+ output_dir = try std.fs.path.resolve(allocator, &_paths);
+ }
+ opts.write = write;
+ },
+ .RunCommand => {
+ if (entry_points.len > 0 and (strings.eqlComptime(
+ entry_points[0],
+ "run",
+ ) or strings.eqlComptime(
+ entry_points[0],
+ "r",
+ ))) {
+ entry_points = entry_points[1..];
+ }
+ },
+ else => {},
}
- opts.write = write;
- }
- opts.entry_points = entry_points;
+ opts.entry_points = entry_points;
+ }
var jsx_factory = args.option("--jsx-factory");
var jsx_fragment = args.option("--jsx-fragment");
@@ -353,13 +429,13 @@ pub const Arguments = struct {
};
if (comptime Command.Tag.cares_about_bun_file.get(cmd)) {
- opts.node_modules_bundle_path = args.option("--bunfile") orelse brk: {
+ opts.node_modules_bundle_path = args.option("--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 brk: {
+ opts.node_modules_bundle_path_server = args.option("--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;
@@ -412,10 +488,11 @@ pub const Arguments = struct {
const PlatformMatcher = strings.ExactSizeMatcher(8);
if (args.option("--platform")) |_platform| {
- opts.platform = switch (PlatformMatcher.match(_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"), PlatformMatcher.case("bun") => Api.Platform.bun,
+ PlatformMatcher.case("macro") => if (cmd == .BuildCommand) Api.Platform.bun_macro else Api.Platform.bun,
+ PlatformMatcher.case("bun") => Api.Platform.bun,
else => invalidPlatform(&diag, _platform),
};
}
@@ -447,11 +524,21 @@ pub const Arguments = struct {
}
if (cmd == .BunCommand or !FeatureFlags.dev_only) {
- if (entry_points.len == 0 and opts.framework == null and opts.node_modules_bundle_path == null) {
+ if (opts.entry_points.len == 0 and opts.framework == null and opts.node_modules_bundle_path == null) {
return error.MissingEntryPoint;
}
}
+ if (opts.log_level) |log_level| {
+ logger.Log.default_log_level = switch (log_level) {
+ .debug => logger.Log.Level.debug,
+ .err => logger.Log.Level.err,
+ .warn => logger.Log.Level.warn,
+ else => logger.Log.Level.err,
+ };
+ ctx.log.level = logger.Log.default_log_level;
+ }
+
opts.output_dir = output_dir;
return opts;
}
@@ -587,6 +674,10 @@ pub const Command = struct {
dump_limits: bool = false,
fallback_only: bool = false,
silent: bool = false,
+
+ // technical debt
+ macros: ?MacroMap = null,
+ package_bundle_map: std.StringArrayHashMapUnmanaged(options.BundlePackage) = std.StringArrayHashMapUnmanaged(options.BundlePackage){},
};
pub const Context = struct {
@@ -1029,8 +1120,13 @@ pub const Command = struct {
.DevCommand = true,
.RunCommand = true,
.TestCommand = true,
+ .InstallCommand = true,
+ .AddCommand = true,
+ .RemoveCommand = true,
});
+ pub const loads_config = cares_about_bun_file;
+
pub const uses_global_options: std.EnumArray(Tag, bool) = std.EnumArray(Tag, bool).initDefault(true, .{
.CreateCommand = false,
.InstallCommand = false,