Skip to content

Commit

Permalink
feat: improved std.progress implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
hendriknielaender committed Nov 26, 2024
1 parent 0c2411d commit 7300983
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 70 deletions.
12 changes: 5 additions & 7 deletions src/command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const command_opts = [_]CommandOption{
};

/// Parse and handle commands
pub fn handle_command(params: []const []const u8) !void {
pub fn handle_command(params: []const []const u8, root_node: std.Progress.Node) !void {
const command: CommandData = blk: {
if (params.len < 2) break :blk CommandData{};

Expand Down Expand Up @@ -90,7 +90,7 @@ pub fn handle_command(params: []const []const u8) !void {

switch (command.cmd) {
.List => try handle_list(command.param),
.Install => try install_version(command.subcmd, command.param),
.Install => try install_version(command.subcmd, command.param, root_node),
.Use => try use_version(command.subcmd, command.param),
.Remove => try remove_version(command.subcmd, command.param),
.Version => try get_version(),
Expand Down Expand Up @@ -182,7 +182,7 @@ fn handle_list(param: ?[]const u8) !void {
}
}

fn install_version(subcmd: ?[]const u8, param: ?[]const u8) !void {
fn install_version(subcmd: ?[]const u8, param: ?[]const u8, root_node: std.Progress.Node) !void {
if (subcmd) |scmd| {
var is_zls: bool = undefined;

Expand All @@ -200,12 +200,10 @@ fn install_version(subcmd: ?[]const u8, param: ?[]const u8) !void {
return;
};

try install.install(version, is_zls);
try install.install(version, is_zls, root_node);
} else if (param) |version| {
// set zig version
try install.install(version, false);
// set zls version
//try install.install(version, true);
try install.install(version, false, root_node);
} else {
std.debug.print("Please specify a version to install: 'install zig/zls <version>' or 'install <version>'.\n", .{});
}
Expand Down
76 changes: 47 additions & 29 deletions src/install.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ const Version = struct {
};

/// try install specified version
pub fn install(version: []const u8, is_zls: bool) !void {
pub fn install(version: []const u8, is_zls: bool, root_node: Progress.Node) !void {
if (is_zls) {
try install_zls(version);
} else {
try install_zig(version);
try install_zig(version, root_node);
}
}

/// Try to install the specified version of zig
fn install_zig(version: []const u8) !void {
fn install_zig(version: []const u8, root_node: Progress.Node) !void {
var allocator = util_data.get_allocator();

const platform_str = try util_arch.platform_str(.{
Expand All @@ -43,15 +43,6 @@ fn install_zig(version: []const u8) !void {

const arena_allocator = arena.allocator();

// Determine the number of steps
const total_steps = 6;

// Initialize progress root node
const root_node = std.Progress.start(.{
.root_name = "Installing Zig",
.estimated_total_items = total_steps,
});

var items_done: usize = 0;

// Step 1: Get version path
Expand Down Expand Up @@ -85,9 +76,9 @@ fn install_zig(version: []const u8) !void {
const parsed_uri = std.Uri.parse(version_data.tarball) catch unreachable;

// Create a child progress node for the download
const download_node = root_node.start("Downloading Zig tarball", version_data.size);
const tarball_file = try util_http.download(parsed_uri, file_name, version_data.shasum, version_data.size);
defer tarball_file.close();
const download_node = root_node.start("download zig", version_data.size);
const tarball_file = try util_http.download(parsed_uri, file_name, version_data.shasum, version_data.size, download_node);
// defer tarball_file.close();
download_node.end();
items_done += 1;

Expand All @@ -110,10 +101,10 @@ fn install_zig(version: []const u8) !void {
);

// Create a child progress node for the signature download
const sig_download_node = root_node.start("Downloading Signature File", 0);
const minisig_file = try util_http.download(signature_uri, signature_file_name, null, null);
const sig_download_node = root_node.start("verifying file signature", 0);
const minisig_file = try util_http.download(signature_uri, signature_file_name, null, null, sig_download_node);
defer minisig_file.close();
sig_download_node.end();
// sig_download_node.end();
items_done += 1;
root_node.setCompletedItems(items_done);

Expand All @@ -133,10 +124,10 @@ fn install_zig(version: []const u8) !void {
root_node.setCompletedItems(items_done);

// Proceed with extraction after successful verification
const extract_node = root_node.start("Extracting Zig tarball", 0);
const extract_node = root_node.start("Extracting zig", 0);
try util_tool.try_create_path(extract_path);
const extract_dir = try std.fs.openDirAbsolute(extract_path, .{});
try util_extract.extract(extract_dir, tarball_file, if (builtin.os.tag == .windows) .zip else .tarxz, false);
try util_extract.extract(extract_dir, tarball_file, if (builtin.os.tag == .windows) .zip else .tarxz, false, extract_node);
extract_node.end();
items_done += 1;
root_node.setCompletedItems(items_done);
Expand Down Expand Up @@ -174,41 +165,68 @@ fn install_zls(version: []const u8) !void {

const arena_allocator = arena.allocator();

// get version path
// Determine total steps
const total_steps = 4;

// Initialize progress root node
const root_node = std.Progress.start(.{
.root_name = "Installing ZLS",
.estimated_total_items = total_steps,
});

var items_done: usize = 0;

// Step 1: Get version path
const version_path = try util_data.get_zvm_zls_version(arena_allocator);
// get extract path
items_done += 1;
root_node.setCompletedItems(items_done);

// Step 2: Get extract path
const extract_path = try std.fs.path.join(arena_allocator, &.{ version_path, true_version });
items_done += 1;
root_node.setCompletedItems(items_done);

if (util_tool.does_path_exist(extract_path)) {
try alias.set_version(true_version, true);
root_node.end();
return;
}

// get version data
// Step 3: Get version data
const version_data: meta.Zls.VersionData = blk: {
const res = try util_http.http_get(arena_allocator, config.zls_url);
var zls_meta = try meta.Zls.init(res, arena_allocator);
const tmp_val = try zls_meta.get_version_data(true_version, reverse_platform_str, arena_allocator);
break :blk tmp_val orelse return error.UnsupportedVersion;
};
items_done += 1;
root_node.setCompletedItems(items_done);

// Step 4: Download the tarball
const file_name = try std.mem.concat(
arena_allocator,
u8,
&.{ "zls-", reverse_platform_str, "-", true_version, ".", config.archive_ext },
);

const parsed_uri = std.Uri.parse(version_data.tarball) catch unreachable;
const new_file = try util_http.download(parsed_uri, file_name, null, version_data.size);

// Create a child progress node for the download
const download_node = root_node.start("Downloading ZLS tarball", version_data.size);
const new_file = try util_http.download(parsed_uri, file_name, null, version_data.size, download_node);
defer new_file.close();
download_node.end();
items_done += 1;
root_node.setCompletedItems(items_done);

// Proceed with extraction
const extract_node = root_node.start("Extracting ZLS tarball", 0);
try util_tool.try_create_path(extract_path);

const extract_dir = try std.fs.openDirAbsolute(extract_path, .{});
try util_extract.extract(extract_dir, new_file, if (builtin.os.tag == .windows)
.zip
else
.tarxz, true);
try util_extract.extract(extract_dir, new_file, if (builtin.os.tag == .windows) .zip else .tarxz, true, extract_node);
extract_node.end();
items_done += 1;
root_node.setCompletedItems(items_done);

try alias.set_version(true_version, true);
}
Expand Down
8 changes: 7 additions & 1 deletion src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ pub fn main() !void {
// this will detect the memory whether leak
defer if (gpa.deinit() == .leak) @panic("memory leaked!");

// Initialize the root progress node
const root_node = std.Progress.start(.{
.root_name = "zig installation",
.estimated_total_items = 6,
});

// init some useful data
try util_data.data_init(gpa.allocator());
// deinit some data
Expand All @@ -23,5 +29,5 @@ pub fn main() !void {
try command.handle_alias(args);

// parse the args and handle command
try command.handle_command(args);
try command.handle_command(args, root_node);
}
25 changes: 18 additions & 7 deletions src/util/extract.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,46 @@ const tool = @import("tool.zig");
const xz = std.compress.xz;
const tar = std.tar;

/// extract file to out_dir
/// Extract file to out_dir
pub fn extract(
out_dir: std.fs.Dir,
file: std.fs.File,
file_type: enum { tarxz, zip },
is_zls: bool,
root_node: std.Progress.Node,
) !void {
switch (file_type) {
.zip => try extract_zip_dir(out_dir, file),
.tarxz => try extract_tarxz_to_dir(out_dir, file, is_zls),
.zip => try extract_zip_dir(out_dir, file, root_node),
.tarxz => try extract_tarxz_to_dir(out_dir, file, is_zls, root_node),
}
}

/// extract tar.xz to dir
fn extract_tarxz_to_dir(out_dir: std.fs.Dir, file: std.fs.File, is_zls: bool) !void {
/// Extract tar.xz to dir
fn extract_tarxz_to_dir(
out_dir: std.fs.Dir,
file: std.fs.File,
is_zls: bool,
root_node: std.Progress.Node,
) !void {
var buffered_reader = std.io.bufferedReader(file.reader());

var decompressed = try xz.decompress(data.get_allocator(), buffered_reader.reader());
defer decompressed.deinit();

// Start extraction with an indeterminate progress indicator
root_node.setEstimatedTotalItems(0);

try tar.pipeToFileSystem(
out_dir,
decompressed.reader(),
.{ .mode_mode = .executable_bit_only, .strip_components = if (is_zls) 0 else 1 },
);

root_node.setCompletedItems(1);
}

/// extract zip to directory
fn extract_zip_dir(out_dir: std.fs.Dir, file: std.fs.File) !void {
/// Extract zip to directory
fn extract_zip_dir(out_dir: std.fs.Dir, file: std.fs.File, _: std.Progress.Node) !void {
var arena = std.heap.ArenaAllocator.init(data.get_allocator());
defer arena.deinit();

Expand Down
Loading

0 comments on commit 7300983

Please sign in to comment.