Commit 5a38924a7d

Igor Anić <igor.anic@gmail.com>
2024-03-30 22:43:27
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.
1 parent ad60b6c
Changed files (2)
src
Package
src/Package/Fetch/git.zig
@@ -46,6 +46,10 @@ pub const Diagnostics = struct {
             file_name: []const u8,
             link_name: []const u8,
         },
+        unable_to_create_file: struct {
+            code: anyerror,
+            file_name: []const u8,
+        },
     };
 
     pub fn deinit(d: *Diagnostics) void {
@@ -55,6 +59,9 @@ pub const Diagnostics = struct {
                     d.allocator.free(info.file_name);
                     d.allocator.free(info.link_name);
                 },
+                .unable_to_create_file => |info| {
+                    d.allocator.free(info.file_name);
+                },
             }
         }
         d.errors.deinit(d.allocator);
@@ -119,11 +126,19 @@ pub const Repository = struct {
                     try repository.checkoutTree(subdir, entry.oid, sub_path, diagnostics);
                 },
                 .file => {
-                    var file = try dir.createFile(entry.name, .{});
-                    defer file.close();
                     try repository.odb.seekOid(entry.oid);
                     const file_object = try repository.odb.readObject();
                     if (file_object.type != .blob) return error.InvalidFile;
+                    var file = dir.createFile(entry.name, .{ .exclusive = true }) catch |e| {
+                        const file_name = try std.fs.path.join(diagnostics.allocator, &.{ current_path, entry.name });
+                        errdefer diagnostics.allocator.free(file_name);
+                        try diagnostics.errors.append(diagnostics.allocator, .{ .unable_to_create_file = .{
+                            .code = e,
+                            .file_name = file_name,
+                        } });
+                        continue;
+                    };
+                    defer file.close();
                     try file.writeAll(file_object.data);
                     try file.sync();
                 },
src/Package/Fetch.zig
@@ -1249,6 +1249,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource) anyerror!Unpac
                 try res.rootErrorMessage("unable to unpack packfile");
                 for (diagnostics.errors.items) |item| {
                     switch (item) {
+                        .unable_to_create_file => |i| try res.unableToCreateFile(i.file_name, i.code),
                         .unable_to_create_sym_link => |i| try res.unableToCreateSymLink(i.file_name, i.link_name, i.code),
                     }
                 }