authorgravatar for alancocanour@gmail.comAlan Cocanour <alancocanour@gmail.com> 2026-05-07 20:12:58-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-26 17:56:40-07:00
log9c565509313cc497739d518e7bf2de69b1f195bb
tree9d5a8e525e2fb1f812d7f7c6e571d7b310e7227d
parent3852c8eae40755340cf9b06e4e3798884b0ecb7f

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.

2 files changed, 29 insertions(+), 19 deletions(-)

lib/std/zig.zig+12
...@@ -65,6 +65,18 @@ pub const Color = enum {...@@ -65,6 +65,18 @@ pub const Color = enum {
65 .off => .no_color,65 .off => .no_color,
66 };66 };
67 }67 }
68
69 /// Determine the preference for color or no color based on the NO_COLOR and
70 /// CLICOLOR_FORCE environment variables. Color is always disabled on WASI per
71 /// https://github.com/WebAssembly/WASI/issues/162
72 pub fn settingFromEnvironment(environ_map: *const std.process.Environ.Map) Color {
73 return if (@import("builtin").os.tag == .wasi or EnvVar.NO_COLOR.isSet(environ_map))
74 .off
75 else if (EnvVar.CLICOLOR_FORCE.isSet(environ_map))
76 .on
77 else
78 .auto;
79 }
68};80};
6981
70/// There are many assumptions in the entire codebase that Zig source files can82/// There are many assumptions in the entire codebase that Zig source files can
src/main.zig+17-19
...@@ -327,6 +327,7 @@ fn mainArgs(...@@ -327,6 +327,7 @@ fn mainArgs(
327 .depend_on_aro = true,327 .depend_on_aro = true,
328 .prepend_zig_lib_dir_path = true,328 .prepend_zig_lib_dir_path = true,
329 .server = use_server,329 .server = use_server,
330 .color = Color.settingFromEnvironment(environ_map),
330 });331 });
331 } else if (mem.eql(u8, cmd, "fmt")) {332 } else if (mem.eql(u8, cmd, "fmt")) {
332 dev.check(.fmt_command);333 dev.check(.fmt_command);
...@@ -335,11 +336,13 @@ fn mainArgs(...@@ -335,11 +336,13 @@ fn mainArgs(
335 return jitCmd(gpa, arena, io, cmd_args, environ_map, .{336 return jitCmd(gpa, arena, io, cmd_args, environ_map, .{
336 .cmd_name = "objcopy",337 .cmd_name = "objcopy",
337 .root_src_path = "objcopy.zig",338 .root_src_path = "objcopy.zig",
339 .color = Color.settingFromEnvironment(environ_map),
338 });340 });
339 } else if (mem.eql(u8, cmd, "objdump")) {341 } else if (mem.eql(u8, cmd, "objdump")) {
340 return jitCmd(gpa, arena, io, cmd_args, environ_map, .{342 return jitCmd(gpa, arena, io, cmd_args, environ_map, .{
341 .cmd_name = "objdump",343 .cmd_name = "objdump",
342 .root_src_path = "objdump.zig",344 .root_src_path = "objdump.zig",
345 .color = Color.settingFromEnvironment(environ_map),
343 });346 });
344 } else if (mem.eql(u8, cmd, "fetch")) {347 } else if (mem.eql(u8, cmd, "fetch")) {
345 return cmdFetch(gpa, arena, io, cmd_args, environ_map);348 return cmdFetch(gpa, arena, io, cmd_args, environ_map);
...@@ -348,6 +351,7 @@ fn mainArgs(...@@ -348,6 +351,7 @@ fn mainArgs(
348 .cmd_name = "libc",351 .cmd_name = "libc",
349 .root_src_path = "libc.zig",352 .root_src_path = "libc.zig",
350 .prepend_zig_lib_dir_path = true,353 .prepend_zig_lib_dir_path = true,
354 .color = Color.settingFromEnvironment(environ_map),
351 });355 });
352 } else if (mem.eql(u8, cmd, "std")) {356 } else if (mem.eql(u8, cmd, "std")) {
353 return jitCmd(gpa, arena, io, cmd_args, environ_map, .{357 return jitCmd(gpa, arena, io, cmd_args, environ_map, .{
...@@ -356,6 +360,7 @@ fn mainArgs(...@@ -356,6 +360,7 @@ fn mainArgs(
356 .prepend_zig_lib_dir_path = true,360 .prepend_zig_lib_dir_path = true,
357 .prepend_zig_exe_path = true,361 .prepend_zig_exe_path = true,
358 .prepend_global_cache_path = true,362 .prepend_global_cache_path = true,
363 .color = Color.settingFromEnvironment(environ_map),
359 });364 });
360 } else if (mem.eql(u8, cmd, "init")) {365 } else if (mem.eql(u8, cmd, "init")) {
361 return cmdInit(gpa, arena, io, cmd_args);366 return cmdInit(gpa, arena, io, cmd_args);
...@@ -387,6 +392,7 @@ fn mainArgs(...@@ -387,6 +392,7 @@ fn mainArgs(
387 return jitCmd(gpa, arena, io, cmd_args, environ_map, .{392 return jitCmd(gpa, arena, io, cmd_args, environ_map, .{
388 .cmd_name = "reduce",393 .cmd_name = "reduce",
389 .root_src_path = "reduce.zig",394 .root_src_path = "reduce.zig",
395 .color = Color.settingFromEnvironment(environ_map),
390 });396 });
391 } else if (mem.eql(u8, cmd, "zen")) {397 } else if (mem.eql(u8, cmd, "zen")) {
392 dev.check(.zen_command);398 dev.check(.zen_command);
...@@ -395,9 +401,9 @@ fn mainArgs(...@@ -395,9 +401,9 @@ fn mainArgs(
395 dev.check(.help_command);401 dev.check(.help_command);
396 return Io.File.stdout().writeStreamingAll(io, usage);402 return Io.File.stdout().writeStreamingAll(io, usage);
397 } else if (mem.eql(u8, cmd, "ast-check")) {403 } else if (mem.eql(u8, cmd, "ast-check")) {
398 return cmdAstCheck(arena, io, cmd_args);404 return cmdAstCheck(arena, io, cmd_args, environ_map);
399 } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "changelist")) {405 } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "changelist")) {
400 return cmdChangelist(arena, io, cmd_args);406 return cmdChangelist(arena, io, cmd_args, environ_map);
401 } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "dump-zir")) {407 } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "dump-zir")) {
402 return cmdDumpZir(arena, io, cmd_args);408 return cmdDumpZir(arena, io, cmd_args);
403 } else {409 } else {
...@@ -1024,16 +1030,7 @@ fn buildOutputType(...@@ -1024,16 +1030,7 @@ fn buildOutputType(
1024 };1030 };
1025 defer create_module.link_inputs.deinit(gpa);1031 defer create_module.link_inputs.deinit(gpa);
10261032
1027 // before arg parsing, check for the NO_COLOR and CLICOLOR_FORCE environment variables1033 var color: Color = Color.settingFromEnvironment(environ_map);
1028 // if set, default the color setting to .off or .on, respectively
1029 // explicit --color arguments will still override this setting.
1030 // Disable color on WASI per https://github.com/WebAssembly/WASI/issues/162
1031 var color: Color = if (native_os == .wasi or EnvVar.NO_COLOR.isSet(environ_map))
1032 .off
1033 else if (EnvVar.CLICOLOR_FORCE.isSet(environ_map))
1034 .on
1035 else
1036 .auto;
1037 var n_jobs: ?u32 = null;1034 var n_jobs: ?u32 = null;
10381035
1039 switch (arg_mode) {1036 switch (arg_mode) {
...@@ -4734,7 +4731,7 @@ fn cmdTranslateC(...@@ -4734,7 +4731,7 @@ fn cmdTranslateC(
4734 p.* = result;4731 p.* = result;
4735 return;4732 return;
4736 } else {4733 } else {
4737 const color: Color = .auto;4734 const color: Color = Color.settingFromEnvironment(environ_map);
4738 result.errors.renderToStderr(io, .{}, color) catch {};4735 result.errors.renderToStderr(io, .{}, color) catch {};
4739 process.exit(1);4736 process.exit(1);
4740 }4737 }
...@@ -4780,6 +4777,7 @@ pub fn translateC(...@@ -4780,6 +4777,7 @@ pub fn translateC(
4780 .root_src_path = "translate-c/main.zig",4777 .root_src_path = "translate-c/main.zig",
4781 .depend_on_aro = true,4778 .depend_on_aro = true,
4782 .capture = capture,4779 .capture = capture,
4780 .color = Color.settingFromEnvironment(environ_map),
4783 });4781 });
4784}4782}
47854783
...@@ -5005,7 +5003,7 @@ fn cmdBuild(...@@ -5005,7 +5003,7 @@ fn cmdBuild(
5005 configure_argv.addManyAsArrayAssumeCapacity(2).* = .{ "--build-root", undefined };5003 configure_argv.addManyAsArrayAssumeCapacity(2).* = .{ "--build-root", undefined };
5006 const conf_argv_index_build_root = configure_argv.items.len - 1;5004 const conf_argv_index_build_root = configure_argv.items.len - 1;
50075005
5008 var color: Color = .auto;5006 var color: Color = Color.settingFromEnvironment(environ_map);
5009 var n_jobs: ?u32 = null;5007 var n_jobs: ?u32 = null;
50105008
5011 {5009 {
...@@ -6543,12 +6541,12 @@ const usage_ast_check =...@@ -6543,12 +6541,12 @@ const usage_ast_check =
6543 \\6541 \\
6544;6542;
65456543
6546fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {6544fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8, environ_map: *const std.process.Environ.Map) !void {
6547 dev.check(.ast_check_command);6545 dev.check(.ast_check_command);
65486546
6549 const Zir = std.zig.Zir;6547 const Zir = std.zig.Zir;
65506548
6551 var color: Color = .auto;6549 var color: Color = Color.settingFromEnvironment(environ_map);
6552 var want_output_text = false;6550 var want_output_text = false;
6553 var force_zon = false;6551 var force_zon = false;
6554 var zig_source_path: ?[]const u8 = null;6552 var zig_source_path: ?[]const u8 = null;
...@@ -6755,10 +6753,10 @@ fn cmdDumpZir(arena: Allocator, io: Io, args: []const []const u8) !void {...@@ -6755,10 +6753,10 @@ fn cmdDumpZir(arena: Allocator, io: Io, args: []const []const u8) !void {
6755}6753}
67566754
6757/// This is only enabled for debug builds.6755/// This is only enabled for debug builds.
6758fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {6756fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8, environ_map: *const std.process.Environ.Map) !void {
6759 dev.check(.changelist_command);6757 dev.check(.changelist_command);
67606758
6761 const color: Color = .auto;6759 const color: Color = Color.settingFromEnvironment(environ_map);
6762 const Zir = std.zig.Zir;6760 const Zir = std.zig.Zir;
67636761
6764 const old_source_path = args[0];6762 const old_source_path = args[0];
...@@ -7130,7 +7128,7 @@ fn cmdFetch(...@@ -7130,7 +7128,7 @@ fn cmdFetch(
7130) !void {7128) !void {
7131 dev.check(.fetch_command);7129 dev.check(.fetch_command);
71327130
7133 const color: Color = .auto;7131 const color: Color = Color.settingFromEnvironment(environ_map);
7134 var opt_path_or_url: ?[]const u8 = null;7132 var opt_path_or_url: ?[]const u8 = null;
7135 var override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(environ_map);7133 var override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(environ_map);
7136 var override_local_cache_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_CACHE_DIR.get(environ_map);7134 var override_local_cache_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_CACHE_DIR.get(environ_map);