diff options
| author | Robert Günzler <r@gnzler.io> | 2025-10-17 22:51:16 +0200 |
|---|---|---|
| committer | Robert Günzler <r@gnzler.io> | 2025-10-18 00:01:46 +0200 |
| commit | 973e5fdb82e0037ba5fc2ff74cf40d32a0e3466b (patch) | |
| tree | 62ec670e836b1e69081c9889fffab4b551de6528 /src | |
| parent | 55efe8b67b850b34c1483ab3be0947d80508a893 (diff) | |
| download | site-973e5fdb82e0037ba5fc2ff74cf40d32a0e3466b.tar.gz | |
get mtime from git
but fallback to mtime anyway Signed-off-by: Robert Günzler <r@gnzler.io>
Diffstat (limited to 'src')
| -rw-r--r-- | src/exe.zig | 4 | ||||
| -rw-r--r-- | src/fs.zig | 29 | ||||
| -rw-r--r-- | src/gen.zig | 4 |
3 files changed, 31 insertions, 6 deletions
diff --git a/src/exe.zig b/src/exe.zig index e0cb7ef..ae5cfdd 100644 --- a/src/exe.zig +++ b/src/exe.zig @@ -37,8 +37,8 @@ fn pandocWorker(ctx: *Context, page: []const u8) !void { defer ctx.allocator().free(target_path); // get mtime of the source document - const mtime = try fs.getMtime(source_path); - const mtime_str = try fs.formatMtime(ctx.allocator(), mtime, "%s"); + const mtime = try (fs.getGitTime(source_path) catch fs.getMtime(source_path)); + const mtime_str = try fs.formatTimespec(ctx.allocator(), mtime, "%s"); defer ctx.allocator().free(mtime_str); const f = try fs.FileSwapper.createAt(ctx.allocator(), target_path); diff --git a/src/fs.zig b/src/fs.zig index 53acc07..045db89 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -1,7 +1,9 @@ const std = @import("std"); const c = @cImport({ + @cInclude("stdlib.h"); @cInclude("time.h"); }); +const exe = @import("exe.zig"); const log = std.log.scoped(.fs); @@ -141,6 +143,29 @@ pub fn joinPathAndFilename(alloc: std.mem.Allocator, paths: []const []const u8, return try std.fs.path.join(alloc, paths2); } +pub fn getGitTime(path: []const u8) !std.posix.timespec { + var buf = std.mem.zeroes([12]u8); + + var p = std.process.Child.init( + &.{ "git", "log", "-1", "--pretty=format:%at", "-z", "--", path }, + std.heap.page_allocator, + ); + p.stdout_behavior = .Pipe; + try p.spawn(); + _ = try p.stdout.?.readAll(&buf); + const result = try p.wait(); + std.debug.assert(result == .Exited and result.Exited == 0); + + // parse result as ulong + const gitAuthorDate: c_ulong = c.strtoul(&buf, null, 10); + + // calculate timespec + return .{ + .sec = std.math.cast(isize, gitAuthorDate) orelse std.math.maxInt(isize), + .nsec = 0, + }; +} + pub fn getMtime(path: []const u8) !std.posix.timespec { const fd = try std.fs.cwd().openFile(path, .{ .mode = .read_only }); defer fd.close(); @@ -155,10 +180,10 @@ pub fn getMtime(path: []const u8) !std.posix.timespec { } // use libc strftime to format time string -pub fn formatMtime(alloc: std.mem.Allocator, mtime: std.posix.timespec, fmt: [*c]const u8) ![]const u8 { +pub fn formatTimespec(alloc: std.mem.Allocator, timespec: std.posix.timespec, fmt: [*c]const u8) ![]const u8 { const mtime_str = try alloc.alloc(u8, std.os.linux.PATH_MAX); var tm: c.struct_tm = undefined; - _ = c.localtime_r(&mtime.sec, &tm); + _ = c.localtime_r(×pec.sec, &tm); const rc = c.strftime( mtime_str.ptr, mtime_str.len, diff --git a/src/gen.zig b/src/gen.zig index 96c31a3..3e5fa9b 100644 --- a/src/gen.zig +++ b/src/gen.zig @@ -111,8 +111,8 @@ fn genSite(ctx: *Context) !void { // build a single html file fn build(allocator: std.mem.Allocator, w: std.io.AnyWriter, page_name: []const u8, srcpath: []const u8) !void { - const mtime = try fs.getMtime(srcpath); - const mtime_str = try fs.formatMtime(allocator, mtime, "%F"); + const mtime = try (fs.getGitTime(srcpath) catch fs.getMtime(srcpath)); + const mtime_str = try fs.formatTimespec(allocator, mtime, "%F"); defer allocator.free(mtime_str); // HEAD |