From f377ea10609c1d3fb82688c51483821e318bd007 Mon Sep 17 00:00:00 2001 From: mlugg Date: Thu, 15 May 2025 21:43:52 +0100 Subject: [PATCH] doctest: handle relative paths correctly Evaluate all child processes in the temporary directory, and use `std.fs.path.relative` to make every other path relative to that child cwd instead of our cwd. Resolves: #22119 --- tools/doctest.zig | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/tools/doctest.zig b/tools/doctest.zig index 025d59517f..301bd8ed98 100644 --- a/tools/doctest.zig +++ b/tools/doctest.zig @@ -89,7 +89,18 @@ pub fn main() !void { const out = bw.writer(); try printSourceBlock(arena, out, source, fs.path.basename(input_path)); - try printOutput(arena, out, code, input_path, zig_path, opt_zig_lib_dir, tmp_dir_path); + try printOutput( + arena, + out, + code, + tmp_dir_path, + try std.fs.path.relative(arena, tmp_dir_path, zig_path), + try std.fs.path.relative(arena, tmp_dir_path, input_path), + if (opt_zig_lib_dir) |zig_lib_dir| + try std.fs.path.relative(arena, tmp_dir_path, zig_lib_dir) + else + null, + ); try bw.flush(); } @@ -98,10 +109,14 @@ fn printOutput( arena: Allocator, out: anytype, code: Code, - input_path: []const u8, - zig_exe: []const u8, - opt_zig_lib_dir: ?[]const u8, + /// Relative to this process' cwd. tmp_dir_path: []const u8, + /// Relative to `tmp_dir_path`. + zig_exe: []const u8, + /// Relative to `tmp_dir_path`. + input_path: []const u8, + /// Relative to `tmp_dir_path`. + opt_zig_lib_dir: ?[]const u8, ) !void { var env_map = try process.getEnvMap(arena); try env_map.put("CLICOLOR_FORCE", "1"); @@ -304,7 +319,7 @@ fn printOutput( }, } } - const result = run(arena, &env_map, null, test_args.items) catch + const result = run(arena, &env_map, tmp_dir_path, test_args.items) catch fatal("test failed", .{}); const escaped_stderr = try escapeHtml(arena, result.stderr); const escaped_stdout = try escapeHtml(arena, result.stdout); @@ -339,6 +354,7 @@ fn printOutput( .allocator = arena, .argv = test_args.items, .env_map = &env_map, + .cwd = tmp_dir_path, .max_output_bytes = max_doc_file_size, }); switch (result.term) { @@ -395,6 +411,7 @@ fn printOutput( .allocator = arena, .argv = test_args.items, .env_map = &env_map, + .cwd = tmp_dir_path, .max_output_bytes = max_doc_file_size, }); switch (result.term) { @@ -432,10 +449,7 @@ fn printOutput( zig_exe, "build-obj", "--color", "on", "--name", code_name, - input_path, - try std.fmt.allocPrint(arena, "-femit-bin={s}{c}{s}", .{ - tmp_dir_path, fs.path.sep, name_plus_obj_ext, - }), + input_path, try std.fmt.allocPrint(arena, "-femit-bin={s}", .{name_plus_obj_ext}), }); if (opt_zig_lib_dir) |zig_lib_dir| { try build_args.appendSlice(&.{ "--zig-lib-dir", zig_lib_dir }); @@ -465,6 +479,7 @@ fn printOutput( .allocator = arena, .argv = build_args.items, .env_map = &env_map, + .cwd = tmp_dir_path, .max_output_bytes = max_doc_file_size, }); switch (result.term) { @@ -489,7 +504,7 @@ fn printOutput( const colored_stderr = try termColor(arena, escaped_stderr); try shell_out.print("\n{s} ", .{colored_stderr}); } else { - _ = run(arena, &env_map, null, build_args.items) catch fatal("example failed to compile", .{}); + _ = run(arena, &env_map, tmp_dir_path, build_args.items) catch fatal("example failed to compile", .{}); } try shell_out.writeAll("\n"); }, @@ -505,10 +520,7 @@ fn printOutput( try test_args.appendSlice(&[_][]const u8{ zig_exe, "build-lib", - input_path, - try std.fmt.allocPrint(arena, "-femit-bin={s}{s}{s}", .{ - tmp_dir_path, fs.path.sep_str, bin_basename, - }), + input_path, try std.fmt.allocPrint(arena, "-femit-bin={s}", .{bin_basename}), }); if (opt_zig_lib_dir) |zig_lib_dir| { try test_args.appendSlice(&.{ "--zig-lib-dir", zig_lib_dir }); @@ -542,7 +554,7 @@ fn printOutput( try test_args.append(option); try shell_out.print("{s} ", .{option}); } - const result = run(arena, &env_map, null, test_args.items) catch fatal("test failed", .{}); + const result = run(arena, &env_map, tmp_dir_path, test_args.items) catch fatal("test failed", .{}); const escaped_stderr = try escapeHtml(arena, result.stderr); const escaped_stdout = try escapeHtml(arena, result.stdout); try shell_out.print("\n{s}{s}\n", .{ escaped_stderr, escaped_stdout }); @@ -1076,7 +1088,7 @@ fn in(slice: []const u8, number: u8) bool { fn run( allocator: Allocator, env_map: *process.EnvMap, - cwd: ?[]const u8, + cwd: []const u8, args: []const []const u8, ) !process.Child.RunResult { const result = try process.Child.run(.{