authorgravatar for igor.anic@gmail.comIgor Anić <igor.anic@gmail.com> 2024-03-30 22:43:27+01:00
committergravatar for igor.anic@gmail.comIgor Anić <igor.anic@gmail.com> 2024-04-09 15:00:21+02:00
log5a38924a7d41fee0ac5544d9ddb85ce82bc92030
tree63ad1a3f562e0ab1c2dd802aa466b853a79cf89e
parentad60b6c1edfc9ee30cf137fb1d56269e0af0941c

fetch.git: collect file create diagnostic errors

On case insensitive file systems, don't overwrite files with same name in different casing. Add diagnostic error so caller could decide what to do.

2 files changed, 18 insertions(+), 2 deletions(-)

src/Package/Fetch.zig+1
...@@ -1249,6 +1249,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource) anyerror!Unpac...@@ -1249,6 +1249,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource) anyerror!Unpac
1249 try res.rootErrorMessage("unable to unpack packfile");1249 try res.rootErrorMessage("unable to unpack packfile");
1250 for (diagnostics.errors.items) |item| {1250 for (diagnostics.errors.items) |item| {
1251 switch (item) {1251 switch (item) {
1252 .unable_to_create_file => |i| try res.unableToCreateFile(i.file_name, i.code),
1252 .unable_to_create_sym_link => |i| try res.unableToCreateSymLink(i.file_name, i.link_name, i.code),1253 .unable_to_create_sym_link => |i| try res.unableToCreateSymLink(i.file_name, i.link_name, i.code),
1253 }1254 }
1254 }1255 }
src/Package/Fetch/git.zig+17-2
...@@ -46,6 +46,10 @@ pub const Diagnostics = struct {...@@ -46,6 +46,10 @@ pub const Diagnostics = struct {
46 file_name: []const u8,46 file_name: []const u8,
47 link_name: []const u8,47 link_name: []const u8,
48 },48 },
49 unable_to_create_file: struct {
50 code: anyerror,
51 file_name: []const u8,
52 },
49 };53 };
5054
51 pub fn deinit(d: *Diagnostics) void {55 pub fn deinit(d: *Diagnostics) void {
...@@ -55,6 +59,9 @@ pub const Diagnostics = struct {...@@ -55,6 +59,9 @@ pub const Diagnostics = struct {
55 d.allocator.free(info.file_name);59 d.allocator.free(info.file_name);
56 d.allocator.free(info.link_name);60 d.allocator.free(info.link_name);
57 },61 },
62 .unable_to_create_file => |info| {
63 d.allocator.free(info.file_name);
64 },
58 }65 }
59 }66 }
60 d.errors.deinit(d.allocator);67 d.errors.deinit(d.allocator);
...@@ -119,11 +126,19 @@ pub const Repository = struct {...@@ -119,11 +126,19 @@ pub const Repository = struct {
119 try repository.checkoutTree(subdir, entry.oid, sub_path, diagnostics);126 try repository.checkoutTree(subdir, entry.oid, sub_path, diagnostics);
120 },127 },
121 .file => {128 .file => {
122 var file = try dir.createFile(entry.name, .{});
123 defer file.close();
124 try repository.odb.seekOid(entry.oid);129 try repository.odb.seekOid(entry.oid);
125 const file_object = try repository.odb.readObject();130 const file_object = try repository.odb.readObject();
126 if (file_object.type != .blob) return error.InvalidFile;131 if (file_object.type != .blob) return error.InvalidFile;
132 var file = dir.createFile(entry.name, .{ .exclusive = true }) catch |e| {
133 const file_name = try std.fs.path.join(diagnostics.allocator, &.{ current_path, entry.name });
134 errdefer diagnostics.allocator.free(file_name);
135 try diagnostics.errors.append(diagnostics.allocator, .{ .unable_to_create_file = .{
136 .code = e,
137 .file_name = file_name,
138 } });
139 continue;
140 };
141 defer file.close();
127 try file.writeAll(file_object.data);142 try file.writeAll(file_object.data);
128 try file.sync();143 try file.sync();
129 },144 },