Skip to content

Commit 53f6172

Browse files
committed
Version Fetching: Cache the master version
1 parent 84be780 commit 53f6172

File tree

7 files changed

+91
-18
lines changed

7 files changed

+91
-18
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
| :---------------: | :----------------------------------------------------------: |
1414
| install [version] | Installs a zig version |
1515
| setup [version] | Installs a zig version and sets it as default in the config. |
16-
| exists [version] | Check if a zig version is installed on the system |
16+
| exists [version] | Check if a zig version is installed on the system |
17+
| recache-master | Re-cache the master version |
1718
| help | Help screen |
1819
| version | Outputs zigd version |
1920

@@ -55,6 +56,10 @@ default=0.13.0
5556

5657
### `zig build`
5758

59+
## Important Stuff to know
60+
61+
### `master` version is cached for 12 hours at (zigd directory)/cached_master, you can use `zigd recache-master` to update it.
62+
5863
## An Example Usage
5964

6065
```

build.zig.zon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.{
22
.name = "zigd",
3-
.version = "0.0.3",
3+
.version = "0.0.4",
44
.minimum_zig_version = "0.13.0",
55
.paths = .{
66
"build.zig",

src/utils.zig

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,21 @@ pub inline fn createDirectoryIgnoreExist(path: []const u8) !void {
5858
};
5959
}
6060

61-
pub inline fn existsReadFileCwd(allocator: std.mem.Allocator, cwd_path: []const u8) !?[]u8 {
61+
pub inline fn existsOpenFile(cwd_path: []const u8, flags: std.fs.File.OpenFlags) !?std.fs.File {
62+
return std.fs.cwd().openFile(cwd_path, flags) catch |e| switch (e) {
63+
std.fs.File.OpenError.FileNotFound => null,
64+
else => e,
65+
};
66+
}
67+
68+
pub inline fn existsReadFile(allocator: std.mem.Allocator, cwd_path: []const u8) !?[]u8 {
6269
return std.fs.cwd().readFileAlloc(allocator, cwd_path, std.math.maxInt(usize)) catch |e| switch (e) {
6370
std.fs.File.OpenError.FileNotFound => null,
6471
else => e,
6572
};
6673
}
6774

68-
pub inline fn existsReadFileCwdSentinel(allocator: std.mem.Allocator, cwd_path: [:0]const u8) !?[:0]u8 {
75+
pub inline fn existsReadFileSentinel(allocator: std.mem.Allocator, cwd_path: [:0]const u8) !?[:0]u8 {
6976
return std.fs.cwd().readFileAllocOptions(allocator, cwd_path, std.math.maxInt(usize), null, 1, 0) catch |e| switch (e) {
7077
std.fs.File.OpenError.FileNotFound => null,
7178
else => e,

src/zigd.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.3
1+
0.0.4

src/zigdcli.zig

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const Command = enum {
66
install,
77
setup,
88
exists,
9+
@"recache-master",
910
help,
1011
version,
1112
};
@@ -28,6 +29,7 @@ pub fn main() !void {
2829
.install => install(allocator, args),
2930
.setup => setup(allocator, args),
3031
.exists => exists(allocator, args),
32+
.@"recache-master" => recache_master(allocator),
3133
.help => help_menu(),
3234
.version => version(),
3335
};
@@ -44,6 +46,7 @@ fn help_menu() !void {
4446
\\install [version] - Install a zig version
4547
\\setup [version] - First time setup (creates a config and installs the version)
4648
\\exists [version] - Check if a zig version is installed on the system
49+
\\recache-master - Re-cache the master version
4750
\\help - Outputs this help Menu
4851
\\version - Outputs zigd version
4952
\\
@@ -69,17 +72,17 @@ fn install(allocator: std.mem.Allocator, args: []const []const u8) !void {
6972
return;
7073
}
7174

72-
var zig_version = try zigdcore.ZigVersion.parse(allocator, args[2], &user_arg, false);
75+
const zigd_path = try zigdcore.getZigdPath(allocator);
76+
defer allocator.free(zigd_path);
77+
78+
var zig_version = try zigdcore.ZigVersion.parse(allocator, args[2], &user_arg, false, zigd_path, true);
7379
defer zig_version.deinitIfMasterOrZigverOrZonver(allocator);
7480

7581
try std.io.getStdOut().writer().print("Installing zig version {s}\n", .{zig_version});
7682

7783
const download_url = try zigdcore.downloadUrlFromVersion(allocator, zig_version.as_string, zig_version.source == .Master);
7884
defer allocator.free(download_url);
7985

80-
const zigd_path = try zigdcore.getZigdPath(allocator);
81-
defer allocator.free(zigd_path);
82-
8386
if (!try zigdcore.install_zig(allocator, download_url, zigd_path, zig_version)) {
8487
std.log.err("Installation failed!", .{});
8588
}
@@ -117,7 +120,7 @@ fn setup(allocator: std.mem.Allocator, args: []const []const u8) !void {
117120
}
118121
}
119122

120-
var zig_version = try zigdcore.ZigVersion.parse(allocator, args[2], &user_arg, false);
123+
var zig_version = try zigdcore.ZigVersion.parse(allocator, args[2], &user_arg, false, zigd_path, true);
121124
defer zig_version.deinitIfMasterOrZigverOrZonver(allocator);
122125

123126
if (zig_version.source == .Master) {
@@ -168,10 +171,10 @@ fn exists(allocator: std.mem.Allocator, args: []const []const u8) !void {
168171
const zigd_path = try zigdcore.getZigdPath(allocator);
169172
defer allocator.free(zigd_path);
170173

171-
var zig_version = try zigdcore.ZigVersion.parse(allocator, args[2], &user_arg, false);
174+
var zig_version = try zigdcore.ZigVersion.parse(allocator, args[2], &user_arg, false, zigd_path, true);
172175
defer zig_version.deinitIfMasterOrZigverOrZonver(allocator);
173176

174-
const version_path = try std.fs.path.join(allocator, &.{ zigd_path, "versions", args[2] });
177+
const version_path = try std.fs.path.join(allocator, &.{ zigd_path, "versions", zig_version.as_string });
175178
defer allocator.free(version_path);
176179

177180
if (try utils.isDirectory(version_path)) {
@@ -180,3 +183,19 @@ fn exists(allocator: std.mem.Allocator, args: []const []const u8) !void {
180183
try std.io.getStdOut().writer().writeAll("No!\n");
181184
}
182185
}
186+
187+
fn recache_master(allocator: std.mem.Allocator) !void {
188+
const zigd_path = try zigdcore.getZigdPath(allocator);
189+
defer allocator.free(zigd_path);
190+
191+
const master = try zigdcore.fetchMaster(allocator, zigd_path, false);
192+
defer allocator.free(master);
193+
194+
const cache_path = try zigdcore.getCachePath(allocator, zigd_path);
195+
defer allocator.free(cache_path);
196+
197+
const cache_file = try zigdcore.getCacheFile(cache_path);
198+
defer cache_file.close();
199+
200+
try cache_file.writer().writeAll(master);
201+
}

src/zigdcore.zig

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,46 @@ pub fn install_zig(allocator: std.mem.Allocator, download_url: []const u8, insta
8484
return true;
8585
}
8686

87-
pub fn masterFromIndex(allocator: std.mem.Allocator) ![]const u8 {
87+
pub fn getCachePath(allocator: std.mem.Allocator, zigd_path: []const u8) ![]u8 {
88+
return try std.fs.path.join(allocator, &.{ zigd_path, "cached_master" });
89+
}
90+
91+
pub fn getCacheFile(cache_path: []const u8) !std.fs.File {
92+
return try utils.existsOpenFile(cache_path, .{ .mode = .read_write }) orelse v: {
93+
break :v try std.fs.createFileAbsolute(cache_path, .{
94+
.read = true,
95+
.truncate = false,
96+
.exclusive = true,
97+
});
98+
};
99+
}
100+
101+
// TODO: Add an command to re-cache or disable cache
102+
// Caller frees the memory
103+
pub fn fetchMaster(allocator: std.mem.Allocator, zigd_path: []const u8, allow_cache: bool) ![]u8 {
104+
const cache_path: ?[]const u8 = if (allow_cache)
105+
try getCachePath(allocator, zigd_path)
106+
else
107+
null;
108+
defer if (cache_path) |cp| allocator.free(cp);
109+
110+
const cache_file: ?std.fs.File = if (allow_cache) try getCacheFile(cache_path orelse unreachable) else null;
111+
defer if (cache_file) |cf| cf.close();
112+
113+
if (allow_cache) {
114+
const file_stat = try (cache_file orelse unreachable).stat();
115+
116+
// If last modified less than 12 hours ago
117+
if (file_stat.mtime > std.time.nanoTimestamp() - (12 * std.time.ns_per_hour)) {
118+
const ver = try (cache_file orelse unreachable).readToEndAlloc(allocator, std.math.maxInt(usize));
119+
120+
if (!std.meta.isError(std.SemanticVersion.parse(ver)))
121+
return ver;
122+
123+
allocator.free(ver);
124+
}
125+
}
126+
88127
var client = std.http.Client{ .allocator = allocator };
89128
defer client.deinit();
90129

@@ -121,6 +160,9 @@ pub fn masterFromIndex(allocator: std.mem.Allocator) ![]const u8 {
121160
return error.VersionNotString;
122161
}
123162

163+
if (allow_cache)
164+
try (cache_file orelse unreachable).writer().writeAll(version.string);
165+
124166
return try allocator.dupe(u8, version.string);
125167
}
126168

@@ -146,7 +188,7 @@ pub const ZigVersion = struct {
146188
};
147189

148190
// Handles the "master" case
149-
pub fn parse(allocator: std.mem.Allocator, str: []const u8, source: *Source, free_instant_if_zigver: bool) !@This() {
191+
pub fn parse(allocator: std.mem.Allocator, str: []const u8, source: *Source, free_instant_if_zigver: bool, zigd_path: []const u8, allow_cache: bool) !@This() {
150192
var zig_version: @This() = .{
151193
.as_string = str,
152194
.source = source.*,
@@ -157,7 +199,7 @@ pub const ZigVersion = struct {
157199
allocator.free(str);
158200

159201
zig_version = .{
160-
.as_string = try masterFromIndex(allocator),
202+
.as_string = try fetchMaster(allocator, zigd_path, allow_cache),
161203
.source = .{ .Master = source },
162204
};
163205
}

src/zigdemu.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ pub fn main() !void {
2222
defer config.deinit();
2323

2424
var zig_version: zigdcore.ZigVersion = v: {
25-
if (try utils.existsReadFileCwd(allocator, "zig.ver")) |zig_ver| {
25+
if (try utils.existsReadFile(allocator, "zig.ver")) |zig_ver| {
2626
// Can't error so no need for errdefer in this scope
2727
break :v zigdcore.ZigVersion{
2828
.as_string = zig_ver,
2929
.source = .Zigver,
3030
};
3131
}
3232

33-
if (try utils.existsReadFileCwdSentinel(allocator, "build.zig.zon")) |build_zig_zon| {
33+
if (try utils.existsReadFileSentinel(allocator, "build.zig.zon")) |build_zig_zon| {
3434
defer allocator.free(build_zig_zon);
3535

3636
if (try zon_minimum_version(allocator, build_zig_zon)) |zonver| {
@@ -62,7 +62,7 @@ pub fn main() !void {
6262
return;
6363
};
6464

65-
zig_version = try zigdcore.ZigVersion.parse(allocator, zig_version.as_string, &zig_version.source, true);
65+
zig_version = try zigdcore.ZigVersion.parse(allocator, zig_version.as_string, &zig_version.source, true, zigd_path, true);
6666
defer zig_version.deinitIfMasterOrZigverOrZonver(allocator);
6767

6868
const zig_binary_path = try std.fs.path.join(allocator, &.{ zigd_path, "versions", zig_version.as_string, "zig" ++ utils.binary_ext });

0 commit comments

Comments
 (0)