build: some style changes, namely we should create steps only in root

This commit is contained in:
Mitchell Hashimoto
2025-02-27 12:33:24 -08:00
committed by Leah Amelia Chen
parent e252932bde
commit 6b1a017a86
3 changed files with 50 additions and 27 deletions

View File

@ -105,4 +105,11 @@ pub fn build(b: *std.Build) !void {
test_step.dependOn(&test_run.step); 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);
}
} }

View File

@ -9,7 +9,7 @@ const std = @import("std");
const global = &@import("../../global.zig").state; const global = &@import("../../global.zig").state;
const build_config = @import("../../build_config.zig"); 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 { pub fn init(alloc: std.mem.Allocator) !void {
const resources_dir = global.resources_dir orelse { const resources_dir = global.resources_dir orelse {

View File

@ -13,28 +13,33 @@ const locales = [_][]const u8{
owner: *std.Build, owner: *std.Build,
steps: []*std.Build.Step, 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 { pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n {
var steps = std.ArrayList(*std.Build.Step).init(b.allocator); var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
errdefer steps.deinit(); defer steps.deinit();
try addUpdateStep(b);
if (cfg.app_runtime == .gtk) { if (cfg.app_runtime == .gtk) {
// Output the .mo files used by the GTK apprt // Output the .mo files used by the GTK apprt
inline for (locales) |locale| { inline for (locales) |locale| {
const msgfmt = b.addSystemCommand(&.{ "msgfmt", "-o", "-" }); const msgfmt = b.addSystemCommand(&.{ "msgfmt", "-o", "-" });
msgfmt.addFileArg(b.path("po/" ++ locale ++ ".po")); msgfmt.addFileArg(b.path("po/" ++ locale ++ ".po"));
try steps.append(&b.addInstallFile( try steps.append(&b.addInstallFile(
msgfmt.captureStdOut(), 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); ).step);
} }
} }
return .{ return .{
.owner = b, .owner = b,
.update_step = try createUpdateStep(b),
.steps = try steps.toOwnedSlice(), .steps = try steps.toOwnedSlice(),
}; };
} }
@ -43,9 +48,7 @@ pub fn install(self: *const GhosttyI18n) void {
for (self.steps) |step| self.owner.getInstallStep().dependOn(step); for (self.steps) |step| self.owner.getInstallStep().dependOn(step);
} }
fn addUpdateStep(b: *std.Build) !void { fn createUpdateStep(b: *std.Build) !*std.Build.Step {
const pot_step = b.step("update-translations", "Update translation files");
const xgettext = b.addSystemCommand(&.{ const xgettext = b.addSystemCommand(&.{
"xgettext", "xgettext",
"--language=C", // Silence the "unknown extension" errors "--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| { inline for (gresource.blueprint_files) |blp| {
// We avoid using addFileArg here since the full, absolute file path // We avoid using addFileArg here since the full, absolute file path
// would be added to the file as its location, which differs for // would be added to the file as its location, which differs for
// everyone's checkout of the repository. // everyone's checkout of the repository.
// This comes at a cost of losing per-file caching, of course. // 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 }); {
var gtk_files = try b.build_root.handle.openDir(
"src/apprt/gtk",
.{ .iterate = true },
);
defer gtk_files.close(); defer gtk_files.close();
var walk = try gtk_files.walk(b.allocator); var walk = try gtk_files.walk(b.allocator);
defer walk.deinit(); defer walk.deinit();
while (try walk.next()) |src| { while (try walk.next()) |src| {
switch (src.kind) { switch (src.kind) {
.file => if (!std.mem.endsWith(u8, src.basename, ".zig")) continue, .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(); const wf = b.addWriteFiles();
wf.addCopyFileToSource(new_pot, "po/" ++ domain ++ ".pot"); wf.addCopyFileToSource(
xgettext.captureStdOut(),
"po/" ++ domain ++ ".pot",
);
inline for (locales) |locale| { inline for (locales) |locale| {
const msgmerge = b.addSystemCommand(&.{ "msgmerge", "-q" }); const msgmerge = b.addSystemCommand(&.{ "msgmerge", "-q" });
msgmerge.addFileArg(b.path("po/" ++ locale ++ ".po")); msgmerge.addFileArg(b.path("po/" ++ locale ++ ".po"));
msgmerge.addFileArg(xgettext.captureStdOut()); msgmerge.addFileArg(xgettext.captureStdOut());
wf.addCopyFileToSource(msgmerge.captureStdOut(), "po/" ++ locale ++ ".po"); wf.addCopyFileToSource(msgmerge.captureStdOut(), "po/" ++ locale ++ ".po");
} }
pot_step.dependOn(&wf.step); return &wf.step;
} }