@@ -37,6 +37,7 @@ pub fn createDisk(dimmer: Interface, size: u64, content: Content) std.Build.Lazy
3737 compile_script .addArg (b .fmt ("--size={d}" , .{size }));
3838
3939 compile_script .addPrefixedFileArg ("--script=" , script_file );
40+ compile_script .addPrefixedDirectoryArg ("--script-root=" , .{ .cwd_relative = "." });
4041
4142 const result_file = compile_script .addPrefixedOutputFileArg ("--output=" , "disk.img" );
4243
@@ -62,14 +63,18 @@ pub fn createDisk(dimmer: Interface, size: u64, content: Content) std.Build.Lazy
6263 return result_file ;
6364}
6465
65- fn renderContent (wfs : * std.Build.Step.WriteFile , allocator : std.mem.Allocator , content : Content ) struct { []const u8 , ContentWriter .VariableMap } {
66- var code : std .ArrayList (u8 ) = .init (allocator );
66+ fn renderContent (
67+ wfs : * std.Build.Step.WriteFile ,
68+ allocator : std.mem.Allocator ,
69+ content : Content ,
70+ ) struct { []const u8 , ContentWriter .VariableMap } {
71+ var code : std.Io.Writer.Allocating = .init (allocator );
6772 defer code .deinit ();
6873
6974 var variables : ContentWriter.VariableMap = .init (allocator );
7075
7176 var cw : ContentWriter = .{
72- .code = code .writer () ,
77+ .code = & code .writer ,
7378 .wfs = wfs ,
7479 .vars = & variables ,
7580 };
@@ -99,7 +104,7 @@ const ContentWriter = struct {
99104 pub const VariableMap = std .StringArrayHashMap (struct { std .Build .LazyPath , ContentWriter .UsageHint });
100105
101106 wfs : * std.Build.Step.WriteFile ,
102- code : std .ArrayList ( u8 ) .Writer ,
107+ code : * std.Io .Writer ,
103108 vars : * VariableMap ,
104109
105110 fn render (cw : ContentWriter , content : Content ) ! void {
@@ -117,7 +122,7 @@ const ContentWriter = struct {
117122 },
118123
119124 .paste_file = > | data | {
120- try cw .code .print ("paste-file {}" , .{cw .fmtLazyPath (data , .file )});
125+ try cw .code .print ("paste-file {f }" , .{cw .fmtLazyPath (data , .file )});
121126 },
122127
123128 .mbr_part_table = > | data | {
@@ -158,7 +163,7 @@ const ContentWriter = struct {
158163 .gpt_part_table = > | data | {
159164 try cw .code .writeAll ("gpt-part\n " );
160165
161- if (data .legacy_bootable ) {
166+ if (data .legacy_bootable ) {
162167 try cw .code .writeAll (" legacy-bootable\n " );
163168 }
164169
@@ -176,7 +181,7 @@ const ContentWriter = struct {
176181 try cw .code .writeByte ('\n ' );
177182
178183 if (part .name ) | name | {
179- try cw .code .print (" name \" {}\" \n " , .{std .zig .fmtEscapes (name )});
184+ try cw .code .print (" name \" {f }\" \n " , .{std .zig .fmtString (name )});
180185 }
181186 if (part .offset ) | offset | {
182187 try cw .code .print (" offset {d}\n " , .{offset });
@@ -198,7 +203,7 @@ const ContentWriter = struct {
198203 @tagName (data .format ),
199204 });
200205 if (data .label ) | label | {
201- try cw .code .print (" label {}\n " , .{
206+ try cw .code .print (" label {f }\n " , .{
202207 fmtPath (label ),
203208 });
204209 }
@@ -213,61 +218,117 @@ const ContentWriter = struct {
213218 fn renderFileSystemTree (cw : ContentWriter , fs : FileSystem ) ! void {
214219 for (fs .items ) | item | {
215220 switch (item ) {
216- .empty_dir = > | dir | try cw .code .print ("mkdir {}\n " , .{
221+ .empty_dir = > | dir | try cw .code .print ("mkdir {f }\n " , .{
217222 fmtPath (dir ),
218223 }),
219224
220- .copy_dir = > | copy | try cw .code .print ("copy-dir {} {}\n " , .{
225+ .copy_dir = > | copy | try cw .code .print ("copy-dir {f } {f }\n " , .{
221226 fmtPath (copy .destination ),
222227 cw .fmtLazyPath (copy .source , .directory ),
223228 }),
224229
225- .copy_file = > | copy | try cw .code .print ("copy-file {} {}\n " , .{
230+ .copy_file = > | copy | try cw .code .print ("copy-file {f } {f }\n " , .{
226231 fmtPath (copy .destination ),
227232 cw .fmtLazyPath (copy .source , .file ),
228233 }),
229234
230- .include_script = > | script | try cw .code .print ("!include {}\n " , .{
235+ .include_script = > | script | try cw .code .print ("!include {f }\n " , .{
231236 cw .fmtLazyPath (script , .file ),
232237 }),
233238 }
234239 }
235240 }
236241
237- const PathFormatter = std .fmt .Formatter (formatPath );
238- const LazyPathFormatter = std .fmt .Formatter (formatLazyPath );
242+ const PathFormatter = struct {
243+ path : []const u8 ,
244+
245+ pub fn format (
246+ p : PathFormatter ,
247+ writer : * std.Io.Writer ,
248+ ) std.Io.Writer.Error ! void {
249+ const path = p .path ;
250+ const is_safe_word = for (path ) | char | {
251+ switch (char ) {
252+ 'A' ... 'Z' ,
253+ 'a' ... 'z' ,
254+ '0' ... '9' ,
255+ '_' ,
256+ '-' ,
257+ '/' ,
258+ '.' ,
259+ ':' ,
260+ = > {},
261+ else = > break false ,
262+ }
263+ } else true ;
264+
265+ if (is_safe_word ) {
266+ try writer .writeAll (path );
267+ } else {
268+ try writer .writeAll ("\" " );
269+
270+ for (path ) | c | {
271+ if (c == '\\ ' ) {
272+ try writer .writeAll ("/" );
273+ } else {
274+ try writer .print ("{f}" , .{std .zig .fmtString (&[_ ]u8 {c })});
275+ }
276+ }
277+
278+ try writer .writeAll ("\" " );
279+ }
280+ }
281+ };
282+ const LazyPathFormatter = std .fmt .Alt (
283+ struct { ContentWriter , std .Build .LazyPath , UsageHint },
284+ formatLazyPath ,
285+ );
239286 const UsageHint = enum { file , directory };
240287
241- fn fmtLazyPath (cw : ContentWriter , path : std.Build.LazyPath , hint : UsageHint ) LazyPathFormatter {
288+ fn fmtLazyPath (
289+ cw : ContentWriter ,
290+ path : std.Build.LazyPath ,
291+ hint : UsageHint ,
292+ ) LazyPathFormatter {
242293 return .{ .data = .{ cw , path , hint } };
243294 }
244295
245296 fn fmtPath (path : []const u8 ) PathFormatter {
246- return .{ .data = path };
297+ return .{ .path = path };
247298 }
248299
249300 fn formatLazyPath (
250301 data : struct { ContentWriter , std .Build .LazyPath , UsageHint },
251- comptime fmt : []const u8 ,
252- options : std.fmt.FormatOptions ,
253- writer : anytype ,
254- ) ! void {
302+ writer : * std.Io.Writer ,
303+ ) std.Io.Writer.Error ! void {
255304 const cw , const path , const hint = data ;
256- _ = fmt ;
257- _ = options ;
258305
259306 switch (path ) {
260307 .cwd_relative ,
261308 .dependency ,
262309 .src_path ,
263310 = > {
311+
264312 // We can safely call getPath2 as we can fully resolve the path
265313 // already
266- const full_path = path .getPath2 (cw .wfs .step .owner , & cw .wfs .step );
267-
268- std .debug .assert (std .fs .path .isAbsolute (full_path ));
314+ const rel_path = path .getPath2 (cw .wfs .step .owner , & cw .wfs .step );
315+
316+ const full_path = if (! std .fs .path .isAbsolute (rel_path ))
317+ std .fs .cwd ().realpathAlloc (cw .wfs .step .owner .allocator , rel_path ) catch @panic ("oom" )
318+ else
319+ rel_path ;
320+
321+ if (! std .fs .path .isAbsolute (full_path )) {
322+ const cwd = std .fs .cwd ().realpathAlloc (cw .wfs .step .owner .allocator , "." ) catch @panic ("oom" );
323+ std .debug .print ("non-absolute path detected for {t}: cwd=\" {f}\" path=\" {f}\" \n " , .{
324+ path ,
325+ std .zig .fmtString (cwd ),
326+ std .zig .fmtString (full_path ),
327+ });
328+ @panic ("non-absolute path detected!" );
329+ }
269330
270- try writer .print ("{}" , .{
331+ try writer .print ("{f }" , .{
271332 fmtPath (full_path ),
272333 });
273334 },
@@ -278,53 +339,12 @@ const ContentWriter = struct {
278339 const var_id = cw .vars .count () + 1 ;
279340 const var_name = cw .wfs .step .owner .fmt ("PATH{}" , .{var_id });
280341
281- try cw .vars .put (var_name , .{ path , hint });
342+ cw .vars .put (var_name , .{ path , hint }) catch return error . WriteFailed ;
282343
283344 try writer .print ("${s}" , .{var_name });
284345 },
285346 }
286347 }
287-
288- fn formatPath (
289- path : []const u8 ,
290- comptime fmt : []const u8 ,
291- options : std.fmt.FormatOptions ,
292- writer : anytype ,
293- ) ! void {
294- _ = fmt ;
295- _ = options ;
296-
297- const is_safe_word = for (path ) | char | {
298- switch (char ) {
299- 'A' ... 'Z' ,
300- 'a' ... 'z' ,
301- '0' ... '9' ,
302- '_' ,
303- '-' ,
304- '/' ,
305- '.' ,
306- ':' ,
307- = > {},
308- else = > break false ,
309- }
310- } else true ;
311-
312- if (is_safe_word ) {
313- try writer .writeAll (path );
314- } else {
315- try writer .writeAll ("\" " );
316-
317- for (path ) | c | {
318- if (c == '\\ ' ) {
319- try writer .writeAll ("/" );
320- } else {
321- try writer .print ("{}" , .{std .zig .fmtEscapes (&[_ ]u8 {c })});
322- }
323- }
324-
325- try writer .writeAll ("\" " );
326- }
327- }
328348};
329349
330350pub const Content = union (enum ) {
@@ -385,7 +405,7 @@ pub const GptPartTable = struct {
385405 @"microsoft-basic-data" ,
386406 @"microsoft-reserved" ,
387407 @"windows-recovery" ,
388- @ " plan9" ,
408+ plan9 ,
389409 @"linux-swap" ,
390410 @"linux-fs" ,
391411 @"linux-reserved" ,
0 commit comments