diff --git a/src/os/env.zig b/src/os/env.zig new file mode 100644 index 000000000..d6c2970c5 --- /dev/null +++ b/src/os/env.zig @@ -0,0 +1,48 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const Allocator = std.mem.Allocator; + +/// Append a value to an environment variable such as PATH. +/// The returned value is always allocated so it must be freed. +pub fn appendEnv( + alloc: Allocator, + current: []const u8, + value: []const u8, +) ![]u8 { + // If there is no prior value, we return it as-is + if (current.len == 0) return try alloc.dupe(u8, value); + + // Otherwise we must prefix. + const sep = switch (builtin.os.tag) { + .windows => ";", + else => ":", + }; + + return try std.fmt.allocPrint(alloc, "{s}{s}{s}", .{ + current, + sep, + value, + }); +} + +test "appendEnv empty" { + const testing = std.testing; + const alloc = testing.allocator; + + const result = try appendEnv(alloc, "", "foo"); + defer alloc.free(result); + try testing.expectEqualStrings(result, "foo"); +} + +test "appendEnv existing" { + const testing = std.testing; + const alloc = testing.allocator; + + const result = try appendEnv(alloc, "a:b", "foo"); + defer alloc.free(result); + if (builtin.os.tag == .windows) { + try testing.expectEqualStrings(result, "a:b;foo"); + } else { + try testing.expectEqualStrings(result, "a:b:foo"); + } +} diff --git a/src/os/main.zig b/src/os/main.zig index b80c116e6..a9df1fca6 100644 --- a/src/os/main.zig +++ b/src/os/main.zig @@ -1,6 +1,7 @@ //! The "os" package contains utilities for interfacing with the operating //! system. +pub usingnamespace @import("env.zig"); pub usingnamespace @import("file.zig"); pub usingnamespace @import("flatpak.zig"); pub usingnamespace @import("homedir.zig");