From 9c565509313cc497739d518e7bf2de69b1f195bb Mon Sep 17 00:00:00 2001 From: Alan Cocanour Date: Thu, 7 May 2026 20:12:58 -0400 Subject: [PATCH] Respect environment variable preference for color in all zig commands This makes all commands in the zig executable that support color output respect the user's preference for color output based on the NO_COLOR and CLICOLOR_FORCE environment variables. Setting color preference via command line option still overrides preferences set via environment variables. --- lib/std/zig.zig | 12 ++++++++++++ src/main.zig | 36 +++++++++++++++++------------------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/lib/std/zig.zig b/lib/std/zig.zig index f667aa13b3d692b13b158773bd5eef7a249cfae0..18d2c1459c6ea20894fe9713b7d7c754d013be8a 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -65,6 +65,18 @@ pub const Color = enum { .off => .no_color, }; } + + /// Determine the preference for color or no color based on the NO_COLOR and + /// CLICOLOR_FORCE environment variables. Color is always disabled on WASI per + /// https://github.com/WebAssembly/WASI/issues/162 + pub fn settingFromEnvironment(environ_map: *const std.process.Environ.Map) Color { + return if (@import("builtin").os.tag == .wasi or EnvVar.NO_COLOR.isSet(environ_map)) + .off + else if (EnvVar.CLICOLOR_FORCE.isSet(environ_map)) + .on + else + .auto; + } }; /// There are many assumptions in the entire codebase that Zig source files can diff --git a/src/main.zig b/src/main.zig index d4a2b0d77c293bddcc1964e8bb5400acf060d376..8d10d31c6895b0a03ad45ca39d78a287e6a5b34b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -327,6 +327,7 @@ fn mainArgs( .depend_on_aro = true, .prepend_zig_lib_dir_path = true, .server = use_server, + .color = Color.settingFromEnvironment(environ_map), }); } else if (mem.eql(u8, cmd, "fmt")) { dev.check(.fmt_command); @@ -335,11 +336,13 @@ fn mainArgs( return jitCmd(gpa, arena, io, cmd_args, environ_map, .{ .cmd_name = "objcopy", .root_src_path = "objcopy.zig", + .color = Color.settingFromEnvironment(environ_map), }); } else if (mem.eql(u8, cmd, "objdump")) { return jitCmd(gpa, arena, io, cmd_args, environ_map, .{ .cmd_name = "objdump", .root_src_path = "objdump.zig", + .color = Color.settingFromEnvironment(environ_map), }); } else if (mem.eql(u8, cmd, "fetch")) { return cmdFetch(gpa, arena, io, cmd_args, environ_map); @@ -348,6 +351,7 @@ fn mainArgs( .cmd_name = "libc", .root_src_path = "libc.zig", .prepend_zig_lib_dir_path = true, + .color = Color.settingFromEnvironment(environ_map), }); } else if (mem.eql(u8, cmd, "std")) { return jitCmd(gpa, arena, io, cmd_args, environ_map, .{ @@ -356,6 +360,7 @@ fn mainArgs( .prepend_zig_lib_dir_path = true, .prepend_zig_exe_path = true, .prepend_global_cache_path = true, + .color = Color.settingFromEnvironment(environ_map), }); } else if (mem.eql(u8, cmd, "init")) { return cmdInit(gpa, arena, io, cmd_args); @@ -387,6 +392,7 @@ fn mainArgs( return jitCmd(gpa, arena, io, cmd_args, environ_map, .{ .cmd_name = "reduce", .root_src_path = "reduce.zig", + .color = Color.settingFromEnvironment(environ_map), }); } else if (mem.eql(u8, cmd, "zen")) { dev.check(.zen_command); @@ -395,9 +401,9 @@ fn mainArgs( dev.check(.help_command); return Io.File.stdout().writeStreamingAll(io, usage); } else if (mem.eql(u8, cmd, "ast-check")) { - return cmdAstCheck(arena, io, cmd_args); + return cmdAstCheck(arena, io, cmd_args, environ_map); } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "changelist")) { - return cmdChangelist(arena, io, cmd_args); + return cmdChangelist(arena, io, cmd_args, environ_map); } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "dump-zir")) { return cmdDumpZir(arena, io, cmd_args); } else { @@ -1024,16 +1030,7 @@ fn buildOutputType( }; defer create_module.link_inputs.deinit(gpa); - // before arg parsing, check for the NO_COLOR and CLICOLOR_FORCE environment variables - // if set, default the color setting to .off or .on, respectively - // explicit --color arguments will still override this setting. - // Disable color on WASI per https://github.com/WebAssembly/WASI/issues/162 - var color: Color = if (native_os == .wasi or EnvVar.NO_COLOR.isSet(environ_map)) - .off - else if (EnvVar.CLICOLOR_FORCE.isSet(environ_map)) - .on - else - .auto; + var color: Color = Color.settingFromEnvironment(environ_map); var n_jobs: ?u32 = null; switch (arg_mode) { @@ -4734,7 +4731,7 @@ fn cmdTranslateC( p.* = result; return; } else { - const color: Color = .auto; + const color: Color = Color.settingFromEnvironment(environ_map); result.errors.renderToStderr(io, .{}, color) catch {}; process.exit(1); } @@ -4780,6 +4777,7 @@ pub fn translateC( .root_src_path = "translate-c/main.zig", .depend_on_aro = true, .capture = capture, + .color = Color.settingFromEnvironment(environ_map), }); } @@ -5005,7 +5003,7 @@ fn cmdBuild( configure_argv.addManyAsArrayAssumeCapacity(2).* = .{ "--build-root", undefined }; const conf_argv_index_build_root = configure_argv.items.len - 1; - var color: Color = .auto; + var color: Color = Color.settingFromEnvironment(environ_map); var n_jobs: ?u32 = null; { @@ -6543,12 +6541,12 @@ const usage_ast_check = \\ ; -fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { +fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8, environ_map: *const std.process.Environ.Map) !void { dev.check(.ast_check_command); const Zir = std.zig.Zir; - var color: Color = .auto; + var color: Color = Color.settingFromEnvironment(environ_map); var want_output_text = false; var force_zon = false; var zig_source_path: ?[]const u8 = null; @@ -6755,10 +6753,10 @@ fn cmdDumpZir(arena: Allocator, io: Io, args: []const []const u8) !void { } /// This is only enabled for debug builds. -fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { +fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8, environ_map: *const std.process.Environ.Map) !void { dev.check(.changelist_command); - const color: Color = .auto; + const color: Color = Color.settingFromEnvironment(environ_map); const Zir = std.zig.Zir; const old_source_path = args[0]; @@ -7130,7 +7128,7 @@ fn cmdFetch( ) !void { dev.check(.fetch_command); - const color: Color = .auto; + const color: Color = Color.settingFromEnvironment(environ_map); var opt_path_or_url: ?[]const u8 = null; var override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(environ_map); var override_local_cache_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_CACHE_DIR.get(environ_map); -- 2.54.0