move to cache dir for downloaded geoip db during tests

This commit is contained in:
Emil Lerch 2026-08-04 16:25:34 -07:00
parent 95f677eb7f
commit a5a9d0d7d7
Signed by: lobo
GPG key ID: A7B62D657EF764F8
2 changed files with 35 additions and 3 deletions

View file

@ -11,6 +11,7 @@ pub fn build(b: *std.Build) void {
const build_options = b.addOptions();
build_options.addOption([]const u8, "version", version);
build_options.addOption(bool, "download_geoip", download_geoip);
build_options.addOption([]const u8, "cache_dir", resolveCacheDir(b));
const httpz = b.dependency("httpz", .{
.target = target,
@ -170,3 +171,26 @@ fn configureCompilationUnit(compile: *std.Build.Step.Compile, libs: []const *std
// option set where `root_module` is created.
for (libs) |lib| compile.root_module.linkLibrary(lib);
}
/// Resolves the runtime cache directory, mirroring `Config.load`'s precedence
/// (`WTTR_CACHE_DIR`, else `${XDG_CACHE_HOME:-$HOME/.cache}/wttr`).
///
/// Tests need this because Zig 0.16 removed process-environment access outside
/// of `main`; build scripts kept it. Without this, `Config.loadForTest` would
/// fall back to `HOME = "/tmp"` and write test artifacts -- including the
/// GeoLite2 database -- into `/tmp`.
fn resolveCacheDir(b: *std.Build) []const u8 {
const env = &b.graph.environ_map;
if (env.get("WTTR_CACHE_DIR")) |dir| return b.dupe(dir);
const xdg_cache = if (env.get("XDG_CACHE_HOME")) |x|
b.dupe(x)
else if (env.get("HOME")) |home|
b.pathJoin(&.{ home, ".cache" })
else
// No home directory to work from; keep artifacts inside the build
// cache rather than falling back to a world-writable location.
b.pathFromRoot(".zig-cache");
return b.pathJoin(&.{ xdg_cache, "wttr" });
}

View file

@ -90,14 +90,22 @@ pub fn load(allocator: std.mem.Allocator, env: *const std.process.Environ.Map) !
};
}
/// Loads configuration from an empty environment, for tests.
/// Loads configuration for tests.
///
/// Zig 0.16 removed any way to reach the process environment outside of `main`,
/// and tests are better off not depending on ambient variables anyway: this
/// keeps them reproducible regardless of the developer's shell.
/// so tests cannot resolve `HOME`/`XDG_CACHE_HOME` themselves. Left to an empty
/// environment, `load` would fall back to `HOME = "/tmp"` and scatter test
/// artifacts (including the ~63 MB GeoLite2 database that `-Ddownload-geoip`
/// fetches) into `/tmp`.
///
/// Instead `build.zig` resolves the cache directory from its own environment --
/// build scripts still have access -- and passes it through `build_options`, so
/// tests read and write the same location the server uses. Everything else is
/// left unset so tests do not depend on the developer's shell.
pub fn loadForTest(allocator: std.mem.Allocator) !Config {
var env: std.process.Environ.Map = .init(allocator);
defer env.deinit();
try env.put("WTTR_CACHE_DIR", @import("build_options").cache_dir);
return load(allocator, &env);
}