| ... | ... | @@ -1189,38 +1189,17 @@ fn unpackTarball(f: *Fetch, out_dir: fs.Dir, reader: anytype) RunError!?[]const |
| 1189 | 1189 | )); |
| 1190 | 1190 | |
| 1191 | 1191 | if (diagnostics.errors.items.len > 0) { |
| 1192 | | const notes_len: u32 = @intCast(diagnostics.errors.items.len); |
| 1193 | | try eb.addRootErrorMessage(.{ |
| 1194 | | .msg = try eb.addString("unable to unpack tarball"), |
| 1195 | | .src_loc = try f.srcLoc(f.location_tok), |
| 1196 | | .notes_len = notes_len, |
| 1197 | | }); |
| 1198 | | const notes_start = try eb.reserveNotes(notes_len); |
| 1199 | | for (diagnostics.errors.items, notes_start..) |item, note_i| { |
| 1192 | var res = UnpackResult.init(gpa); |
| 1193 | defer res.deinit(); |
| 1194 | |
| 1195 | for (diagnostics.errors.items) |item| { |
| 1200 | 1196 | switch (item) { |
| 1201 | | .unable_to_create_sym_link => |info| { |
| 1202 | | eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{ |
| 1203 | | .msg = try eb.printString("unable to create symlink from '{s}' to '{s}': {s}", .{ |
| 1204 | | info.file_name, info.link_name, @errorName(info.code), |
| 1205 | | }), |
| 1206 | | })); |
| 1207 | | }, |
| 1208 | | .unable_to_create_file => |info| { |
| 1209 | | eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{ |
| 1210 | | .msg = try eb.printString("unable to create file '{s}': {s}", .{ |
| 1211 | | info.file_name, @errorName(info.code), |
| 1212 | | }), |
| 1213 | | })); |
| 1214 | | }, |
| 1215 | | .unsupported_file_type => |info| { |
| 1216 | | eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{ |
| 1217 | | .msg = try eb.printString("file '{s}' has unsupported type '{c}'", .{ |
| 1218 | | info.file_name, @intFromEnum(info.file_type), |
| 1219 | | }), |
| 1220 | | })); |
| 1221 | | }, |
| 1197 | .unable_to_create_file => |i| try res.createFile(i.file_name, i.code), |
| 1198 | .unable_to_create_sym_link => |i| try res.symLink(i.file_name, i.link_name, i.code), |
| 1199 | .unsupported_file_type => |i| try res.unsupportedFileType(i.file_name, @intFromEnum(i.file_type)), |
| 1222 | 1200 | } |
| 1223 | 1201 | } |
| 1202 | try res.bundleErrors(eb, "unable to unpack tarball", try f.srcLoc(f.location_tok)); |
| 1224 | 1203 | return error.FetchFailed; |
| 1225 | 1204 | } |
| 1226 | 1205 | |
| ... | ... | @@ -1270,24 +1249,16 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource) anyerror!void |
| 1270 | 1249 | try repository.checkout(out_dir, want_oid, &diagnostics); |
| 1271 | 1250 | |
| 1272 | 1251 | if (diagnostics.errors.items.len > 0) { |
| 1273 | | const notes_len: u32 = @intCast(diagnostics.errors.items.len); |
| 1274 | | try eb.addRootErrorMessage(.{ |
| 1275 | | .msg = try eb.addString("unable to unpack packfile"), |
| 1276 | | .src_loc = try f.srcLoc(f.location_tok), |
| 1277 | | .notes_len = notes_len, |
| 1278 | | }); |
| 1279 | | const notes_start = try eb.reserveNotes(notes_len); |
| 1280 | | for (diagnostics.errors.items, notes_start..) |item, note_i| { |
| 1252 | var res = UnpackResult.init(gpa); |
| 1253 | defer res.deinit(); |
| 1254 | |
| 1255 | for (diagnostics.errors.items) |item| { |
| 1281 | 1256 | switch (item) { |
| 1282 | | .unable_to_create_sym_link => |info| { |
| 1283 | | eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{ |
| 1284 | | .msg = try eb.printString("unable to create symlink from '{s}' to '{s}': {s}", .{ |
| 1285 | | info.file_name, info.link_name, @errorName(info.code), |
| 1286 | | }), |
| 1287 | | })); |
| 1288 | | }, |
| 1257 | .unable_to_create_sym_link => |i| try res.symLink(i.file_name, i.link_name, i.code), |
| 1289 | 1258 | } |
| 1290 | 1259 | } |
| 1260 | try res.bundleErrors(eb, "unable to unpack packfile", try f.srcLoc(f.location_tok)); |
| 1261 | |
| 1291 | 1262 | return error.InvalidGitPack; |
| 1292 | 1263 | } |
| 1293 | 1264 | } |
| ... | ... | @@ -1779,6 +1750,140 @@ test FileHeader { |
| 1779 | 1750 | try std.testing.expect(h.isExecutable()); |
| 1780 | 1751 | } |
| 1781 | 1752 | |
| 1753 | const UnpackResult = struct { |
| 1754 | allocator: std.mem.Allocator, |
| 1755 | errors: std.ArrayListUnmanaged(Error) = .{}, |
| 1756 | |
| 1757 | const Error = union(enum) { |
| 1758 | unable_to_create_sym_link: struct { |
| 1759 | code: anyerror, |
| 1760 | file_name: []const u8, |
| 1761 | link_name: []const u8, |
| 1762 | }, |
| 1763 | unable_to_create_file: struct { |
| 1764 | code: anyerror, |
| 1765 | file_name: []const u8, |
| 1766 | }, |
| 1767 | unsupported_file_type: struct { |
| 1768 | file_name: []const u8, |
| 1769 | file_type: u8, |
| 1770 | }, |
| 1771 | |
| 1772 | fn excluded(self: Error, filter: Filter) bool { |
| 1773 | switch (self) { |
| 1774 | .unable_to_create_file => |info| return !filter.includePath(info.file_name), |
| 1775 | .unable_to_create_sym_link => |info| return !filter.includePath(info.file_name), |
| 1776 | .unsupported_file_type => |info| return !filter.includePath(info.file_name), |
| 1777 | } |
| 1778 | } |
| 1779 | |
| 1780 | fn free(self: Error, allocator: std.mem.Allocator) void { |
| 1781 | switch (self) { |
| 1782 | .unable_to_create_sym_link => |info| { |
| 1783 | allocator.free(info.file_name); |
| 1784 | allocator.free(info.link_name); |
| 1785 | }, |
| 1786 | .unable_to_create_file => |info| { |
| 1787 | allocator.free(info.file_name); |
| 1788 | }, |
| 1789 | .unsupported_file_type => |info| { |
| 1790 | allocator.free(info.file_name); |
| 1791 | }, |
| 1792 | } |
| 1793 | } |
| 1794 | }; |
| 1795 | |
| 1796 | fn init(allocator: std.mem.Allocator) UnpackResult { |
| 1797 | return .{ .allocator = allocator }; |
| 1798 | } |
| 1799 | |
| 1800 | fn deinit(self: *UnpackResult) void { |
| 1801 | for (self.errors.items) |item| { |
| 1802 | item.free(self.allocator); |
| 1803 | } |
| 1804 | self.errors.deinit(self.allocator); |
| 1805 | self.* = undefined; |
| 1806 | } |
| 1807 | |
| 1808 | fn hasErrors(self: *UnpackResult) bool { |
| 1809 | return self.errors.items.len > 0; |
| 1810 | } |
| 1811 | |
| 1812 | fn createFile(self: *UnpackResult, file_name: []const u8, err: anyerror) !void { |
| 1813 | try self.errors.append(self.allocator, .{ .unable_to_create_file = .{ |
| 1814 | .code = err, |
| 1815 | .file_name = try self.allocator.dupe(u8, file_name), |
| 1816 | } }); |
| 1817 | } |
| 1818 | |
| 1819 | fn symLink(self: *UnpackResult, file_name: []const u8, link_name: []const u8, err: anyerror) !void { |
| 1820 | try self.errors.append(self.allocator, .{ .unable_to_create_sym_link = .{ |
| 1821 | .code = err, |
| 1822 | .file_name = try self.allocator.dupe(u8, file_name), |
| 1823 | .link_name = try self.allocator.dupe(u8, link_name), |
| 1824 | } }); |
| 1825 | } |
| 1826 | |
| 1827 | fn unsupportedFileType(self: *UnpackResult, file_name: []const u8, file_type: u8) !void { |
| 1828 | try self.errors.append(self.allocator, .{ .unsupported_file_type = .{ |
| 1829 | .file_name = try self.allocator.dupe(u8, file_name), |
| 1830 | .file_type = file_type, |
| 1831 | } }); |
| 1832 | } |
| 1833 | |
| 1834 | fn filterErrors(self: *UnpackResult, filter: Filter) !void { |
| 1835 | var i = self.errors.items.len; |
| 1836 | while (i > 0) { |
| 1837 | i -= 1; |
| 1838 | const item = self.errors.items[i]; |
| 1839 | if (item.excluded(filter)) { |
| 1840 | _ = self.errors.swapRemove(i); |
| 1841 | item.free(self.allocator); |
| 1842 | } |
| 1843 | } |
| 1844 | } |
| 1845 | |
| 1846 | fn bundleErrors( |
| 1847 | self: *UnpackResult, |
| 1848 | eb: *ErrorBundle.Wip, |
| 1849 | msg: []const u8, |
| 1850 | src_loc: ErrorBundle.SourceLocationIndex, |
| 1851 | ) !void { |
| 1852 | const notes_len: u32 = @intCast(self.errors.items.len); |
| 1853 | try eb.addRootErrorMessage(.{ |
| 1854 | .msg = try eb.addString(msg), |
| 1855 | .src_loc = src_loc, |
| 1856 | .notes_len = notes_len, |
| 1857 | }); |
| 1858 | const notes_start = try eb.reserveNotes(notes_len); |
| 1859 | for (self.errors.items, notes_start..) |item, note_i| { |
| 1860 | switch (item) { |
| 1861 | .unable_to_create_sym_link => |info| { |
| 1862 | eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{ |
| 1863 | .msg = try eb.printString("unable to create symlink from '{s}' to '{s}': {s}", .{ |
| 1864 | info.file_name, info.link_name, @errorName(info.code), |
| 1865 | }), |
| 1866 | })); |
| 1867 | }, |
| 1868 | .unable_to_create_file => |info| { |
| 1869 | eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{ |
| 1870 | .msg = try eb.printString("unable to create file '{s}': {s}", .{ |
| 1871 | info.file_name, @errorName(info.code), |
| 1872 | }), |
| 1873 | })); |
| 1874 | }, |
| 1875 | .unsupported_file_type => |info| { |
| 1876 | eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{ |
| 1877 | .msg = try eb.printString("file '{s}' has unsupported type '{c}'", .{ |
| 1878 | info.file_name, info.file_type, |
| 1879 | }), |
| 1880 | })); |
| 1881 | }, |
| 1882 | } |
| 1883 | } |
| 1884 | } |
| 1885 | }; |
| 1886 | |
| 1782 | 1887 | // Removing dependencies |
| 1783 | 1888 | const Package = struct { |
| 1784 | 1889 | const build_zig_basename = "build.zig"; |