| ... | @@ -73,18 +73,24 @@ pub fn make( | ... | @@ -73,18 +73,24 @@ pub fn make( |
| 73 | man.hash.add(conf_run.flags.color); | 73 | man.hash.add(conf_run.flags.color); |
| 74 | man.hash.add(conf_run.flags.disable_zig_progress); | 74 | man.hash.add(conf_run.flags.disable_zig_progress); |
| 75 | | 75 | |
| 76 | var any_dep_files = false; | 76 | var any_discovered_inputs = switch (conf_run.flags.stdio) { |
| | 77 | .infer_from_args, .inherit, .check, .zig_test => false, |
| | 78 | .protocol => true, |
| | 79 | }; |
| 77 | var any_output_args = false; | 80 | var any_output_args = false; |
| 78 | var any_cli_positionals = false; | 81 | var any_cli_positionals = false; |
| 79 | | 82 | |
| 80 | for (conf_run.args.slice) |arg_index| { | 83 | for (switch (conf_run.flags.stdio) { |
| | 84 | .infer_from_args, .inherit, .check, .zig_test => conf_run.args.slice, |
| | 85 | .protocol => conf_run.args.slice[0..1], // arguments communicated over protocol |
| | 86 | }) |arg_index| { |
| 81 | const arg = arg_index.get(conf); | 87 | const arg = arg_index.get(conf); |
| 82 | try argv_list.ensureUnusedCapacity(gpa, 1); | 88 | try argv_list.ensureUnusedCapacity(gpa, 1); |
| 83 | switch (arg.flags.tag) { | 89 | switch (arg.flags.tag) { |
| 84 | .string => { | 90 | .string => { |
| 85 | const prefix = arg.prefix.value.?.slice(conf); | 91 | const string = arg.prefix.value.?.slice(conf); |
| 86 | argv_list.appendAssumeCapacity(prefix); | 92 | argv_list.appendAssumeCapacity(string); |
| 87 | man.hash.addBytesZ(prefix); | 93 | man.hash.addBytesZ(string); |
| 88 | }, | 94 | }, |
| 89 | .path_file => { | 95 | .path_file => { |
| 90 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; | 96 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| ... | @@ -118,14 +124,14 @@ pub fn make( | ... | @@ -118,14 +124,14 @@ pub fn make( |
| 118 | result.writer.writeAll(prefix) catch return error.OutOfMemory; | 124 | result.writer.writeAll(prefix) catch return error.OutOfMemory; |
| 119 | | 125 | |
| 120 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| | 126 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 121 | return step.fail(maker, "unable to open input file {f}: {t}", .{ file_path, err }); | 127 | return step.fail(maker, "unable to open input file {qf}: {t}", .{ file_path, err }); |
| 122 | defer file.close(io); | 128 | defer file.close(io); |
| 123 | | 129 | |
| 124 | var file_reader = file.reader(io, &.{}); | 130 | var file_reader = file.reader(io, &.{}); |
| 125 | _ = file_reader.interface.streamRemaining(&result.writer) catch |err| switch (err) { | 131 | _ = file_reader.interface.streamRemaining(&result.writer) catch |err| switch (err) { |
| 126 | error.ReadFailed => switch (file_reader.err.?) { | 132 | error.ReadFailed => switch (file_reader.err.?) { |
| 127 | error.Canceled => |e| return e, | 133 | error.Canceled => |e| return e, |
| 128 | else => |e| return step.fail(maker, "failed to read from {f}: {t}", .{ file_path, e }), | 134 | else => |e| return step.fail(maker, "failed to read from {qf}: {t}", .{ file_path, e }), |
| 129 | }, | 135 | }, |
| 130 | error.WriteFailed => return error.OutOfMemory, | 136 | error.WriteFailed => return error.OutOfMemory, |
| 131 | }; | 137 | }; |
| ... | @@ -133,8 +139,8 @@ pub fn make( | ... | @@ -133,8 +139,8 @@ pub fn make( |
| 133 | | 139 | |
| 134 | argv_list.appendAssumeCapacity(result.written()); | 140 | argv_list.appendAssumeCapacity(result.written()); |
| 135 | man.hash.addBytesZ(prefix); | 141 | man.hash.addBytesZ(prefix); |
| 136 | man.hash.addBytesZ(suffix); | | |
| 137 | _ = try man.addInputPath(file_path, .{}); | 142 | _ = try man.addInputPath(file_path, .{}); |
| | 143 | man.hash.addBytesZ(suffix); |
| 138 | }, | 144 | }, |
| 139 | .artifact => { | 145 | .artifact => { |
| 140 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; | 146 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| ... | @@ -168,7 +174,7 @@ pub fn make( | ... | @@ -168,7 +174,7 @@ pub fn make( |
| 168 | man.hash.addBytesZ(suffix); | 174 | man.hash.addBytesZ(suffix); |
| 169 | man.hash.add(arg.flags.dep_file); | 175 | man.hash.add(arg.flags.dep_file); |
| 170 | | 176 | |
| 171 | any_dep_files = any_dep_files or arg.flags.dep_file; | 177 | if (arg.flags.dep_file) any_discovered_inputs = true; |
| 172 | any_output_args = true; | 178 | any_output_args = true; |
| 173 | | 179 | |
| 174 | // Add a placeholder into the argument list because we need the | 180 | // Add a placeholder into the argument list because we need the |
| ... | @@ -176,9 +182,10 @@ pub fn make( | ... | @@ -176,9 +182,10 @@ pub fn make( |
| 176 | // object directory is computed. | 182 | // object directory is computed. |
| 177 | try output_placeholders.append(gpa, .{ | 183 | try output_placeholders.append(gpa, .{ |
| 178 | .index = @intCast(argv_list.items.len), | 184 | .index = @intCast(argv_list.items.len), |
| | 185 | .offset = 0, |
| 179 | .arg_index = arg_index, | 186 | .arg_index = arg_index, |
| 180 | }); | 187 | }); |
| 181 | argv_list.items.len += 1; | 188 | _ = argv_list.addOneAssumeCapacity(); |
| 182 | }, | 189 | }, |
| 183 | .passthru => { | 190 | .passthru => { |
| 184 | any_cli_positionals = true; | 191 | any_cli_positionals = true; |
| ... | @@ -195,14 +202,285 @@ pub fn make( | ... | @@ -195,14 +202,285 @@ pub fn make( |
| 195 | } | 202 | } |
| 196 | } | 203 | } |
| 197 | | 204 | |
| 198 | man.hash.add(conf_run.flags.test_runner_mode); | 205 | var owned_dirs: std.bit_set.Dynamic = .{}; |
| 199 | if (conf_run.flags.test_runner_mode) { | 206 | var inherit_dirs: std.ArrayList(Io.Dir) = .empty; |
| 200 | const cache_dir_string = try convertPathArg(arena, run_index, maker, .{ .root_dir = cache_root }, false); | 207 | var owned_files: std.bit_set.Dynamic = .{}; |
| | 208 | var inherit_files: std.ArrayList(Io.File) = .empty; |
| | 209 | var protocol_args: std.ArrayList(u8) = .empty; |
| | 210 | defer { |
| | 211 | for (inherit_dirs.items, 0..) |inherit_dir, inherit_dir_index| |
| | 212 | if (owned_dirs.isSet(inherit_dir_index)) inherit_dir.close(io); |
| | 213 | for (inherit_files.items, 0..) |inherit_file, inherit_file_index| |
| | 214 | if (owned_files.isSet(inherit_file_index)) inherit_file.close(io); |
| | 215 | owned_dirs.deinit(gpa); |
| | 216 | inherit_dirs.deinit(gpa); |
| | 217 | owned_files.deinit(gpa); |
| | 218 | inherit_files.deinit(gpa); |
| | 219 | protocol_args.deinit(gpa); |
| | 220 | } |
| | 221 | switch (conf_run.flags.stdio) { |
| | 222 | .infer_from_args, .inherit, .check => {}, |
| | 223 | .zig_test => { |
| | 224 | const cache_dir_string = try convertPathArg(arena, run_index, maker, .{ .root_dir = cache_root }, false); |
| | 225 | |
| | 226 | try argv_list.ensureUnusedCapacity(gpa, 3); |
| | 227 | argv_list.appendAssumeCapacity(try arena.print("--cache-dir={s}", .{cache_dir_string})); |
| | 228 | argv_list.appendAssumeCapacity(try arena.print("--seed=0x{x}", .{graph.random_seed})); |
| | 229 | argv_list.appendAssumeCapacity("--listen=-"); |
| | 230 | }, |
| | 231 | .protocol => for (conf_run.args.slice[1..]) |arg_index| { |
| | 232 | const arg = arg_index.get(conf); |
| | 233 | switch (arg.flags.tag) { |
| | 234 | .string => { |
| | 235 | const string = arg.prefix.value.?.slice(conf); |
| | 236 | |
| | 237 | man.hash.addBytesZ(string); |
| | 238 | |
| | 239 | try protocol_args.ensureUnusedCapacity(gpa, 1 + string.len + 1); |
| | 240 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.string)); |
| | 241 | protocol_args.appendSliceAssumeCapacity(string); |
| | 242 | protocol_args.appendAssumeCapacity(0); |
| | 243 | }, |
| | 244 | .path_file => { |
| | 245 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| | 246 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| | 247 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| | 248 | |
| | 249 | try owned_files.resize(gpa, owned_files.bit_length + 1, true); |
| | 250 | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| | 251 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| | 252 | return step.fail(maker, "unable to open input file {qf}: {t}", .{ file_path, err }); |
| | 253 | inherit_files.appendAssumeCapacity(file); |
| | 254 | |
| | 255 | man.hash.addBytesZ(prefix); |
| | 256 | _ = try man.addInputPath(file_path, .{}); |
| | 257 | man.hash.addBytesZ(suffix); |
| | 258 | |
| | 259 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| | 260 | 1 + @sizeOf(Io.File.Handle) + |
| | 261 | 1 + suffix.len + 1); |
| | 262 | if (prefix.len > 0) { |
| | 263 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| | 264 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 265 | protocol_args.appendAssumeCapacity(0); |
| | 266 | } |
| | 267 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_file)); |
| | 268 | const file_handle: *align(1) Io.File.Handle = |
| | 269 | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle))); |
| | 270 | file_handle.* = file.handle; |
| | 271 | if (suffix.len > 0) { |
| | 272 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| | 273 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 274 | protocol_args.appendAssumeCapacity(0); |
| | 275 | } |
| | 276 | }, |
| | 277 | .path_directory => { |
| | 278 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| | 279 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| | 280 | const dir_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| | 281 | |
| | 282 | const has_sub_path = dir_path.sub_path.len > 0; |
| | 283 | try owned_dirs.resize(gpa, owned_dirs.bit_length + 1, has_sub_path); |
| | 284 | try inherit_dirs.ensureUnusedCapacity(gpa, 1); |
| | 285 | const dir = if (has_sub_path) |
| | 286 | dir_path.root_dir.handle.openDir(io, dir_path.sub_path, .{ |
| | 287 | .iterate = true, |
| | 288 | }) catch |err| return step.fail(maker, "unable to open input dir {qf}: {t}", .{ dir_path, err }) |
| | 289 | else |
| | 290 | dir_path.root_dir.handle; |
| | 291 | inherit_dirs.appendAssumeCapacity(dir); |
| | 292 | |
| | 293 | man.hash.addBytesZ(prefix); |
| | 294 | man.hash.addOptionalBytes(dir_path.root_dir.path); |
| | 295 | man.hash.addBytes(dir_path.sub_path); |
| | 296 | man.hash.addBytesZ(suffix); |
| | 297 | |
| | 298 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| | 299 | 1 + @sizeOf(Io.Dir.Handle) + |
| | 300 | 1 + suffix.len + 1); |
| | 301 | if (prefix.len > 0) { |
| | 302 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| | 303 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 304 | protocol_args.appendAssumeCapacity(0); |
| | 305 | } |
| | 306 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_dir)); |
| | 307 | const dir_handle: *align(1) Io.Dir.Handle = |
| | 308 | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.Dir.Handle))); |
| | 309 | dir_handle.* = dir.handle; |
| | 310 | if (suffix.len > 0) { |
| | 311 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| | 312 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 313 | protocol_args.appendAssumeCapacity(0); |
| | 314 | } |
| | 315 | }, |
| | 316 | .file_content => { |
| | 317 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| | 318 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| | 319 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| | 320 | |
| | 321 | try owned_files.resize(gpa, owned_files.bit_length + 1, true); |
| | 322 | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| | 323 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| | 324 | return step.fail(maker, "unable to open input file {qf}: {t}", .{ file_path, err }); |
| | 325 | inherit_files.appendAssumeCapacity(file); |
| | 326 | |
| | 327 | man.hash.addBytesZ(prefix); |
| | 328 | _ = try man.addInputPath(file_path, .{}); |
| | 329 | man.hash.addBytesZ(suffix); |
| | 330 | |
| | 331 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| | 332 | 1 + @sizeOf(Io.File.Handle) + |
| | 333 | 1 + suffix.len + 1); |
| | 334 | if (prefix.len > 0) { |
| | 335 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| | 336 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 337 | protocol_args.appendAssumeCapacity(0); |
| | 338 | } |
| | 339 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_file_content)); |
| | 340 | const file_handle: *align(1) Io.File.Handle = |
| | 341 | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle))); |
| | 342 | file_handle.* = file.handle; |
| | 343 | if (suffix.len > 0) { |
| | 344 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| | 345 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 346 | protocol_args.appendAssumeCapacity(0); |
| | 347 | } |
| | 348 | }, |
| | 349 | .artifact => { |
| | 350 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| | 351 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| | 352 | const producer_index = arg.producer.value.?; |
| | 353 | const producer_step = producer_index.ptr(conf); |
| | 354 | const producer = producer_step.extended.get(conf.extra).compile; |
| | 355 | const producer_make_comp_step = maker.stepByIndex(producer_index); |
| | 356 | const producer_make_comp = &producer_make_comp_step.extended.compile; |
| | 357 | |
| | 358 | const file_path = producer_make_comp.installed_path orelse |
| | 359 | maker.generatedPath(producer.generated_bin.value.?); |
| | 360 | |
| | 361 | try owned_files.resize(gpa, owned_files.bit_length + 1, true); |
| | 362 | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| | 363 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| | 364 | return step.fail(maker, "unable to open input artifact {qf}: {t}", .{ file_path, err }); |
| | 365 | inherit_files.appendAssumeCapacity(file); |
| | 366 | |
| | 367 | man.hash.addBytesZ(prefix); |
| | 368 | _ = try man.addInputPath(file_path, .{}); |
| | 369 | man.hash.addBytesZ(suffix); |
| | 370 | |
| | 371 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| | 372 | 1 + @sizeOf(Io.File.Handle) + |
| | 373 | 1 + suffix.len + 1); |
| | 374 | if (prefix.len > 0) { |
| | 375 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| | 376 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 377 | protocol_args.appendAssumeCapacity(0); |
| | 378 | } |
| | 379 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.input_file)); |
| | 380 | const file_handle: *align(1) Io.File.Handle = |
| | 381 | @ptrCast(protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle))); |
| | 382 | file_handle.* = file.handle; |
| | 383 | if (suffix.len > 0) { |
| | 384 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| | 385 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 386 | protocol_args.appendAssumeCapacity(0); |
| | 387 | } |
| | 388 | }, |
| | 389 | .output_file => { |
| | 390 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| | 391 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| | 392 | const basename = arg.basename.value.?.slice(conf); |
| | 393 | |
| | 394 | man.hash.addBytesZ(prefix); |
| | 395 | man.hash.addBytesZ(basename); |
| | 396 | man.hash.addBytesZ(suffix); |
| | 397 | assert(!arg.flags.dep_file); |
| | 398 | |
| | 399 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| | 400 | 1 + @sizeOf(Io.File.Handle) + |
| | 401 | 1 + suffix.len + 1); |
| | 402 | if (prefix.len > 0) { |
| | 403 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| | 404 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 405 | protocol_args.appendAssumeCapacity(0); |
| | 406 | } |
| | 407 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.output_file)); |
| | 408 | |
| | 409 | // Add a placeholder into the argument list because we need the |
| | 410 | // manifest hash to be updated with all arguments before the |
| | 411 | // object directory is computed. |
| | 412 | try owned_files.resize(gpa, owned_files.bit_length + 1, false); |
| | 413 | try inherit_files.ensureUnusedCapacity(gpa, 1); |
| | 414 | try output_placeholders.append(gpa, .{ |
| | 415 | .index = @intCast(inherit_files.items.len), |
| | 416 | .offset = @intCast(protocol_args.items.len), |
| | 417 | .arg_index = arg_index, |
| | 418 | }); |
| | 419 | _ = inherit_files.addOneAssumeCapacity(); |
| | 420 | |
| | 421 | _ = protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.File.Handle)); |
| | 422 | if (suffix.len > 0) { |
| | 423 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| | 424 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 425 | protocol_args.appendAssumeCapacity(0); |
| | 426 | } |
| | 427 | }, |
| | 428 | .output_directory => { |
| | 429 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| | 430 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| | 431 | const basename = arg.basename.value.?.slice(conf); |
| | 432 | |
| | 433 | man.hash.addBytesZ(prefix); |
| | 434 | man.hash.addBytesZ(basename); |
| | 435 | man.hash.addBytesZ(suffix); |
| | 436 | assert(!arg.flags.dep_file); |
| | 437 | |
| | 438 | try protocol_args.ensureUnusedCapacity(gpa, 1 + prefix.len + 1 + |
| | 439 | 1 + @sizeOf(Io.Dir.Handle) + |
| | 440 | 1 + suffix.len + 1); |
| | 441 | if (prefix.len > 0) { |
| | 442 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.prefix)); |
| | 443 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 444 | protocol_args.appendAssumeCapacity(0); |
| | 445 | } |
| | 446 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.output_dir)); |
| | 447 | |
| | 448 | // Add a placeholder into the argument list because we need the |
| | 449 | // manifest hash to be updated with all arguments before the |
| | 450 | // object directory is computed. |
| | 451 | try owned_dirs.resize(gpa, owned_dirs.bit_length + 1, false); |
| | 452 | try inherit_dirs.ensureUnusedCapacity(gpa, 1); |
| | 453 | try output_placeholders.append(gpa, .{ |
| | 454 | .index = @intCast(inherit_dirs.items.len), |
| | 455 | .offset = @intCast(protocol_args.items.len), |
| | 456 | .arg_index = arg_index, |
| | 457 | }); |
| | 458 | _ = inherit_dirs.addOneAssumeCapacity(); |
| 201 | | 459 | |
| 202 | try argv_list.ensureUnusedCapacity(gpa, 3); | 460 | _ = protocol_args.addManyAsArrayAssumeCapacity(@sizeOf(Io.Dir.Handle)); |
| 203 | argv_list.appendAssumeCapacity(try arena.print("--cache-dir={s}", .{cache_dir_string})); | 461 | if (suffix.len > 0) { |
| 204 | argv_list.appendAssumeCapacity(try arena.print("--seed=0x{x}", .{graph.random_seed})); | 462 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.suffix)); |
| 205 | argv_list.appendAssumeCapacity("--listen=-"); | 463 | protocol_args.appendSliceAssumeCapacity(prefix); |
| | 464 | protocol_args.appendAssumeCapacity(0); |
| | 465 | } |
| | 466 | }, |
| | 467 | .passthru => if (maker.run_args) |run_args| { |
| | 468 | man.hash.addListOfBytes(run_args); |
| | 469 | |
| | 470 | for (run_args) |run_arg| { |
| | 471 | try protocol_args.ensureUnusedCapacity(gpa, 1 + run_arg.len + 1); |
| | 472 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.string)); |
| | 473 | protocol_args.appendSliceAssumeCapacity(run_arg); |
| | 474 | protocol_args.appendAssumeCapacity(0); |
| | 475 | } |
| | 476 | }, |
| | 477 | .enable_darling => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_darling, arg.prefix.value, arg.suffix.value), |
| | 478 | .enable_qemu => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_qemu, arg.prefix.value, arg.suffix.value), |
| | 479 | .enable_rosetta => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_rosetta, arg.prefix.value, arg.suffix.value), |
| | 480 | .enable_wasmtime => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_wasmtime, arg.prefix.value, arg.suffix.value), |
| | 481 | .enable_wine => try thirdPartyToggleProtocol(gpa, &man.hash, &protocol_args, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), |
| | 482 | } |
| | 483 | }, |
| 206 | } | 484 | } |
| 207 | | 485 | |
| 208 | switch (conf_run.stdin.u) { | 486 | switch (conf_run.stdin.u) { |
| ... | @@ -227,7 +505,7 @@ pub fn make( | ... | @@ -227,7 +505,7 @@ pub fn make( |
| 227 | } | 505 | } |
| 228 | | 506 | |
| 229 | switch (conf_run.flags.stdio) { | 507 | switch (conf_run.flags.stdio) { |
| 230 | .infer_from_args, .inherit, .zig_test => {}, | 508 | .infer_from_args, .inherit, .zig_test, .protocol => {}, |
| 231 | .check => { | 509 | .check => { |
| 232 | man.hash.addBytes(if (conf_run.expect_stderr_exact.value) |bytes| bytes.slice(conf) else ""); | 510 | man.hash.addBytes(if (conf_run.expect_stderr_exact.value) |bytes| bytes.slice(conf) else ""); |
| 233 | man.hash.addBytes(if (conf_run.expect_stdout_exact.value) |bytes| bytes.slice(conf) else ""); | 511 | man.hash.addBytes(if (conf_run.expect_stdout_exact.value) |bytes| bytes.slice(conf) else ""); |
| ... | @@ -256,7 +534,7 @@ pub fn make( | ... | @@ -256,7 +534,7 @@ pub fn make( |
| 256 | conf_run.captured_stdout.value == null and | 534 | conf_run.captured_stdout.value == null and |
| 257 | conf_run.captured_stderr.value == null, | 535 | conf_run.captured_stderr.value == null, |
| 258 | .inherit => true, | 536 | .inherit => true, |
| 259 | .check, .zig_test => false, | 537 | .check, .zig_test, .protocol => false, |
| 260 | }; | 538 | }; |
| 261 | | 539 | |
| 262 | if (!has_side_effects and try step.cacheHitWatched(maker, &man, progress_node)) { | 540 | if (!has_side_effects and try step.cacheHitWatched(maker, &man, progress_node)) { |
| ... | @@ -268,13 +546,22 @@ pub fn make( | ... | @@ -268,13 +546,22 @@ pub fn make( |
| 268 | return; | 546 | return; |
| 269 | } | 547 | } |
| 270 | | 548 | |
| 271 | if (!any_dep_files) { | 549 | if (!any_discovered_inputs) { |
| 272 | // We already know the final output paths; use them directly. | 550 | // We already know the final output paths; use them directly. |
| 273 | const digest = if (has_side_effects) man.hash.final() else man.missDigestHex(); | 551 | const digest = if (has_side_effects) man.hash.final() else man.missDigestHex(); |
| 274 | const output_dir_path = "o" ++ Dir.path.sep_str ++ &digest; | 552 | const output_dir_path = "o" ++ Dir.path.sep_str ++ &digest; |
| 275 | try populateGeneratedStdIo(maker, &conf_run, &digest); | 553 | try populateGeneratedStdIo(maker, &conf_run, &digest); |
| 276 | try populateGeneratedPathsCreateDirs(arena, run_index, maker, output_dir_path, output_placeholders.items, argv_list.items); | 554 | try populateGeneratedPathsCreateDirs(arena, run_index, maker, output_dir_path, output_placeholders.items, switch (conf_run.flags.stdio) { |
| 277 | try runCommand(arena, run, run_index, maker, progress_node, argv_list.items, has_side_effects, output_dir_path, null); | 555 | .infer_from_args, .inherit, .check, .zig_test => .{ .argv = argv_list.items }, |
| | 556 | .protocol => .{ .protocol = .{ |
| | 557 | .owned_dirs = &owned_dirs, |
| | 558 | .inherit_dirs = inherit_dirs.items, |
| | 559 | .owned_files = &owned_files, |
| | 560 | .inherit_files = inherit_files.items, |
| | 561 | .args = protocol_args.items, |
| | 562 | } }, |
| | 563 | }); |
| | 564 | try runCommand(arena, run, run_index, maker, progress_node, argv_list.items, inherit_dirs.items, inherit_files.items, protocol_args.items, has_side_effects, output_dir_path, null); |
| 278 | if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man); | 565 | if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man); |
| 279 | return; | 566 | return; |
| 280 | } | 567 | } |
| ... | @@ -284,8 +571,17 @@ pub fn make( | ... | @@ -284,8 +571,17 @@ pub fn make( |
| 284 | io.random(@ptrCast(&rand_int)); | 571 | io.random(@ptrCast(&rand_int)); |
| 285 | const tmp_dir_path = "tmp" ++ Dir.path.sep_str ++ std.fmt.hex(rand_int); | 572 | const tmp_dir_path = "tmp" ++ Dir.path.sep_str ++ std.fmt.hex(rand_int); |
| 286 | | 573 | |
| 287 | try populateGeneratedPathsCreateDirs(arena, run_index, maker, tmp_dir_path, output_placeholders.items, argv_list.items); | 574 | try populateGeneratedPathsCreateDirs(arena, run_index, maker, tmp_dir_path, output_placeholders.items, switch (conf_run.flags.stdio) { |
| 288 | try runCommand(arena, run, run_index, maker, progress_node, argv_list.items, has_side_effects, tmp_dir_path, null); | 575 | .infer_from_args, .inherit, .check, .zig_test => .{ .argv = argv_list.items }, |
| | 576 | .protocol => .{ .protocol = .{ |
| | 577 | .owned_dirs = &owned_dirs, |
| | 578 | .inherit_dirs = inherit_dirs.items, |
| | 579 | .owned_files = &owned_files, |
| | 580 | .inherit_files = inherit_files.items, |
| | 581 | .args = protocol_args.items, |
| | 582 | } }, |
| | 583 | }); |
| | 584 | try runCommand(arena, run, run_index, maker, progress_node, argv_list.items, inherit_dirs.items, inherit_files.items, protocol_args.items, has_side_effects, tmp_dir_path, null); |
| 289 | | 585 | |
| 290 | for (output_placeholders.items) |placeholder| { | 586 | for (output_placeholders.items) |placeholder| { |
| 291 | const arg = placeholder.arg_index.get(conf); | 587 | const arg = placeholder.arg_index.get(conf); |
| ... | @@ -296,10 +592,10 @@ pub fn make( | ... | @@ -296,10 +592,10 @@ pub fn make( |
| 296 | var diagnostic: Cache.DepTokenizer.Token = undefined; | 592 | var diagnostic: Cache.DepTokenizer.Token = undefined; |
| 297 | man.addInputDepFile(generated_path, &diagnostic) catch |err| switch (err) { | 593 | man.addInputDepFile(generated_path, &diagnostic) catch |err| switch (err) { |
| 298 | error.OutOfMemory, error.Canceled => |e| return e, | 594 | error.OutOfMemory, error.Canceled => |e| return e, |
| 299 | error.InvalidDepFile => return step.fail(maker, "failed adding dep file {f} to cache: {f}", .{ | 595 | error.InvalidDepFile => return step.fail(maker, "failed adding dep file {qf} to cache: {f}", .{ |
| 300 | generated_path, diagnostic, | 596 | generated_path, diagnostic, |
| 301 | }), | 597 | }), |
| 302 | else => |e| return step.fail(maker, "failed adding dep file {f} to cache: {t}", .{ | 598 | else => |e| return step.fail(maker, "failed adding dep file {qf} to cache: {t}", .{ |
| 303 | generated_path, e, | 599 | generated_path, e, |
| 304 | }), | 600 | }), |
| 305 | }; | 601 | }; |
| ... | @@ -307,13 +603,13 @@ pub fn make( | ... | @@ -307,13 +603,13 @@ pub fn make( |
| 307 | var diagnostic: Cache.Manifest.AddDiscoveredDepFileDiagnostic = undefined; | 603 | var diagnostic: Cache.Manifest.AddDiscoveredDepFileDiagnostic = undefined; |
| 308 | man.addDiscoveredDepFile(generated_path, &diagnostic) catch |err| switch (err) { | 604 | man.addDiscoveredDepFile(generated_path, &diagnostic) catch |err| switch (err) { |
| 309 | error.OutOfMemory, error.Canceled => |e| return e, | 605 | error.OutOfMemory, error.Canceled => |e| return e, |
| 310 | error.InvalidDepFile => return step.fail(maker, "failed adding dep file {f} to cache: {f}", .{ | 606 | error.InvalidDepFile => return step.fail(maker, "failed adding dep file {qf} to cache: {f}", .{ |
| 311 | generated_path, diagnostic.dep_tokenizer, | 607 | generated_path, diagnostic.dep_tokenizer, |
| 312 | }), | 608 | }), |
| 313 | error.FileSystemFailure => return step.fail(maker, "failed adding a path from dep file {f} to cache: {f}", .{ | 609 | error.FileSystemFailure => return step.fail(maker, "failed adding a path from dep file {qf} to cache: {f}", .{ |
| 314 | generated_path, diagnostic.add_discovered_path, | 610 | generated_path, diagnostic.add_discovered_path, |
| 315 | }), | 611 | }), |
| 316 | else => |e| return step.fail(maker, "failed adding dep file {f} to cache: {t}", .{ | 612 | else => |e| return step.fail(maker, "failed adding dep file {qf} to cache: {t}", .{ |
| 317 | generated_path, e, | 613 | generated_path, e, |
| 318 | }), | 614 | }), |
| 319 | }; | 615 | }; |
| ... | @@ -342,7 +638,7 @@ pub fn make( | ... | @@ -342,7 +638,7 @@ pub fn make( |
| 342 | ) catch |err| switch (err) { | 638 | ) catch |err| switch (err) { |
| 343 | error.DirNotEmpty => { | 639 | error.DirNotEmpty => { |
| 344 | dst_path.root_dir.handle.deleteTree(io, dst_path.sub_path) catch |del_err| | 640 | dst_path.root_dir.handle.deleteTree(io, dst_path.sub_path) catch |del_err| |
| 345 | return step.fail(maker, "failed to remove tree {f}: {t}", .{ dst_path, del_err }); | 641 | return step.fail(maker, "failed to remove tree {qf}: {t}", .{ dst_path, del_err }); |
| 346 | | 642 | |
| 347 | Dir.rename( | 643 | Dir.rename( |
| 348 | tmp_path.root_dir.handle, | 644 | tmp_path.root_dir.handle, |
| ... | @@ -350,11 +646,11 @@ pub fn make( | ... | @@ -350,11 +646,11 @@ pub fn make( |
| 350 | dst_path.root_dir.handle, | 646 | dst_path.root_dir.handle, |
| 351 | dst_path.sub_path, | 647 | dst_path.sub_path, |
| 352 | io, | 648 | io, |
| 353 | ) catch |retry_err| return step.fail(maker, "failed to rename directory {f} to {f}: {t}", .{ | 649 | ) catch |retry_err| return step.fail(maker, "failed to rename directory {qf} to {qf}: {t}", .{ |
| 354 | tmp_path, dst_path, retry_err, | 650 | tmp_path, dst_path, retry_err, |
| 355 | }); | 651 | }); |
| 356 | }, | 652 | }, |
| 357 | else => return step.fail(maker, "failed to rename directory {f} to {f}: {t}", .{ | 653 | else => return step.fail(maker, "failed to rename directory {qf} to {qf}: {t}", .{ |
| 358 | tmp_path, dst_path, err, | 654 | tmp_path, dst_path, err, |
| 359 | }), | 655 | }), |
| 360 | }; | 656 | }; |
| ... | @@ -386,19 +682,30 @@ fn thirdPartyToggle( | ... | @@ -386,19 +682,30 @@ fn thirdPartyToggle( |
| 386 | enable: ?Configuration.String, | 682 | enable: ?Configuration.String, |
| 387 | disable: ?Configuration.String, | 683 | disable: ?Configuration.String, |
| 388 | ) void { | 684 | ) void { |
| 389 | if (setting) { | 685 | const string = (if (setting) enable else disable) orelse return; |
| 390 | if (enable) |string| { | 686 | const slice = string.slice(conf); |
| 391 | const slice = string.slice(conf); | 687 | if (man_hash) |h| h.addBytesZ(slice); |
| 392 | if (man_hash) |h| h.addBytesZ(slice); | 688 | argv_list.appendAssumeCapacity(slice); |
| 393 | argv_list.appendAssumeCapacity(slice); | 689 | } |
| 394 | } | 690 | |
| 395 | } else { | 691 | fn thirdPartyToggleProtocol( |
| 396 | if (disable) |string| { | 692 | gpa: Allocator, |
| 397 | const slice = string.slice(conf); | 693 | man_hash: *Cache.HashHelper, |
| 398 | if (man_hash) |h| h.addBytesZ(slice); | 694 | protocol_args: *std.ArrayList(u8), |
| 399 | argv_list.appendAssumeCapacity(slice); | 695 | conf: *const Configuration, |
| 400 | } | 696 | setting: bool, |
| 401 | } | 697 | enable: ?Configuration.String, |
| | 698 | disable: ?Configuration.String, |
| | 699 | ) Allocator.Error!void { |
| | 700 | const string = (if (setting) enable else disable) orelse return; |
| | 701 | const slice = string.slice(conf); |
| | 702 | |
| | 703 | man_hash.addBytesZ(slice); |
| | 704 | |
| | 705 | try protocol_args.ensureUnusedCapacity(gpa, 1 + slice.len + 1); |
| | 706 | protocol_args.appendAssumeCapacity(@backingInt(std.zig.Client.Message.Arg.string)); |
| | 707 | protocol_args.appendSliceAssumeCapacity(slice); |
| | 708 | protocol_args.appendAssumeCapacity(0); |
| 402 | } | 709 | } |
| 403 | | 710 | |
| 404 | /// Reads stdout of a Zig test process until a termination condition is reached: | 711 | /// Reads stdout of a Zig test process until a termination condition is reached: |
| ... | @@ -412,6 +719,7 @@ fn waitZigTest( | ... | @@ -412,6 +719,7 @@ fn waitZigTest( |
| 412 | maker: *Maker, | 719 | maker: *Maker, |
| 413 | child: *process.Child, | 720 | child: *process.Child, |
| 414 | progress_node: std.Progress.Node, | 721 | progress_node: std.Progress.Node, |
| | 722 | protocol_args: []const u8, |
| 415 | multi_reader: *Io.File.MultiReader, | 723 | multi_reader: *Io.File.MultiReader, |
| 416 | opt_metadata: *?TestMetadata, | 724 | opt_metadata: *?TestMetadata, |
| 417 | results: *Step.TestResults, | 725 | results: *Step.TestResults, |
| ... | @@ -444,6 +752,14 @@ fn waitZigTest( | ... | @@ -444,6 +752,14 @@ fn waitZigTest( |
| 444 | .out = &stdin_writer.interface, | 752 | .out = &stdin_writer.interface, |
| 445 | }; | 753 | }; |
| 446 | | 754 | |
| | 755 | if (protocol_args.len > 0) { |
| | 756 | try client.serveMessageHeader(.{ |
| | 757 | .tag = .args, |
| | 758 | .bytes_len = @intCast(protocol_args.len), |
| | 759 | }); |
| | 760 | try client.out.writeAll(protocol_args); |
| | 761 | } |
| | 762 | |
| 447 | if (opt_metadata.*) |*md| { | 763 | if (opt_metadata.*) |*md| { |
| 448 | // Previous unit test process died or was killed; we're continuing where it left off | 764 | // Previous unit test process died or was killed; we're continuing where it left off |
| 449 | requestNextTest(&client, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; | 765 | requestNextTest(&client, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; |
| ... | @@ -492,6 +808,7 @@ fn waitZigTest( | ... | @@ -492,6 +808,7 @@ fn waitZigTest( |
| 492 | var body_r: std.Io.Reader = .fixed(body); | 808 | var body_r: std.Io.Reader = .fixed(body); |
| 493 | | 809 | |
| 494 | switch (header.tag) { | 810 | switch (header.tag) { |
| | 811 | else => {}, // ignore other messages |
| 495 | .zig_version => { | 812 | .zig_version => { |
| 496 | if (!std.mem.eql(u8, builtin.zig_version_string, body)) return step.fail( | 813 | if (!std.mem.eql(u8, builtin.zig_version_string, body)) return step.fail( |
| 497 | maker, | 814 | maker, |
| ... | @@ -583,7 +900,6 @@ fn waitZigTest( | ... | @@ -583,7 +900,6 @@ fn waitZigTest( |
| 583 | | 900 | |
| 584 | requestNextTest(&client, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; | 901 | requestNextTest(&client, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; |
| 585 | }, | 902 | }, |
| 586 | else => {}, // ignore other messages | | |
| 587 | } | 903 | } |
| 588 | } | 904 | } |
| 589 | } | 905 | } |
| ... | @@ -820,6 +1136,7 @@ const FuzzTestRunner = struct { | ... | @@ -820,6 +1136,7 @@ const FuzzTestRunner = struct { |
| 820 | } | 1136 | } |
| 821 | | 1137 | |
| 822 | switch (header.tag) { | 1138 | switch (header.tag) { |
| | 1139 | else => {}, // ignore other messages |
| 823 | .zig_version => { | 1140 | .zig_version => { |
| 824 | if (!std.mem.eql(u8, builtin.zig_version_string, body)) return step.fail( | 1141 | if (!std.mem.eql(u8, builtin.zig_version_string, body)) return step.fail( |
| 825 | maker, | 1142 | maker, |
| ... | @@ -882,7 +1199,6 @@ const FuzzTestRunner = struct { | ... | @@ -882,7 +1199,6 @@ const FuzzTestRunner = struct { |
| 882 | f.pending_broadcasts.appendSliceAssumeCapacity(@ptrCast(&footer)); | 1199 | f.pending_broadcasts.appendSliceAssumeCapacity(@ptrCast(&footer)); |
| 883 | } | 1200 | } |
| 884 | }, | 1201 | }, |
| 885 | else => {}, // ignore other messages | | |
| 886 | } | 1202 | } |
| 887 | | 1203 | |
| 888 | instance.message.clearRetainingCapacity(); | 1204 | instance.message.clearRetainingCapacity(); |
| ... | @@ -1146,6 +1462,7 @@ fn evalZigTest( | ... | @@ -1146,6 +1462,7 @@ fn evalZigTest( |
| 1146 | maker: *Maker, | 1462 | maker: *Maker, |
| 1147 | progress_node: std.Progress.Node, | 1463 | progress_node: std.Progress.Node, |
| 1148 | spawn_options: process.SpawnOptions, | 1464 | spawn_options: process.SpawnOptions, |
| | 1465 | protocol_args: []const u8, |
| 1149 | fuzz_context: ?FuzzContext, | 1466 | fuzz_context: ?FuzzContext, |
| 1150 | ) !void { | 1467 | ) !void { |
| 1151 | if (fuzz_context != null) { | 1468 | if (fuzz_context != null) { |
| ... | @@ -1194,6 +1511,7 @@ fn evalZigTest( | ... | @@ -1194,6 +1511,7 @@ fn evalZigTest( |
| 1194 | maker, | 1511 | maker, |
| 1195 | &child, | 1512 | &child, |
| 1196 | progress_node, | 1513 | progress_node, |
| | 1514 | protocol_args, |
| 1197 | &multi_reader, | 1515 | &multi_reader, |
| 1198 | &test_metadata, | 1516 | &test_metadata, |
| 1199 | &test_results, | 1517 | &test_results, |
| ... | @@ -1402,7 +1720,7 @@ fn evalGeneric( | ... | @@ -1402,7 +1720,7 @@ fn evalGeneric( |
| 1402 | var write_buffer: [1024]u8 = undefined; | 1720 | var write_buffer: [1024]u8 = undefined; |
| 1403 | var stdin_writer = child.stdin.?.writerStreaming(io, &write_buffer); | 1721 | var stdin_writer = child.stdin.?.writerStreaming(io, &write_buffer); |
| 1404 | _ = stdin_writer.interface.sendFileAll(&file_reader, .unlimited) catch |err| switch (err) { | 1722 | _ = stdin_writer.interface.sendFileAll(&file_reader, .unlimited) catch |err| switch (err) { |
| 1405 | error.ReadFailed => return step.fail(maker, "failed to read from {f}: {t}", .{ | 1723 | error.ReadFailed => return step.fail(maker, "failed to read from {qf}: {t}", .{ |
| 1406 | path, file_reader.err.?, | 1724 | path, file_reader.err.?, |
| 1407 | }), | 1725 | }), |
| 1408 | error.WriteFailed => return step.fail(maker, "failed to write to stdin: {t}", .{ | 1726 | error.WriteFailed => return step.fail(maker, "failed to write to stdin: {t}", .{ |
| ... | @@ -1490,6 +1808,7 @@ fn evalGeneric( | ... | @@ -1490,6 +1808,7 @@ fn evalGeneric( |
| 1490 | | 1808 | |
| 1491 | const IndexedOutput = struct { | 1809 | const IndexedOutput = struct { |
| 1492 | index: u32, | 1810 | index: u32, |
| | 1811 | offset: u32, |
| 1493 | arg_index: Configuration.Step.Run.Arg.Index, | 1812 | arg_index: Configuration.Step.Run.Arg.Index, |
| 1494 | }; | 1813 | }; |
| 1495 | | 1814 | |
| ... | @@ -1516,13 +1835,16 @@ pub fn rerunInFuzzMode( | ... | @@ -1516,13 +1835,16 @@ pub fn rerunInFuzzMode( |
| 1516 | var argv_list: std.ArrayList([]const u8) = .empty; | 1835 | var argv_list: std.ArrayList([]const u8) = .empty; |
| 1517 | defer argv_list.deinit(gpa); | 1836 | defer argv_list.deinit(gpa); |
| 1518 | | 1837 | |
| 1519 | for (conf_run.args.slice) |arg_index| { | 1838 | for (switch (conf_run.flags.stdio) { |
| | 1839 | .infer_from_args, .inherit, .check, .zig_test => conf_run.args.slice, |
| | 1840 | .protocol => @panic("protocol fuzz unimplemented"), |
| | 1841 | }) |arg_index| { |
| 1520 | const arg = arg_index.get(conf); | 1842 | const arg = arg_index.get(conf); |
| 1521 | try argv_list.ensureUnusedCapacity(gpa, 1); | 1843 | try argv_list.ensureUnusedCapacity(gpa, 1); |
| 1522 | switch (arg.flags.tag) { | 1844 | switch (arg.flags.tag) { |
| 1523 | .string => { | 1845 | .string => { |
| 1524 | const prefix = arg.prefix.value.?.slice(conf); | 1846 | const string = arg.prefix.value.?.slice(conf); |
| 1525 | argv_list.appendAssumeCapacity(prefix); | 1847 | argv_list.appendAssumeCapacity(string); |
| 1526 | }, | 1848 | }, |
| 1527 | .path_file => { | 1849 | .path_file => { |
| 1528 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; | 1850 | const prefix = if (arg.prefix.value) |p| p.slice(conf) else ""; |
| ... | @@ -1550,14 +1872,14 @@ pub fn rerunInFuzzMode( | ... | @@ -1550,14 +1872,14 @@ pub fn rerunInFuzzMode( |
| 1550 | result.writer.writeAll(prefix) catch return error.OutOfMemory; | 1872 | result.writer.writeAll(prefix) catch return error.OutOfMemory; |
| 1551 | | 1873 | |
| 1552 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| | 1874 | const file = file_path.root_dir.handle.openFile(io, file_path.sub_path, .{}) catch |err| |
| 1553 | return step.fail(maker, "unable to open input file {f}: {t}", .{ file_path, err }); | 1875 | return step.fail(maker, "unable to open input file {qf}: {t}", .{ file_path, err }); |
| 1554 | defer file.close(io); | 1876 | defer file.close(io); |
| 1555 | | 1877 | |
| 1556 | var file_reader = file.reader(io, &.{}); | 1878 | var file_reader = file.reader(io, &.{}); |
| 1557 | _ = file_reader.interface.streamRemaining(&result.writer) catch |err| switch (err) { | 1879 | _ = file_reader.interface.streamRemaining(&result.writer) catch |err| switch (err) { |
| 1558 | error.ReadFailed => switch (file_reader.err.?) { | 1880 | error.ReadFailed => switch (file_reader.err.?) { |
| 1559 | error.Canceled => |e| return e, | 1881 | error.Canceled => |e| return e, |
| 1560 | else => |e| return step.fail(maker, "failed to read from {f}: {t}", .{ file_path, e }), | 1882 | else => |e| return step.fail(maker, "failed to read from {qf}: {t}", .{ file_path, e }), |
| 1561 | }, | 1883 | }, |
| 1562 | error.WriteFailed => return error.OutOfMemory, | 1884 | error.WriteFailed => return error.OutOfMemory, |
| 1563 | }; | 1885 | }; |
| ... | @@ -1591,14 +1913,17 @@ pub fn rerunInFuzzMode( | ... | @@ -1591,14 +1913,17 @@ pub fn rerunInFuzzMode( |
| 1591 | .enable_wine => thirdPartyToggle(null, &argv_list, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), | 1913 | .enable_wine => thirdPartyToggle(null, &argv_list, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), |
| 1592 | } | 1914 | } |
| 1593 | } | 1915 | } |
| 1594 | | 1916 | switch (conf_run.flags.stdio) { |
| 1595 | if (conf_run.flags.test_runner_mode) { | 1917 | .infer_from_args, .inherit, .check => {}, |
| 1596 | const cache_dir_string = try convertPathArg(arena, run_index, maker, .{ .root_dir = cache_root }, false); | 1918 | .zig_test => { |
| 1597 | | 1919 | const cache_dir_string = try convertPathArg(arena, run_index, maker, .{ .root_dir = cache_root }, false); |
| 1598 | try argv_list.ensureUnusedCapacity(gpa, 3); | 1920 | |
| 1599 | argv_list.appendAssumeCapacity(try arena.print("--cache-dir={s}", .{cache_dir_string})); | 1921 | try argv_list.ensureUnusedCapacity(gpa, 3); |
| 1600 | argv_list.appendAssumeCapacity(try arena.print("--seed=0x{x}", .{graph.random_seed})); | 1922 | argv_list.appendAssumeCapacity(try arena.print("--cache-dir={s}", .{cache_dir_string})); |
| 1601 | argv_list.appendAssumeCapacity("--listen=-"); | 1923 | argv_list.appendAssumeCapacity(try arena.print("--seed=0x{x}", .{graph.random_seed})); |
| | 1924 | argv_list.appendAssumeCapacity("--listen=-"); |
| | 1925 | }, |
| | 1926 | .protocol => unreachable, |
| 1602 | } | 1927 | } |
| 1603 | | 1928 | |
| 1604 | step.clearFailedCommand(gpa); | 1929 | step.clearFailedCommand(gpa); |
| ... | @@ -1607,7 +1932,7 @@ pub fn rerunInFuzzMode( | ... | @@ -1607,7 +1932,7 @@ pub fn rerunInFuzzMode( |
| 1607 | var rand_int: u64 = undefined; | 1932 | var rand_int: u64 = undefined; |
| 1608 | io.random(@ptrCast(&rand_int)); | 1933 | io.random(@ptrCast(&rand_int)); |
| 1609 | const tmp_dir_path = "tmp" ++ Dir.path.sep_str ++ std.fmt.hex(rand_int); | 1934 | const tmp_dir_path = "tmp" ++ Dir.path.sep_str ++ std.fmt.hex(rand_int); |
| 1610 | try runCommand(arena, run, run_index, maker, prog_node, argv_list.items, has_side_effects, tmp_dir_path, .{ | 1935 | try runCommand(arena, run, run_index, maker, prog_node, argv_list.items, &.{}, &.{}, &.{}, has_side_effects, tmp_dir_path, .{ |
| 1611 | .fuzz = fuzz, | 1936 | .fuzz = fuzz, |
| 1612 | }); | 1937 | }); |
| 1613 | } | 1938 | } |
| ... | @@ -1633,7 +1958,16 @@ fn populateGeneratedPathsCreateDirs( | ... | @@ -1633,7 +1958,16 @@ fn populateGeneratedPathsCreateDirs( |
| 1633 | maker: *Maker, | 1958 | maker: *Maker, |
| 1634 | output_dir_path: []const u8, | 1959 | output_dir_path: []const u8, |
| 1635 | output_placeholders: []const IndexedOutput, | 1960 | output_placeholders: []const IndexedOutput, |
| 1636 | argv: [][]const u8, | 1961 | populate: union(enum) { |
| | 1962 | argv: [][]const u8, |
| | 1963 | protocol: struct { |
| | 1964 | owned_dirs: *std.bit_set.Dynamic, |
| | 1965 | inherit_dirs: []Io.Dir, |
| | 1966 | owned_files: *std.bit_set.Dynamic, |
| | 1967 | inherit_files: []Io.File, |
| | 1968 | args: []u8, |
| | 1969 | }, |
| | 1970 | }, |
| 1637 | ) !void { | 1971 | ) !void { |
| 1638 | const step = maker.stepByIndex(run_index); | 1972 | const step = maker.stepByIndex(run_index); |
| 1639 | const conf = &maker.scanned_config.configuration; | 1973 | const conf = &maker.scanned_config.configuration; |
| ... | @@ -1653,16 +1987,52 @@ fn populateGeneratedPathsCreateDirs( | ... | @@ -1653,16 +1987,52 @@ fn populateGeneratedPathsCreateDirs( |
| 1653 | const create_path: Path = .{ | 1987 | const create_path: Path = .{ |
| 1654 | .root_dir = cache_root, | 1988 | .root_dir = cache_root, |
| 1655 | .sub_path = switch (arg.flags.tag) { | 1989 | .sub_path = switch (arg.flags.tag) { |
| | 1990 | else => unreachable, |
| 1656 | .output_file => Dir.path.dirname(generated_path.sub_path).?, | 1991 | .output_file => Dir.path.dirname(generated_path.sub_path).?, |
| 1657 | .output_directory => generated_path.sub_path, | 1992 | .output_directory => generated_path.sub_path, |
| 1658 | else => unreachable, | | |
| 1659 | }, | 1993 | }, |
| 1660 | }; | 1994 | }; |
| 1661 | create_path.root_dir.handle.createDirPath(io, create_path.sub_path) catch |err| | 1995 | create_path.root_dir.handle.createDirPath(io, create_path.sub_path) catch |err| |
| 1662 | return step.fail(maker, "unable to make path {f}: {t}", .{ create_path, err }); | 1996 | return step.fail(maker, "unable to make path {qf}: {t}", .{ create_path, err }); |
| 1663 | | 1997 | |
| 1664 | const arg_output_path = try convertPathArg(arena, run_index, maker, generated_path, arg.flags.make_absolute); | 1998 | switch (populate) { |
| 1665 | argv[placeholder.index] = try mem.concat(arena, u8, &.{ prefix, arg_output_path, suffix }); | 1999 | .argv => |argv| { |
| | 2000 | const arg_output_path = try convertPathArg(arena, run_index, maker, generated_path, arg.flags.make_absolute); |
| | 2001 | argv[placeholder.index] = try mem.concat(arena, u8, &.{ prefix, arg_output_path, suffix }); |
| | 2002 | }, |
| | 2003 | .protocol => |protocol| switch (arg.flags.tag) { |
| | 2004 | else => unreachable, |
| | 2005 | .output_file => { |
| | 2006 | const file = generated_path.root_dir.handle.createFile( |
| | 2007 | io, |
| | 2008 | generated_path.sub_path, |
| | 2009 | .{ .read = true }, |
| | 2010 | ) catch |err| return step.fail(maker, "unable to create output file {qf}: {t}", .{ |
| | 2011 | generated_path, err, |
| | 2012 | }); |
| | 2013 | protocol.inherit_files[placeholder.index] = file; |
| | 2014 | protocol.owned_files.set(placeholder.index); |
| | 2015 | const file_handle: *align(1) Io.File.Handle = |
| | 2016 | @ptrCast(protocol.args[placeholder.offset..][0..@sizeOf(Io.File.Handle)]); |
| | 2017 | file_handle.* = file.handle; |
| | 2018 | }, |
| | 2019 | .output_directory => { |
| | 2020 | assert(generated_path.sub_path.len > 0); |
| | 2021 | const dir = generated_path.root_dir.handle.openDir( |
| | 2022 | io, |
| | 2023 | generated_path.sub_path, |
| | 2024 | .{ .iterate = true }, |
| | 2025 | ) catch |err| return step.fail(maker, "unable to open output dir {qf}: {t}", .{ |
| | 2026 | generated_path, err, |
| | 2027 | }); |
| | 2028 | protocol.inherit_dirs[placeholder.index] = dir; |
| | 2029 | protocol.owned_dirs.set(placeholder.index); |
| | 2030 | const dir_handle: *align(1) Io.Dir.Handle = |
| | 2031 | @ptrCast(protocol.args[placeholder.offset..][0..@sizeOf(Io.Dir.Handle)]); |
| | 2032 | dir_handle.* = dir.handle; |
| | 2033 | }, |
| | 2034 | }, |
| | 2035 | } |
| 1666 | } | 2036 | } |
| 1667 | } | 2037 | } |
| 1668 | | 2038 | |
| ... | @@ -1711,6 +2081,9 @@ fn runCommand( | ... | @@ -1711,6 +2081,9 @@ fn runCommand( |
| 1711 | maker: *Maker, | 2081 | maker: *Maker, |
| 1712 | progress_node: std.Progress.Node, | 2082 | progress_node: std.Progress.Node, |
| 1713 | argv: []const []const u8, | 2083 | argv: []const []const u8, |
| | 2084 | inherit_dirs: []const Io.Dir, |
| | 2085 | inherit_files: []const Io.File, |
| | 2086 | protocol_args: []const u8, |
| 1714 | has_side_effects: bool, | 2087 | has_side_effects: bool, |
| 1715 | output_dir_path: []const u8, | 2088 | output_dir_path: []const u8, |
| 1716 | fuzz_context: ?FuzzContext, | 2089 | fuzz_context: ?FuzzContext, |
| ... | @@ -1777,10 +2150,14 @@ fn runCommand( | ... | @@ -1777,10 +2150,14 @@ fn runCommand( |
| 1777 | progress_node, | 2150 | progress_node, |
| 1778 | argv, | 2151 | argv, |
| 1779 | &environ_map, | 2152 | &environ_map, |
| | 2153 | inherit_dirs, |
| | 2154 | inherit_files, |
| | 2155 | protocol_args, |
| 1780 | has_side_effects, | 2156 | has_side_effects, |
| 1781 | fuzz_context, | 2157 | fuzz_context, |
| 1782 | ) catch |err| term: { | 2158 | ) catch |err| term: { |
| 1783 | switch (err) { | 2159 | switch (err) { |
| | 2160 | else => {}, |
| 1784 | error.InvalidExe, // cpu arch mismatch | 2161 | error.InvalidExe, // cpu arch mismatch |
| 1785 | error.FileNotFound, // can happen with a wrong dynamic linker path | 2162 | error.FileNotFound, // can happen with a wrong dynamic linker path |
| 1786 | => interpret: { | 2163 | => interpret: { |
| ... | @@ -1928,6 +2305,9 @@ fn runCommand( | ... | @@ -1928,6 +2305,9 @@ fn runCommand( |
| 1928 | progress_node, | 2305 | progress_node, |
| 1929 | interp_argv.items, | 2306 | interp_argv.items, |
| 1930 | &environ_map, | 2307 | &environ_map, |
| | 2308 | inherit_dirs, |
| | 2309 | inherit_files, |
| | 2310 | protocol_args, |
| 1931 | has_side_effects, | 2311 | has_side_effects, |
| 1932 | fuzz_context, | 2312 | fuzz_context, |
| 1933 | ) catch |e| { | 2313 | ) catch |e| { |
| ... | @@ -1937,21 +2317,21 @@ fn runCommand( | ... | @@ -1937,21 +2317,21 @@ fn runCommand( |
| 1937 | }; | 2317 | }; |
| 1938 | }, | 2318 | }, |
| 1939 | error.MakeFailed, error.OutOfMemory, error.Canceled => |e| return e, | 2319 | error.MakeFailed, error.OutOfMemory, error.Canceled => |e| return e, |
| 1940 | else => {}, | | |
| 1941 | } | 2320 | } |
| 1942 | return step.fail(maker, "failed to spawn and capture stdio from {s}: {t}", .{ argv[0], err }); | 2321 | return step.fail(maker, "failed to spawn and capture stdio from {s}: {t}", .{ argv[0], err }); |
| 1943 | }; | 2322 | }; |
| 1944 | | 2323 | |
| 1945 | const generic_result = opt_generic_result orelse { | 2324 | const generic_result = switch (conf_run.flags.stdio) { |
| 1946 | assert(conf_run.flags.stdio == .zig_test); | 2325 | .infer_from_args, .inherit, .check => opt_generic_result.?, |
| 1947 | // Specific errors have already been reported, and test results are populated. All we need | 2326 | .zig_test, .protocol => { |
| 1948 | // to do is report step failure if any test failed. | 2327 | assert(opt_generic_result == null); |
| 1949 | if (!step.test_results.isSuccess()) return error.MakeFailed; | 2328 | // Specific errors have already been reported, and test results are populated. All we need |
| 1950 | return; | 2329 | // to do is report step failure if any test failed. |
| | 2330 | if (!step.test_results.isSuccess()) return error.MakeFailed; |
| | 2331 | return; |
| | 2332 | }, |
| 1951 | }; | 2333 | }; |
| 1952 | | | |
| 1953 | assert(fuzz_context == null); | 2334 | assert(fuzz_context == null); |
| 1954 | assert(conf_run.flags.stdio != .zig_test); | | |
| 1955 | | 2335 | |
| 1956 | // Capture stdout and stderr to GeneratedFile objects. | 2336 | // Capture stdout and stderr to GeneratedFile objects. |
| 1957 | const Stream = struct { | 2337 | const Stream = struct { |
| ... | @@ -1978,7 +2358,7 @@ fn runCommand( | ... | @@ -1978,7 +2358,7 @@ fn runCommand( |
| 1978 | | 2358 | |
| 1979 | const sub_path_parent = output_path.dirname().?; | 2359 | const sub_path_parent = output_path.dirname().?; |
| 1980 | sub_path_parent.root_dir.handle.createDirPath(io, sub_path_parent.sub_path) catch |err| | 2360 | sub_path_parent.root_dir.handle.createDirPath(io, sub_path_parent.sub_path) catch |err| |
| 1981 | return step.fail(maker, "unable to make path {f}: {t}", .{ sub_path_parent, err }); | 2361 | return step.fail(maker, "unable to make path {qf}: {t}", .{ sub_path_parent, err }); |
| 1982 | | 2362 | |
| 1983 | const data = switch (stream.trim_whitespace) { | 2363 | const data = switch (stream.trim_whitespace) { |
| 1984 | .none => stream.bytes.?, | 2364 | .none => stream.bytes.?, |
| ... | @@ -1989,12 +2369,12 @@ fn runCommand( | ... | @@ -1989,12 +2369,12 @@ fn runCommand( |
| 1989 | output_path.root_dir.handle.writeFile(io, .{ | 2369 | output_path.root_dir.handle.writeFile(io, .{ |
| 1990 | .sub_path = output_path.sub_path, | 2370 | .sub_path = output_path.sub_path, |
| 1991 | .data = data, | 2371 | .data = data, |
| 1992 | }) catch |err| return step.fail(maker, "unable to write file {f}: {t}", .{ output_path, err }); | 2372 | }) catch |err| return step.fail(maker, "unable to write file {qf}: {t}", .{ output_path, err }); |
| 1993 | } | 2373 | } |
| 1994 | } | 2374 | } |
| 1995 | | 2375 | |
| 1996 | switch (conf_run.flags.stdio) { | 2376 | switch (conf_run.flags.stdio) { |
| 1997 | .zig_test => unreachable, | 2377 | .zig_test, .protocol => unreachable, |
| 1998 | .check => { | 2378 | .check => { |
| 1999 | if (conf_run.expect_stderr_exact.value) |bytes| { | 2379 | if (conf_run.expect_stderr_exact.value) |bytes| { |
| 2000 | const expected_bytes = bytes.slice(conf); | 2380 | const expected_bytes = bytes.slice(conf); |
| ... | @@ -2186,6 +2566,9 @@ fn spawnChildAndCollect( | ... | @@ -2186,6 +2566,9 @@ fn spawnChildAndCollect( |
| 2186 | progress_node: std.Progress.Node, | 2566 | progress_node: std.Progress.Node, |
| 2187 | argv: []const []const u8, | 2567 | argv: []const []const u8, |
| 2188 | environ_map: *EnvMap, | 2568 | environ_map: *EnvMap, |
| | 2569 | inherit_dirs: []const Io.Dir, |
| | 2570 | inherit_files: []const Io.File, |
| | 2571 | protocol_args: []const u8, |
| 2189 | has_side_effects: bool, | 2572 | has_side_effects: bool, |
| 2190 | fuzz_context: ?FuzzContext, | 2573 | fuzz_context: ?FuzzContext, |
| 2191 | ) !?EvalGenericResult { | 2574 | ) !?EvalGenericResult { |
| ... | @@ -2199,7 +2582,10 @@ fn spawnChildAndCollect( | ... | @@ -2199,7 +2582,10 @@ fn spawnChildAndCollect( |
| 2199 | | 2582 | |
| 2200 | if (fuzz_context != null) { | 2583 | if (fuzz_context != null) { |
| 2201 | assert(!has_side_effects); | 2584 | assert(!has_side_effects); |
| 2202 | assert(conf_run.flags.stdio == .zig_test); | 2585 | switch (conf_run.flags.stdio) { |
| | 2586 | .infer_from_args, .inherit, .check => unreachable, |
| | 2587 | .zig_test, .protocol => {}, |
| | 2588 | } |
| 2203 | } | 2589 | } |
| 2204 | | 2590 | |
| 2205 | const child_cwd: process.Child.Cwd = if (conf_run.cwd.value) |lazy_cwd| | 2591 | const child_cwd: process.Child.Cwd = if (conf_run.cwd.value) |lazy_cwd| |
| ... | @@ -2237,20 +2623,22 @@ fn spawnChildAndCollect( | ... | @@ -2237,20 +2623,22 @@ fn spawnChildAndCollect( |
| 2237 | .infer_from_args => if (maker.protocol_server == null and has_side_effects) .inherit else .ignore, | 2623 | .infer_from_args => if (maker.protocol_server == null and has_side_effects) .inherit else .ignore, |
| 2238 | .inherit => .inherit, | 2624 | .inherit => .inherit, |
| 2239 | .check => .ignore, | 2625 | .check => .ignore, |
| 2240 | .zig_test => .pipe, | 2626 | .zig_test, .protocol => .pipe, |
| 2241 | }, | 2627 | }, |
| 2242 | .stdout = if (conf_run.captured_stdout.value != null) .pipe else switch (conf_run.flags.stdio) { | 2628 | .stdout = if (conf_run.captured_stdout.value != null) .pipe else switch (conf_run.flags.stdio) { |
| 2243 | .infer_from_args => if (maker.protocol_server == null and has_side_effects) .inherit else .ignore, | 2629 | .infer_from_args => if (maker.protocol_server == null and has_side_effects) .inherit else .ignore, |
| 2244 | .inherit => .inherit, | 2630 | .inherit => .inherit, |
| 2245 | .check => if (checksContainStdout(&conf_run)) .pipe else .ignore, | 2631 | .check => if (checksContainStdout(&conf_run)) .pipe else .ignore, |
| 2246 | .zig_test => .pipe, | 2632 | .zig_test, .protocol => .pipe, |
| 2247 | }, | 2633 | }, |
| 2248 | .stderr = if (conf_run.captured_stderr.value != null) .pipe else switch (conf_run.flags.stdio) { | 2634 | .stderr = if (conf_run.captured_stderr.value != null) .pipe else switch (conf_run.flags.stdio) { |
| 2249 | .infer_from_args => if (maker.protocol_server == null and has_side_effects) .inherit else .pipe, | 2635 | .infer_from_args => if (maker.protocol_server == null and has_side_effects) .inherit else .pipe, |
| 2250 | .inherit => if (maker.protocol_server == null) .inherit else .pipe, | 2636 | .inherit => if (maker.protocol_server == null) .inherit else .pipe, |
| 2251 | .check => .pipe, | 2637 | .check => .pipe, |
| 2252 | .zig_test => .pipe, | 2638 | .zig_test, .protocol => .pipe, |
| 2253 | }, | 2639 | }, |
| | 2640 | .inherit_dirs = inherit_dirs, |
| | 2641 | .inherit_files = inherit_files, |
| 2254 | }; | 2642 | }; |
| 2255 | | 2643 | |
| 2256 | if (maker.protocol_server != null) { | 2644 | if (maker.protocol_server != null) { |
| ... | @@ -2263,35 +2651,38 @@ fn spawnChildAndCollect( | ... | @@ -2263,35 +2651,38 @@ fn spawnChildAndCollect( |
| 2263 | assert(spawn_options.stderr != .inherit); | 2651 | assert(spawn_options.stderr != .inherit); |
| 2264 | } | 2652 | } |
| 2265 | | 2653 | |
| 2266 | if (conf_run.flags.stdio == .zig_test) { | 2654 | switch (conf_run.flags.stdio) { |
| 2267 | try setColorEnvironmentVariables(&conf_run, environ_map, graph.stderr_mode.?); | 2655 | .infer_from_args, .inherit, .check => { |
| 2268 | const started: Io.Clock.Timestamp = .now(io, .awake); | 2656 | const inherit = spawn_options.stdout == .inherit or spawn_options.stderr == .inherit; |
| 2269 | const result = evalZigTest(run, run_index, maker, progress_node, spawn_options, fuzz_context) catch |err| switch (err) { | 2657 | if (!conf_run.flags.disable_zig_progress and !inherit) { |
| 2270 | error.Canceled => |e| return e, | 2658 | spawn_options.progress_node = progress_node; |
| 2271 | else => |e| e, | 2659 | } |
| 2272 | }; | 2660 | const terminal_mode: Io.Terminal.Mode = if (inherit) m: { |
| 2273 | step.result_duration_ns = @intCast(started.untilNow(io).raw.nanoseconds); | 2661 | const stderr = try io.lockStderr(&.{}, graph.stderr_mode); |
| 2274 | try result; | 2662 | break :m stderr.terminal_mode; |
| 2275 | return null; | 2663 | } else .no_color; |
| 2276 | } else { | 2664 | defer if (inherit) io.unlockStderr(); |
| 2277 | const inherit = spawn_options.stdout == .inherit or spawn_options.stderr == .inherit; | 2665 | try setColorEnvironmentVariables(&conf_run, environ_map, terminal_mode); |
| 2278 | if (!conf_run.flags.disable_zig_progress and !inherit) { | 2666 | |
| 2279 | spawn_options.progress_node = progress_node; | 2667 | const started: Io.Clock.Timestamp = .now(io, .awake); |
| 2280 | } | 2668 | const result = evalGeneric(arena, run_index, maker, spawn_options) catch |err| switch (err) { |
| 2281 | const terminal_mode: Io.Terminal.Mode = if (inherit) m: { | 2669 | error.Canceled => |e| return e, |
| 2282 | const stderr = try io.lockStderr(&.{}, graph.stderr_mode); | 2670 | else => |e| e, |
| 2283 | break :m stderr.terminal_mode; | 2671 | }; |
| 2284 | } else .no_color; | 2672 | step.result_duration_ns = @intCast(started.untilNow(io).raw.nanoseconds); |
| 2285 | defer if (inherit) io.unlockStderr(); | 2673 | return try result; |
| 2286 | try setColorEnvironmentVariables(&conf_run, environ_map, terminal_mode); | 2674 | }, |
| 2287 | | 2675 | .zig_test, .protocol => { |
| 2288 | const started: Io.Clock.Timestamp = .now(io, .awake); | 2676 | try setColorEnvironmentVariables(&conf_run, environ_map, graph.stderr_mode.?); |
| 2289 | const result = evalGeneric(arena, run_index, maker, spawn_options) catch |err| switch (err) { | 2677 | const started: Io.Clock.Timestamp = .now(io, .awake); |
| 2290 | error.Canceled => |e| return e, | 2678 | const result = evalZigTest(run, run_index, maker, progress_node, spawn_options, protocol_args, fuzz_context) catch |err| switch (err) { |
| 2291 | else => |e| e, | 2679 | error.Canceled => |e| return e, |
| 2292 | }; | 2680 | else => |e| e, |
| 2293 | step.result_duration_ns = @intCast(started.untilNow(io).raw.nanoseconds); | 2681 | }; |
| 2294 | return try result; | 2682 | step.result_duration_ns = @intCast(started.untilNow(io).raw.nanoseconds); |
| | 2683 | try result; |
| | 2684 | return null; |
| | 2685 | }, |
| 2295 | } | 2686 | } |
| 2296 | } | 2687 | } |
| 2297 | | 2688 | |
| ... | @@ -2341,7 +2732,7 @@ fn setColorEnvironmentVariables( | ... | @@ -2341,7 +2732,7 @@ fn setColorEnvironmentVariables( |
| 2341 | .auto => { | 2732 | .auto => { |
| 2342 | const capture_stderr = conf_run.captured_stderr.value != null or switch (conf_run.flags.stdio) { | 2733 | const capture_stderr = conf_run.captured_stderr.value != null or switch (conf_run.flags.stdio) { |
| 2343 | .check => checksContainStderr(conf_run), | 2734 | .check => checksContainStderr(conf_run), |
| 2344 | .infer_from_args, .inherit, .zig_test => false, | 2735 | .infer_from_args, .inherit, .zig_test, .protocol => false, |
| 2345 | }; | 2736 | }; |
| 2346 | if (capture_stderr) { | 2737 | if (capture_stderr) { |
| 2347 | continue :color .disable; | 2738 | continue :color .disable; |