aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-16 17:37:22 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-16 17:37:22 -0700
commit9511bf94d5eac2360e1d8bf201c1f3195f919763 (patch)
tree6de440cbac834f50106b52ac5c9f4770206e3bd9 /src
parent03983ac24ee48fecc3364bcb50570f1476cf6acd (diff)
downloadbun-9511bf94d5eac2360e1d8bf201c1f3195f919763.tar.gz
bun-9511bf94d5eac2360e1d8bf201c1f3195f919763.tar.zst
bun-9511bf94d5eac2360e1d8bf201c1f3195f919763.zip
Colorize build/resolve errors and add a ^
Diffstat (limited to 'src')
-rw-r--r--src/cli/build_command.zig26
-rw-r--r--src/cli/bun_command.zig4
-rw-r--r--src/global.zig37
-rw-r--r--src/http.zig42
-rw-r--r--src/javascript/jsc/javascript.zig14
-rw-r--r--src/js_parser/js_parser.zig9
-rw-r--r--src/logger.zig205
7 files changed, 210 insertions, 127 deletions
diff --git a/src/cli/build_command.zig b/src/cli/build_command.zig
index 0779a691a..2a85f48b2 100644
--- a/src/cli/build_command.zig
+++ b/src/cli/build_command.zig
@@ -140,14 +140,26 @@ pub const BuildCommand = struct {
}) catch {};
}
- for (result.errors) |err| {
- try err.writeFormat(err_writer);
- _ = try err_writer.write("\n");
- }
+ if (Output.enable_ansi_colors) {
+ for (result.errors) |err| {
+ try err.writeFormat(err_writer, true);
+ _ = try err_writer.write("\n");
+ }
+
+ for (result.warnings) |err| {
+ try err.writeFormat(err_writer, true);
+ _ = try err_writer.write("\n");
+ }
+ } else {
+ for (result.errors) |err| {
+ try err.writeFormat(err_writer, false);
+ _ = try err_writer.write("\n");
+ }
- for (result.warnings) |err| {
- try err.writeFormat(err_writer);
- _ = try err_writer.write("\n");
+ for (result.warnings) |err| {
+ try err.writeFormat(err_writer, false);
+ _ = try err_writer.write("\n");
+ }
}
const duration = std.time.nanoTimestamp() - ctx.start_time;
diff --git a/src/cli/bun_command.zig b/src/cli/bun_command.zig
index afe2a345a..32b62367d 100644
--- a/src/cli/bun_command.zig
+++ b/src/cli/bun_command.zig
@@ -170,7 +170,7 @@ pub const BunCommand = struct {
if (node_modules_) |node_modules| {
if (log.errors > 0) {
- try log.print(Output.errorWriter());
+ try log.printForLogLevel(Output.errorWriter());
} else {
var elapsed = @divTrunc(std.time.nanoTimestamp() - ctx.start_time, @as(i128, std.time.ns_per_ms));
const print_summary = !(ctx.args.no_summary orelse false);
@@ -190,7 +190,7 @@ pub const BunCommand = struct {
try log.printForLogLevel(Output.errorWriter());
}
} else {
- try log.print(Output.errorWriter());
+ try log.printForLogLevel(Output.errorWriter());
}
}
}
diff --git a/src/global.zig b/src/global.zig
index 1d696cc65..1fec9ac5c 100644
--- a/src/global.zig
+++ b/src/global.zig
@@ -192,10 +192,23 @@ pub const Output = struct {
// <d> - dim
// </r> - reset
// <r> - reset
+ const ED = "\x1b[";
+ pub const color_map = std.ComptimeStringMap(string, .{
+ &.{ "black", ED ++ "30m" },
+ &.{ "blue", ED ++ "34m" },
+ &.{ "b", ED ++ "1m" },
+ &.{ "d", ED ++ "2m" },
+ &.{ "cyan", ED ++ "36m" },
+ &.{ "green", ED ++ "32m" },
+ &.{ "magenta", ED ++ "35m" },
+ &.{ "red", ED ++ "31m" },
+ &.{ "white", ED ++ "37m" },
+ &.{ "yellow", ED ++ "33m" },
+ });
+
pub fn prettyFmt(comptime fmt: string, comptime is_enabled: bool) string {
comptime var new_fmt: [fmt.len * 4]u8 = undefined;
comptime var new_fmt_i: usize = 0;
- const ED = comptime "\x1b[";
@setEvalBranchQuota(9999);
comptime var i: usize = 0;
@@ -239,26 +252,8 @@ pub const Output = struct {
const color_name = fmt[start..i];
const color_str = color_picker: {
- if (std.mem.eql(u8, color_name, "black")) {
- break :color_picker ED ++ "30m";
- } else if (std.mem.eql(u8, color_name, "blue")) {
- break :color_picker ED ++ "34m";
- } else if (std.mem.eql(u8, color_name, "b")) {
- break :color_picker ED ++ "1m";
- } else if (std.mem.eql(u8, color_name, "d")) {
- break :color_picker ED ++ "2m";
- } else if (std.mem.eql(u8, color_name, "cyan")) {
- break :color_picker ED ++ "36m";
- } else if (std.mem.eql(u8, color_name, "green")) {
- break :color_picker ED ++ "32m";
- } else if (std.mem.eql(u8, color_name, "magenta")) {
- break :color_picker ED ++ "35m";
- } else if (std.mem.eql(u8, color_name, "red")) {
- break :color_picker ED ++ "31m";
- } else if (std.mem.eql(u8, color_name, "white")) {
- break :color_picker ED ++ "37m";
- } else if (std.mem.eql(u8, color_name, "yellow")) {
- break :color_picker ED ++ "33m";
+ if (color_map.get(color_name)) |color_name_literal| {
+ break :color_picker color_name_literal;
} else if (std.mem.eql(u8, color_name, "r")) {
is_reset = true;
break :color_picker "";
diff --git a/src/http.zig b/src/http.zig
index 65a769e59..93deb5556 100644
--- a/src/http.zig
+++ b/src/http.zig
@@ -957,9 +957,17 @@ pub const RequestContext = struct {
defer this.log.msgs.clearRetainingCapacity();
- if (this.log.msgs.items.len > 0) {
- for (this.log.msgs.items) |msg| {
- msg.writeFormat(Output.errorWriter()) catch continue;
+ if (Output.enable_ansi_colors) {
+ if (this.log.msgs.items.len > 0) {
+ for (this.log.msgs.items) |msg| {
+ msg.writeFormat(Output.errorWriter(), true) catch continue;
+ }
+ }
+ } else {
+ if (this.log.msgs.items.len > 0) {
+ for (this.log.msgs.items) |msg| {
+ msg.writeFormat(Output.errorWriter(), false) catch continue;
+ }
}
}
@@ -995,9 +1003,17 @@ pub const RequestContext = struct {
&exception_list,
);
} else {
- if (this.log.msgs.items.len > 0) {
- for (this.log.msgs.items) |msg| {
- msg.writeFormat(Output.errorWriter()) catch continue;
+ if (Output.enable_ansi_colors) {
+ if (this.log.msgs.items.len > 0) {
+ for (this.log.msgs.items) |msg| {
+ msg.writeFormat(Output.errorWriter(), true) catch continue;
+ }
+ }
+ } else {
+ if (this.log.msgs.items.len > 0) {
+ for (this.log.msgs.items) |msg| {
+ msg.writeFormat(Output.errorWriter(), false) catch continue;
+ }
}
}
@@ -1036,9 +1052,17 @@ pub const RequestContext = struct {
);
did_log_messages = start_count != this.log.msgs.items.len and exception_list.items.len == 0;
} else {
- if (this.log.msgs.items.len > 0) {
- for (this.log.msgs.items) |msg| {
- msg.writeFormat(Output.errorWriter()) catch continue;
+ if (Output.enable_ansi_colors) {
+ if (this.log.msgs.items.len > 0) {
+ for (this.log.msgs.items) |msg| {
+ msg.writeFormat(Output.errorWriter(), true) catch continue;
+ }
+ }
+ } else {
+ if (this.log.msgs.items.len > 0) {
+ for (this.log.msgs.items) |msg| {
+ msg.writeFormat(Output.errorWriter(), false) catch continue;
+ }
}
}
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index a84437851..bd9b470a9 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -834,9 +834,17 @@ pub const VirtualMachine = struct {
if (log.warnings > 0) {
var writer = Output.errorWriter();
- for (log.msgs.items) |msg| {
- if (msg.kind == .warn) {
- msg.writeFormat(writer) catch {};
+ if (Output.enable_ansi_colors) {
+ for (log.msgs.items) |msg| {
+ if (msg.kind == .warn) {
+ msg.writeFormat(writer, true) catch {};
+ }
+ }
+ } else {
+ for (log.msgs.items) |msg| {
+ if (msg.kind == .warn) {
+ msg.writeFormat(writer, false) catch {};
+ }
}
}
}
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index d4dc4f0d0..1c70212a0 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -3237,8 +3237,8 @@ pub fn NewParser(
js_lexer.rangeOfIdentifier(p.source, loc),
p.allocator,
notes,
- "Multiple exports with the same name {s}",
- .{alias},
+ "Multiple exports with the same name \"{s}\"",
+ .{std.mem.trim(u8, alias, "\"'")},
);
} else {
try p.named_exports.put(alias, js_ast.NamedExport{ .alias_loc = loc, .ref = ref });
@@ -9467,7 +9467,10 @@ pub fn NewParser(
var panic_buffer = p.allocator.alloc(u8, 32 * 1024) catch unreachable;
var panic_stream = std.io.fixedBufferStream(panic_buffer);
p.log.addRangeErrorFmt(p.source, p.lexer.range(), p.allocator, str, args) catch unreachable;
- p.log.print(panic_stream.writer()) catch unreachable;
+
+ p.log.printForLogLevel(
+ panic_stream.writer(),
+ ) catch unreachable;
Global.panic("{s}", .{panic_buffer[0..panic_stream.pos]});
}
diff --git a/src/logger.zig b/src/logger.zig
index b693584a4..177bee189 100644
--- a/src/logger.zig
+++ b/src/logger.zig
@@ -61,12 +61,10 @@ pub const Loc = packed struct {
return if (loc.start == -1) null else loc.*;
}
- // TODO: remove this stupidity
pub inline fn toUsize(self: *const Loc) usize {
return @intCast(usize, self.start);
}
- // TODO: remove this stupidity
pub inline fn i(self: *const Loc) usize {
return @intCast(usize, self.start);
}
@@ -179,24 +177,123 @@ pub const Data = struct {
this: *const Data,
to: anytype,
kind: Kind,
+ comptime enable_ansi_colors: bool,
+ comptime is_note: bool,
) !void {
if (this.text.len == 0) return;
+ const message_color = switch (kind) {
+ .err => comptime Output.color_map.get("b").?,
+ .note => comptime Output.color_map.get("cyan").? ++ Output.color_map.get("d").?,
+ else => comptime Output.color_map.get("d").? ++ Output.color_map.get("b").?,
+ };
+
+ const color_name: string = switch (kind) {
+ .err => comptime Output.color_map.get("red").?,
+ .note => comptime Output.color_map.get("cyan").?,
+ else => comptime Output.color_map.get("d").?,
+ };
+
+ try to.writeAll("\n\n");
+
+ if (comptime enable_ansi_colors) {
+ try to.writeAll(color_name);
+ }
+
+ try to.writeAll(kind.string());
+
+ try std.fmt.format(to, comptime Output.prettyFmt("<r><d>: <r>", enable_ansi_colors), .{});
+
+ if (comptime enable_ansi_colors) {
+ try to.writeAll(message_color);
+ }
+
+ try std.fmt.format(to, comptime Output.prettyFmt("{s}<r>\n", enable_ansi_colors), .{this.text});
+
if (this.location) |location| {
- try std.fmt.format(to, "\n\n{s}: {s}\n{s}\n{s}:{}:{} {d}", .{
- kind.string(),
- this.text,
- location.line_text,
- location.file,
- location.line,
- location.column,
- location.offset,
- });
- } else {
- try std.fmt.format(to, "\n\n{s}: {s}\n", .{
- kind.string(),
- this.text,
- });
+ if (location.line_text) |line_text_| {
+ const line_text = std.mem.trimRight(u8, line_text_, "\r\n\t");
+
+ const location_in_line_text = @intCast(u32, std.math.max(location.column, 1) - 1);
+ const has_position = location.column > -1 and line_text.len > 0 and location_in_line_text < line_text.len;
+
+ if (has_position) {
+ if (comptime enable_ansi_colors) {
+ const is_colored = message_color.len > 0;
+
+ const before_segment = line_text[0..location_in_line_text];
+
+ try to.writeAll(before_segment);
+
+ if (is_colored) {
+ try to.writeAll(color_name);
+ }
+
+ var end_of_segment: usize = 1;
+ // extremely naive: we should really use IsIdentifierContinue || isIdentifierStart here
+ var rest_of_line = line_text[location_in_line_text..];
+ while (end_of_segment < rest_of_line.len) : (end_of_segment += 1) {
+ if (!switch (rest_of_line[end_of_segment]) {
+ 'A'...'Z', 'a'...'z', '0'...'9', '_', '$', '(', ')' => true,
+ else => false,
+ }) break;
+ }
+
+ try to.writeAll(rest_of_line[0..end_of_segment]);
+ if (is_colored) {
+ try to.writeAll("\x1b[0m");
+ }
+
+ try to.writeAll(rest_of_line[end_of_segment..]);
+ } else {
+ try to.writeAll(line_text);
+ }
+
+ try to.writeAll("\n");
+
+ try to.writeByteNTimes(' ', location_in_line_text);
+ if (comptime enable_ansi_colors) {
+ const is_colored = message_color.len > 0;
+ if (is_colored) {
+ try to.writeAll(message_color);
+ try to.writeAll(color_name);
+ }
+
+ try to.writeByte('^');
+
+ if (is_colored) {
+ try to.writeAll("\x1b[0m\n");
+ }
+ } else {
+ try to.writeAll("^\n");
+ }
+ }
+ }
+
+ if (location.file.len > 0) {
+ if (comptime enable_ansi_colors) {
+ if (!is_note and kind == .err) {
+ try to.writeAll(comptime Output.color_map.get("b").?);
+ } else {}
+ }
+
+ try std.fmt.format(to, comptime Output.prettyFmt("{s}<r>", enable_ansi_colors), .{
+ location.file,
+ });
+
+ if (location.line > -1 and location.column > -1) {
+ try std.fmt.format(to, comptime Output.prettyFmt("<d>:<r><yellow>{d}<r><d>:<r><yellow>{d}<r> <d>{d}<r>", enable_ansi_colors), .{
+ location.line,
+ location.column,
+ location.offset,
+ });
+ } else if (location.line > -1) {
+ try std.fmt.format(to, comptime Output.prettyFmt("<d>:<r><yellow>{d}<r> <d>{d}<r>", enable_ansi_colors), .{
+ location.line,
+ location.offset,
+ });
+ }
+ }
}
}
};
@@ -286,28 +383,17 @@ pub const Msg = struct {
pub fn writeFormat(
msg: *const Msg,
to: anytype,
+ comptime enable_ansi_colors: bool,
) !void {
- try msg.data.writeFormat(to, msg.kind);
+ try msg.data.writeFormat(to, msg.kind, enable_ansi_colors, false);
if (msg.notes) |notes| {
for (notes) |note| {
- try note.writeFormat(to, msg.kind);
+ try note.writeFormat(to, .note, enable_ansi_colors, true);
}
}
}
- pub fn doFormat(msg: *const Msg, to: anytype, formatterFunc: anytype) !void {
- try formatterFunc(to, "\n\n{s}: {s}\n{s}\n{s}:{s}:{s} {d}", .{
- msg.kind.string(),
- msg.data.text,
- msg.data.location.?.line_text,
- msg.data.location.?.file,
- msg.data.location.?.line,
- msg.data.location.?.column,
- msg.data.location.?.offset,
- });
- }
-
pub fn formatWriter(
msg: *const Msg,
comptime Writer: type,
@@ -694,29 +780,28 @@ pub const Log = struct {
});
}
- // TODO:
pub fn addMsg(self: *Log, msg: Msg) !void {
try self.msgs.append(msg);
}
- // TODO:
pub fn addError(self: *Log, _source: ?*const Source, loc: Loc, text: string) !void {
self.errors += 1;
try self.addMsg(Msg{ .kind = .err, .data = rangeData(_source, Range{ .loc = loc }, text) });
}
- // TODO:
- pub fn print(self: *Log, to: anytype) !void {
- for (self.msgs.items) |msg| {
- try msg.writeFormat(to);
+ pub fn printForLogLevel(self: *Log, to: anytype) !void {
+ if (Output.enable_ansi_colors) {
+ return self.printForLogLevelWithEnableAnsiColors(to, true);
+ } else {
+ return self.printForLogLevelWithEnableAnsiColors(to, false);
}
}
- pub fn printForLogLevel(self: *Log, to: anytype) !void {
+ pub fn printForLogLevelWithEnableAnsiColors(self: *Log, to: anytype, comptime enable_ansi_colors: bool) !void {
var printed = false;
for (self.msgs.items) |msg| {
if (msg.kind.shouldPrint(self.level)) {
- try msg.writeFormat(to);
+ try msg.writeFormat(to, enable_ansi_colors);
printed = true;
}
}
@@ -923,47 +1008,3 @@ pub const Source = struct {
pub fn rangeData(source: ?*const Source, r: Range, text: string) Data {
return Data{ .text = text, .location = Location.init_or_nil(source, r) };
}
-
-test "print msg" {
- var msgs = ArrayList(Msg).init(std.testing.allocator);
- var log = Log{ .msgs = msgs };
- defer log.msgs.deinit();
- var filename = "test.js".*;
- var syntax = "for (i".*;
- var err = "invalid syntax".*;
- var namespace = "file".*;
-
- try log.addMsg(Msg{
- .kind = .err,
- .data = Data{
- .location = Location.init_file(&filename, 1, 3, 0, &syntax, ""),
- .text = &err,
- },
- });
-
- const stdout = std.io.getStdOut().writer();
-
- // try log.print(stdout);
-}
-
-test "ErrorPosition" {
- const source = Source.initPathString("/src/test/fixtures/simple.jsx", @embedFile("./test/fixtures/simple.jsx"));
- const error_position = source.initErrorPosition(Loc{ .start = 979 });
-
- std.testing.expectEqual(@as(usize, 973), @as(usize, error_position.line_start));
- std.testing.expectEqual(@as(usize, 1016), @as(usize, error_position.line_end));
-
- var msgs = ArrayList(Msg).init(std.testing.allocator);
- var log = Log{ .msgs = msgs };
- defer log.msgs.deinit();
-
- try log.addMsg(Msg{
- .kind = .err,
- .data = rangeData(&source, Range{ .loc = Loc{
- .start = 979,
- }, .len = 15 }, "Oh no"),
- });
-
- const stdout = std.io.getStdOut().writer();
- try log.print(stdout);
-}