diff options
Diffstat (limited to 'src/cli')
-rw-r--r-- | src/cli/bunx_command.zig | 193 | ||||
-rw-r--r-- | src/cli/create_command.zig | 659 | ||||
-rw-r--r-- | src/cli/gitignore-for-init | 4 | ||||
-rw-r--r-- | src/cli/package_manager_command.zig | 29 | ||||
-rw-r--r-- | src/cli/run_command.zig | 42 | ||||
-rw-r--r-- | src/cli/test_command.zig | 11 | ||||
-rw-r--r-- | src/cli/tsconfig-for-init.json | 2 | ||||
-rw-r--r-- | src/cli/upgrade_command.zig | 7 |
8 files changed, 515 insertions, 432 deletions
diff --git a/src/cli/bunx_command.zig b/src/cli/bunx_command.zig index f721eb98b..e7f35d10d 100644 --- a/src/cli/bunx_command.zig +++ b/src/cli/bunx_command.zig @@ -23,7 +23,8 @@ pub const BunxCommand = struct { var new_str = try allocator.allocSentinel(u8, input.len + prefixLength, 0); if (input[0] == '@') { - if (strings.indexAnyComptime(input, "/")) |index| { + if (strings.indexAnyComptime(input, "/")) |slashIndex| { + const index = slashIndex + 1; @memcpy(new_str[0..index], input[0..index]); @memcpy(new_str[index .. index + prefixLength], "create-"); @memcpy(new_str[index + prefixLength ..], input[index..]); @@ -159,7 +160,8 @@ pub const BunxCommand = struct { Global.exit(1); } - pub fn exec(ctx: bun.CLI.Command.Context, argv: [][*:0]const u8) !void { + pub fn exec(ctx_: bun.CLI.Command.Context, argv: [][*:0]const u8) !void { + var ctx = ctx_; var requests_buf = bun.PackageManager.UpdateRequest.Array.init(0) catch unreachable; var run_in_bun = ctx.debug.run_in_bun; @@ -220,6 +222,9 @@ pub const BunxCommand = struct { Global.exit(1); } + // Don't log stuff + ctx.debug.silent = true; + var update_request = update_requests[0]; // if you type "tsc" and TypeScript is not installed: @@ -231,6 +236,8 @@ pub const BunxCommand = struct { const initial_bin_name = if (strings.eqlComptime(update_request.name, "typescript")) "tsc" + else if (update_request.version.tag == .github) + update_request.version.value.github.repo.slice(update_request.version_buf) else if (strings.lastIndexOfChar(update_request.name, '/')) |index| update_request.name[index + 1 ..] else @@ -257,94 +264,123 @@ pub const BunxCommand = struct { else update_request.version.literal.slice(update_request.version_buf); + const package_fmt = brk: { + if (update_request.version.tag == .github) { + break :brk update_request.version.literal.slice(update_request.version_buf); + } + + break :brk try std.fmt.allocPrint( + ctx.allocator, + "{s}@{s}", + .{ + update_request.name, + display_version, + }, + ); + }; + const PATH_FOR_BIN_DIRS = PATH; if (PATH.len > 0) { PATH = try std.fmt.allocPrint( ctx.allocator, - bun.fs.FileSystem.RealFS.PLATFORM_TMP_DIR ++ "/{s}@{s}--bunx/node_modules/.bin:{s}", - .{ update_request.name, display_version, PATH }, + bun.fs.FileSystem.RealFS.PLATFORM_TMP_DIR ++ "/{s}--bunx/node_modules/.bin:{s}", + .{ package_fmt, PATH }, ); } else { PATH = try std.fmt.allocPrint( ctx.allocator, - bun.fs.FileSystem.RealFS.PLATFORM_TMP_DIR ++ "/{s}@{s}--bunx/node_modules/.bin", - .{ update_request.name, display_version }, + bun.fs.FileSystem.RealFS.PLATFORM_TMP_DIR ++ "/{s}--bunx/node_modules/.bin", + .{package_fmt}, ); } try this_bundler.env.map.put("PATH", PATH); - const bunx_cache_dir = PATH[0 .. bun.fs.FileSystem.RealFS.PLATFORM_TMP_DIR.len + "/--bunx@".len + update_request.name.len + display_version.len]; + const bunx_cache_dir = PATH[0 .. bun.fs.FileSystem.RealFS.PLATFORM_TMP_DIR.len + "/--bunx".len + package_fmt.len]; var absolute_in_cache_dir_buf: [bun.MAX_PATH_BYTES]u8 = undefined; var absolute_in_cache_dir = std.fmt.bufPrint(&absolute_in_cache_dir_buf, "/{s}/node_modules/.bin/{s}", .{ bunx_cache_dir, initial_bin_name }) catch unreachable; const passthrough = passthrough_list.items; - // Similar to "npx": - // - // 1. Try the bin in the current node_modules and then we try the bin in the global cache - if (bun.which( - &path_buf, - PATH_FOR_BIN_DIRS, - this_bundler.fs.top_level_dir, - initial_bin_name, - ) orelse bun.which( - &path_buf, - bunx_cache_dir, - this_bundler.fs.top_level_dir, - absolute_in_cache_dir, - )) |destination| { - const out = bun.asByteSlice(destination); - _ = try Run.runBinary( - ctx, - try this_bundler.fs.dirname_store.append(@TypeOf(out), out), - this_bundler.fs.top_level_dir, - this_bundler.env, - passthrough, - ); - // we are done! - Global.exit(0); - } + if (update_request.version.literal.isEmpty() or update_request.version.tag != .dist_tag) { + var destination_: ?[:0]const u8 = null; - // 2. The "bin" is possibly not the same as the package name, so we load the package.json to figure out what "bin" to use - if (getBinName(&this_bundler, bun.fdcast(root_dir_info.getFileDescriptor()), bunx_cache_dir, initial_bin_name)) |package_name_for_bin| { - // if we check the bin name and its actually the same, we don't need to check $PATH here again - if (!strings.eqlLong(package_name_for_bin, initial_bin_name, true)) { - absolute_in_cache_dir = std.fmt.bufPrint(&absolute_in_cache_dir_buf, "{s}/node_modules/.bin/{s}", .{ bunx_cache_dir, package_name_for_bin }) catch unreachable; - - if (bun.which( + // Only use the system-installed version if there is no version specified + if (update_request.version.literal.isEmpty()) { + destination_ = bun.which( &path_buf, PATH_FOR_BIN_DIRS, this_bundler.fs.top_level_dir, - package_name_for_bin, - ) orelse bun.which( - &path_buf, - bunx_cache_dir, + initial_bin_name, + ); + } + + // Similar to "npx": + // + // 1. Try the bin in the current node_modules and then we try the bin in the global cache + if (destination_ orelse bun.which( + &path_buf, + bunx_cache_dir, + this_bundler.fs.top_level_dir, + absolute_in_cache_dir, + )) |destination| { + const out = bun.asByteSlice(destination); + _ = try Run.runBinary( + ctx, + try this_bundler.fs.dirname_store.append(@TypeOf(out), out), this_bundler.fs.top_level_dir, - absolute_in_cache_dir, - )) |destination| { - const out = bun.asByteSlice(destination); - _ = try Run.runBinary( - ctx, - try this_bundler.fs.dirname_store.append(@TypeOf(out), out), + this_bundler.env, + passthrough, + ); + // we are done! + Global.exit(0); + } + + // 2. The "bin" is possibly not the same as the package name, so we load the package.json to figure out what "bin" to use + if (getBinName(&this_bundler, bun.fdcast(root_dir_info.getFileDescriptor()), bunx_cache_dir, initial_bin_name)) |package_name_for_bin| { + // if we check the bin name and its actually the same, we don't need to check $PATH here again + if (!strings.eqlLong(package_name_for_bin, initial_bin_name, true)) { + absolute_in_cache_dir = std.fmt.bufPrint(&absolute_in_cache_dir_buf, "{s}/node_modules/.bin/{s}", .{ bunx_cache_dir, package_name_for_bin }) catch unreachable; + + // Only use the system-installed version if there is no version specified + if (update_request.version.literal.isEmpty()) { + destination_ = bun.which( + &path_buf, + PATH_FOR_BIN_DIRS, + this_bundler.fs.top_level_dir, + package_name_for_bin, + ); + } + + if (destination_ orelse bun.which( + &path_buf, + bunx_cache_dir, this_bundler.fs.top_level_dir, - this_bundler.env, - passthrough, - ); - // we are done! - Global.exit(0); + absolute_in_cache_dir, + )) |destination| { + const out = bun.asByteSlice(destination); + _ = try Run.runBinary( + ctx, + try this_bundler.fs.dirname_store.append(@TypeOf(out), out), + this_bundler.fs.top_level_dir, + this_bundler.env, + passthrough, + ); + // we are done! + Global.exit(0); + } + } + } else |err| { + if (err == error.NoBinFound) { + Output.prettyErrorln("<r><red>error<r><d>:<r> could not determine executable to run for package <r><b>{s}<r>", .{update_request.name}); + Global.exit(1); } - } - } else |err| { - if (err == error.NoBinFound) { - Output.prettyErrorln("<r><red>error<r><d>:<r> could not determine executable to run for package <r><b>{s}<r>", .{update_request.name}); - Global.exit(1); } } var bunx_install_dir_path = try std.fmt.allocPrint( ctx.allocator, - bun.fs.FileSystem.RealFS.PLATFORM_TMP_DIR ++ "/{s}@{s}--bunx", - .{ update_request.name, display_version }, + bun.fs.FileSystem.RealFS.PLATFORM_TMP_DIR ++ "/{s}--bunx", + .{package_fmt}, ); // TODO: fix this after zig upgrade @@ -353,22 +389,22 @@ pub const BunxCommand = struct { create_package_json: { // create package.json, but only if it doesn't exist - var package_json = bunx_install_dir.createFileZ("package.json", .{ .truncate = false }) catch break :create_package_json; + var package_json = bunx_install_dir.createFileZ("package.json", .{ .truncate = true }) catch break :create_package_json; defer package_json.close(); package_json.writeAll("{}\n") catch {}; } var args_buf = [_]string{ - try std.fs.selfExePathAlloc(ctx.allocator), "add", "--no-summary", try std.fmt.allocPrint( - ctx.allocator, - "{s}@{s}", - .{ - update_request.name, - display_version, - }, - ), + try std.fs.selfExePathAlloc(ctx.allocator), "add", "--no-summary", + package_fmt, + // disable the manifest cache when a tag is specified + // so that @latest is fetched from the registry + "--no-cache", }; - var child_process = std.ChildProcess.init(&args_buf, default_allocator); + + const argv_to_use: []const string = args_buf[0 .. args_buf.len - @as(usize, @intFromBool(update_request.version.tag != .dist_tag))]; + + var child_process = std.ChildProcess.init(argv_to_use, default_allocator); child_process.cwd = bunx_install_dir_path; child_process.cwd_dir = bunx_install_dir; const env_map = try this_bundler.env.map.cloneToEnvMap(ctx.allocator); @@ -400,14 +436,10 @@ pub const BunxCommand = struct { // Similar to "npx": // - // 1. Try the bin in the current node_modules and then we try the bin in the global cache + // 1. Try the bin in the global cache + // Do not try $PATH because we already checked it above if we should if (bun.which( &path_buf, - PATH_FOR_BIN_DIRS, - this_bundler.fs.top_level_dir, - initial_bin_name, - ) orelse bun.which( - &path_buf, bunx_cache_dir, this_bundler.fs.top_level_dir, absolute_in_cache_dir, @@ -426,18 +458,11 @@ pub const BunxCommand = struct { // 2. The "bin" is possibly not the same as the package name, so we load the package.json to figure out what "bin" to use if (getBinNameFromTempDirectory(&this_bundler, bunx_cache_dir, update_request.name)) |package_name_for_bin| { - - // if we check the bin name and its actually the same, we don't need to check $PATH here again if (!strings.eqlLong(package_name_for_bin, initial_bin_name, true)) { absolute_in_cache_dir = std.fmt.bufPrint(&absolute_in_cache_dir_buf, "{s}/node_modules/.bin/{s}", .{ bunx_cache_dir, package_name_for_bin }) catch unreachable; if (bun.which( &path_buf, - PATH_FOR_BIN_DIRS, - this_bundler.fs.top_level_dir, - package_name_for_bin, - ) orelse bun.which( - &path_buf, bunx_cache_dir, this_bundler.fs.top_level_dir, absolute_in_cache_dir, diff --git a/src/cli/create_command.zig b/src/cli/create_command.zig index b052a11df..b112d5899 100644 --- a/src/cli/create_command.zig +++ b/src/cli/create_command.zig @@ -272,7 +272,7 @@ pub const CreateCommand = struct { var example_tag = Example.Tag.unknown; - var unsupported_packages = UnsupportedPackages{}; + // var unsupported_packages = UnsupportedPackages{}; const template = brk: { var positional = positionals[0]; @@ -753,55 +753,55 @@ pub const CreateCommand = struct { } } - const Needs = struct { - bun_bun_for_nextjs: bool = false, - bun_macro_relay: bool = false, - bun_macro_relay_dependency: bool = false, - bun_framework_next: bool = false, - react_refresh: bool = false, - }; - var needs = Needs{}; - var has_relay = false; - var has_bun_framework_next = false; - var has_react_refresh = false; - var has_bun_macro_relay = false; - var has_react = false; - var has_react_scripts = false; - - const Prune = struct { - pub const packages = ComptimeStringMap(void, .{ - .{ "@parcel/babel-preset", {} }, - .{ "@parcel/core", {} }, - .{ "@swc/cli", {} }, - .{ "@swc/core", {} }, - .{ "@webpack/cli", {} }, - .{ "react-scripts", {} }, - .{ "webpack-cli", {} }, - .{ "webpack", {} }, - - // one of cosmic config's imports breaks stuff - .{ "cosmiconfig", {} }, - }); - pub var prune_count: u16 = 0; - - pub fn prune(list: []js_ast.G.Property) []js_ast.G.Property { - var i: usize = 0; - var out_i: usize = 0; - while (i < list.len) : (i += 1) { - const key = list[i].key.?.data.e_string.data; - - const do_prune = packages.has(key); - prune_count += @as(u16, @intCast(@intFromBool(do_prune))); - - if (!do_prune) { - list[out_i] = list[i]; - out_i += 1; - } - } - - return list[0..out_i]; - } - }; + // const Needs = struct { + // bun_bun_for_nextjs: bool = false, + // bun_macro_relay: bool = false, + // bun_macro_relay_dependency: bool = false, + // bun_framework_next: bool = false, + // react_refresh: bool = false, + // }; + // var needs = Needs{}; + // var has_relay = false; + // var has_bun_framework_next = false; + // var has_react_refresh = false; + // var has_bun_macro_relay = false; + // var has_react = false; + // var has_react_scripts = false; + + // const Prune = struct { + // pub const packages = ComptimeStringMap(void, .{ + // .{ "@parcel/babel-preset", {} }, + // .{ "@parcel/core", {} }, + // .{ "@swc/cli", {} }, + // .{ "@swc/core", {} }, + // .{ "@webpack/cli", {} }, + // .{ "react-scripts", {} }, + // .{ "webpack-cli", {} }, + // .{ "webpack", {} }, + + // // one of cosmic config's imports breaks stuff + // .{ "cosmiconfig", {} }, + // }); + // pub var prune_count: u16 = 0; + + // pub fn prune(list: []js_ast.G.Property) []js_ast.G.Property { + // var i: usize = 0; + // var out_i: usize = 0; + // while (i < list.len) : (i += 1) { + // const key = list[i].key.?.data.e_string.data; + + // const do_prune = packages.has(key); + // prune_count += @as(u16, @intCast(@intFromBool(do_prune))); + + // if (!do_prune) { + // list[out_i] = list[i]; + // out_i += 1; + // } + // } + + // return list[0..out_i]; + // } + // }; var dev_dependencies: ?js_ast.Expr = null; var dependencies: ?js_ast.Expr = null; @@ -810,20 +810,20 @@ pub const CreateCommand = struct { const property = q.expr; if (property.data == .e_object and property.data.e_object.properties.len > 0) { - unsupported_packages.update(property); + // unsupported_packages.update(property); - has_react_scripts = has_react_scripts or property.hasAnyPropertyNamed(&.{"react-scripts"}); - has_relay = has_relay or property.hasAnyPropertyNamed(&.{ "react-relay", "relay-runtime", "babel-plugin-relay" }); + // has_react_scripts = has_react_scripts or property.hasAnyPropertyNamed(&.{"react-scripts"}); + // has_relay = has_relay or property.hasAnyPropertyNamed(&.{ "react-relay", "relay-runtime", "babel-plugin-relay" }); - property.data.e_object.properties = js_ast.G.Property.List.init(Prune.prune(property.data.e_object.properties.slice())); + // property.data.e_object.properties = js_ast.G.Property.List.init(Prune.prune(property.data.e_object.properties.slice())); if (property.data.e_object.properties.len > 0) { has_dependencies = true; dev_dependencies = q.expr; - has_bun_framework_next = has_bun_framework_next or property.hasAnyPropertyNamed(&.{"bun-framework-next"}); - has_react = has_react or property.hasAnyPropertyNamed(&.{ "react", "react-dom", "react-relay", "@emotion/react" }); - has_bun_macro_relay = has_bun_macro_relay or property.hasAnyPropertyNamed(&.{"bun-macro-relay"}); - has_react_refresh = has_react_refresh or property.hasAnyPropertyNamed(&.{"react-refresh"}); + // has_bun_framework_next = has_bun_framework_next or property.hasAnyPropertyNamed(&.{"bun-framework-next"}); + // has_react = has_react or property.hasAnyPropertyNamed(&.{ "react", "react-dom", "react-relay", "@emotion/react" }); + // has_bun_macro_relay = has_bun_macro_relay or property.hasAnyPropertyNamed(&.{"bun-macro-relay"}); + // has_react_refresh = has_react_refresh or property.hasAnyPropertyNamed(&.{"react-refresh"}); } } } @@ -832,101 +832,102 @@ pub const CreateCommand = struct { const property = q.expr; if (property.data == .e_object and property.data.e_object.properties.len > 0) { - unsupported_packages.update(property); + // unsupported_packages.update(property); - has_react_scripts = has_react_scripts or property.hasAnyPropertyNamed(&.{"react-scripts"}); - has_relay = has_relay or property.hasAnyPropertyNamed(&.{ "react-relay", "relay-runtime", "babel-plugin-relay" }); - property.data.e_object.properties = js_ast.G.Property.List.init(Prune.prune(property.data.e_object.properties.slice())); + // has_react_scripts = has_react_scripts or property.hasAnyPropertyNamed(&.{"react-scripts"}); + // has_relay = has_relay or property.hasAnyPropertyNamed(&.{ "react-relay", "relay-runtime", "babel-plugin-relay" }); + // property.data.e_object.properties = js_ast.G.Property.List.init(Prune.prune(property.data.e_object.properties.slice())); + property.data.e_object.properties = js_ast.G.Property.List.init(property.data.e_object.properties.slice()); if (property.data.e_object.properties.len > 0) { has_dependencies = true; dependencies = q.expr; - if (property.asProperty("next")) |next_q| { - is_nextjs = true; - needs.bun_bun_for_nextjs = true; + // if (property.asProperty("next")) |next_q| { + // is_nextjs = true; + // needs.bun_bun_for_nextjs = true; - next_q.expr.data.e_string.data = constStrToU8(target_nextjs_version); - } + // next_q.expr.data.e_string.data = constStrToU8(target_nextjs_version); + // } - has_bun_framework_next = has_bun_framework_next or property.hasAnyPropertyNamed(&.{"bun-framework-next"}); - has_react = has_react or is_nextjs or property.hasAnyPropertyNamed(&.{ "react", "react-dom", "react-relay", "@emotion/react" }); - has_react_refresh = has_react_refresh or property.hasAnyPropertyNamed(&.{"react-refresh"}); - has_bun_macro_relay = has_bun_macro_relay or property.hasAnyPropertyNamed(&.{"bun-macro-relay"}); + // has_bun_framework_next = has_bun_framework_next or property.hasAnyPropertyNamed(&.{"bun-framework-next"}); + // has_react = has_react or is_nextjs or property.hasAnyPropertyNamed(&.{ "react", "react-dom", "react-relay", "@emotion/react" }); + // has_react_refresh = has_react_refresh or property.hasAnyPropertyNamed(&.{"react-refresh"}); + // has_bun_macro_relay = has_bun_macro_relay or property.hasAnyPropertyNamed(&.{"bun-macro-relay"}); } } } - needs.bun_macro_relay = !has_bun_macro_relay and has_relay; - needs.react_refresh = !has_react_refresh and has_react; - needs.bun_framework_next = is_nextjs and !has_bun_framework_next; - needs.bun_bun_for_nextjs = is_nextjs; - needs.bun_macro_relay_dependency = needs.bun_macro_relay; - var bun_bun_for_react_scripts = false; - - var bun_macros_prop: ?js_ast.Expr = null; - var bun_prop: ?js_ast.Expr = null; - var bun_relay_prop: ?js_ast.Expr = null; - - var needs_bun_prop = needs.bun_macro_relay or has_bun_macro_relay; - var needs_bun_macros_prop = needs_bun_prop; - - if (needs_bun_macros_prop) { - if (package_json_expr.asProperty("bun")) |bun_| { - needs_bun_prop = false; - bun_prop = bun_.expr; - if (bun_.expr.asProperty("macros")) |macros_q| { - bun_macros_prop = macros_q.expr; - needs_bun_macros_prop = false; - if (macros_q.expr.asProperty("react-relay")) |react_relay_q| { - bun_relay_prop = react_relay_q.expr; - needs.bun_macro_relay = react_relay_q.expr.asProperty("graphql") == null; - } - - if (macros_q.expr.asProperty("babel-plugin-relay/macro")) |react_relay_q| { - bun_relay_prop = react_relay_q.expr; - needs.bun_macro_relay = react_relay_q.expr.asProperty("graphql") == null; - } - } - } - } + // needs.bun_macro_relay = !has_bun_macro_relay and has_relay; + // needs.react_refresh = !has_react_refresh and has_react; + // needs.bun_framework_next = is_nextjs and !has_bun_framework_next; + // needs.bun_bun_for_nextjs = is_nextjs; + // needs.bun_macro_relay_dependency = needs.bun_macro_relay; + // var bun_bun_for_react_scripts = false; + + // var bun_macros_prop: ?js_ast.Expr = null; + // var bun_prop: ?js_ast.Expr = null; + // var bun_relay_prop: ?js_ast.Expr = null; + + // var needs_bun_prop = needs.bun_macro_relay or has_bun_macro_relay; + // var needs_bun_macros_prop = needs_bun_prop; + + // if (needs_bun_macros_prop) { + // if (package_json_expr.asProperty("bun")) |bun_| { + // needs_bun_prop = false; + // bun_prop = bun_.expr; + // if (bun_.expr.asProperty("macros")) |macros_q| { + // bun_macros_prop = macros_q.expr; + // needs_bun_macros_prop = false; + // if (macros_q.expr.asProperty("react-relay")) |react_relay_q| { + // bun_relay_prop = react_relay_q.expr; + // needs.bun_macro_relay = react_relay_q.expr.asProperty("graphql") == null; + // } + + // if (macros_q.expr.asProperty("babel-plugin-relay/macro")) |react_relay_q| { + // bun_relay_prop = react_relay_q.expr; + // needs.bun_macro_relay = react_relay_q.expr.asProperty("graphql") == null; + // } + // } + // } + // } - if (Prune.prune_count > 0) { - Output.prettyErrorln("<r><d>[package.json] Pruned {d} unnecessary packages<r>", .{Prune.prune_count}); - } + // if (Prune.prune_count > 0) { + // Output.prettyErrorln("<r><d>[package.json] Pruned {d} unnecessary packages<r>", .{Prune.prune_count}); + // } // if (create_options.verbose) { - if (needs.bun_macro_relay) { - Output.prettyErrorln("<r><d>[package.json] Detected Relay -> added \"bun-macro-relay\"<r>", .{}); - } + // if (needs.bun_macro_relay) { + // Output.prettyErrorln("<r><d>[package.json] Detected Relay -> added \"bun-macro-relay\"<r>", .{}); + // } - if (needs.react_refresh) { - Output.prettyErrorln("<r><d>[package.json] Detected React -> added \"react-refresh\"<r>", .{}); - } + // if (needs.react_refresh) { + // Output.prettyErrorln("<r><d>[package.json] Detected React -> added \"react-refresh\"<r>", .{}); + // } - if (needs.bun_framework_next) { - Output.prettyErrorln("<r><d>[package.json] Detected Next -> added \"bun-framework-next\"<r>", .{}); - } else if (is_nextjs) { - Output.prettyErrorln("<r><d>[package.json] Detected Next.js<r>", .{}); - } + // if (needs.bun_framework_next) { + // Output.prettyErrorln("<r><d>[package.json] Detected Next -> added \"bun-framework-next\"<r>", .{}); + // } else if (is_nextjs) { + // Output.prettyErrorln("<r><d>[package.json] Detected Next.js<r>", .{}); + // } // } - var needs_to_inject_dev_dependency = needs.react_refresh or needs.bun_macro_relay; - var needs_to_inject_dependency = needs.bun_framework_next; + // var needs_to_inject_dev_dependency = needs.react_refresh or needs.bun_macro_relay; + // var needs_to_inject_dependency = needs.bun_framework_next; - const dependencies_to_inject_count = @as(usize, @intCast(@intFromBool(needs.bun_framework_next))); + // const dependencies_to_inject_count = @as(usize, @intCast(@intFromBool(needs.bun_framework_next))); - const dev_dependencies_to_inject_count = @as(usize, @intCast(@intFromBool(needs.react_refresh))) + - @as(usize, @intCast(@intFromBool(needs.bun_macro_relay))); + // const dev_dependencies_to_inject_count = @as(usize, @intCast(@intFromBool(needs.react_refresh))) + + // @as(usize, @intCast(@intFromBool(needs.bun_macro_relay))); - const new_properties_count = @as(usize, @intCast(@intFromBool(needs_to_inject_dev_dependency and dev_dependencies == null))) + - @as(usize, @intCast(@intFromBool(needs_to_inject_dependency and dependencies == null))) + - @as(usize, @intCast(@intFromBool(needs_bun_prop))); + // const new_properties_count = @as(usize, @intCast(@intFromBool(needs_to_inject_dev_dependency and dev_dependencies == null))) + + // @as(usize, @intCast(@intFromBool(needs_to_inject_dependency and dependencies == null))) + + // @as(usize, @intCast(@intFromBool(needs_bun_prop))); - if (new_properties_count != 0) { - try properties_list.ensureUnusedCapacity(new_properties_count); - } + // if (new_properties_count != 0) { + // try properties_list.ensureUnusedCapacity(new_properties_count); + // } const E = js_ast.E; @@ -1126,31 +1127,31 @@ pub const CreateCommand = struct { InjectionPrefill.bun_macros_relay_object.properties = js_ast.G.Property.List.init(&InjectionPrefill.bun_macros_relay_object_properties); InjectionPrefill.bun_macros_relay_only_object.properties = js_ast.G.Property.List.init(&InjectionPrefill.bun_macros_relay_only_object_properties); - if (needs_to_inject_dev_dependency and dev_dependencies == null) { - var e_object = try ctx.allocator.create(E.Object); + // if (needs_to_inject_dev_dependency and dev_dependencies == null) { + // var e_object = try ctx.allocator.create(E.Object); - e_object.* = E.Object{}; + // e_object.* = E.Object{}; - const value = js_ast.Expr{ .data = .{ .e_object = e_object }, .loc = logger.Loc.Empty }; - properties_list.appendAssumeCapacity(js_ast.G.Property{ - .key = InjectionPrefill.dev_dependencies_key, - .value = value, - }); - dev_dependencies = value; - } + // const value = js_ast.Expr{ .data = .{ .e_object = e_object }, .loc = logger.Loc.Empty }; + // properties_list.appendAssumeCapacity(js_ast.G.Property{ + // .key = InjectionPrefill.dev_dependencies_key, + // .value = value, + // }); + // dev_dependencies = value; + // } - if (needs_to_inject_dependency and dependencies == null) { - var e_object = try ctx.allocator.create(E.Object); + // if (needs_to_inject_dependency and dependencies == null) { + // var e_object = try ctx.allocator.create(E.Object); - e_object.* = E.Object{}; + // e_object.* = E.Object{}; - const value = js_ast.Expr{ .data = .{ .e_object = e_object }, .loc = logger.Loc.Empty }; - properties_list.appendAssumeCapacity(js_ast.G.Property{ - .key = InjectionPrefill.dependencies_key, - .value = value, - }); - dependencies = value; - } + // const value = js_ast.Expr{ .data = .{ .e_object = e_object }, .loc = logger.Loc.Empty }; + // properties_list.appendAssumeCapacity(js_ast.G.Property{ + // .key = InjectionPrefill.dependencies_key, + // .value = value, + // }); + // dependencies = value; + // } // inject an object like this, handling each permutation of what may or may not exist: // { @@ -1162,80 +1163,80 @@ pub const CreateCommand = struct { // } // } // } - bun_section: { - - // "bun.macros.react-relay.graphql" - if (needs.bun_macro_relay and !needs_bun_prop and !needs_bun_macros_prop) { - // "graphql" is the only valid one for now, so anything else in this object is invalid. - bun_relay_prop.?.data.e_object = InjectionPrefill.bun_macros_relay_object.properties.ptr[0].value.?.data.e_object; - needs_bun_macros_prop = false; - needs_bun_prop = false; - needs.bun_macro_relay = false; - break :bun_section; - } - - // "bun.macros" - if (needs_bun_macros_prop and !needs_bun_prop) { - var obj = bun_prop.?.data.e_object; - var properties = try std.ArrayList(js_ast.G.Property).initCapacity( - ctx.allocator, - obj.properties.len + InjectionPrefill.bun_macros_relay_object.properties.len, - ); - defer obj.properties.update(properties); - - try properties.insertSlice(0, obj.properties.slice()); - try properties.insertSlice(0, InjectionPrefill.bun_macros_relay_object.properties.slice()); - - needs_bun_macros_prop = false; - needs_bun_prop = false; - needs.bun_macro_relay = false; - break :bun_section; - } + // bun_section: { + + // "bun.macros.react-relay.graphql" + // if (needs.bun_macro_relay and !needs_bun_prop and !needs_bun_macros_prop) { + // // "graphql" is the only valid one for now, so anything else in this object is invalid. + // bun_relay_prop.?.data.e_object = InjectionPrefill.bun_macros_relay_object.properties.ptr[0].value.?.data.e_object; + // needs_bun_macros_prop = false; + // needs_bun_prop = false; + // needs.bun_macro_relay = false; + // break :bun_section; + // } - // "bun" - if (needs_bun_prop) { - try properties_list.append(InjectionPrefill.bun_only_macros_relay_property); - needs_bun_macros_prop = false; - needs_bun_prop = false; - needs.bun_macro_relay = false; - break :bun_section; - } - } + // "bun.macros" + // if (needs_bun_macros_prop and !needs_bun_prop) { + // var obj = bun_prop.?.data.e_object; + // var properties = try std.ArrayList(js_ast.G.Property).initCapacity( + // ctx.allocator, + // obj.properties.len + InjectionPrefill.bun_macros_relay_object.properties.len, + // ); + // defer obj.properties.update(properties); + + // try properties.insertSlice(0, obj.properties.slice()); + // try properties.insertSlice(0, InjectionPrefill.bun_macros_relay_object.properties.slice()); + + // needs_bun_macros_prop = false; + // needs_bun_prop = false; + // needs.bun_macro_relay = false; + // break :bun_section; + // } - if (needs_to_inject_dependency) { - defer needs_to_inject_dependency = false; - var obj = dependencies.?.data.e_object; - var properties = try std.ArrayList(js_ast.G.Property).initCapacity( - ctx.allocator, - obj.properties.len + dependencies_to_inject_count, - ); - try properties.insertSlice(0, obj.properties.slice()); - defer obj.properties.update(properties); - if (needs.bun_framework_next) { - properties.appendAssumeCapacity(InjectionPrefill.bun_framework_next_property); - needs.bun_framework_next = false; - } - } + // "bun" + // if (needs_bun_prop) { + // try properties_list.append(InjectionPrefill.bun_only_macros_relay_property); + // needs_bun_macros_prop = false; + // needs_bun_prop = false; + // needs.bun_macro_relay = false; + // break :bun_section; + // } + // } - if (needs_to_inject_dev_dependency) { - defer needs_to_inject_dev_dependency = false; - var obj = dev_dependencies.?.data.e_object; - var properties = try std.ArrayList(js_ast.G.Property).initCapacity( - ctx.allocator, - obj.properties.len + dev_dependencies_to_inject_count, - ); - try properties.insertSlice(0, obj.properties.slice()); - defer obj.properties.update(properties); - if (needs.bun_macro_relay_dependency) { - properties.appendAssumeCapacity(InjectionPrefill.bun_macro_relay_dependency); - needs.bun_macro_relay_dependency = false; - } + // if (needs_to_inject_dependency) { + // defer needs_to_inject_dependency = false; + // var obj = dependencies.?.data.e_object; + // var properties = try std.ArrayList(js_ast.G.Property).initCapacity( + // ctx.allocator, + // obj.properties.len + dependencies_to_inject_count, + // ); + // try properties.insertSlice(0, obj.properties.slice()); + // defer obj.properties.update(properties); + // if (needs.bun_framework_next) { + // properties.appendAssumeCapacity(InjectionPrefill.bun_framework_next_property); + // needs.bun_framework_next = false; + // } + // } - if (needs.react_refresh) { - properties.appendAssumeCapacity(InjectionPrefill.react_refresh_dependency); - needs.react_refresh = false; - } - } + // if (needs_to_inject_dev_dependency) { + // defer needs_to_inject_dev_dependency = false; + // var obj = dev_dependencies.?.data.e_object; + // var properties = try std.ArrayList(js_ast.G.Property).initCapacity( + // ctx.allocator, + // obj.properties.len + dev_dependencies_to_inject_count, + // ); + // try properties.insertSlice(0, obj.properties.slice()); + // defer obj.properties.update(properties); + // if (needs.bun_macro_relay_dependency) { + // properties.appendAssumeCapacity(InjectionPrefill.bun_macro_relay_dependency); + // needs.bun_macro_relay_dependency = false; + // } + + // if (needs.react_refresh) { + // properties.appendAssumeCapacity(InjectionPrefill.react_refresh_dependency); + // needs.react_refresh = false; + // } + // } // this is a little dicey // The idea is: @@ -1248,89 +1249,89 @@ pub const CreateCommand = struct { // 3. has a src/index.{jsx,tsx,ts,mts,mcjs} // If at any point those expectations are not matched OR the string /src/index.js already exists in the HTML // don't do it! - if (has_react_scripts) { - bail: { - var public_index_html_parts = [_]string{ destination, "public/index.html" }; - var public_index_html_path = filesystem.absBuf(&public_index_html_parts, &bun_path_buf); - - const public_index_html_file = std.fs.openFileAbsolute(public_index_html_path, .{ .mode = .read_write }) catch break :bail; - defer public_index_html_file.close(); - - const file_extensions_to_try = [_]string{ ".tsx", ".ts", ".jsx", ".js", ".mts", ".mcjs" }; - - var found_file = false; - var entry_point_path: string = ""; - var entry_point_file_parts = [_]string{ destination, "src/index" }; - var entry_point_file_path_base = filesystem.absBuf(&entry_point_file_parts, &bun_path_buf); - - for (file_extensions_to_try) |ext| { - bun.copy(u8, bun_path_buf[entry_point_file_path_base.len..], ext); - entry_point_path = bun_path_buf[0 .. entry_point_file_path_base.len + ext.len]; - std.fs.accessAbsolute(entry_point_path, .{}) catch continue; - found_file = true; - break; - } - if (!found_file) break :bail; - - var public_index_file_contents = public_index_html_file.readToEndAlloc(ctx.allocator, public_index_html_file.getEndPos() catch break :bail) catch break :bail; - - if (std.mem.indexOf(u8, public_index_file_contents, entry_point_path[destination.len..]) != null) { - break :bail; - } - - var body_closing_tag: usize = std.mem.lastIndexOf(u8, public_index_file_contents, "</body>") orelse break :bail; - - var public_index_file_out = std.ArrayList(u8).initCapacity(ctx.allocator, public_index_file_contents.len) catch break :bail; - var html_writer = public_index_file_out.writer(); - - _ = html_writer.writeAll(public_index_file_contents[0..body_closing_tag]) catch break :bail; - - create_react_app_entry_point_path = std.fmt.allocPrint( - ctx.allocator, - "./{s}", - - .{ - std.mem.trimLeft( - u8, - entry_point_path[destination.len..], - "/", - ), - }, - ) catch break :bail; - - html_writer.print( - "<script type=\"module\" async src=\"/{s}\"></script>\n{s}", - .{ - create_react_app_entry_point_path[2..], - public_index_file_contents[body_closing_tag..], - }, - ) catch break :bail; - - var outfile = std.mem.replaceOwned(u8, ctx.allocator, public_index_file_out.items, "%PUBLIC_URL%", "") catch break :bail; - - // don't do this actually - // it completely breaks when there is more than one CSS file loaded - // // bonus: check for an index.css file - // // inject it into the .html file statically if the file exists but isn't already in - // inject_css: { - // const head_i: usize = std.mem.indexOf(u8, outfile, "<head>") orelse break :inject_css; - // if (std.mem.indexOf(u8, outfile, "/src/index.css") != null) break :inject_css; - - // bun.copy(u8, bun_path_buf[destination.len + "/src/index".len ..], ".css"); - // var index_css_file_path = bun_path_buf[0 .. destination.len + "/src/index.css".len]; - // std.fs.accessAbsolute(index_css_file_path, .{}) catch break :inject_css; - // var list = std.ArrayList(u8).fromOwnedSlice(ctx.allocator, outfile); - // list.insertSlice(head_i + "<head>".len, "<link rel=\"stylesheet\" href=\"/src/index.css\">\n") catch break :inject_css; - // outfile =try list.toOwnedSlice(); - // } - - public_index_html_file.pwriteAll(outfile, 0) catch break :bail; - std.os.ftruncate(public_index_html_file.handle, outfile.len + 1) catch break :bail; - bun_bun_for_react_scripts = true; - is_create_react_app = true; - Output.prettyln("<r><d>[package.json] Added entry point {s} to public/index.html", .{create_react_app_entry_point_path}); - } - } + // if (has_react_scripts) { + // bail: { + // var public_index_html_parts = [_]string{ destination, "public/index.html" }; + // var public_index_html_path = filesystem.absBuf(&public_index_html_parts, &bun_path_buf); + + // const public_index_html_file = std.fs.openFileAbsolute(public_index_html_path, .{ .mode = .read_write }) catch break :bail; + // defer public_index_html_file.close(); + + // const file_extensions_to_try = [_]string{ ".tsx", ".ts", ".jsx", ".js", ".mts", ".mcjs" }; + + // var found_file = false; + // var entry_point_path: string = ""; + // var entry_point_file_parts = [_]string{ destination, "src/index" }; + // var entry_point_file_path_base = filesystem.absBuf(&entry_point_file_parts, &bun_path_buf); + + // for (file_extensions_to_try) |ext| { + // bun.copy(u8, bun_path_buf[entry_point_file_path_base.len..], ext); + // entry_point_path = bun_path_buf[0 .. entry_point_file_path_base.len + ext.len]; + // std.fs.accessAbsolute(entry_point_path, .{}) catch continue; + // found_file = true; + // break; + // } + // if (!found_file) break :bail; + + // var public_index_file_contents = public_index_html_file.readToEndAlloc(ctx.allocator, public_index_html_file.getEndPos() catch break :bail) catch break :bail; + + // if (std.mem.indexOf(u8, public_index_file_contents, entry_point_path[destination.len..]) != null) { + // break :bail; + // } + + // var body_closing_tag: usize = std.mem.lastIndexOf(u8, public_index_file_contents, "</body>") orelse break :bail; + + // var public_index_file_out = std.ArrayList(u8).initCapacity(ctx.allocator, public_index_file_contents.len) catch break :bail; + // var html_writer = public_index_file_out.writer(); + + // _ = html_writer.writeAll(public_index_file_contents[0..body_closing_tag]) catch break :bail; + + // create_react_app_entry_point_path = std.fmt.allocPrint( + // ctx.allocator, + // "./{s}", + + // .{ + // std.mem.trimLeft( + // u8, + // entry_point_path[destination.len..], + // "/", + // ), + // }, + // ) catch break :bail; + + // html_writer.print( + // "<script type=\"module\" async src=\"/{s}\"></script>\n{s}", + // .{ + // create_react_app_entry_point_path[2..], + // public_index_file_contents[body_closing_tag..], + // }, + // ) catch break :bail; + + // var outfile = std.mem.replaceOwned(u8, ctx.allocator, public_index_file_out.items, "%PUBLIC_URL%", "") catch break :bail; + + // // don't do this actually + // // it completely breaks when there is more than one CSS file loaded + // // // bonus: check for an index.css file + // // // inject it into the .html file statically if the file exists but isn't already in + // // inject_css: { + // // const head_i: usize = std.mem.indexOf(u8, outfile, "<head>") orelse break :inject_css; + // // if (std.mem.indexOf(u8, outfile, "/src/index.css") != null) break :inject_css; + + // // bun.copy(u8, bun_path_buf[destination.len + "/src/index".len ..], ".css"); + // // var index_css_file_path = bun_path_buf[0 .. destination.len + "/src/index.css".len]; + // // std.fs.accessAbsolute(index_css_file_path, .{}) catch break :inject_css; + // // var list = std.ArrayList(u8).fromOwnedSlice(ctx.allocator, outfile); + // // list.insertSlice(head_i + "<head>".len, "<link rel=\"stylesheet\" href=\"/src/index.css\">\n") catch break :inject_css; + // // outfile =try list.toOwnedSlice(); + // // } + + // public_index_html_file.pwriteAll(outfile, 0) catch break :bail; + // std.os.ftruncate(public_index_html_file.handle, outfile.len + 1) catch break :bail; + // bun_bun_for_react_scripts = true; + // is_create_react_app = true; + // Output.prettyln("<r><d>[package.json] Added entry point {s} to public/index.html", .{create_react_app_entry_point_path}); + // } + // } package_json_expr.data.e_object.is_single_line = false; @@ -1396,20 +1397,20 @@ pub const CreateCommand = struct { const items = tasks.slice(); for (items) |task| { if (task.asString(ctx.allocator)) |task_entry| { - if (needs.bun_bun_for_nextjs or bun_bun_for_react_scripts) { - var iter = std.mem.split(u8, task_entry, " "); - var last_was_bun = false; - while (iter.next()) |current| { - if (strings.eqlComptime(current, "bun")) { - if (last_was_bun) { - needs.bun_bun_for_nextjs = false; - bun_bun_for_react_scripts = false; - break; - } - last_was_bun = true; - } - } - } + // if (needs.bun_bun_for_nextjs or bun_bun_for_react_scripts) { + // var iter = std.mem.split(u8, task_entry, " "); + // var last_was_bun = false; + // while (iter.next()) |current| { + // if (strings.eqlComptime(current, "bun")) { + // if (last_was_bun) { + // needs.bun_bun_for_nextjs = false; + // bun_bun_for_react_scripts = false; + // break; + // } + // last_was_bun = true; + // } + // } + // } try postinstall_tasks.append( ctx.allocator, @@ -1465,13 +1466,13 @@ pub const CreateCommand = struct { std.os.ftruncate(package_json_file.?.handle, written + 1) catch {}; - if (!create_options.skip_install) { - if (needs.bun_bun_for_nextjs) { - try postinstall_tasks.append(ctx.allocator, InjectionPrefill.bun_bun_for_nextjs_task); - } else if (bun_bun_for_react_scripts) { - try postinstall_tasks.append(ctx.allocator, try std.fmt.allocPrint(ctx.allocator, "bun bun {s}", .{create_react_app_entry_point_path})); - } - } + // if (!create_options.skip_install) { + // if (needs.bun_bun_for_nextjs) { + // try postinstall_tasks.append(ctx.allocator, InjectionPrefill.bun_bun_for_nextjs_task); + // } else if (bun_bun_for_react_scripts) { + // try postinstall_tasks.append(ctx.allocator, try std.fmt.allocPrint(ctx.allocator, "bun bun {s}", .{create_react_app_entry_point_path})); + // } + // } } } @@ -1573,12 +1574,12 @@ pub const CreateCommand = struct { Output.flush(); } - if (unsupported_packages.@"styled-jsx") { - Output.prettyErrorln("\n", .{}); - unsupported_packages.print(); - Output.prettyErrorln("\n", .{}); - Output.flush(); - } + // if (unsupported_packages.@"styled-jsx") { + // Output.prettyErrorln("\n", .{}); + // unsupported_packages.print(); + // Output.prettyErrorln("\n", .{}); + // Output.flush(); + // } if (!create_options.skip_git and !create_options.skip_install) { Output.pretty( diff --git a/src/cli/gitignore-for-init b/src/cli/gitignore-for-init index 3d75225a1..ab5afb295 100644 --- a/src/cli/gitignore-for-init +++ b/src/cli/gitignore-for-init @@ -170,3 +170,7 @@ dist # IntelliJ based IDEs .idea + +# Finder (MacOS) folder config +.DS_Store + diff --git a/src/cli/package_manager_command.zig b/src/cli/package_manager_command.zig index a70dec020..00326bc97 100644 --- a/src/cli/package_manager_command.zig +++ b/src/cli/package_manager_command.zig @@ -162,7 +162,7 @@ pub const PackageManagerCommand = struct { Global.crash(); }; - if (pm.options.positionals.len > 0 and strings.eqlComptime(pm.options.positionals[0], "rm")) { + if (pm.options.positionals.len > 1 and strings.eqlComptime(pm.options.positionals[1], "rm")) { std.fs.deleteTreeAbsolute(outpath) catch |err| { Output.prettyErrorln("{s} deleting cache directory", .{@errorName(err)}); Global.crash(); @@ -244,6 +244,32 @@ pub const PackageManagerCommand = struct { } Global.exit(0); + } else if (strings.eqlComptime(subcommand, "migrate")) { + if (!pm.options.enable.force_save_lockfile) try_load_bun: { + std.fs.cwd().accessZ("bun.lockb", .{ .mode = .read_only }) catch break :try_load_bun; + + Output.prettyErrorln( + \\<r><red>error<r>: bun.lockb already exists + \\run with --force to overwrite + , .{}); + Global.exit(1); + } + const load_lockfile = @import("../install/migration.zig").detectAndLoadOtherLockfile( + pm.lockfile, + ctx.allocator, + pm.log, + pm.options.lockfile_path, + ); + if (load_lockfile == .not_found) { + Output.prettyErrorln( + \\<r><red>error<r>: could not find any other lockfile + , .{}); + Global.exit(1); + } + handleLoadLockfileErrors(load_lockfile, pm); + const lockfile = load_lockfile.ok; + lockfile.saveToDisk(pm.options.lockfile_path); + Global.exit(0); } Output.prettyln( @@ -258,6 +284,7 @@ pub const PackageManagerCommand = struct { \\ bun pm <b>hash-print<r> print the hash stored in the current lockfile \\ bun pm <b>cache<r> print the path to the cache folder \\ bun pm <b>cache rm<r> clear the cache + \\ bun pm <b>migrate<r> migrate another package manager's lockfile without installing anything \\ \\Learn more about these at <magenta>https://bun.sh/docs/install/utilities<r> \\ diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index f5240246c..cf1e4dc99 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -618,7 +618,10 @@ pub const RunCommand = struct { child_process.stdout_behavior = .Inherit; const result = child_process.spawnAndWait() catch |err| { - Output.prettyErrorln("<r><red>error<r>: Failed to run script <b>{s}<r> due to error <b>{s}<r>", .{ name, @errorName(err) }); + if (!silent) { + Output.prettyErrorln("<r><red>error<r>: Failed to run script <b>{s}<r> due to error <b>{s}<r>", .{ name, @errorName(err) }); + } + Output.flush(); return true; }; @@ -626,7 +629,7 @@ pub const RunCommand = struct { switch (result) { .Exited => |code| { if (code > 0) { - if (code != 2) { + if (code != 2 and !silent) { Output.prettyErrorln("<r><red>error<r><d>:<r> script <b>\"{s}\"<r> exited with {any}<r>", .{ name, bun.SignalCode.from(code) }); Output.flush(); } @@ -635,14 +638,18 @@ pub const RunCommand = struct { } }, .Signal => |signal| { - Output.prettyErrorln("<r><red>error<r><d>:<r> script <b>\"{s}\"<r> exited with {any}<r>", .{ name, bun.SignalCode.from(signal) }); - Output.flush(); + if (!silent) { + Output.prettyErrorln("<r><red>error<r><d>:<r> script <b>\"{s}\"<r> exited with {any}<r>", .{ name, bun.SignalCode.from(signal) }); + Output.flush(); + } Global.exit(1); }, .Stopped => |signal| { - Output.prettyErrorln("<r><red>error<r><d>:<r> script <b>\"{s}\"<r> was stopped by signal {any}<r>", .{ name, bun.SignalCode.from(signal) }); - Output.flush(); + if (!silent) { + Output.prettyErrorln("<r><red>error<r><d>:<r> script <b>\"{s}\"<r> was stopped by signal {any}<r>", .{ name, bun.SignalCode.from(signal) }); + Output.flush(); + } Global.exit(1); }, @@ -678,6 +685,7 @@ pub const RunCommand = struct { child_process.stderr_behavior = .Inherit; child_process.stdin_behavior = .Inherit; child_process.stdout_behavior = .Inherit; + const silent = ctx.debug.silent; const result = child_process.spawnAndWait() catch |err| { if (err == error.AccessDenied) { @@ -686,7 +694,8 @@ pub const RunCommand = struct { const rc = bun.C.stat(executable[0.. :0].ptr, &stat); if (rc == 0) { if (std.os.S.ISDIR(stat.mode)) { - Output.prettyErrorln("<r><red>error<r>: Failed to run directory \"<b>{s}<r>\"\n", .{executable}); + if (!silent) + Output.prettyErrorln("<r><red>error<r>: Failed to run directory \"<b>{s}<r>\"\n", .{executable}); Global.exit(1); } } @@ -698,24 +707,25 @@ pub const RunCommand = struct { switch (result) { .Exited => |sig| { // 2 is SIGINT, which is CTRL + C so that's kind of annoying to show - if (sig > 0 and sig != 2) + if (sig > 0 and sig != 2 and !silent) Output.prettyErrorln("<r><red>error<r><d>:<r> \"<b>{s}<r>\" exited with <b>{any}<r>", .{ std.fs.path.basename(executable), bun.SignalCode.from(sig) }); Global.exit(sig); }, .Signal => |sig| { // 2 is SIGINT, which is CTRL + C so that's kind of annoying to show - if (sig > 0 and sig != 2) { + if (sig > 0 and sig != 2 and !silent) { Output.prettyErrorln("<r><red>error<r><d>:<r> \"<b>{s}<r>\" exited with <b>{any}<r>", .{ std.fs.path.basename(executable), bun.SignalCode.from(sig) }); } Global.exit(std.mem.asBytes(&sig)[0]); }, .Stopped => |sig| { - if (sig > 0) + if (sig > 0 and !silent) Output.prettyErrorln("<r><red>error<r> \"<b>{s}<r>\" stopped with {any}<r>", .{ std.fs.path.basename(executable), bun.SignalCode.from(sig) }); Global.exit(std.mem.asBytes(&sig)[0]); }, .Unknown => |sig| { - Output.prettyErrorln("<r><red>error<r> \"<b>{s}<r>\" stopped: {d}<r>", .{ std.fs.path.basename(executable), sig }); + if (!silent) + Output.prettyErrorln("<r><red>error<r> \"<b>{s}<r>\" stopped: {d}<r>", .{ std.fs.path.basename(executable), sig }); Global.exit(1); }, } @@ -965,7 +975,7 @@ pub const RunCommand = struct { // the use of npm/? is copying yarn // e.g. // > "yarn/1.22.4 npm/? node/v12.16.3 darwin x64", - "bun/" ++ Global.package_json_version ++ " npm/? node/v18.15.0 " ++ Global.os_name ++ " " ++ Global.arch_name, + "bun/" ++ Global.package_json_version ++ " npm/? node/v20.8.0 " ++ Global.os_name ++ " " ++ Global.arch_name, ) catch unreachable; if (this_bundler.env.get("npm_execpath") == null) { @@ -1292,14 +1302,14 @@ pub const RunCommand = struct { // "White space after #! is optional." var shebang_buf: [64]u8 = undefined; const shebang_size = file.pread(&shebang_buf, 0) catch |err| { - Output.prettyErrorln("<r><red>error<r>: Failed to read file <b>{s}<r> due to error <b>{s}<r>", .{ file_path, @errorName(err) }); + if (!ctx.debug.silent) + Output.prettyErrorln("<r><red>error<r>: Failed to read file <b>{s}<r> due to error <b>{s}<r>", .{ file_path, @errorName(err) }); Global.exit(1); }; var shebang: string = shebang_buf[0..shebang_size]; shebang = std.mem.trim(u8, shebang, " \r\n\t"); - if (shebang.len == 0) break :possibly_open_with_bun_js; if (strings.hasPrefixComptime(shebang, "#!")) { const first_arg: string = if (bun.argv().len > 0) bun.span(bun.argv()[0]) else ""; const filename = std.fs.path.basename(first_arg); @@ -1487,6 +1497,10 @@ pub const RunCommand = struct { } } + if (ctx.runtime_options.if_present) { + return true; + } + if (comptime log_errors) { Output.prettyError("<r><red>error<r><d>:<r> missing script \"<b>{s}<r>\"\n", .{script_name_to_search}); Global.exit(1); diff --git a/src/cli/test_command.zig b/src/cli/test_command.zig index 75ac87e5d..141d7ff25 100644 --- a/src/cli/test_command.zig +++ b/src/cli/test_command.zig @@ -669,7 +669,7 @@ pub const TestCommand = struct { .dirs_to_scan = Scanner.Fifo.init(ctx.allocator), .options = &vm.bundler.options, .fs = vm.bundler.fs, - .filter_names = ctx.positionals[1..], + .filter_names = if (ctx.positionals.len == 0) &[0][]const u8{} else ctx.positionals[1..], .results = std.ArrayList(PathString).init(ctx.allocator), }; const dir_to_scan = brk: { @@ -685,8 +685,13 @@ pub const TestCommand = struct { const test_files = try scanner.results.toOwnedSlice(); if (test_files.len > 0) { vm.hot_reload = ctx.debug.hot_reload; - if (vm.hot_reload != .none) - JSC.HotReloader.enableHotModuleReloading(vm); + + switch (vm.hot_reload) { + .hot => JSC.HotReloader.enableHotModuleReloading(vm), + .watch => JSC.WatchReloader.enableHotModuleReloading(vm), + else => {}, + } + // vm.bundler.fs.fs.readDirectory(_dir: string, _handle: ?std.fs.Dir) runAllTests(reporter, vm, test_files, ctx.allocator); } diff --git a/src/cli/tsconfig-for-init.json b/src/cli/tsconfig-for-init.json index 1449bc3d9..7556e1d4b 100644 --- a/src/cli/tsconfig-for-init.json +++ b/src/cli/tsconfig-for-init.json @@ -11,7 +11,7 @@ "strict": true, "downlevelIteration": true, "skipLibCheck": true, - "jsx": "preserve", + "jsx": "react-jsx", "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, "allowJs": true, diff --git a/src/cli/upgrade_command.zig b/src/cli/upgrade_command.zig index 60ae953d3..d865d990d 100644 --- a/src/cli/upgrade_command.zig +++ b/src/cli/upgrade_command.zig @@ -83,7 +83,9 @@ pub const Version = struct { pub const triplet = platform_label ++ "-" ++ arch_label; const suffix = if (Environment.baseline) "-baseline" else ""; pub const folder_name = "bun-" ++ triplet ++ suffix; + pub const baseline_folder_name = "bun-" ++ triplet ++ "-baseline"; pub const zip_filename = folder_name ++ ".zip"; + pub const baseline_zip_filename = baseline_folder_name ++ ".zip"; pub const profile_folder_name = "bun-" ++ triplet ++ suffix ++ "-profile"; pub const profile_zip_filename = profile_folder_name ++ ".zip"; @@ -95,6 +97,11 @@ pub const Version = struct { zip_filename, }); + pub const Bun__githubBaselineURL: [:0]const u8 = std.fmt.comptimePrint("https://github.com/oven-sh/bun/release/bun-v{s}/{s}", .{ + Global.package_json_version, + baseline_zip_filename, + }); + pub fn isCurrent(this: Version) bool { return strings.eqlComptime(this.tag, current_version); } |