authorgravatar for mrjbq7@gmail.comJohn Benediktsson <mrjbq7@gmail.com> 2025-02-04 21:19:02-08:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-02-06 15:00:48+01:00
log1c07eacc7f26d2545d4c2149e3e3513875951370
tree130b8ec167c7fc61cfdd852e0c1907dc553e092e
parent62e251dcaa366c15e1e591d859738bb0d735dc9a

std.process: adding hasNonEmptyEnvVar() and using for NO_COLOR


4 files changed, 50 insertions(+), 16 deletions(-)

lib/std/io/tty.zig+2-2
......@@ -12,9 +12,9 @@ const native_os = builtin.os.tag;
1212pub fn detectConfig(file: File) Config {
1313 const force_color: ?bool = if (builtin.os.tag == .wasi)
1414 null // wasi does not support environment variables
15 else if (process.hasEnvVarConstant("NO_COLOR"))
15 else if (process.hasNonEmptyEnvVarConstant("NO_COLOR"))
1616 false
17 else if (process.hasEnvVarConstant("CLICOLOR_FORCE"))
17 else if (process.hasNonEmptyEnvVarConstant("CLICOLOR_FORCE"))
1818 true
1919 else
2020 null;
lib/std/process.zig+35
......@@ -431,6 +431,20 @@ pub fn hasEnvVarConstant(comptime key: []const u8) bool {
431431 }
432432}
433433
434/// On Windows, `key` must be valid UTF-8.
435pub fn hasNonEmptyEnvVarConstant(comptime key: []const u8) bool {
436 if (native_os == .windows) {
437 const key_w = comptime unicode.utf8ToUtf16LeStringLiteral(key);
438 const value = getenvW(key_w) orelse return false;
439 return value.len != 0;
440 } else if (native_os == .wasi and !builtin.link_libc) {
441 @compileError("hasNonEmptyEnvVarConstant is not supported for WASI without libc");
442 } else {
443 const value = posix.getenv(key) orelse return false;
444 return value.len != 0;
445 }
446}
447
434448pub const ParseEnvVarIntError = std.fmt.ParseIntError || error{EnvironmentVariableNotFound};
435449
436450/// Parses an environment variable as an integer.
......@@ -477,6 +491,27 @@ pub fn hasEnvVar(allocator: Allocator, key: []const u8) HasEnvVarError!bool {
477491 }
478492}
479493
494/// On Windows, if `key` is not valid [WTF-8](https://simonsapin.github.io/wtf-8/),
495/// then `error.InvalidWtf8` is returned.
496pub fn hasNonEmptyEnvVar(allocator: Allocator, key: []const u8) HasEnvVarError!bool {
497 if (native_os == .windows) {
498 var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator);
499 const stack_allocator = stack_alloc.get();
500 const key_w = try unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key);
501 defer stack_allocator.free(key_w);
502 const value = getenvW(key_w) orelse return false;
503 return value.len != 0;
504 } else if (native_os == .wasi and !builtin.link_libc) {
505 var envmap = getEnvMap(allocator) catch return error.OutOfMemory;
506 defer envmap.deinit();
507 const value = envmap.getPtr(key) orelse return false;
508 return value.len != 0;
509 } else {
510 const value = posix.getenv(key) orelse return false;
511 return value.len != 0;
512 }
513}
514
480515/// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name.
481516///
482517/// This function performs a Unicode-aware case-insensitive lookup using RtlEqualUnicodeString.
lib/std/zig.zig+4-5
......@@ -697,6 +697,10 @@ pub const EnvVar = enum {
697697 XDG_CACHE_HOME,
698698 HOME,
699699
700 pub fn isSet(comptime ev: EnvVar) bool {
701 return std.process.hasNonEmptyEnvVarConstant(@tagName(ev));
702 }
703
700704 pub fn get(ev: EnvVar, arena: std.mem.Allocator) !?[]u8 {
701705 if (std.process.getEnvVarOwned(arena, @tagName(ev))) |value| {
702706 return value;
......@@ -709,11 +713,6 @@ pub const EnvVar = enum {
709713 pub fn getPosix(comptime ev: EnvVar) ?[:0]const u8 {
710714 return std.posix.getenvZ(@tagName(ev));
711715 }
712
713 pub fn isSet(ev: EnvVar, arena: std.mem.Allocator) !bool {
714 const value = try ev.get(arena) orelse return false;
715 return value.len != 0;
716 }
717716};
718717
719718pub const SimpleComptimeReason = enum(u32) {
src/main.zig+9-9
......@@ -826,9 +826,9 @@ fn buildOutputType(
826826 var listen: Listen = .none;
827827 var debug_compile_errors = false;
828828 var verbose_link = (native_os != .wasi or builtin.link_libc) and
829 try EnvVar.ZIG_VERBOSE_LINK.isSet(arena);
829 EnvVar.ZIG_VERBOSE_LINK.isSet();
830830 var verbose_cc = (native_os != .wasi or builtin.link_libc) and
831 try EnvVar.ZIG_VERBOSE_CC.isSet(arena);
831 EnvVar.ZIG_VERBOSE_CC.isSet();
832832 var verbose_air = false;
833833 var verbose_intern_pool = false;
834834 var verbose_generic_instances = false;
......@@ -1006,9 +1006,9 @@ fn buildOutputType(
10061006 // if set, default the color setting to .off or .on, respectively
10071007 // explicit --color arguments will still override this setting.
10081008 // Disable color on WASI per https://github.com/WebAssembly/WASI/issues/162
1009 var color: Color = if (native_os == .wasi or try EnvVar.NO_COLOR.isSet(arena))
1009 var color: Color = if (native_os == .wasi or EnvVar.NO_COLOR.isSet())
10101010 .off
1011 else if (try EnvVar.CLICOLOR_FORCE.isSet(arena))
1011 else if (EnvVar.CLICOLOR_FORCE.isSet())
10121012 .on
10131013 else
10141014 .auto;
......@@ -4769,9 +4769,9 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
47694769 var reference_trace: ?u32 = null;
47704770 var debug_compile_errors = false;
47714771 var verbose_link = (native_os != .wasi or builtin.link_libc) and
4772 try EnvVar.ZIG_VERBOSE_LINK.isSet(arena);
4772 EnvVar.ZIG_VERBOSE_LINK.isSet();
47734773 var verbose_cc = (native_os != .wasi or builtin.link_libc) and
4774 try EnvVar.ZIG_VERBOSE_CC.isSet(arena);
4774 EnvVar.ZIG_VERBOSE_CC.isSet();
47754775 var verbose_air = false;
47764776 var verbose_intern_pool = false;
47774777 var verbose_generic_instances = false;
......@@ -4954,7 +4954,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
49544954 }
49554955
49564956 const work_around_btrfs_bug = native_os == .linux and
4957 try EnvVar.ZIG_BTRFS_WORKAROUND.isSet(arena);
4957 EnvVar.ZIG_BTRFS_WORKAROUND.isSet();
49584958 const root_prog_node = std.Progress.start(.{
49594959 .disable_printing = (color == .off),
49604960 .root_name = "Compile Build Script",
......@@ -5461,7 +5461,7 @@ fn jitCmd(
54615461 fatal("unable to find self exe path: {s}", .{@errorName(err)});
54625462 };
54635463
5464 const optimize_mode: std.builtin.OptimizeMode = if (try EnvVar.ZIG_DEBUG_CMD.isSet(arena))
5464 const optimize_mode: std.builtin.OptimizeMode = if (EnvVar.ZIG_DEBUG_CMD.isSet())
54655465 .Debug
54665466 else
54675467 .ReleaseFast;
......@@ -6976,7 +6976,7 @@ fn cmdFetch(
69766976
69776977 const color: Color = .auto;
69786978 const work_around_btrfs_bug = native_os == .linux and
6979 try EnvVar.ZIG_BTRFS_WORKAROUND.isSet(arena);
6979 EnvVar.ZIG_BTRFS_WORKAROUND.isSet();
69806980 var opt_path_or_url: ?[]const u8 = null;
69816981 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
69826982 var debug_hash: bool = false;