Skip to content

Commit 802a8ac

Browse files
committed
refactor: upgrade to Zig v0.15.1
The first commit targets porting the entire codebase to Zig v0.15.1 compiler and stdlib. However there are still a lot of unsolved logic errors. Further commits will address those
1 parent aa02c4f commit 802a8ac

File tree

9 files changed

+138
-97
lines changed

9 files changed

+138
-97
lines changed

build.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub fn build(b: *std.Build) !void {
1010
if (default_os.isBSD() or default_os.isDarwin() or default_os == std.Target.Os.Tag.linux) {
1111
common.link_libc = true;
1212
}
13+
const zip = b.dependency("zip", .{});
1314

1415
const strip = if (optimize == std.builtin.OptimizeMode.ReleaseSafe) true else null;
1516

@@ -22,6 +23,8 @@ pub fn build(b: *std.Build) !void {
2223
}) },
2324
);
2425
zigverm.subsystem = .Console;
26+
zigverm.root_module.addImport("zip", zip.module("zip"));
27+
2528
const zig = b.addExecutable(.{ .name = "zig", .root_module = b.createModule(.{
2629
.root_source_file = b.path("src/zig/main.zig"),
2730
.target = target,

build.zig.zon

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
.{
22
.name = .zigverm,
3-
.version = "0.6.2",
4-
.minimum_zig_version = "0.11.0",
3+
.version = "0.7.0",
4+
.dependencies = .{
5+
.zip = .{
6+
.url = "https://github.com/AMythicDev/zip.zig/archive/refs/tags/v0.3.0.tar.gz",
7+
.hash = "zip-0.3.0-eQGR_4tTAAAOUDb0yPv2-cdgLuXIrDsnRroGc9SLZ78p",
8+
},
9+
},
10+
.minimum_zig_version = "0.15.1",
511
.fingerprint = 0xffdf55ceb1c7efde,
612

713
.paths = .{

src/common/overrides.zig

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const Allocator = std.mem.Allocator;
33
const StringArrayHashMap = std.StringArrayHashMap;
44
const json = std.json;
55
const CommonPaths = @import("paths.zig").CommonPaths;
6+
const File = std.fs.File;
67

78
pub const OverrideMap = struct {
89
backing_map: json.ObjectMap,
@@ -51,8 +52,9 @@ pub const OverrideMap = struct {
5152
};
5253

5354
pub fn read_overrides(alloc: Allocator, cp: CommonPaths) !OverrideMap {
54-
var file_bufreader = std.io.bufferedReader(cp.overrides.reader());
55-
const file_reader = file_bufreader.reader();
55+
var buf: [4096]u8 = undefined;
56+
var file_bufreader = File.Reader.init(cp.overrides, &buf);
57+
const file_reader = &file_bufreader.interface;
5658

5759
var overrides = OverrideMap{ .backing_map = json.ObjectMap.init(alloc), .allocator = alloc };
5860

@@ -62,7 +64,7 @@ pub fn read_overrides(alloc: Allocator, cp: CommonPaths) !OverrideMap {
6264
// by checking if there bytes can be read and then resetting the file cursor back to 0.
6365
if (try cp.overrides.getEndPos() != 0) {
6466
try cp.overrides.seekTo(0);
65-
var json_reader = json.reader(alloc, file_reader);
67+
var json_reader = json.Reader.init(alloc, file_reader);
6668
const parsed = try json.parseFromTokenSource(json.Value, alloc, &json_reader, .{});
6769
defer {
6870
json_reader.deinit();
@@ -87,9 +89,11 @@ pub fn write_overrides(overrides: OverrideMap, cp: CommonPaths) !void {
8789
// isn't any weird byte writings at the beginning of the file.
8890
try cp.overrides.seekTo(0);
8991
try cp.overrides.setEndPos(0);
90-
var file_writer = std.io.bufferedWriter(cp.overrides.writer());
92+
var buf: [4096]u8 = undefined;
93+
var file_writer = cp.overrides.writer(&buf);
94+
const intf = &file_writer.interface;
9195

92-
try json.stringify(json.Value{ .object = overrides.backing_map }, .{ .whitespace = .indent_2 }, file_writer.writer());
93-
_ = try file_writer.write("\n");
94-
try file_writer.flush();
96+
try json.Stringify.value(json.Value{ .object = overrides.backing_map }, .{ .whitespace = .indent_2 }, intf);
97+
_ = try intf.write("\n");
98+
try file_writer.end();
9599
}

src/common/root.zig

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const RelError = error{
1212
InvalidVersionSpec,
1313
Overflow,
1414
OutOfMemory,
15+
WriteFailed,
1516
};
1617

1718
pub const ReleaseSpec = union(enum) { Master, Stable, MajorMinorVersionSpec: []const u8, FullVersionSpec: []const u8 };
@@ -28,9 +29,11 @@ pub const Release = struct {
2829
ReleaseSpec.FullVersionSpec => |v| return try alloc.dupe(u8, v),
2930
else => {
3031
if (self.actual_version == null) @panic("actual_version() called without resolving");
31-
var buffer = std.ArrayList(u8).init(alloc);
32-
defer buffer.deinit();
33-
try self.actual_version.?.format("", .{}, buffer.writer());
32+
var buffer: std.ArrayListUnmanaged(u8) = .empty;
33+
defer buffer.deinit(alloc);
34+
var writer = std.Io.Writer.Allocating.fromArrayList(alloc, &buffer);
35+
const intf = &writer.writer;
36+
try self.actual_version.?.format(intf);
3437
return try alloc.dupe(u8, buffer.items);
3538
},
3639
}
@@ -98,13 +101,15 @@ pub const Release = struct {
98101

99102
pub inline fn completeSpec(spec: []const u8) RelError!std.SemanticVersion {
100103
const count = std.mem.count(u8, spec, ".");
101-
var buffer = try std.BoundedArray(u8, 24).fromSlice(spec);
104+
var buf: [24]u8 = undefined;
105+
var buffer = std.ArrayListUnmanaged(u8).initBuffer(&buf);
106+
try buffer.appendSliceBounded(spec);
102107

103108
if (count == 2)
104109
return std.SemanticVersion.parse(spec) catch return RelError.InvalidVersionSpec
105110
else if (count == 1) {
106-
try buffer.appendSlice(".0");
107-
return std.SemanticVersion.parse(buffer.slice()) catch return RelError.InvalidVersionSpec;
111+
try buffer.appendSliceBounded(".0");
112+
return std.SemanticVersion.parse(buffer.items) catch return RelError.InvalidVersionSpec;
108113
} else return RelError.InvalidVersionSpec;
109114
}
110115
};

src/install.zig

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const Sha256 = std.crypto.hash.sha2.Sha256;
1414
const release_name = common.release_name;
1515
const AtomicOrder = std.builtin.AtomicOrder;
1616
const time = std.time;
17+
const File = std.fs.File;
1718

1819
const default_os = builtin.target.os.tag;
1920
const default_arch = builtin.target.cpu.arch;
@@ -43,11 +44,13 @@ pub fn install_release(alloc: Allocator, client: *Client, releases: json.Value,
4344
var tarball = try get_correct_tarball(alloc, client, tarball_dw_filename, tarball_url, total_size, shasum, cp, 0);
4445
defer tarball.close();
4546

46-
var tarball_reader = std.io.bufferedReader(tarball.reader());
47+
var buf: [4096]u8 = undefined;
48+
var tarball_reader = tarball.reader(&buf);
49+
const tbl_intf = &tarball_reader.interface;
4750

4851
std.log.info("Extracting {s}", .{tarball_dw_filename});
4952
try cp.install_dir.deleteTree(try release_name(alloc, rel.*));
50-
try extract_xz(alloc, cp, rel.*, tarball_reader.reader());
53+
try extract_xz(alloc, cp, rel.*, tbl_intf);
5154

5255
try cp.download_dir.deleteFile(tarball_dw_filename);
5356
}
@@ -58,11 +61,13 @@ fn get_correct_tarball(alloc: Allocator, client: *Client, tarball_dw_filename: [
5861
// open the file with .truncate = false and then later move the file cursor to the end of the file using seekFromEnd().
5962
// This is basically Zig's equivalent to *open in append mode*.
6063
var tarball = try cp.download_dir.createFile(tarball_dw_filename, .{ .read = true, .truncate = force_redownload });
61-
const tarball_size = if (force_redownload) 0 else (try tarball.metadata()).size();
64+
const tarball_size = if (force_redownload) 0 else try tarball.getEndPos();
65+
66+
var buf: [4096]u8 = undefined;
6267

6368
if (tarball_size < total_size or force_redownload) {
6469
try tarball.seekTo(tarball_size);
65-
var tarball_writer = std.io.bufferedWriter(tarball.writer());
70+
var tarball_writer = tarball.writer(&buf);
6671
try download_tarball(
6772
alloc,
6873
client,
@@ -76,8 +81,9 @@ fn get_correct_tarball(alloc: Allocator, client: *Client, tarball_dw_filename: [
7681
std.log.info("Found already existing tarball, using that", .{});
7782
}
7883

79-
var tarball_reader = std.io.bufferedReader(tarball.reader());
80-
const hash_matched = try check_hash(shasum, tarball_reader.reader());
84+
var tarball_reader = tarball.reader(&buf);
85+
const tbl_intf = &tarball_reader.interface;
86+
const hash_matched = try check_hash(shasum, tbl_intf);
8187

8288
if (!hash_matched) {
8389
if (tries < 3) {
@@ -92,7 +98,7 @@ fn get_correct_tarball(alloc: Allocator, client: *Client, tarball_dw_filename: [
9298
return tarball;
9399
}
94100

95-
pub fn download_tarball(alloc: Allocator, client: *Client, tb_url: []const u8, tb_writer: anytype, tarball_size: u64, total_size: usize) !void {
101+
pub fn download_tarball(alloc: Allocator, client: *Client, tb_url: []const u8, tb_writer: *std.fs.File.Writer, tarball_size: u64, total_size: usize) !void {
96102
std.log.info("Downloading {s}", .{tb_url});
97103
const tarball_uri = try std.Uri.parse(tb_url);
98104

@@ -105,17 +111,15 @@ pub fn download_tarball(alloc: Allocator, client: *Client, tb_url: []const u8, t
105111

106112
// Attach the Range header for partial downloads
107113
if (tarball_size > 0) {
108-
var size = std.ArrayList(u8).init(alloc);
109-
try size.appendSlice("bytes=");
110-
var size_writer = size.writer();
111-
try std.fmt.formatInt(tarball_size, 10, .lower, .{}, &size_writer);
112-
try size.append('-');
114+
var size: std.ArrayListUnmanaged(u8) = .empty;
115+
try size.print(alloc, "bytes={}-", .{tarball_size});
113116
req.?.extra_headers = &.{http.Header{ .name = "Range", .value = size.items }};
114117
}
115118

116-
try req.?.send();
117-
try req.?.wait();
118-
var reader = req.?.reader();
119+
try req.?.sendBodiless();
120+
var response = try req.?.receiveHead(&.{});
121+
122+
var reader = response.reader(&.{});
119123

120124
var buff: [1024]u8 = undefined;
121125

@@ -125,21 +129,24 @@ pub fn download_tarball(alloc: Allocator, client: *Client, tb_url: []const u8, t
125129
const tarball_size_d: f64 = @floatFromInt(tarball_size);
126130

127131
const progress_thread = try std.Thread.spawn(.{}, download_progress_bar, .{ &dlnow, tarball_size_d, total_size_d });
132+
const tbw_intf = &tb_writer.interface;
128133
while (tarball_size_d + dlnow.load(AtomicOrder.monotonic) <= total_size_d) {
129-
const len = try reader.read(&buff);
134+
const len = try reader.readSliceShort(&buff);
130135
if (len == 0) {
131136
break;
132137
}
133-
_ = try tb_writer.write(buff[0..len]);
138+
_ = try tbw_intf.write(buff[0..len]);
134139

135140
_ = dlnow.fetchAdd(@floatFromInt(len), AtomicOrder.monotonic);
136141
}
137142
progress_thread.join();
138-
try tb_writer.flush();
143+
try tb_writer.end();
139144
}
140145

141146
pub fn download_progress_bar(dlnow: *std.atomic.Value(f32), tarball_size: f64, total_size: f64) !void {
142-
var stderr_writer = std.io.getStdErr().writer();
147+
const stderr = std.fs.File.stderr();
148+
var stderrw = std.fs.File.Writer.init(stderr, &.{});
149+
const stderr_writer = &stderrw.interface;
143150
var progress_bar: [150]u8 = ("░" ** 50).*;
144151
var bars: u8 = 0;
145152
var timer = try time.Timer.start();
@@ -157,7 +164,7 @@ pub fn download_progress_bar(dlnow: *std.atomic.Value(f32), tarball_size: f64, t
157164

158165
if (downloaded + tarball_size >= total_size) break;
159166

160-
std.time.sleep(500 * time.ns_per_ms);
167+
std.Thread.sleep(500 * time.ns_per_ms);
161168
downloaded = dlnow.load(AtomicOrder.monotonic);
162169
}
163170
try stderr_writer.print("\n", .{});
@@ -174,40 +181,39 @@ pub fn get_json_dslist(client: *Client) anyerror!JsonResponse {
174181
std.process.exit(1);
175182
}
176183

177-
try req.?.send();
178-
try req.?.wait();
184+
try req.?.sendBodiless();
185+
var response = try req.?.receiveHead(&.{});
179186

180187
var json_buff: [1024 * 100]u8 = undefined;
181-
const bytes_read = try req.?.reader().readAll(&json_buff);
188+
const res_r = response.reader(&.{});
189+
const bytes_read = try res_r.readSliceShort(&json_buff);
182190

183191
return JsonResponse{ .body = json_buff, .length = bytes_read };
184192
}
185193

186194
pub fn make_request(client: *Client, uri: std.Uri) ?Client.Request {
195+
// TODO: REMOVE THIS IF UNUSED
187196
var http_header_buff: [8192]u8 = undefined;
197+
_ = &http_header_buff;
188198
for (0..5) |i| {
189-
const tryreq = client.open(
190-
http.Method.GET,
191-
uri,
192-
Client.RequestOptions{ .server_header_buffer = &http_header_buff },
193-
);
199+
const tryreq = client.request(http.Method.GET, uri, .{});
194200
if (tryreq) |r| {
195201
return r;
196202
} else |err| {
197203
std.log.warn("{}. Retrying again [{}/5]", .{ err, i + 1 });
198-
std.time.sleep(std.time.ns_per_ms * 500);
204+
std.Thread.sleep(std.time.ns_per_ms * 500);
199205
}
200206
}
201207
return null;
202208
}
203209

204-
pub fn check_hash(hashstr: *const [64]u8, reader: anytype) !bool {
210+
pub fn check_hash(hashstr: *const [64]u8, reader: *std.Io.Reader) !bool {
205211
var buff: [1024]u8 = undefined;
206212

207213
var hasher = Sha256.init(.{});
208214

209215
while (true) {
210-
const len = try reader.read(&buff);
216+
const len = try reader.readSliceShort(&buff);
211217
if (len == 0) {
212218
break;
213219
}
@@ -218,10 +224,14 @@ pub fn check_hash(hashstr: *const [64]u8, reader: anytype) !bool {
218224
return std.mem.eql(u8, &hasher.finalResult(), &hash);
219225
}
220226

221-
inline fn extract_xz(alloc: Allocator, dirs: CommonPaths, rel: Release, reader: anytype) !void {
222-
var xz = try std.compress.xz.decompress(alloc, reader);
227+
inline fn extract_xz(alloc: Allocator, dirs: CommonPaths, rel: Release, reader: *std.Io.Reader) !void {
228+
// HACK: Use the older interface until Zig upgrades this
229+
const r = reader.adaptToOldInterface();
230+
var xz = try std.compress.xz.decompress(alloc, r);
223231
const release_dir = try dirs.install_dir.makeOpenPath(try release_name(alloc, rel), .{});
224-
try std.tar.pipeToFileSystem(release_dir, xz.reader(), .{ .strip_components = 1 });
232+
var adpt = xz.reader().adaptToNewApi(&.{});
233+
const intf = &adpt.new_interface;
234+
try std.tar.pipeToFileSystem(release_dir, intf, .{ .strip_components = 1 });
225235
}
226236

227237
pub fn target_name() []const u8 {

src/main.zig

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ fn open_std(alloc: Allocator, cp: CommonPaths, ver: ?[]const u8) !void {
9898
"zig",
9999
});
100100

101-
var executable = std.ArrayList([]const u8).init(alloc);
102-
try executable.append(zig_path);
103-
try executable.append("std");
101+
var executable: std.ArrayListUnmanaged([]const u8) = .empty;
102+
try executable.append(alloc, zig_path);
103+
try executable.append(alloc, "std");
104104
var child = std.process.Child.init(executable.items, alloc);
105105
const term = try child.spawnAndWait();
106106
std.process.exit(term.Exited);
@@ -132,9 +132,9 @@ fn open_reference(alloc: Allocator, cp: CommonPaths, ver: ?[]const u8) !void {
132132
else => "xdg-open",
133133
};
134134

135-
var executable = std.ArrayList([]const u8).init(alloc);
136-
try executable.append(main_exe);
137-
try executable.append(langref_path);
135+
var executable: std.ArrayListUnmanaged([]const u8) = .empty;
136+
try executable.append(alloc, main_exe);
137+
try executable.append(alloc, langref_path);
138138
var child = std.process.Child.init(executable.items, alloc);
139139
try child.spawn();
140140
}
@@ -199,14 +199,14 @@ fn override_rm(alloc: Allocator, cp: CommonPaths, directory: []const u8) !void {
199199

200200
fn installed_versions(alloc: Allocator, cp: CommonPaths) ![][]const u8 {
201201
var iter = cp.install_dir.iterate();
202-
var versions = std.ArrayList([]const u8).init(alloc);
202+
var versions: std.ArrayList([]const u8) = .empty;
203203
while (try iter.next()) |i| {
204204
if (!utils.check_install_name(i.name)) continue;
205205
var components = std.mem.splitScalar(u8, i.name[4..], '-');
206206
_ = components.next();
207207
_ = components.next();
208208
const version = components.next() orelse unreachable;
209-
try versions.append(try alloc.dupe(u8, version));
209+
try versions.append(alloc, try alloc.dupe(u8, version));
210210
}
211211
return versions.items;
212212
}
@@ -238,8 +238,8 @@ fn update_zig_installation(alloc: Allocator, cp: CommonPaths, version_possible:
238238
versions = @constCast(&[1][]const u8{v});
239239
} else versions = try installed_versions(alloc, cp);
240240

241-
var updated_now = std.ArrayList([]const u8).init(alloc);
242-
var already_update = std.ArrayList([]const u8).init(alloc);
241+
var updated_now: std.ArrayList([]const u8) = .empty;
242+
var already_update: std.ArrayList([]const u8) = .empty;
243243
var client = Client{ .allocator = alloc };
244244
defer client.deinit();
245245
const resp = try install.get_json_dslist(&client);
@@ -270,21 +270,21 @@ fn update_zig_installation(alloc: Allocator, cp: CommonPaths, version_possible:
270270
} else {
271271
var zig_version = try std.SemanticVersion.parse((try get_version_from_exe(alloc, release_name)).items);
272272
var format_buf: [32]u8 = undefined;
273-
var format_buf_stream = std.io.fixedBufferStream(&format_buf);
273+
var format_buf_stream = std.Io.Writer.fixed(&format_buf);
274274
zig_version.patch += 1;
275-
try zig_version.format("", .{}, format_buf_stream.writer());
276-
to_update = releases.object.contains(format_buf_stream.getWritten());
277-
while (releases.object.contains(format_buf_stream.getWritten())) {
275+
try zig_version.format(&format_buf_stream);
276+
to_update = releases.object.contains(format_buf_stream.buffered());
277+
while (releases.object.contains(format_buf_stream.buffered())) {
278278
zig_version.patch += 1;
279-
try format_buf_stream.seekTo(0);
280-
try zig_version.format("", .{}, format_buf_stream.writer());
279+
format_buf_stream.end = 0;
280+
try zig_version.format(&format_buf_stream);
281281
}
282282
}
283283
if (to_update) {
284-
try updated_now.append(v);
284+
try updated_now.append(alloc, v);
285285
try install.install_release(alloc, &client, releases, &rel, cp);
286286
} else {
287-
try already_update.append(v);
287+
try already_update.append(alloc, v);
288288
}
289289
} else |_| {
290290
try install.install_release(alloc, &client, releases, &rel, cp);

0 commit comments

Comments
 (0)