Skip to content

Commit 9cfac47

Browse files
ianicandrewrk
authored andcommitted
fetch: combine unpack error validation in a single function
Follow up of: #19500 [discussion](#19500 (comment))
1 parent 0ac15b9 commit 9cfac47

File tree

1 file changed

+46
-49
lines changed

1 file changed

+46
-49
lines changed

src/Package/Fetch.zig

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,45 +1802,25 @@ const UnpackResult = struct {
18021802
}
18031803

18041804
fn validate(self: *UnpackResult, f: *Fetch, filter: Filter) !void {
1805-
self.filterErrors(filter);
1806-
if (self.hasErrors()) {
1807-
const eb = &f.error_bundle;
1808-
try self.bundleErrors(eb, try f.srcLoc(f.location_tok));
1809-
return error.FetchFailed;
1810-
}
1811-
}
1805+
if (self.errors_count == 0) return;
18121806

1813-
// Filter errors by manifest inclusion rules.
1814-
fn filterErrors(self: *UnpackResult, filter: Filter) void {
1815-
var i = self.errors_count;
1816-
while (i > 0) {
1817-
i -= 1;
1818-
if (self.errors[i].excluded(filter)) {
1819-
self.errors_count -= 1;
1820-
const tmp = self.errors[i];
1821-
self.errors[i] = self.errors[self.errors_count];
1822-
self.errors[self.errors_count] = tmp;
1823-
}
1807+
var unfiltered_errors: u32 = 0;
1808+
for (self.errors) |item| {
1809+
if (item.excluded(filter)) continue;
1810+
unfiltered_errors += 1;
18241811
}
1825-
}
1826-
1827-
// Emmit errors to an `ErrorBundle`.
1828-
fn bundleErrors(
1829-
self: *UnpackResult,
1830-
eb: *ErrorBundle.Wip,
1831-
src_loc: ErrorBundle.SourceLocationIndex,
1832-
) !void {
1833-
if (self.errors_count == 0 and self.root_error_message.len == 0)
1834-
return;
1812+
if (unfiltered_errors == 0) return;
18351813

1836-
const notes_len: u32 = @intCast(self.errors_count);
1814+
// Emmit errors to an `ErrorBundle`.
1815+
const eb = &f.error_bundle;
18371816
try eb.addRootErrorMessage(.{
18381817
.msg = try eb.addString(self.root_error_message),
1839-
.src_loc = src_loc,
1840-
.notes_len = notes_len,
1818+
.src_loc = try f.srcLoc(f.location_tok),
1819+
.notes_len = unfiltered_errors,
18411820
});
1842-
const notes_start = try eb.reserveNotes(notes_len);
1843-
for (self.errors, notes_start..) |item, note_i| {
1821+
var note_i: u32 = try eb.reserveNotes(unfiltered_errors);
1822+
for (self.errors) |item| {
1823+
if (item.excluded(filter)) continue;
18441824
switch (item) {
18451825
.unable_to_create_sym_link => |info| {
18461826
eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{
@@ -1864,37 +1844,54 @@ const UnpackResult = struct {
18641844
}));
18651845
},
18661846
}
1847+
note_i += 1;
18671848
}
1849+
1850+
return error.FetchFailed;
18681851
}
18691852

1870-
test filterErrors {
1871-
var arena_instance = std.heap.ArenaAllocator.init(std.testing.allocator);
1853+
test validate {
1854+
const gpa = std.testing.allocator;
1855+
var arena_instance = std.heap.ArenaAllocator.init(gpa);
18721856
defer arena_instance.deinit();
18731857
const arena = arena_instance.allocator();
18741858

1875-
// init
1859+
// fill UnpackResult with errors
18761860
var res: UnpackResult = .{};
1877-
try res.allocErrors(arena, 4, "error");
1861+
try res.allocErrors(arena, 4, "unable to unpack");
18781862
try std.testing.expectEqual(0, res.errors_count);
1879-
1880-
// create errors
18811863
res.unableToCreateFile("dir1/file1", error.File1);
1882-
res.unableToCreateSymLink("dir2/file2", "", error.File2);
1864+
res.unableToCreateSymLink("dir2/file2", "filename", error.SymlinkError);
18831865
res.unableToCreateFile("dir1/file3", error.File3);
18841866
res.unsupportedFileType("dir2/file4", 'x');
18851867
try std.testing.expectEqual(4, res.errors_count);
18861868

1887-
// filter errors
1869+
// create filter, includes dir2, excludes dir1
18881870
var filter: Filter = .{};
18891871
try filter.include_paths.put(arena, "dir2", {});
1890-
res.filterErrors(filter);
1891-
1892-
try std.testing.expectEqual(2, res.errors_count);
1893-
try std.testing.expect(res.errors[0] == Error.unsupported_file_type);
1894-
try std.testing.expect(res.errors[1] == Error.unable_to_create_sym_link);
1895-
// filtered: moved to the list end
1896-
try std.testing.expect(res.errors[2] == Error.unable_to_create_file);
1897-
try std.testing.expect(res.errors[3] == Error.unable_to_create_file);
1872+
1873+
// init Fetch
1874+
var fetch: Fetch = undefined;
1875+
fetch.parent_manifest_ast = null;
1876+
fetch.location_tok = 0;
1877+
try fetch.error_bundle.init(gpa);
1878+
defer fetch.error_bundle.deinit();
1879+
1880+
// validate errors with filter
1881+
try std.testing.expectError(error.FetchFailed, res.validate(&fetch, filter));
1882+
1883+
// output errors to string
1884+
var errors = try fetch.error_bundle.toOwnedBundle("");
1885+
defer errors.deinit(gpa);
1886+
var out = std.ArrayList(u8).init(gpa);
1887+
defer out.deinit();
1888+
try errors.renderToWriter(.{ .ttyconf = .no_color }, out.writer());
1889+
try std.testing.expectEqualStrings(
1890+
\\error: unable to unpack
1891+
\\ note: unable to create symlink from 'dir2/file2' to 'filename': SymlinkError
1892+
\\ note: file 'dir2/file4' has unsupported type 'x'
1893+
\\
1894+
, out.items);
18981895
}
18991896
};
19001897

0 commit comments

Comments
 (0)