From 0f2c85f276471bf83bf36c7942f101f709231777 Mon Sep 17 00:00:00 2001 From: jinzhongjia Date: Tue, 6 Aug 2024 23:35:09 +0800 Subject: [PATCH] feat: support install zls --- src/alias.zig | 37 ++++++++++++++++++++++++++++++++----- src/command.zig | 4 ++-- src/config.zig | 7 +++++++ src/install.zig | 20 +++++++++++++------- src/tools.zig | 21 ++++++++++++++++----- 5 files changed, 70 insertions(+), 19 deletions(-) diff --git a/src/alias.zig b/src/alias.zig index 6e58a1b..1fc236a 100644 --- a/src/alias.zig +++ b/src/alias.zig @@ -7,7 +7,7 @@ const config = @import("config.zig"); /// try to set zig version /// this will use system link on unix-like /// for windows, this will use copy dir -pub fn set_zig_version(version: []const u8) !void { +pub fn set_version(version: []const u8, is_zls: bool) !void { var arena = std.heap.ArenaAllocator.init(tools.get_allocator()); defer arena.deinit(); const arena_allocator = arena.allocator(); @@ -16,7 +16,13 @@ pub fn set_zig_version(version: []const u8) !void { const version_path = try std.fs.path.join( arena_allocator, - &.{ try tools.get_zvm_zig_version(arena_allocator), version }, + &.{ + if (is_zls) + try tools.get_zvm_zls_version(arena_allocator) + else + try tools.get_zvm_zig_version(arena_allocator), + version, + }, ); std.fs.accessAbsolute(version_path, .{}) catch |err| { @@ -27,10 +33,17 @@ pub fn set_zig_version(version: []const u8) !void { std.process.exit(1); }; - const symlink_path = try tools.get_zvm_current_zig(arena_allocator); + const symlink_path = if (is_zls) + try tools.get_zvm_current_zls(arena_allocator) + else + try tools.get_zvm_current_zig(arena_allocator); try update_current(version_path, symlink_path); - try verify_zig_version(version); + if (is_zls) { + try verify_zls_version(version); + } else { + try verify_zig_version(version); + } } fn update_current(zig_path: []const u8, symlink_path: []const u8) !void { @@ -56,7 +69,7 @@ fn update_current(zig_path: []const u8, symlink_path: []const u8) !void { fn verify_zig_version(expected_version: []const u8) !void { const allocator = tools.get_allocator(); - const actual_version = try tools.get_zig_version(allocator); + const actual_version = try tools.get_version(allocator, false); defer allocator.free(actual_version); if (!std.mem.eql(u8, expected_version, actual_version)) { @@ -65,3 +78,17 @@ fn verify_zig_version(expected_version: []const u8) !void { std.debug.print("Now using Zig version {s}\n", .{expected_version}); } } + +/// verify current zig version +fn verify_zls_version(expected_version: []const u8) !void { + const allocator = tools.get_allocator(); + + const actual_version = try tools.get_version(allocator, true); + defer allocator.free(actual_version); + + if (!std.mem.eql(u8, expected_version, actual_version)) { + std.debug.print("Expected Zls version {s}, but currently using {s}. Please check.\n", .{ expected_version, actual_version }); + } else { + std.debug.print("Now using Zls version {s}\n", .{expected_version}); + } +} diff --git a/src/command.zig b/src/command.zig index d542881..387ba3f 100644 --- a/src/command.zig +++ b/src/command.zig @@ -109,7 +109,7 @@ pub fn handle_alias(params: []const []const u8) !void { const new_params = try allocator.dupe([]const u8, params); - const current_zig = try tools.get_zvm_current_zig(allocator) ; + const current_zig = try tools.get_zvm_current_zig(allocator); const current_zig_path = try std.fs.path.join(allocator, &.{ current_zig, "zig" }); std.fs.accessAbsolute(current_zig_path, .{}) catch |err| { @@ -191,7 +191,7 @@ fn install_version(subcmd: ?[]const u8, param: ?[]const u8) !void { fn use_version(params: ?[]const u8) !void { if (params) |version| { - try alias.set_zig_version(version); + try alias.set_version(version, false); } else { std.debug.print("Error: Please specify a version to use with 'use '.\n", .{}); } diff --git a/src/config.zig b/src/config.zig index 2bc01ad..ed6f7b3 100644 --- a/src/config.zig +++ b/src/config.zig @@ -27,6 +27,13 @@ pub const zig_name = switch (builtin.os.tag) { else => @compileError("not support current platform"), }; +/// zig file name +pub const zls_name = switch (builtin.os.tag) { + .windows => "zls.exe", + .linux, .macos => "zls", + else => @compileError("not support current platform"), +}; + /// zig archive_ext pub const archive_ext = if (builtin.os.tag == .windows) "zip" diff --git a/src/install.zig b/src/install.zig index f2fbc2d..49c6603 100644 --- a/src/install.zig +++ b/src/install.zig @@ -35,7 +35,7 @@ pub fn install_zig(version: []const u8) !void { const extract_path = try std.fs.path.join(arena_allocator, &.{ version_path, version }); if (tools.does_path_exist(extract_path)) { - try alias.set_zig_version(version); + try alias.set_version(version, false); return; } @@ -68,7 +68,7 @@ pub fn install_zig(version: []const u8) !void { try extract.extract(extract_dir, new_file, if (builtin.os.tag == .windows) .zip else .tarxz, false); - try alias.set_zig_version(version); + try alias.set_version(version, false); } /// Try to install the specified version of zls @@ -86,6 +86,16 @@ pub fn install_zls(version: []const u8) !void { const arena_allocator = arena.allocator(); + // get version path + const version_path = try tools.get_zvm_zls_version(arena_allocator); + // get extract path + const extract_path = try std.fs.path.join(arena_allocator, &.{ version_path, version }); + + if (tools.does_path_exist(extract_path)) { + try alias.set_version(version, true); + return; + } + // get version data const version_data: meta.Zls.VersionData = blk: { const res = try tools.http_get(arena_allocator, config.zls_url); @@ -104,16 +114,12 @@ pub fn install_zls(version: []const u8) !void { const new_file = try tools.download(parsed_uri, file_name, null, version_data.size); defer new_file.close(); - // get version path - const version_path = try tools.get_zvm_zls_version(arena_allocator); - // get extract path - const extract_path = try std.fs.path.join(arena_allocator, &.{ version_path, version }); - try tools.try_create_path(extract_path); const extract_dir = try std.fs.openDirAbsolute(extract_path, .{}); try extract.extract(extract_dir, new_file, if (builtin.os.tag == .windows) .zip else .tarxz, true); + try alias.set_version(version, true); std.debug.print( \\zls version data: \\version: {s} diff --git a/src/tools.zig b/src/tools.zig index 1420c65..832c7ac 100644 --- a/src/tools.zig +++ b/src/tools.zig @@ -156,14 +156,25 @@ pub fn try_create_path(path: []const u8) !void { } /// try to get zig version -pub fn get_zig_version(allocator: std.mem.Allocator) ![]u8 { - const home_dir = get_home(); - const current_zig_path = try std.fs.path.join(allocator, &.{ home_dir, ".zm", "current", "zig", config.zig_name }); - defer allocator.free(current_zig_path); +pub fn get_version(allocator: std.mem.Allocator, is_zls: bool) ![]u8 { + var arena = std.heap.ArenaAllocator.init(allocator); + defer arena.deinit(); + const arena_allocator = arena.allocator(); + + const current_path = try std.fs.path.join(arena_allocator, &.{ + if (is_zls) + try get_zvm_current_zls(arena_allocator) + else + try get_zvm_current_zig(arena_allocator), + if (is_zls) + config.zls_name + else + config.zig_name, + }); // here we must use the absolute path, we can not just use "zig" // because child process will use environment variable - var child_process = std.process.Child.init(&[_][]const u8{ current_zig_path, "version" }, allocator); + var child_process = std.process.Child.init(&[_][]const u8{ current_path, if (is_zls) "--version" else "version" }, arena_allocator); child_process.stdin_behavior = .Close; child_process.stdout_behavior = .Pipe;