@@ -36,8 +36,10 @@ env_map: ?*EnvMap,
36
36
/// be skipped if all output files are up-to-date and input files are
37
37
/// unchanged.
38
38
stdio : StdIo = .infer_from_args ,
39
- /// This field must be `null` if stdio is `inherit`.
40
- stdin : ? []const u8 = null ,
39
+
40
+ /// This field must be `.none` if stdio is `inherit`.
41
+ /// It should be only set using `setStdIn`.
42
+ stdin : StdIn = .none ,
41
43
42
44
/// Additional file paths relative to build.zig that, when modified, indicate
43
45
/// that the Run step should be re-executed.
@@ -77,6 +79,12 @@ captured_stderr: ?*Output = null,
77
79
78
80
has_side_effects : bool = false ,
79
81
82
+ pub const StdIn = union (enum ) {
83
+ none ,
84
+ bytes : []const u8 ,
85
+ file_source : std.Build.FileSource ,
86
+ };
87
+
80
88
pub const StdIo = union (enum ) {
81
89
/// Whether the Run step has side-effects will be determined by whether or not one
82
90
/// of the args is an output file (added with `addOutputFileArg`).
@@ -229,6 +237,14 @@ pub fn addArgs(self: *Run, args: []const []const u8) void {
229
237
}
230
238
}
231
239
240
+ pub fn setStdIn (self : * Run , stdin : StdIn ) void {
241
+ switch (stdin ) {
242
+ .file_source = > | file_source | file_source .addStepDependencies (& self .step ),
243
+ .bytes , .none = > {},
244
+ }
245
+ self .stdin = stdin ;
246
+ }
247
+
232
248
pub fn clearEnvironment (self : * Run ) void {
233
249
const b = self .step .owner ;
234
250
const new_env_map = b .allocator .create (EnvMap ) catch @panic ("OOM" );
@@ -454,8 +470,15 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
454
470
}
455
471
}
456
472
457
- if (self .stdin ) | bytes | {
458
- man .hash .addBytes (bytes );
473
+ switch (self .stdin ) {
474
+ .bytes = > | bytes | {
475
+ man .hash .addBytes (bytes );
476
+ },
477
+ .file_source = > | file_source | {
478
+ const file_path = file_source .getPath (b );
479
+ _ = try man .addFile (file_path , null );
480
+ },
481
+ .none = > {},
459
482
}
460
483
461
484
if (self .captured_stdout ) | output | {
@@ -934,7 +957,7 @@ fn spawnChildAndCollect(
934
957
};
935
958
if (self .captured_stdout != null ) child .stdout_behavior = .Pipe ;
936
959
if (self .captured_stderr != null ) child .stderr_behavior = .Pipe ;
937
- if (self .stdin != null ) {
960
+ if (self .stdin != .none ) {
938
961
assert (child .stdin_behavior != .Inherit );
939
962
child .stdin_behavior = .Pipe ;
940
963
}
@@ -1158,12 +1181,27 @@ fn sendRunTestMessage(file: std.fs.File, index: u32) !void {
1158
1181
fn evalGeneric (self : * Run , child : * std.process.Child ) ! StdIoResult {
1159
1182
const arena = self .step .owner .allocator ;
1160
1183
1161
- if (self .stdin ) | stdin | {
1162
- child .stdin .? .writeAll (stdin ) catch | err | {
1163
- return self .step .fail ("unable to write stdin: {s}" , .{@errorName (err )});
1164
- };
1165
- child .stdin .? .close ();
1166
- child .stdin = null ;
1184
+ switch (self .stdin ) {
1185
+ .bytes = > | bytes | {
1186
+ child .stdin .? .writeAll (bytes ) catch | err | {
1187
+ return self .step .fail ("unable to write stdin: {s}" , .{@errorName (err )});
1188
+ };
1189
+ child .stdin .? .close ();
1190
+ child .stdin = null ;
1191
+ },
1192
+ .file_source = > | file_source | {
1193
+ const path = file_source .getPath (self .step .owner );
1194
+ const file = self .step .owner .build_root .handle .openFile (path , .{}) catch | err | {
1195
+ return self .step .fail ("unable to open stdin file: {s}" , .{@errorName (err )});
1196
+ };
1197
+ defer file .close ();
1198
+ child .stdin .? .writeFileAll (file , .{}) catch | err | {
1199
+ return self .step .fail ("unable to write file to stdin: {s}" , .{@errorName (err )});
1200
+ };
1201
+ child .stdin .? .close ();
1202
+ child .stdin = null ;
1203
+ },
1204
+ .none = > {},
1167
1205
}
1168
1206
1169
1207
// These are not optionals, as a workaround for
0 commit comments