authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-02 17:00:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-02 17:02:25-07:00
log21181181bf1060d5e55738651c109d7c47647633
treeee868ceb21ddb959808b7619e0597b3f546ca1ae
parentef9966c9855dd855afda767f212abec6e5a36307

zig fetch: enhanced error reporting

* Package: use std.tar diagnostics to give detailed error messages * std.tar: add diagnostic for unsupported file type

4 files changed, 148 insertions(+), 55 deletions(-)

lib/std/tar.zig+24-12
...@@ -29,6 +29,10 @@ pub const Options = struct {...@@ -29,6 +29,10 @@ pub const Options = struct {
29 file_name: []const u8,29 file_name: []const u8,
30 link_name: []const u8,30 link_name: []const u8,
31 },31 },
32 unsupported_file_type: struct {
33 file_name: []const u8,
34 file_type: Header.FileType,
35 },
32 };36 };
3337
34 pub fn deinit(d: *Diagnostics) void {38 pub fn deinit(d: *Diagnostics) void {
...@@ -38,6 +42,9 @@ pub const Options = struct {...@@ -38,6 +42,9 @@ pub const Options = struct {
38 d.allocator.free(info.file_name);42 d.allocator.free(info.file_name);
39 d.allocator.free(info.link_name);43 d.allocator.free(info.link_name);
40 },44 },
45 .unsupported_file_type => |info| {
46 d.allocator.free(info.file_name);
47 },
41 }48 }
42 }49 }
43 d.errors.deinit(d.allocator);50 d.errors.deinit(d.allocator);
...@@ -50,6 +57,7 @@ pub const Header = struct {...@@ -50,6 +57,7 @@ pub const Header = struct {
50 bytes: *const [512]u8,57 bytes: *const [512]u8,
5158
52 pub const FileType = enum(u8) {59 pub const FileType = enum(u8) {
60 normal_alias = 0,
53 normal = '0',61 normal = '0',
54 hard_link = '1',62 hard_link = '1',
55 symbolic_link = '2',63 symbolic_link = '2',
...@@ -105,8 +113,9 @@ pub const Header = struct {...@@ -105,8 +113,9 @@ pub const Header = struct {
105 }113 }
106114
107 pub fn fileType(header: Header) FileType {115 pub fn fileType(header: Header) FileType {
108 const result = @as(FileType, @enumFromInt(header.bytes[156]));116 const result: FileType = @enumFromInt(header.bytes[156]);
109 return if (result == @as(FileType, @enumFromInt(0))) .normal else result;117 if (result == .normal_alias) return .normal;
118 return result;
110 }119 }
111120
112 fn str(header: Header, start: usize, end: usize) []const u8 {121 fn str(header: Header, start: usize, end: usize) []const u8 {
...@@ -268,18 +277,21 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi...@@ -268,18 +277,21 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
268 const link_name = header.linkName();277 const link_name = header.linkName();
269278
270 dir.symLink(link_name, file_name, .{}) catch |err| {279 dir.symLink(link_name, file_name, .{}) catch |err| {
271 if (options.diagnostics) |d| {280 const d = options.diagnostics orelse return error.UnableToCreateSymLink;
272 try d.errors.append(d.allocator, .{ .unable_to_create_sym_link = .{281 try d.errors.append(d.allocator, .{ .unable_to_create_sym_link = .{
273 .code = err,282 .code = err,
274 .file_name = try d.allocator.dupe(u8, file_name),283 .file_name = try d.allocator.dupe(u8, file_name),
275 .link_name = try d.allocator.dupe(u8, link_name),284 .link_name = try d.allocator.dupe(u8, link_name),
276 } });285 } });
277 } else {
278 return error.UnableToCreateSymLink;
279 }
280 };286 };
281 },287 },
282 else => return error.TarUnsupportedFileType,288 else => |file_type| {
289 const d = options.diagnostics orelse return error.TarUnsupportedFileType;
290 try d.errors.append(d.allocator, .{ .unsupported_file_type = .{
291 .file_name = try d.allocator.dupe(u8, unstripped_file_name),
292 .file_type = file_type,
293 } });
294 },
283 }295 }
284 }296 }
285}297}
lib/std/zig/ErrorBundle.zig+12-12
...@@ -202,7 +202,7 @@ fn renderErrorMessageToWriter(...@@ -202,7 +202,7 @@ fn renderErrorMessageToWriter(
202 try counting_stderr.writeAll(": ");202 try counting_stderr.writeAll(": ");
203 // This is the length of the part before the error message:203 // This is the length of the part before the error message:
204 // e.g. "file.zig:4:5: error: "204 // e.g. "file.zig:4:5: error: "
205 const prefix_len = @as(usize, @intCast(counting_stderr.context.bytes_written));205 const prefix_len: usize = @intCast(counting_stderr.context.bytes_written);
206 try ttyconf.setColor(stderr, .reset);206 try ttyconf.setColor(stderr, .reset);
207 try ttyconf.setColor(stderr, .bold);207 try ttyconf.setColor(stderr, .bold);
208 if (err_msg.count == 1) {208 if (err_msg.count == 1) {
...@@ -356,7 +356,7 @@ pub const Wip = struct {...@@ -356,7 +356,7 @@ pub const Wip = struct {
356 }356 }
357357
358 const compile_log_str_index = if (compile_log_text.len == 0) 0 else str: {358 const compile_log_str_index = if (compile_log_text.len == 0) 0 else str: {
359 const str = @as(u32, @intCast(wip.string_bytes.items.len));359 const str: u32 = @intCast(wip.string_bytes.items.len);
360 try wip.string_bytes.ensureUnusedCapacity(gpa, compile_log_text.len + 1);360 try wip.string_bytes.ensureUnusedCapacity(gpa, compile_log_text.len + 1);
361 wip.string_bytes.appendSliceAssumeCapacity(compile_log_text);361 wip.string_bytes.appendSliceAssumeCapacity(compile_log_text);
362 wip.string_bytes.appendAssumeCapacity(0);362 wip.string_bytes.appendAssumeCapacity(0);
...@@ -364,8 +364,8 @@ pub const Wip = struct {...@@ -364,8 +364,8 @@ pub const Wip = struct {
364 };364 };
365365
366 wip.setExtra(0, ErrorMessageList{366 wip.setExtra(0, ErrorMessageList{
367 .len = @as(u32, @intCast(wip.root_list.items.len)),367 .len = @intCast(wip.root_list.items.len),
368 .start = @as(u32, @intCast(wip.extra.items.len)),368 .start = @intCast(wip.extra.items.len),
369 .compile_log_text = compile_log_str_index,369 .compile_log_text = compile_log_str_index,
370 });370 });
371 try wip.extra.appendSlice(gpa, @as([]const u32, @ptrCast(wip.root_list.items)));371 try wip.extra.appendSlice(gpa, @as([]const u32, @ptrCast(wip.root_list.items)));
...@@ -385,7 +385,7 @@ pub const Wip = struct {...@@ -385,7 +385,7 @@ pub const Wip = struct {
385385
386 pub fn addString(wip: *Wip, s: []const u8) !u32 {386 pub fn addString(wip: *Wip, s: []const u8) !u32 {
387 const gpa = wip.gpa;387 const gpa = wip.gpa;
388 const index = @as(u32, @intCast(wip.string_bytes.items.len));388 const index: u32 = @intCast(wip.string_bytes.items.len);
389 try wip.string_bytes.ensureUnusedCapacity(gpa, s.len + 1);389 try wip.string_bytes.ensureUnusedCapacity(gpa, s.len + 1);
390 wip.string_bytes.appendSliceAssumeCapacity(s);390 wip.string_bytes.appendSliceAssumeCapacity(s);
391 wip.string_bytes.appendAssumeCapacity(0);391 wip.string_bytes.appendAssumeCapacity(0);
...@@ -394,7 +394,7 @@ pub const Wip = struct {...@@ -394,7 +394,7 @@ pub const Wip = struct {
394394
395 pub fn printString(wip: *Wip, comptime fmt: []const u8, args: anytype) !u32 {395 pub fn printString(wip: *Wip, comptime fmt: []const u8, args: anytype) !u32 {
396 const gpa = wip.gpa;396 const gpa = wip.gpa;
397 const index = @as(u32, @intCast(wip.string_bytes.items.len));397 const index: u32 = @intCast(wip.string_bytes.items.len);
398 try wip.string_bytes.writer(gpa).print(fmt, args);398 try wip.string_bytes.writer(gpa).print(fmt, args);
399 try wip.string_bytes.append(gpa, 0);399 try wip.string_bytes.append(gpa, 0);
400 return index;400 return index;
...@@ -406,15 +406,15 @@ pub const Wip = struct {...@@ -406,15 +406,15 @@ pub const Wip = struct {
406 }406 }
407407
408 pub fn addErrorMessage(wip: *Wip, em: ErrorMessage) !MessageIndex {408 pub fn addErrorMessage(wip: *Wip, em: ErrorMessage) !MessageIndex {
409 return @as(MessageIndex, @enumFromInt(try addExtra(wip, em)));409 return @enumFromInt(try addExtra(wip, em));
410 }410 }
411411
412 pub fn addErrorMessageAssumeCapacity(wip: *Wip, em: ErrorMessage) MessageIndex {412 pub fn addErrorMessageAssumeCapacity(wip: *Wip, em: ErrorMessage) MessageIndex {
413 return @as(MessageIndex, @enumFromInt(addExtraAssumeCapacity(wip, em)));413 return @enumFromInt(addExtraAssumeCapacity(wip, em));
414 }414 }
415415
416 pub fn addSourceLocation(wip: *Wip, sl: SourceLocation) !SourceLocationIndex {416 pub fn addSourceLocation(wip: *Wip, sl: SourceLocation) !SourceLocationIndex {
417 return @as(SourceLocationIndex, @enumFromInt(try addExtra(wip, sl)));417 return @enumFromInt(try addExtra(wip, sl));
418 }418 }
419419
420 pub fn addReferenceTrace(wip: *Wip, rt: ReferenceTrace) !void {420 pub fn addReferenceTrace(wip: *Wip, rt: ReferenceTrace) !void {
...@@ -430,7 +430,7 @@ pub const Wip = struct {...@@ -430,7 +430,7 @@ pub const Wip = struct {
430 const other_list = other.getMessages();430 const other_list = other.getMessages();
431431
432 // The ensureUnusedCapacity call above guarantees this.432 // The ensureUnusedCapacity call above guarantees this.
433 const notes_start = wip.reserveNotes(@as(u32, @intCast(other_list.len))) catch unreachable;433 const notes_start = wip.reserveNotes(@intCast(other_list.len)) catch unreachable;
434 for (notes_start.., other_list) |note, message| {434 for (notes_start.., other_list) |note, message| {
435 wip.extra.items[note] = @intFromEnum(wip.addOtherMessage(other, message) catch unreachable);435 wip.extra.items[note] = @intFromEnum(wip.addOtherMessage(other, message) catch unreachable);
436 }436 }
...@@ -455,7 +455,7 @@ pub const Wip = struct {...@@ -455,7 +455,7 @@ pub const Wip = struct {
455 try wip.extra.ensureUnusedCapacity(wip.gpa, notes_len +455 try wip.extra.ensureUnusedCapacity(wip.gpa, notes_len +
456 notes_len * @typeInfo(ErrorBundle.ErrorMessage).Struct.fields.len);456 notes_len * @typeInfo(ErrorBundle.ErrorMessage).Struct.fields.len);
457 wip.extra.items.len += notes_len;457 wip.extra.items.len += notes_len;
458 return @as(u32, @intCast(wip.extra.items.len - notes_len));458 return @intCast(wip.extra.items.len - notes_len);
459 }459 }
460460
461 fn addOtherMessage(wip: *Wip, other: ErrorBundle, msg_index: MessageIndex) !MessageIndex {461 fn addOtherMessage(wip: *Wip, other: ErrorBundle, msg_index: MessageIndex) !MessageIndex {
...@@ -510,7 +510,7 @@ pub const Wip = struct {...@@ -510,7 +510,7 @@ pub const Wip = struct {
510510
511 fn addExtraAssumeCapacity(wip: *Wip, extra: anytype) u32 {511 fn addExtraAssumeCapacity(wip: *Wip, extra: anytype) u32 {
512 const fields = @typeInfo(@TypeOf(extra)).Struct.fields;512 const fields = @typeInfo(@TypeOf(extra)).Struct.fields;
513 const result = @as(u32, @intCast(wip.extra.items.len));513 const result: u32 = @intCast(wip.extra.items.len);
514 wip.extra.items.len += fields.len;514 wip.extra.items.len += fields.len;
515 setExtra(wip, result, extra);515 setExtra(wip, result, extra);
516 return result;516 return result;
src/Package.zig+92-27
...@@ -285,7 +285,8 @@ pub fn fetchAndAddDependencies(...@@ -285,7 +285,8 @@ pub fn fetchAndAddDependencies(
285 if (manifest.errors.len > 0) {285 if (manifest.errors.len > 0) {
286 const file_path = try directory.join(arena, &.{Manifest.basename});286 const file_path = try directory.join(arena, &.{Manifest.basename});
287 for (manifest.errors) |msg| {287 for (manifest.errors) |msg| {
288 try Report.addErrorMessage(ast, file_path, error_bundle, 0, msg);288 const str = try error_bundle.addString(msg.msg);
289 try Report.addErrorMessage(&ast, file_path, error_bundle, 0, str, msg.tok, msg.off);
289 }290 }
290 return error.PackageFetchFailed;291 return error.PackageFetchFailed;
291 }292 }
...@@ -465,20 +466,31 @@ pub const Report = struct {...@@ -465,20 +466,31 @@ pub const Report = struct {
465 comptime fmt_string: []const u8,466 comptime fmt_string: []const u8,
466 fmt_args: anytype,467 fmt_args: anytype,
467 ) error{ PackageFetchFailed, OutOfMemory } {468 ) error{ PackageFetchFailed, OutOfMemory } {
468 const ast = report.ast orelse main.fatal(fmt_string, fmt_args);469 const msg = try report.error_bundle.printString(fmt_string, fmt_args);
470 return failMsg(report, tok, msg);
471 }
472
473 fn failMsg(
474 report: Report,
475 tok: std.zig.Ast.TokenIndex,
476 msg: u32,
477 ) error{ PackageFetchFailed, OutOfMemory } {
469 const gpa = report.error_bundle.gpa;478 const gpa = report.error_bundle.gpa;
470479
471 const file_path = try report.directory.join(gpa, &.{Manifest.basename});480 const file_path = try report.directory.join(gpa, &.{Manifest.basename});
472 defer gpa.free(file_path);481 defer gpa.free(file_path);
473482
474 const msg = try std.fmt.allocPrint(gpa, fmt_string, fmt_args);483 const eb = report.error_bundle;
475 defer gpa.free(msg);
476484
477 try addErrorMessage(ast.*, file_path, report.error_bundle, 0, .{485 if (report.ast) |ast| {
478 .tok = tok,486 try addErrorMessage(ast, file_path, eb, 0, msg, tok, 0);
479 .off = 0,487 } else {
480 .msg = msg,488 try eb.addRootErrorMessage(.{
481 });489 .msg = msg,
490 .src_loc = .none,
491 .notes_len = 0,
492 });
493 }
482494
483 return error.PackageFetchFailed;495 return error.PackageFetchFailed;
484 }496 }
...@@ -488,31 +500,42 @@ pub const Report = struct {...@@ -488,31 +500,42 @@ pub const Report = struct {
488 notes_len: u32,500 notes_len: u32,
489 msg: Manifest.ErrorMessage,501 msg: Manifest.ErrorMessage,
490 ) error{OutOfMemory}!void {502 ) error{OutOfMemory}!void {
491 const ast = report.ast orelse main.fatal("{s}", .{msg.msg});503 const eb = report.error_bundle;
492 const gpa = report.error_bundle.gpa;504 const msg_str = try eb.addString(msg.msg);
493 const file_path = try report.directory.join(gpa, &.{Manifest.basename});505 if (report.ast) |ast| {
494 defer gpa.free(file_path);506 const gpa = eb.gpa;
495 return addErrorMessage(ast.*, file_path, report.error_bundle, notes_len, msg);507 const file_path = try report.directory.join(gpa, &.{Manifest.basename});
508 defer gpa.free(file_path);
509 return addErrorMessage(ast, file_path, eb, notes_len, msg_str, msg.tok, msg.off);
510 } else {
511 return eb.addRootErrorMessage(.{
512 .msg = msg_str,
513 .src_loc = .none,
514 .notes_len = notes_len,
515 });
516 }
496 }517 }
497518
498 fn addErrorMessage(519 fn addErrorMessage(
499 ast: std.zig.Ast,520 ast: *const std.zig.Ast,
500 file_path: []const u8,521 file_path: []const u8,
501 eb: *std.zig.ErrorBundle.Wip,522 eb: *std.zig.ErrorBundle.Wip,
502 notes_len: u32,523 notes_len: u32,
503 msg: Manifest.ErrorMessage,524 msg_str: u32,
525 msg_tok: std.zig.Ast.TokenIndex,
526 msg_off: u32,
504 ) error{OutOfMemory}!void {527 ) error{OutOfMemory}!void {
505 const token_starts = ast.tokens.items(.start);528 const token_starts = ast.tokens.items(.start);
506 const start_loc = ast.tokenLocation(0, msg.tok);529 const start_loc = ast.tokenLocation(0, msg_tok);
507530
508 try eb.addRootErrorMessage(.{531 try eb.addRootErrorMessage(.{
509 .msg = try eb.addString(msg.msg),532 .msg = msg_str,
510 .src_loc = try eb.addSourceLocation(.{533 .src_loc = try eb.addSourceLocation(.{
511 .src_path = try eb.addString(file_path),534 .src_path = try eb.addString(file_path),
512 .span_start = token_starts[msg.tok],535 .span_start = token_starts[msg_tok],
513 .span_end = @as(u32, @intCast(token_starts[msg.tok] + ast.tokenSlice(msg.tok).len)),536 .span_end = @as(u32, @intCast(token_starts[msg_tok] + ast.tokenSlice(msg_tok).len)),
514 .span_main = token_starts[msg.tok] + msg.off,537 .span_main = token_starts[msg_tok] + msg_off,
515 .line = @as(u32, @intCast(start_loc.line)),538 .line = @intCast(start_loc.line),
516 .column = @as(u32, @intCast(start_loc.column)),539 .column = @as(u32, @intCast(start_loc.column)),
517 .source_line = try eb.addString(ast.source[start_loc.line_start..start_loc.line_end]),540 .source_line = try eb.addString(ast.source[start_loc.line_start..start_loc.line_end]),
518 }),541 }),
...@@ -752,9 +775,9 @@ pub const ReadableResource = struct {...@@ -752,9 +775,9 @@ pub const ReadableResource = struct {
752 };775 };
753776
754 switch (try rr.getFileType(dep_location_tok, report)) {777 switch (try rr.getFileType(dep_location_tok, report)) {
755 .tar => try unpackTarball(prog_reader.reader(), tmp_directory.handle),778 .tar => try unpackTarball(allocator, prog_reader.reader(), tmp_directory.handle, dep_location_tok, report),
756 .@"tar.gz" => try unpackTarballCompressed(allocator, prog_reader, tmp_directory.handle, std.compress.gzip),779 .@"tar.gz" => try unpackTarballCompressed(allocator, prog_reader, tmp_directory.handle, dep_location_tok, report, std.compress.gzip),
757 .@"tar.xz" => try unpackTarballCompressed(allocator, prog_reader, tmp_directory.handle, std.compress.xz),780 .@"tar.xz" => try unpackTarballCompressed(allocator, prog_reader, tmp_directory.handle, dep_location_tok, report, std.compress.xz),
758 .git_pack => try unpackGitPack(allocator, &prog_reader, git.parseOid(rr.path) catch unreachable, tmp_directory.handle),781 .git_pack => try unpackGitPack(allocator, &prog_reader, git.parseOid(rr.path) catch unreachable, tmp_directory.handle),
759 }782 }
760 } else {783 } else {
...@@ -1128,6 +1151,8 @@ fn unpackTarballCompressed(...@@ -1128,6 +1151,8 @@ fn unpackTarballCompressed(
1128 gpa: Allocator,1151 gpa: Allocator,
1129 reader: anytype,1152 reader: anytype,
1130 out_dir: fs.Dir,1153 out_dir: fs.Dir,
1154 dep_location_tok: std.zig.Ast.TokenIndex,
1155 report: Report,
1131 comptime Compression: type,1156 comptime Compression: type,
1132) !void {1157) !void {
1133 var br = std.io.bufferedReaderSize(std.crypto.tls.max_ciphertext_record_len, reader);1158 var br = std.io.bufferedReaderSize(std.crypto.tls.max_ciphertext_record_len, reader);
...@@ -1135,11 +1160,21 @@ fn unpackTarballCompressed(...@@ -1135,11 +1160,21 @@ fn unpackTarballCompressed(
1135 var decompress = try Compression.decompress(gpa, br.reader());1160 var decompress = try Compression.decompress(gpa, br.reader());
1136 defer decompress.deinit();1161 defer decompress.deinit();
11371162
1138 return unpackTarball(decompress.reader(), out_dir);1163 return unpackTarball(gpa, decompress.reader(), out_dir, dep_location_tok, report);
1139}1164}
11401165
1141fn unpackTarball(reader: anytype, out_dir: fs.Dir) !void {1166fn unpackTarball(
1167 gpa: Allocator,
1168 reader: anytype,
1169 out_dir: fs.Dir,
1170 dep_location_tok: std.zig.Ast.TokenIndex,
1171 report: Report,
1172) !void {
1173 var diagnostics: std.tar.Options.Diagnostics = .{ .allocator = gpa };
1174 defer diagnostics.deinit();
1175
1142 try std.tar.pipeToFileSystem(out_dir, reader, .{1176 try std.tar.pipeToFileSystem(out_dir, reader, .{
1177 .diagnostics = &diagnostics,
1143 .strip_components = 1,1178 .strip_components = 1,
1144 // TODO: we would like to set this to executable_bit_only, but two1179 // TODO: we would like to set this to executable_bit_only, but two
1145 // things need to happen before that:1180 // things need to happen before that:
...@@ -1148,6 +1183,36 @@ fn unpackTarball(reader: anytype, out_dir: fs.Dir) !void {...@@ -1148,6 +1183,36 @@ fn unpackTarball(reader: anytype, out_dir: fs.Dir) !void {
1148 // bit on Windows from the ACLs (see the isExecutable function).1183 // bit on Windows from the ACLs (see the isExecutable function).
1149 .mode_mode = .ignore,1184 .mode_mode = .ignore,
1150 });1185 });
1186
1187 if (diagnostics.errors.items.len > 0) {
1188 const notes_len: u32 = @intCast(diagnostics.errors.items.len);
1189 try report.addErrorWithNotes(notes_len, .{
1190 .tok = dep_location_tok,
1191 .off = 0,
1192 .msg = "unable to unpack tarball",
1193 });
1194 const eb = report.error_bundle;
1195 const notes_start = try eb.reserveNotes(notes_len);
1196 for (diagnostics.errors.items, notes_start..) |item, note_i| {
1197 switch (item) {
1198 .unable_to_create_sym_link => |info| {
1199 eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{
1200 .msg = try eb.printString("unable to create symlink from '{s}' to '{s}': {s}", .{
1201 info.file_name, info.link_name, @errorName(info.code),
1202 }),
1203 }));
1204 },
1205 .unsupported_file_type => |info| {
1206 eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{
1207 .msg = try eb.printString("file '{s}' has unsupported type '{c}'", .{
1208 info.file_name, @intFromEnum(info.file_type),
1209 }),
1210 }));
1211 },
1212 }
1213 }
1214 return error.InvalidTarball;
1215 }
1151}1216}
11521217
1153fn unpackGitPack(1218fn unpackGitPack(
src/main.zig+20-4
...@@ -6610,6 +6610,7 @@ fn cmdFetch(...@@ -6610,6 +6610,7 @@ fn cmdFetch(
6610 arena: Allocator,6610 arena: Allocator,
6611 args: []const []const u8,6611 args: []const []const u8,
6612) !void {6612) !void {
6613 const color: Color = .auto;
6613 var opt_url: ?[]const u8 = null;6614 var opt_url: ?[]const u8 = null;
6614 var override_global_cache_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_GLOBAL_CACHE_DIR");6615 var override_global_cache_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_GLOBAL_CACHE_DIR");
66156616
...@@ -6651,10 +6652,17 @@ fn cmdFetch(...@@ -6651,10 +6652,17 @@ fn cmdFetch(
6651 const root_prog_node = progress.start("Fetch", 0);6652 const root_prog_node = progress.start("Fetch", 0);
6652 defer root_prog_node.end();6653 defer root_prog_node.end();
66536654
6655 var wip_errors: std.zig.ErrorBundle.Wip = undefined;
6656 try wip_errors.init(gpa);
6657 defer wip_errors.deinit();
6658
6654 var report: Package.Report = .{6659 var report: Package.Report = .{
6655 .ast = null,6660 .ast = null,
6656 .directory = undefined,6661 .directory = .{
6657 .error_bundle = undefined,6662 .handle = fs.cwd(),
6663 .path = null,
6664 },
6665 .error_bundle = &wip_errors,
6658 };6666 };
66596667
6660 var global_cache_directory: Compilation.Directory = l: {6668 var global_cache_directory: Compilation.Directory = l: {
...@@ -6697,14 +6705,22 @@ fn cmdFetch(...@@ -6697,14 +6705,22 @@ fn cmdFetch(
6697 };6705 };
6698 defer readable_resource.deinit(gpa);6706 defer readable_resource.deinit(gpa);
66996707
6700 var package_location = try readable_resource.unpack(6708 var package_location = readable_resource.unpack(
6701 gpa,6709 gpa,
6702 &thread_pool,6710 &thread_pool,
6703 global_cache_directory,6711 global_cache_directory,
6704 0,6712 0,
6705 report,6713 report,
6706 root_prog_node,6714 root_prog_node,
6707 );6715 ) catch |err| {
6716 if (wip_errors.root_list.items.len > 0) {
6717 var errors = try wip_errors.toOwnedBundle("");
6718 defer errors.deinit(gpa);
6719 errors.renderToStdErr(renderOptions(color));
6720 process.exit(1);
6721 }
6722 fatal("unable to unpack '{s}': {s}", .{ url, @errorName(err) });
6723 };
6708 defer package_location.deinit(gpa);6724 defer package_location.deinit(gpa);
67096725
6710 const hex_digest = Package.Manifest.hexDigest(package_location.hash);6726 const hex_digest = Package.Manifest.hexDigest(package_location.hash);