Run `zig fmt` on generated code

I’m generating zig code which I want to run zig fmt on after generation, however I’m struggling to do so.
The code I got in the build,zig file to do this essentially this

const fmt_run = b.addSystemCommand(&.{"zig", "fmt"});
fmt_run.addFileArg(b.path("test.zig"));

generator_step.dependOn(&fmt_run.step);

Where test.zig is the generated file,[1].

To me it feels like this should run, but the examples in the build documentation only describe tools that create a new file, not anything modifying a file in place.

Anybody know what I should do to run zig fmt here?


  1. The code has nothing to do with testing, just the first name I could think of. ↩︎

You can use std.Build.addFmt() to do this.

If you only have a LazyPath to your generated file you can addInstallFile() it first and get a proper relative path to it with getInstallPath(), there might be a more elegant solution though.

2 Likes

How do I use it?
I tried adding it as

// Here I generate the file
const output = tool_step.addOutputFileArg("test.zig");
const wf = b.addUpdateSourceFiles();
wf.addCopyFileToSource(output, "src/test.zig");

// Then I format it
const fmt_step = b.addFmt(.{ .paths = &.{"test.zig"} });

// Add steps
const generator_step = b.step("generate", "Generate the code");
generator_step.dependOn(&wf.step);
generator_step.dependOn(&fmt_step.step);

but the file is still left unformatted. I also tried giving the filename as src/test.zig but it didn’t work either.

I think you have to make fmt_step depend on wf.step

You want generator step dep. on fmt step dep. on wf step dep. on tool step.

1 Like

Alright, I’ll try it out tomorrow, thanks!

1 Like

Another possibility you might want to consider is formatting the code as part of the initial code generation. The same logic used by zig fmt is exposed in the standard library std.zig.Ast, so if you have a buffer containing your unformatted generated code already, it only takes a few lines to parse it into an Ast and then call render to get the formatted output back: zig-gobject/src/translate.zig at d7f1edaf50193d49b56c60568dfaa9f23195565b · ianprime0509/zig-gobject · GitHub

6 Likes

That did the trick, thanks!

@ianprime0509 I was also considering that approach, I’ve done something similar in Python, but I didn’t know exactly how to do it in Zig and I think relying on a CLI tool is slightly more robust than relying on “internal” APIs, in that I think those APIs are more likely to change over time than the CLI tool.

Good advice all around in this thread.

1 Like