diff --git a/src/alias.zig b/src/alias.zig index 5a9408d..7fb7c46 100644 --- a/src/alias.zig +++ b/src/alias.zig @@ -3,14 +3,16 @@ const builtin = @import("builtin"); const tools = @import("tools.zig"); pub fn setZigVersion(version: []const u8) !void { - const allocator = std.heap.page_allocator; - const userHome = tools.getHome(); + const allocator = tools.getAllocator(); - const zigPath = try std.fs.path.join(allocator, &[_][]const u8{ userHome, ".zm", "versions", version }); - defer allocator.free(zigPath); + var arena = std.heap.ArenaAllocator.init(allocator); + defer arena.deinit(); + const arena_allocator = arena.allocator(); - const symlinkPath = try std.fs.path.join(allocator, &[_][]const u8{ userHome, ".zm", "current" }); - defer allocator.free(symlinkPath); + const userHome = tools.getHome(); + + const zigPath = try std.fs.path.join(arena_allocator, &[_][]const u8{ userHome, ".zm", "versions", version }); + const symlinkPath = try std.fs.path.join(arena_allocator, &[_][]const u8{ userHome, ".zm", "current" }); try updateSymlink(zigPath, symlinkPath); try verifyZigVersion(allocator, version); diff --git a/src/command.zig b/src/command.zig index b9f1da8..3024f23 100644 --- a/src/command.zig +++ b/src/command.zig @@ -2,6 +2,7 @@ const std = @import("std"); const versions = @import("versions.zig"); const install = @import("install.zig"); const alias = @import("alias.zig"); +const tools = @import("tools.zig"); const options = @import("options"); @@ -42,10 +43,11 @@ pub fn handleCommands(cmd: Command, params: ?[]const u8) !void { } fn handleList() !void { - const allocator = std.heap.page_allocator; - const versionsList = try versions.list(allocator); - defer versionsList.deinit(); - for (versionsList.items) |version| { + const allocator = tools.getAllocator(); + var version_list = try versions.VersionList.init(allocator); + defer version_list.deinit(); + + for (version_list.slice()) |version| { std.debug.print("{s}\n", .{version}); } } diff --git a/src/download.zig b/src/download.zig index 9001de9..0e106ab 100644 --- a/src/download.zig +++ b/src/download.zig @@ -148,7 +148,6 @@ fn downloadAndExtract( download_node.end(); var extract_node = root_node.start("Extracting", 1); - const c_allocator = std.heap.c_allocator; // ~/.zm/versions/zig-macos-x86_64-0.10.0.tar.xz const data_allocator = tools.getAllocator(); @@ -175,12 +174,16 @@ fn downloadAndExtract( const downloaded_file = try zvm_dir.openFile(downloaded_file_path, .{}); defer downloaded_file.close(); - _ = try lib.extract_tarxz_to_dir(c_allocator, zvm_dir_version, downloaded_file); + if (builtin.os.tag == .windows) { + try lib.extract_zip_dir(zvm_dir_version, downloaded_file); + } else { + try lib.extract_tarxz_to_dir(allocator, zvm_dir_version, downloaded_file); + } + extract_node.end(); var result: [32]u8 = undefined; sha256.final(&result); - //std.debug.print("Hash computation complete. Hash: {s}\n", .{std.fmt.fmtSliceHexLower(&result)}); return result; } diff --git a/src/extract.zig b/src/extract.zig index 6175342..ae55c1c 100644 --- a/src/extract.zig +++ b/src/extract.zig @@ -3,14 +3,10 @@ const builtin = @import("builtin"); const tools = @import("tools.zig"); pub fn extract_tarxz_to_dir(allocator: std.mem.Allocator, outDir: std.fs.Dir, file: std.fs.File) !void { - if (builtin.os.tag == .windows) { - try extract_zip_dir(outDir, file); - } else { - var buffered_reader = std.io.bufferedReader(file.reader()); - var decompressed = try std.compress.xz.decompress(allocator, buffered_reader.reader()); - defer decompressed.deinit(); - try std.tar.pipeToFileSystem(outDir, decompressed.reader(), .{ .mode_mode = .executable_bit_only, .strip_components = 1 }); - } + var buffered_reader = std.io.bufferedReader(file.reader()); + var decompressed = try std.compress.xz.decompress(allocator, buffered_reader.reader()); + defer decompressed.deinit(); + try std.tar.pipeToFileSystem(outDir, decompressed.reader(), .{ .mode_mode = .executable_bit_only, .strip_components = 1 }); } pub fn extract_zip_dir(outDir: std.fs.Dir, file: std.fs.File) !void { diff --git a/src/install.zig b/src/install.zig index 9d008e2..bb9206d 100644 --- a/src/install.zig +++ b/src/install.zig @@ -3,6 +3,7 @@ const builtin = @import("builtin"); const hash = @import("hash.zig"); const download = @import("download.zig"); const architecture = @import("architecture.zig"); +const tools = @import("tools.zig"); const Allocator = std.mem.Allocator; const io = std.io; const json = std.json; @@ -27,8 +28,9 @@ const Error = error{ ContentMissing, }; +const url = "https://ziglang.org/download/index.json"; + fn fetchVersionData(allocator: Allocator, requested_version: []const u8, sub_key: []const u8) !?Version { - const url = "https://ziglang.org/download/index.json"; const uri = std.Uri.parse(url) catch unreachable; // Initialize HTTP client @@ -105,10 +107,18 @@ fn fetchVersionData(allocator: Allocator, requested_version: []const u8, sub_key } pub fn fromVersion(version: []const u8) !void { - var allocator = std.heap.page_allocator; - const platform = try architecture.detect(allocator, architecture.DetectParams{ .os = builtin.os.tag, .arch = builtin.cpu.arch, .reverse = true }) orelse unreachable; - defer allocator.free(platform); - const version_data = try fetchVersionData(allocator, version, platform); + var allocator = tools.getAllocator(); + + const platform_str = try architecture.detect(allocator, architecture.DetectParams{ + .os = builtin.os.tag, + .arch = builtin.cpu.arch, + .reverse = true, + }) orelse unreachable; + defer allocator.free(platform_str); + + var arena = std.heap.ArenaAllocator.init(allocator); + defer arena.deinit(); + const version_data = try fetchVersionData(arena.allocator(), version, platform_str); if (version_data) |data| { std.debug.print("Install {s}\n", .{data.name}); diff --git a/src/main.zig b/src/main.zig index 8a204ff..c4e3016 100644 --- a/src/main.zig +++ b/src/main.zig @@ -21,8 +21,10 @@ pub fn main() !void { try tools.dataInit(gpa.allocator()); defer tools.dataDeinit(); - const args = try std.process.argsAlloc(tools.getAllocator()); - defer std.process.argsFree(tools.getAllocator(), args); + const allocator = tools.getAllocator(); + + const args = try std.process.argsAlloc(allocator); + defer std.process.argsFree(allocator, args); const cmd_data = try parseArgs(args); try handleCommands(cmd_data.cmd, cmd_data.params); diff --git a/src/versions.zig b/src/versions.zig index f31d226..35ffb6b 100644 --- a/src/versions.zig +++ b/src/versions.zig @@ -1,42 +1,69 @@ const std = @import("std"); -pub fn list(allocator: std.mem.Allocator) !std.ArrayList([]const u8) { - const url = "https://ziglang.org/download/index.json"; - const uri = std.Uri.parse(url) catch unreachable; +// TODO: The url should be stored in a separate config file +const url = "https://ziglang.org/download/index.json"; - // Initialize HTTP client - var client = std.http.Client{ .allocator = allocator }; - defer client.deinit(); +const uri = std.Uri.parse(url) catch unreachable; - // Read the response body with 256kb buffer allocation - var buffer: [262144]u8 = undefined; // 256 * 1024 = 262kb +pub const VersionList = struct { + const List = std.ArrayList([]const u8); + lists: List, + allocator: std.mem.Allocator, - // Make the HTTP request - var req = try client.open(.GET, uri, .{ .server_header_buffer = &buffer }); - defer req.deinit(); - try req.send(); - try req.wait(); + pub fn init(allocator: std.mem.Allocator) !VersionList { + // Initialize HTTP client + var client = std.http.Client{ .allocator = allocator }; + defer client.deinit(); - // Check if request was successful - try std.testing.expect(req.response.status == .ok); + // Read the response body with 256kb buffer allocation + var buffer: [262144]u8 = undefined; // 256 * 1024 = 262kb - const read_len = try req.readAll(buffer[0..]); + // Make the HTTP request + var req = try client.open(.GET, uri, .{ .server_header_buffer = &buffer }); + defer req.deinit(); - const parsed = try std.json.parseFromSlice(std.json.Value, allocator, buffer[0..read_len], .{}); - defer parsed.deinit(); - const root = parsed.value; + // send http request + try req.send(); - // Initialize array list to hold versions - var versions = std.ArrayList([]const u8).init(allocator); + // wait response + try req.wait(); - var it = root.object.iterator(); - while (it.next()) |entry| { - const key_ptr = entry.key_ptr; - const key = key_ptr.*; + // Check if request was successful + if (req.response.status != .ok) + return error.ListResponseNotOk; - const key_copy = try allocator.dupe(u8, key); - try versions.append(key_copy); + const len = try req.readAll(buffer[0..]); + + const json = try std.json.parseFromSlice(std.json.Value, allocator, buffer[0..len], .{}); + defer json.deinit(); + const root = json.value; + + // Initialize array list to hold versions + var lists = std.ArrayList([]const u8).init(allocator); + + var iterate = root.object.iterator(); + while (iterate.next()) |entry| { + const key_ptr = entry.key_ptr; + const key = key_ptr.*; + + const key_copy = try allocator.dupe(u8, key); + try lists.append(key_copy); + } + + return VersionList{ + .lists = lists, + .allocator = allocator, + }; + } + + pub fn slice(self: *VersionList) [][]const u8 { + return self.lists.items; } - return versions; -} + pub fn deinit(self: *VersionList) void { + defer self.lists.deinit(); + for (self.lists.items) |value| { + self.allocator.free(value); + } + } +};