commit e956948f99338a7cef7d0e9f0602930f3e0528e1 (tree)
parent 96ba0ab930214e15ce09cde0cbddec797f0d2d9f
Author: Andrew Kelley <andrew@ziglang.org>
Date: Tue, 30 Dec 2025 13:34:18 -0800
std: remove fs.getAppDataDir with no replacement
This API is a bit too opinionated for the Zig standard library.
Applications should contain this logic instead.
Diffstat:
6 files changed, 38 insertions(+), 91 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -436,7 +436,6 @@ set(ZIG_STAGE2_SOURCES
lib/std/fmt.zig
lib/std/fmt/parse_float.zig
lib/std/fs.zig
- lib/std/fs/get_app_data_dir.zig
lib/std/fs/path.zig
lib/std/hash.zig
lib/std/hash/auto_hash.zig
diff --git a/lib/std/fs.zig b/lib/std/fs.zig
@@ -6,9 +6,6 @@ const std = @import("std.zig");
pub const path = @import("fs/path.zig");
pub const wasi = @import("fs/wasi.zig");
-pub const getAppDataDir = @import("fs/get_app_data_dir.zig").getAppDataDir;
-pub const GetAppDataDirError = @import("fs/get_app_data_dir.zig").GetAppDataDirError;
-
pub const base64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".*;
/// Base64 encoder, replacing the standard `+/` with `-_` so that it can be used in a file name on any filesystem.
@@ -25,5 +22,4 @@ pub const max_name_bytes = std.Io.Dir.max_name_bytes;
test {
_ = path;
_ = @import("fs/test.zig");
- _ = @import("fs/get_app_data_dir.zig");
}
diff --git a/lib/std/fs/get_app_data_dir.zig b/lib/std/fs/get_app_data_dir.zig
@@ -1,66 +0,0 @@
-const std = @import("../std.zig");
-const builtin = @import("builtin");
-const unicode = std.unicode;
-const mem = std.mem;
-const fs = std.fs;
-const native_os = builtin.os.tag;
-const posix = std.posix;
-
-pub const GetAppDataDirError = error{
- OutOfMemory,
- AppDataDirUnavailable,
-};
-
-/// Caller owns returned memory.
-/// TODO determine if we can remove the allocator requirement
-pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDirError![]u8 {
- switch (native_os) {
- .windows => {
- const local_app_data_dir = std.process.getEnvVarOwned(allocator, "LOCALAPPDATA") catch |err| switch (err) {
- error.OutOfMemory => |e| return e,
- else => return error.AppDataDirUnavailable,
- };
- defer allocator.free(local_app_data_dir);
- return fs.path.join(allocator, &[_][]const u8{ local_app_data_dir, appname });
- },
- .maccatalyst, .macos => {
- const home_dir = posix.getenv("HOME") orelse {
- // TODO look in /etc/passwd
- return error.AppDataDirUnavailable;
- };
- return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
- },
- .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .illumos, .serenity => {
- if (posix.getenv("XDG_DATA_HOME")) |xdg| {
- if (xdg.len > 0) {
- return fs.path.join(allocator, &[_][]const u8{ xdg, appname });
- }
- }
-
- const home_dir = posix.getenv("HOME") orelse {
- // TODO look in /etc/passwd
- return error.AppDataDirUnavailable;
- };
- return fs.path.join(allocator, &[_][]const u8{ home_dir, ".local", "share", appname });
- },
- .haiku => {
- var dir_path_buf: [std.fs.max_path_bytes]u8 = undefined;
- const rc = std.c.find_directory(.B_USER_SETTINGS_DIRECTORY, -1, true, &dir_path_buf, dir_path_buf.len);
- const settings_dir = try allocator.dupeZ(u8, mem.sliceTo(&dir_path_buf, 0));
- defer allocator.free(settings_dir);
- switch (rc) {
- 0 => return fs.path.join(allocator, &[_][]const u8{ settings_dir, appname }),
- else => return error.AppDataDirUnavailable,
- }
- },
- else => @compileError("Unsupported OS"),
- }
-}
-
-test getAppDataDir {
- if (native_os == .wasi) return error.SkipZigTest;
-
- // We can't actually validate the result
- const dir = getAppDataDir(std.testing.allocator, "zig") catch return;
- defer std.testing.allocator.free(dir);
-}
diff --git a/lib/std/zig.zig b/lib/std/zig.zig
@@ -743,6 +743,7 @@ pub const EnvVar = enum {
NO_COLOR,
CLICOLOR_FORCE,
XDG_CACHE_HOME,
+ LOCALAPPDATA,
HOME,
pub fn isSet(comptime ev: EnvVar) bool {
diff --git a/lib/std/zig/WindowsSdk.zig b/lib/std/zig/WindowsSdk.zig
@@ -860,7 +860,14 @@ const MsvcLibDir = struct {
// %localappdata%\Microsoft\VisualStudio\
// %appdata%\Local\Microsoft\VisualStudio\
- const visualstudio_folder_path = std.fs.getAppDataDir(gpa, "Microsoft\\VisualStudio\\") catch return error.PathNotFound;
+ const local_app_data_path = (std.zig.EnvVar.LOCALAPPDATA.get(gpa) catch |err| switch (err) {
+ error.OutOfMemory => |e| return e,
+ error.InvalidWtf8 => return error.PathNotFound,
+ }) orelse return error.PathNotFound;
+ defer gpa.free(local_app_data_path);
+ const visualstudio_folder_path = try Dir.path.join(gpa, &.{
+ local_app_data_path, "Microsoft\\VisualStudio\\",
+ });
defer gpa.free(visualstudio_folder_path);
const vs_versions: []const []const u8 = vs_versions: {
diff --git a/src/introspect.zig b/src/introspect.zig
@@ -1,5 +1,4 @@
const builtin = @import("builtin");
-const build_options = @import("build_options");
const std = @import("std");
const Io = std.Io;
@@ -8,6 +7,8 @@ const mem = std.mem;
const Allocator = std.mem.Allocator;
const Cache = std.Build.Cache;
+const build_options = @import("build_options");
+
const Compilation = @import("Compilation.zig");
const Package = @import("Package.zig");
@@ -101,26 +102,35 @@ pub fn findZigLibDirFromSelfExe(
}
/// Caller owns returned memory.
-pub fn resolveGlobalCacheDir(allocator: Allocator) ![]u8 {
- if (builtin.os.tag == .wasi)
- @compileError("on WASI the global cache dir must be resolved with preopens");
-
- if (try std.zig.EnvVar.ZIG_GLOBAL_CACHE_DIR.get(allocator)) |value| return value;
-
- const appname = "zig";
-
- if (builtin.os.tag != .windows) {
- if (std.zig.EnvVar.XDG_CACHE_HOME.getPosix()) |cache_root| {
- if (cache_root.len > 0) {
- return Dir.path.join(allocator, &.{ cache_root, appname });
+pub fn resolveGlobalCacheDir(gpa: Allocator) ![]u8 {
+ if (try std.zig.EnvVar.ZIG_GLOBAL_CACHE_DIR.get(gpa)) |value| return value;
+
+ const app_name = "zig";
+
+ switch (builtin.os.tag) {
+ .wasi => @compileError("on WASI the global cache dir must be resolved with preopens"),
+ .windows => {
+ const local_app_data_dir = (std.zig.EnvVar.LOCALAPPDATA.get(gpa) catch |err| switch (err) {
+ error.OutOfMemory => |e| return e,
+ error.InvalidWtf8 => return error.AppDataDirUnavailable,
+ }) orelse return error.AppDataDirUnavailable;
+ defer gpa.free(local_app_data_dir);
+ return Dir.path.join(gpa, &.{ local_app_data_dir, app_name });
+ },
+ else => {
+ if (std.zig.EnvVar.XDG_CACHE_HOME.getPosix()) |cache_root| {
+ if (cache_root.len > 0) {
+ return Dir.path.join(gpa, &.{ cache_root, app_name });
+ }
}
- }
- if (std.zig.EnvVar.HOME.getPosix()) |home| {
- return Dir.path.join(allocator, &.{ home, ".cache", appname });
- }
+ if (std.zig.EnvVar.HOME.getPosix()) |home| {
+ if (home.len > 0) {
+ return Dir.path.join(gpa, &.{ home, ".cache", app_name });
+ }
+ }
+ return error.AppDataDirUnavailable;
+ },
}
-
- return std.fs.getAppDataDir(allocator, appname);
}
/// Similar to `Dir.path.resolve`, but converts to a cwd-relative path, or, if that would