diff --git a/build.zig b/build.zig index d41b47ab7..4e96a5bbf 100644 --- a/build.zig +++ b/build.zig @@ -105,4 +105,11 @@ pub fn build(b: *std.Build) !void { test_step.dependOn(&test_run.step); } } + + // update-translations does what it sounds like and updates the "pot" + // files. These should be committed to the repo. + { + const step = b.step("update-translations", "Update translation files"); + step.dependOn(i18n.update_step); + } } diff --git a/src/apprt/gtk/i18n.zig b/src/apprt/gtk/i18n.zig index 4417796a7..630d150a6 100644 --- a/src/apprt/gtk/i18n.zig +++ b/src/apprt/gtk/i18n.zig @@ -9,7 +9,7 @@ const std = @import("std"); const global = &@import("../../global.zig").state; const build_config = @import("../../build_config.zig"); -const log = std.log.scoped(.i18n); +const log = std.log.scoped(.gtk_i18n); pub fn init(alloc: std.mem.Allocator) !void { const resources_dir = global.resources_dir orelse { diff --git a/src/build/GhosttyI18n.zig b/src/build/GhosttyI18n.zig index db48c12dc..5ca564268 100644 --- a/src/build/GhosttyI18n.zig +++ b/src/build/GhosttyI18n.zig @@ -13,28 +13,33 @@ const locales = [_][]const u8{ owner: *std.Build, steps: []*std.Build.Step, +/// This step updates the translation files on disk that should be +/// committed to the repo. +update_step: *std.Build.Step, + pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n { var steps = std.ArrayList(*std.Build.Step).init(b.allocator); - errdefer steps.deinit(); - - try addUpdateStep(b); + defer steps.deinit(); if (cfg.app_runtime == .gtk) { // Output the .mo files used by the GTK apprt inline for (locales) |locale| { const msgfmt = b.addSystemCommand(&.{ "msgfmt", "-o", "-" }); - msgfmt.addFileArg(b.path("po/" ++ locale ++ ".po")); try steps.append(&b.addInstallFile( msgfmt.captureStdOut(), - std.fmt.comptimePrint("share/locale/{s}/LC_MESSAGES/{s}.mo", .{ locale, domain }), + std.fmt.comptimePrint( + "share/locale/{s}/LC_MESSAGES/{s}.mo", + .{ locale, domain }, + ), ).step); } } return .{ .owner = b, + .update_step = try createUpdateStep(b), .steps = try steps.toOwnedSlice(), }; } @@ -43,9 +48,7 @@ pub fn install(self: *const GhosttyI18n) void { for (self.steps) |step| self.owner.getInstallStep().dependOn(step); } -fn addUpdateStep(b: *std.Build) !void { - const pot_step = b.step("update-translations", "Update translation files"); - +fn createUpdateStep(b: *std.Build) !*std.Build.Step { const xgettext = b.addSystemCommand(&.{ "xgettext", "--language=C", // Silence the "unknown extension" errors @@ -60,43 +63,56 @@ fn addUpdateStep(b: *std.Build) !void { "-", }); + // Not cacheable due to the gresource files + xgettext.has_side_effects = true; + inline for (gresource.blueprint_files) |blp| { // We avoid using addFileArg here since the full, absolute file path // would be added to the file as its location, which differs for // everyone's checkout of the repository. // This comes at a cost of losing per-file caching, of course. - xgettext.addArg(std.fmt.comptimePrint("src/apprt/gtk/ui/{[major]}.{[minor]}/{[name]s}.blp", blp)); + xgettext.addArg(std.fmt.comptimePrint( + "src/apprt/gtk/ui/{[major]}.{[minor]}/{[name]s}.blp", + blp, + )); } - var gtk_files = try b.build_root.handle.openDir("src/apprt/gtk", .{ .iterate = true }); - defer gtk_files.close(); + { + var gtk_files = try b.build_root.handle.openDir( + "src/apprt/gtk", + .{ .iterate = true }, + ); + defer gtk_files.close(); - var walk = try gtk_files.walk(b.allocator); - defer walk.deinit(); + var walk = try gtk_files.walk(b.allocator); + defer walk.deinit(); + while (try walk.next()) |src| { + switch (src.kind) { + .file => if (!std.mem.endsWith( + u8, + src.basename, + ".zig", + )) continue, - while (try walk.next()) |src| { - switch (src.kind) { - .file => if (!std.mem.endsWith(u8, src.basename, ".zig")) continue, - else => continue, + else => continue, + } + + xgettext.addArg((b.pathJoin(&.{ "src/apprt/gtk", src.path }))); } - xgettext.addArg((b.pathJoin(&.{ "src/apprt/gtk", src.path }))); } - // Don't make Zig cache it - xgettext.has_side_effects = true; - - const new_pot = xgettext.captureStdOut(); - const wf = b.addWriteFiles(); - wf.addCopyFileToSource(new_pot, "po/" ++ domain ++ ".pot"); + wf.addCopyFileToSource( + xgettext.captureStdOut(), + "po/" ++ domain ++ ".pot", + ); inline for (locales) |locale| { const msgmerge = b.addSystemCommand(&.{ "msgmerge", "-q" }); msgmerge.addFileArg(b.path("po/" ++ locale ++ ".po")); msgmerge.addFileArg(xgettext.captureStdOut()); - wf.addCopyFileToSource(msgmerge.captureStdOut(), "po/" ++ locale ++ ".po"); } - pot_step.dependOn(&wf.step); + return &wf.step; }