aboutsummaryrefslogtreecommitdiff
path: root/src/cli.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli.zig')
-rw-r--r--src/cli.zig178
1 files changed, 124 insertions, 54 deletions
diff --git a/src/cli.zig b/src/cli.zig
index b17dc8396..40b59b928 100644
--- a/src/cli.zig
+++ b/src/cli.zig
@@ -36,30 +36,35 @@ const Router = @import("./router.zig");
const NodeModuleBundle = @import("./node_module_bundle.zig").NodeModuleBundle;
-const BunCommand = @import("./cli/bun_command.zig").BunCommand;
-const DevCommand = @import("./cli/dev_command.zig").DevCommand;
-const DiscordCommand = @import("./cli/discord_command.zig").DiscordCommand;
+const AddCommand = @import("./cli/add_command.zig").AddCommand;
const BuildCommand = @import("./cli/build_command.zig").BuildCommand;
+const BunCommand = @import("./cli/bun_command.zig").BunCommand;
const CreateCommand = @import("./cli/create_command.zig").CreateCommand;
const CreateListExamplesCommand = @import("./cli/create_command.zig").CreateListExamplesCommand;
-const RunCommand = @import("./cli/run_command.zig").RunCommand;
-const UpgradeCommand = @import("./cli/upgrade_command.zig").UpgradeCommand;
+const DevCommand = @import("./cli/dev_command.zig").DevCommand;
+const DiscordCommand = @import("./cli/discord_command.zig").DiscordCommand;
const InstallCommand = @import("./cli/install_command.zig").InstallCommand;
-const AddCommand = @import("./cli/add_command.zig").AddCommand;
-const RemoveCommand = @import("./cli/remove_command.zig").RemoveCommand;
-const PackageManagerCommand = @import("./cli/package_manager_command.zig").PackageManagerCommand;
const InstallCompletionsCommand = @import("./cli/install_completions_command.zig").InstallCompletionsCommand;
+const PackageManagerCommand = @import("./cli/package_manager_command.zig").PackageManagerCommand;
+const RemoveCommand = @import("./cli/remove_command.zig").RemoveCommand;
+const RunCommand = @import("./cli/run_command.zig").RunCommand;
const ShellCompletions = @import("./cli/shell_completions.zig");
+const TestCommand = @import("./cli/test_command.zig").TestCommand;
+const UpgradeCommand = @import("./cli/upgrade_command.zig").UpgradeCommand;
+const Reporter = @import("./report.zig");
var start_time: i128 = undefined;
pub const Cli = struct {
var wait_group: sync.WaitGroup = undefined;
+ var log_: logger.Log = undefined;
pub fn startTransform(_: std.mem.Allocator, _: Api.TransformOptions, _: *logger.Log) anyerror!void {}
- pub fn start(allocator: std.mem.Allocator, _: anytype, _: anytype, comptime MainPanicHandler: type) anyerror!void {
+ pub fn start(allocator: std.mem.Allocator, _: anytype, _: anytype, comptime MainPanicHandler: type) void {
start_time = std.time.nanoTimestamp();
- var log = try allocator.create(logger.Log);
- log.* = logger.Log.init(allocator);
+ log_ = logger.Log.init(allocator);
+
+ var log = &log_;
+
var panicker = MainPanicHandler.init(log);
MainPanicHandler.Singleton = &panicker;
@@ -71,7 +76,14 @@ pub const Cli = struct {
std.os.exit(1);
},
else => {
- return err;
+ // Always dump the logs
+ if (Output.enable_ansi_colors_stderr) {
+ log.printForLogLevelWithEnableAnsiColors(Output.errorWriter(), true) catch {};
+ } else {
+ log.printForLogLevelWithEnableAnsiColors(Output.errorWriter(), false) catch {};
+ }
+
+ Reporter.globalError(err);
},
}
};
@@ -84,7 +96,13 @@ const LoaderMatcher = strings.ExactSizeMatcher(4);
const ColonListType = @import("./cli/colon_list_type.zig").ColonListType;
pub const LoaderColonList = ColonListType(Api.Loader, Arguments.loader_resolver);
pub const DefineColonList = ColonListType(string, Arguments.noop_resolver);
-
+fn invalidPlatform(diag: *clap.Diagnostic, _platform: []const u8) noreturn {
+ @setCold(true);
+ diag.name.long = "--platform";
+ diag.arg = _platform;
+ diag.report(Output.errorWriter(), error.InvalidPlatform) catch {};
+ std.process.exit(1);
+}
pub const Arguments = struct {
pub fn loader_resolver(in: string) !Api.Loader {
const Matcher = strings.ExactSizeMatcher(4);
@@ -199,11 +217,16 @@ pub const Arguments = struct {
printVersionAndExit();
}
- var cwd_paths = [_]string{args.option("--cwd") orelse try std.process.getCwdAlloc(allocator)};
- var cwd = try std.fs.path.resolve(allocator, &cwd_paths);
+ var cwd: []u8 = undefined;
+ if (args.option("--cwd")) |cwd_| {
+ var cwd_paths = [_]string{cwd_};
+ cwd = try std.fs.path.resolve(allocator, &cwd_paths);
+ } else {
+ cwd = try std.process.getCwdAlloc(allocator);
+ }
var defines_tuple = try DefineColonList.resolve(allocator, args.options("--define"));
- var loader_tuple = try LoaderColonList.resolve(allocator, args.options("--define"));
+ var loader_tuple = try LoaderColonList.resolve(allocator, args.options("--loader"));
var externals = std.mem.zeroes([][]u8);
if (args.options("--external").len > 0) {
externals = try allocator.alloc([]u8, args.options("--external").len);
@@ -329,17 +352,19 @@ pub const Arguments = struct {
else => true,
};
- opts.node_modules_bundle_path = args.option("--bunfile") orelse brk: {
- const node_modules_bundle_path_absolute = resolve_path.joinAbs(cwd, .auto, "node_modules.bun");
+ if (comptime Command.Tag.cares_about_bun_file.get(cmd)) {
+ opts.node_modules_bundle_path = args.option("--bunfile") 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;
- };
+ 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: {
- const node_modules_bundle_path_absolute = resolve_path.joinAbs(cwd, .auto, "node_modules.server.bun");
+ opts.node_modules_bundle_path_server = args.option("--server-bunfile") 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;
- };
+ break :brk std.fs.realpathAlloc(allocator, node_modules_bundle_path_absolute) catch null;
+ };
+ }
switch (comptime cmd) {
.AutoCommand, .DevCommand, .BuildCommand, .BunCommand => {
@@ -387,23 +412,12 @@ pub const Arguments = struct {
const PlatformMatcher = strings.ExactSizeMatcher(8);
if (args.option("--platform")) |_platform| {
- switch (PlatformMatcher.match(_platform)) {
- PlatformMatcher.case("browser") => {
- opts.platform = Api.Platform.browser;
- },
- PlatformMatcher.case("node") => {
- opts.platform = Api.Platform.node;
- },
- PlatformMatcher.case("macro"), PlatformMatcher.case("bun") => {
- opts.platform = Api.Platform.bun;
- },
- else => {
- diag.name.long = "--platform";
- diag.arg = _platform;
- try diag.report(Output.errorWriter(), error.InvalidPlatform);
- std.process.exit(1);
- },
- }
+ opts.platform = 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,
+ else => invalidPlatform(&diag, _platform),
+ };
}
if (jsx_factory != null or
@@ -577,22 +591,26 @@ pub const Command = struct {
pub const Context = struct {
start_time: i128,
- args: Api.TransformOptions = std.mem.zeroes(Api.TransformOptions),
+ args: Api.TransformOptions,
log: *logger.Log,
allocator: std.mem.Allocator,
positionals: []const string = &[_]string{},
debug: DebugOptions = DebugOptions{},
+ const _ctx = Command.Context{
+ .args = std.mem.zeroes(Api.TransformOptions),
+ .log = undefined,
+ .start_time = 0,
+ .allocator = undefined,
+ };
+
pub fn create(allocator: std.mem.Allocator, log: *logger.Log, comptime command: Command.Tag) anyerror!Context {
Cli.cmd = command;
-
- var ctx = Command.Context{
- .args = std.mem.zeroes(Api.TransformOptions),
- .log = log,
- .start_time = start_time,
- .allocator = allocator,
- };
+ var ctx = _ctx;
+ ctx.log = log;
+ ctx.start_time = start_time;
+ ctx.allocator = allocator;
if (comptime Command.Tag.uses_global_options.get(command)) {
ctx.args = try Arguments.parse(allocator, &ctx, command);
@@ -602,8 +620,27 @@ pub const Command = struct {
}
};
- pub fn which(allocator: std.mem.Allocator) Tag {
- var args_iter = std.process.args();
+ // std.process.args allocates!
+ const ArgsIterator = struct {
+ buf: [][*:0]u8 = undefined,
+ i: u32 = 0,
+
+ pub fn next(this: *ArgsIterator) ?[]const u8 {
+ if (this.buf.len <= this.i) {
+ return null;
+ }
+ const i = this.i;
+ this.i += 1;
+ return std.mem.span(this.buf[i]);
+ }
+
+ pub fn skip(this: *ArgsIterator) bool {
+ return this.next() != null;
+ }
+ };
+
+ pub fn which() Tag {
+ var args_iter = ArgsIterator{ .buf = std.os.argv };
// first one is the executable name
const skipped = args_iter.skip();
@@ -611,9 +648,9 @@ pub const Command = struct {
return .AutoCommand;
}
- var next_arg = ((args_iter.next(allocator) catch null) orelse return .AutoCommand);
+ var next_arg = ((args_iter.next()) orelse return .AutoCommand);
while (next_arg[0] == '-') {
- next_arg = ((args_iter.next(allocator) catch null) orelse return .AutoCommand);
+ next_arg = ((args_iter.next()) orelse return .AutoCommand);
}
const first_arg_name = std.mem.span(next_arg);
@@ -630,6 +667,8 @@ pub const Command = struct {
RootCommandMatcher.case("i"), RootCommandMatcher.case("install") => .InstallCommand,
RootCommandMatcher.case("c"), RootCommandMatcher.case("create") => .CreateCommand,
+ RootCommandMatcher.case(TestCommand.name) => .TestCommand,
+
RootCommandMatcher.case("pm") => .PackageManagerCommand,
RootCommandMatcher.case("add"), RootCommandMatcher.case("update"), RootCommandMatcher.case("a") => .AddCommand,
@@ -665,7 +704,7 @@ pub const Command = struct {
};
pub fn start(allocator: std.mem.Allocator, log: *logger.Log) !void {
- const tag = which(allocator);
+ const tag = which();
switch (tag) {
.DiscordCommand => return try DiscordCommand.exec(allocator),
.HelpCommand => return try HelpCommand.exec(allocator),
@@ -717,6 +756,12 @@ pub const Command = struct {
try PackageManagerCommand.exec(ctx);
return;
},
+ .TestCommand => {
+ const ctx = try Command.Context.create(allocator, log, .TestCommand);
+
+ try TestCommand.exec(ctx);
+ return;
+ },
.GetCompletionsCommand => {
const ctx = try Command.Context.create(allocator, log, .GetCompletionsCommand);
var filter = ctx.positionals;
@@ -881,6 +926,21 @@ pub const Command = struct {
const file_: std.fs.File.OpenError!std.fs.File = brk: {
if (script_name_to_search[0] == std.fs.path.sep) {
break :brk std.fs.openFileAbsolute(script_name_to_search, .{ .read = true });
+ } else if (!strings.hasPrefix(script_name_to_search, "..") and script_name_to_search[0] != '~') {
+ const file_pathZ = brk2: {
+ if (!strings.hasPrefix(file_path, "./")) {
+ script_name_buf[0..2].* = "./".*;
+ @memcpy(script_name_buf[2..], file_path.ptr, file_path.len);
+ script_name_buf[file_path.len + 2] = 0;
+ break :brk2 script_name_buf[0 .. file_path.len + 2 :0];
+ } else {
+ @memcpy(&script_name_buf, file_path.ptr, file_path.len);
+ script_name_buf[file_path.len] = 0;
+ break :brk2 script_name_buf[0..file_path.len :0];
+ }
+ };
+
+ break :brk std.fs.cwd().openFileZ(file_pathZ, .{ .read = true });
} else {
var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const cwd = std.os.getcwd(&path_buf) catch break :possibly_open_with_bun_js;
@@ -954,6 +1014,16 @@ pub const Command = struct {
RunCommand,
UpgradeCommand,
PackageManagerCommand,
+ TestCommand,
+
+ pub const cares_about_bun_file: std.EnumArray(Tag, bool) = std.EnumArray(Tag, bool).initDefault(false, .{
+ .AutoCommand = true,
+ .BuildCommand = true,
+ .BunCommand = true,
+ .DevCommand = true,
+ .RunCommand = true,
+ .TestCommand = true,
+ });
pub const uses_global_options: std.EnumArray(Tag, bool) = std.EnumArray(Tag, bool).initDefault(true, .{
.CreateCommand = false,