Skip to content

Commit 8fb7b21

Browse files
committed
fix: create parent directories recursively to avoid FileNotFound on fresh systems
std.fs.makeDirAbsolute fails with FileNotFound when parent directories (e.g. ~/.local/share) don't exist, which happens on fresh CI runners. Added makeDirAbsoluteRecursive helper and use it everywhere XDG directories are created.
1 parent 5b5ac71 commit 8fb7b21

4 files changed

Lines changed: 20 additions & 24 deletions

File tree

src/main.zig

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,7 @@ fn acquireLock(allocator: std.mem.Allocator) !std.fs.File {
8787
const data_dir = try xdg.dataDir(allocator);
8888
defer allocator.free(data_dir);
8989

90-
std.fs.makeDirAbsolute(data_dir) catch |err| switch (err) {
91-
error.PathAlreadyExists => {},
92-
else => return err,
93-
};
90+
try xdg.makeDirAbsoluteRecursive(data_dir);
9491

9592
const lock_path = try std.fmt.allocPrint(allocator, "{s}/lock", .{data_dir});
9693
defer allocator.free(lock_path);
@@ -279,10 +276,7 @@ fn installThirdParty(allocator: std.mem.Allocator, ref: cli.PackageRef, src_type
279276
const cache_dir = try xdg.cacheDir(allocator);
280277
defer allocator.free(cache_dir);
281278

282-
std.fs.makeDirAbsolute(cache_dir) catch |err| switch (err) {
283-
error.PathAlreadyExists => {},
284-
else => return err,
285-
};
279+
try xdg.makeDirAbsoluteRecursive(cache_dir);
286280

287281
const archive_path = try std.fmt.allocPrint(allocator, "{s}/{s}.tar.gz", .{ cache_dir, pkg.name });
288282
defer allocator.free(archive_path);

src/resolver.zig

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,7 @@ fn ensureIndexInner(allocator: std.mem.Allocator, refresh: bool) ![]const u8 {
219219
const cache_dir = try xdg.cacheDir(allocator);
220220
defer allocator.free(cache_dir);
221221

222-
std.fs.makeDirAbsolute(cache_dir) catch |err| switch (err) {
223-
error.PathAlreadyExists => {},
224-
else => return err,
225-
};
222+
try xdg.makeDirAbsoluteRecursive(cache_dir);
226223

227224
const index_path = try std.fmt.allocPrint(allocator, "{s}/index.json", .{cache_dir});
228225
defer allocator.free(index_path);

src/store.zig

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,7 @@ pub const Database = struct {
155155
pub fn save(self: *Database, path: []const u8) !void {
156156
// Ensure parent directory exists
157157
if (std.fs.path.dirname(path)) |dir| {
158-
std.fs.makeDirAbsolute(dir) catch |err| switch (err) {
159-
error.PathAlreadyExists => {},
160-
else => return err,
161-
};
158+
try xdg.makeDirAbsoluteRecursive(dir);
162159
}
163160

164161
var aw: std.Io.Writer.Allocating = .init(self.allocator);
@@ -347,10 +344,7 @@ pub const Database = struct {
347344
const bin_dir_path = try xdg.binDir(allocator);
348345
defer allocator.free(bin_dir_path);
349346

350-
std.fs.makeDirAbsolute(bin_dir_path) catch |err| switch (err) {
351-
error.PathAlreadyExists => {},
352-
else => return err,
353-
};
347+
try xdg.makeDirAbsoluteRecursive(bin_dir_path);
354348

355349
var bin_dir = try std.fs.openDirAbsolute(bin_dir_path, .{});
356350
defer bin_dir.close();

src/xdg.zig

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ pub fn statePath(allocator: std.mem.Allocator) ![]const u8 {
4343
return std.fmt.allocPrint(allocator, "{s}/state.json", .{data});
4444
}
4545

46+
pub fn makeDirAbsoluteRecursive(path: []const u8) !void {
47+
std.fs.makeDirAbsolute(path) catch |err| switch (err) {
48+
error.PathAlreadyExists => return,
49+
error.FileNotFound => {
50+
// Parent doesn't exist, create it first
51+
if (std.fs.path.dirname(path)) |parent| {
52+
try makeDirAbsoluteRecursive(parent);
53+
try std.fs.makeDirAbsolute(path);
54+
} else return err;
55+
},
56+
else => return err,
57+
};
58+
}
59+
4660
pub fn ensureDirs(allocator: std.mem.Allocator) !void {
4761
const data = try dataDir(allocator);
4862
defer allocator.free(data);
@@ -55,9 +69,6 @@ pub fn ensureDirs(allocator: std.mem.Allocator) !void {
5569

5670
const dirs = [_][]const u8{ data, cache, bin };
5771
for (dirs) |dir| {
58-
std.fs.makeDirAbsolute(dir) catch |err| switch (err) {
59-
error.PathAlreadyExists => {},
60-
else => return err,
61-
};
72+
try makeDirAbsoluteRecursive(dir);
6273
}
6374
}

0 commit comments

Comments
 (0)