diff --git a/src/StandaloneModuleGraph.zig b/src/StandaloneModuleGraph.zig index 0fba80c9a3..5c963a7508 100644 --- a/src/StandaloneModuleGraph.zig +++ b/src/StandaloneModuleGraph.zig @@ -47,7 +47,7 @@ pub const StandaloneModuleGraph = struct { // by normalized file path pub fn find(this: *const StandaloneModuleGraph, name: []const u8) ?*File { - if (!bun.strings.hasPrefixComptime(name, base_path)) { + if (!isBunStandaloneFilePath(base_path)) { return null; } if (Environment.isWindows) { @@ -170,7 +170,7 @@ pub const StandaloneModuleGraph = struct { } pub fn toBytes(allocator: std.mem.Allocator, prefix: []const u8, output_files: []const bun.options.OutputFile) ![]u8 { - var serialize_trace = bun.tracy.traceNamed(@src(), "ModuleGraph.serialize"); + var serialize_trace = bun.tracy.traceNamed(@src(), "StandaloneModuleGraph.serialize"); defer serialize_trace.end(); var entry_point_id: ?usize = null; var string_builder = bun.StringBuilder{}; @@ -218,10 +218,7 @@ pub const StandaloneModuleGraph = struct { continue; } - var dest_path = output_file.dest_path; - if (bun.strings.hasPrefixComptime(dest_path, "./")) { - dest_path = dest_path[2..]; - } + const dest_path = bun.strings.removeLeadingDotSlash(output_file.dest_path); var module = CompiledModuleGraphFile{ .name = string_builder.fmtAppendCount("{s}{s}", .{ diff --git a/src/bundler/bundle_v2.zig b/src/bundler/bundle_v2.zig index 2d297b1370..8e16b8981e 100644 --- a/src/bundler/bundle_v2.zig +++ b/src/bundler/bundle_v2.zig @@ -11586,8 +11586,8 @@ fn cheapPrefixNormalizer(prefix: []const u8, suffix: []const u8) [2]string { // There are a few cases here we want to handle: // ["https://example.com/", "/out.js"] => "https://example.com/out.js" // ["/foo/", "/bar.js"] => "/foo/bar.js" - if (strings.endsWithChar(prefix, '/')) { - if (strings.startsWithChar(suffix, '/')) { + if (strings.endsWithChar(prefix, '/') or (Environment.isWindows and strings.endsWithChar(prefix, '\\'))) { + if (strings.startsWithChar(suffix, '/') or (Environment.isWindows and strings.startsWithChar(suffix, '\\'))) { return .{ prefix[0..prefix.len], suffix[1..suffix.len], @@ -11602,14 +11602,10 @@ fn cheapPrefixNormalizer(prefix: []const u8, suffix: []const u8) [2]string { // But it's not worth the complexity to handle these cases right now. } - if (suffix.len > "./".len and strings.hasPrefixComptime(suffix, "./")) { - return .{ - prefix, - suffix[2..], - }; - } - - return .{ prefix, suffix }; + return .{ + prefix, + bun.strings.removeLeadingDotSlash(suffix), + }; } const components_manifest_path = "./components-manifest.blob"; diff --git a/src/deps/zig b/src/deps/zig index 593a407f12..7fe33d94ea 160000 --- a/src/deps/zig +++ b/src/deps/zig @@ -1 +1 @@ -Subproject commit 593a407f121a2870e9c645da33c11db5e4331920 +Subproject commit 7fe33d94eaeb1af7705e9c5f43a3b243aa895436 diff --git a/src/output.zig b/src/output.zig index 253fe3d45b..040deb0594 100644 --- a/src/output.zig +++ b/src/output.zig @@ -562,21 +562,25 @@ pub noinline fn print(comptime fmt: string, args: anytype) callconv(std.builtin. /// BUN_DEBUG_foo=1 /// To enable all logs, set the environment variable /// BUN_DEBUG_ALL=1 -const _log_fn = fn (comptime fmt: string, args: anytype) void; -pub fn scoped(comptime tag: anytype, comptime disabled: bool) _log_fn { +const LogFunction = fn (comptime fmt: string, args: anytype) void; +pub fn Scoped(comptime tag: anytype, comptime disabled: bool) type { const tagname = switch (@TypeOf(tag)) { @Type(.EnumLiteral) => @tagName(tag), - []const u8 => tag, - else => @compileError("Output.scoped expected @Type(.EnumLiteral) or []const u8, you gave: " ++ @typeName(@Type(tag))), + else => tag, }; - if (comptime !Environment.isDebug or !Environment.isNative) { + + if (comptime !Environment.isDebug) { return struct { + pub fn isVisible() bool { + return false; + } pub fn log(comptime _: string, _: anytype) void {} - }.log; + }; } return struct { const BufferedWriter = std.io.BufferedWriter(4096, bun.sys.File.QuietWriter); + var buffered_writer: BufferedWriter = undefined; var out: BufferedWriter.Writer = undefined; var out_set = false; @@ -584,6 +588,20 @@ pub fn scoped(comptime tag: anytype, comptime disabled: bool) _log_fn { var evaluated_disable = false; var lock = std.Thread.Mutex{}; + pub fn isVisible() bool { + if (!evaluated_disable) { + evaluated_disable = true; + if (bun.getenvZ("BUN_DEBUG_" ++ tagname)) |val| { + really_disable = strings.eqlComptime(val, "0"); + } else if (bun.getenvZ("BUN_DEBUG_ALL")) |val| { + really_disable = strings.eqlComptime(val, "0"); + } else if (bun.getenvZ("BUN_DEBUG_QUIET_LOGS")) |val| { + really_disable = really_disable or !strings.eqlComptime(val, "0"); + } + } + return !really_disable; + } + /// Debug-only logs which should not appear in release mode /// To enable a specific log at runtime, set the environment variable /// BUN_DEBUG_${TAG} to 1 @@ -600,18 +618,7 @@ pub fn scoped(comptime tag: anytype, comptime disabled: bool) _log_fn { return; } - if (!evaluated_disable) { - evaluated_disable = true; - if (bun.getenvZ("BUN_DEBUG_" ++ tagname)) |val| { - really_disable = strings.eqlComptime(val, "0"); - } else if (bun.getenvZ("BUN_DEBUG_ALL")) |val| { - really_disable = strings.eqlComptime(val, "0"); - } else if (bun.getenvZ("BUN_DEBUG_QUIET_LOGS")) |val| { - really_disable = really_disable or !strings.eqlComptime(val, "0"); - } - } - - if (really_disable) + if (!isVisible()) return; if (!out_set) { @@ -644,7 +651,11 @@ pub fn scoped(comptime tag: anytype, comptime disabled: bool) _log_fn { }; } } - }.log; + }; +} + +pub fn scoped(comptime tag: anytype, comptime disabled: bool) LogFunction { + return Scoped(tag, disabled).log; } // Valid "colors": @@ -862,9 +873,11 @@ pub inline fn warn(comptime fmt: []const u8, args: anytype) void { prettyErrorln("warn: " ++ fmt, args); } +const debugWarnScope = Scoped("debug warn", false); + /// Print a yellow warning message, only in debug mode pub inline fn debugWarn(comptime fmt: []const u8, args: anytype) void { - if (Environment.isDebug) { + if (debugWarnScope.isVisible()) { prettyErrorln("debug warn: " ++ fmt, args); flush(); } diff --git a/src/resolver/resolve_path.zig b/src/resolver/resolve_path.zig index fe8b753b8a..6bebb1e076 100644 --- a/src/resolver/resolve_path.zig +++ b/src/resolver/resolve_path.zig @@ -59,10 +59,6 @@ inline fn @"is .. with type"(comptime T: type, slice: []const T) bool { return slice.len >= 2 and slice[0] == '.' and slice[1] == '.'; } -inline fn isDotSlash(slice: []const u8) bool { - return @as(u16, @bitCast(slice[0..2].*)) == comptime std.mem.readInt(u16, "./", .little); -} - inline fn @"is ../"(slice: []const u8) bool { return strings.hasPrefixComptime(slice, "../"); } diff --git a/src/string_immutable.zig b/src/string_immutable.zig index 9ff5d75985..9fae3feccb 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -32,6 +32,17 @@ pub inline fn contains(self: string, str: string) bool { return indexOf(self, str) != null; } +pub inline fn removeLeadingDotSlash(slice: []const u8) []const u8 { + if (slice.len >= 2) { + if ((@as(u16, @bitCast(slice[0..2].*)) == comptime std.mem.readInt(u16, "./", .little)) or + (Environment.isWindows and @as(u16, @bitCast(slice[0..2].*)) == comptime std.mem.readInt(u16, ".\\", .little))) + { + return slice[2..]; + } + } + return slice; +} + pub inline fn w(comptime str: []const u8) [:0]const u16 { if (!@inComptime()) @compileError("strings.w() must be called in a comptime context"); comptime var output: [str.len + 1]u16 = undefined; diff --git a/test/bundler/expectBundled.ts b/test/bundler/expectBundled.ts index 4d4dd85faa..0af0e6f55d 100644 --- a/test/bundler/expectBundled.ts +++ b/test/bundler/expectBundled.ts @@ -813,6 +813,9 @@ function expectBundled( return testRef(id, opts); } + if (allErrors.length === 0) { + throw new Error("Bundle Failed\ncode: " + exitCode + "\nstdout: " + stdout + "\nstderr: " + stderr); + } throw new Error("Bundle Failed\n" + [...allErrors].map(formatError).join("\n")); } else if (!expectedErrors) { throw new Error("Bundle Failed\n" + stderr?.toUnixString());