about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/fs.zig81
-rw-r--r--src/gen.zig2
2 files changed, 47 insertions, 36 deletions
diff --git a/src/fs.zig b/src/fs.zig
index d14d7b0..4a3b049 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -48,33 +48,6 @@ pub const FileSwapper = struct {
         return self.tmp.writer(buffer);
     }
 
-    pub fn diff(self: FileSwapper) !bool {
-        var target_found = true;
-        std.fs.cwd().access(self.target_path, .{}) catch |e| switch (e) {
-            error.FileNotFound => target_found = false,
-            else => |err| return err,
-        };
-
-        // exit early if target_path was not found
-        if (!target_found) return error.TargetNotFound;
-
-        var p = std.process.Child.init(&.{
-            "diff",
-            "-q",
-            self.tmp_path,
-            self.target_path,
-        }, std.heap.page_allocator);
-        try p.spawn();
-        switch (try p.wait()) {
-            .Exited => |exit_code| switch (exit_code) {
-                0 => return false,
-                1 => return true,
-                else => return error.UnknownDiffError,
-            },
-            else => return error.UnknownDiffError,
-        }
-    }
-
     pub fn swap(self: FileSwapper) !void {
         std.log.debug("swapping {s} -> {s}", .{ self.tmp_path, self.target_path });
 
@@ -92,20 +65,30 @@ pub const FileSwapper = struct {
         );
     }
 
-    pub fn undo(self: FileSwapper) !void {
-        try std.posix.unlink(self.tmp_path);
-    }
-
     pub fn close(self: FileSwapper) void {
         var found = true;
         std.fs.cwd().access(self.tmp_path, .{}) catch |e| switch (e) {
             error.FileNotFound => found = false,
             else => @panic("access tmp path"),
         };
-        if (found) self.swap() catch @panic("failed to swap target file");
 
-        self.allocator.free(self.tmp_path);
-        self.tmp.close();
+        defer self.allocator.free(self.tmp_path);
+        defer self.allocator.destroy(self.swapped);
+        defer self.tmp.close();
+
+        if (found) {
+            const changed = diff(self.tmp_path, self.target_path) catch
+                @panic("failed to diff tmp and target file");
+
+            if (changed) {
+                self.swap() catch
+                    @panic("failed to swap target file");
+            } else {
+                log.debug("{s} no changes, skipping", .{ self.target_path });
+                std.posix.unlink(self.tmp_path) catch
+                    @panic("failed to cleanup tmp file");
+            }
+        }
     }
 };
 
@@ -218,3 +201,33 @@ pub fn formatTimespec(alloc: std.mem.Allocator, timespec: std.posix.timespec, fm
     }
     return try alloc.realloc(mtime_str, rc);
 }
+
+pub fn diff(a: []const u8, b: []const u8) !bool {
+    std.fs.cwd().access(a, .{}) catch |e| switch (e) {
+        error.FileNotFound => return true,
+        else => return e,
+    };
+    std.fs.cwd().access(b, .{}) catch |e| switch (e) {
+        error.FileNotFound => return true,
+        else => return e,
+    };
+
+    var p = std.process.Child.init(&.{
+        "diff",
+        "-q",
+        a,
+        b,
+    }, std.heap.page_allocator);
+    p.stdin_behavior = .Close;
+    p.stderr_behavior = .Ignore;
+    p.stdout_behavior = .Ignore;
+    try p.spawn();
+    switch (try p.wait()) {
+        .Exited => |exit_code| switch (exit_code) {
+            0 => return false,
+            1 => return true,
+            else => return error.UnknownDiffError,
+        },
+        else => return error.UnknownDiffError,
+    }
+}
diff --git a/src/gen.zig b/src/gen.zig
index ebd0bdb..fdd33bf 100644
--- a/src/gen.zig
+++ b/src/gen.zig
@@ -72,8 +72,6 @@ fn genIndex(ctx: *Context) !void {
     );
 
     try w.interface.flush();
-
-    if (!try f.diff()) try f.undo();
 }
 
 fn genSite(ctx: *Context) !void {