Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add zls support #58

Merged
merged 26 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4ad28d0
fix typo
jinzhongjia Jul 28, 2024
c9863ff
support parse zls version list
jinzhongjia Jul 28, 2024
2d86d1b
fix command parse
jinzhongjia Jul 31, 2024
ae3f8fa
some change
jinzhongjia Jul 31, 2024
7cd8355
remove `hash.zig`
jinzhongjia Jul 31, 2024
b8a6cbd
feat: add `zvm ls zig` and `zvm ls zls`
jinzhongjia Aug 2, 2024
eaf79c5
remove useless comment
jinzhongjia Aug 2, 2024
c980dd2
function integration, remove `fetch_version_data` and use `meta.Zig.g…
jinzhongjia Aug 2, 2024
b0d1698
simplify code
jinzhongjia Aug 4, 2024
7e3cd05
Refactoring the zig download section
jinzhongjia Aug 4, 2024
f553563
Before downloading, check whether the file already exists. If there i…
jinzhongjia Aug 4, 2024
37cf22c
When there is content in the version directory, use it directly
jinzhongjia Aug 4, 2024
1d42ad8
Modify zls resource acquisition logic
jinzhongjia Aug 5, 2024
305c5e9
remove download file
jinzhongjia Aug 5, 2024
25053c7
feat: support download zls
jinzhongjia Aug 6, 2024
0f2c85f
feat: support install zls
jinzhongjia Aug 6, 2024
148de26
feat: support alias zig and zls
jinzhongjia Aug 7, 2024
ffc245d
add command `remove <version>` and `remove zig/zls <version>`
jinzhongjia Aug 7, 2024
cba75d5
rename `tools.get_version` to `tools.get_current_version`
jinzhongjia Aug 7, 2024
c82c31c
add file module comment
jinzhongjia Aug 7, 2024
c4da338
Text modification
jinzhongjia Aug 8, 2024
ada0c04
Split `tools.zig` into `util/*.zig`, and put arch and extract related…
jinzhongjia Aug 8, 2024
1940599
remove useless code
jinzhongjia Aug 8, 2024
4487078
format code
jinzhongjia Aug 8, 2024
2f5061a
fix
jinzhongjia Aug 9, 2024
6045071
fix for windows platform
jinzhongjia Aug 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 48 additions & 96 deletions src/alias.zig
Original file line number Diff line number Diff line change
@@ -1,145 +1,97 @@
//! This file is used to create soft links and verify version
//! for Windows, we will use copy dir(when Windows create soft link it requires admin)
//! for set version
const std = @import("std");
const assert = std.debug.assert;
const builtin = @import("builtin");
const tools = @import("tools.zig");
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();

const user_home = tools.get_home();
const version_path = try std.fs.path.join(arena_allocator, &[_][]const u8{ user_home, ".zm", "versions", version });
const symlink_path = try tools.get_zvm_path_segment(arena_allocator, "current");
try tools.try_create_path(try tools.get_zvm_path_segment(arena_allocator, "current"));

const version_path = try std.fs.path.join(
arena_allocator,
&.{
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| {
if (err != error.FileNotFound)
return err;

std.debug.print("zig {s} is not installed, please install it!\n", .{version});
jinzhongjia marked this conversation as resolved.
Show resolved Hide resolved
std.process.exit(1);
};

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 {
assert(zig_path.len > 0);
assert(symlink_path.len > 0);

if (builtin.os.tag == .windows) {
if (does_dir_exist(symlink_path)) try std.fs.deleteTreeAbsolute(symlink_path);
try copy_dir(zig_path, symlink_path);
if (tools.does_path_exist(symlink_path)) try std.fs.deleteTreeAbsolute(symlink_path);
try tools.copy_dir(zig_path, symlink_path);
return;
}

// when platform is not windows, this is execute here

// when file exist(it is a systemlink), delete it
if (does_file_exist(symlink_path)) try std.fs.cwd().deleteFile(symlink_path);
if (tools.does_path_exist(symlink_path)) try std.fs.deleteFileAbsolute(symlink_path);

// system link it
try std.posix.symlink(zig_path, symlink_path);
}

/// Nested copy dir
/// only copy dir and file, no including link
fn copy_dir(source_dir: []const u8, dest_dir: []const u8) !void {
assert(source_dir.len > 0);
assert(dest_dir.len > 0);

var source = try std.fs.openDirAbsolute(source_dir, .{ .iterate = true });
defer source.close();

std.fs.makeDirAbsolute(dest_dir) catch |err| switch (err) {
error.PathAlreadyExists => {},
else => {
tools.log.err("Failed to create directory: {s}", .{dest_dir});
return err;
},
};

var dest = try std.fs.openDirAbsolute(dest_dir, .{ .iterate = true });
defer dest.close();

var iterate = source.iterate();
const allocator = tools.get_allocator();
while (try iterate.next()) |entry| {
const entry_name = entry.name;

const source_sub_path = try std.fs.path.join(allocator, &.{ source_dir, entry_name });
defer allocator.free(source_sub_path);

const dest_sub_path = try std.fs.path.join(allocator, &.{ dest_dir, entry_name });
defer allocator.free(dest_sub_path);

switch (entry.kind) {
.directory => try copy_dir(source_sub_path, dest_sub_path),
.file => try std.fs.copyFileAbsolute(source_sub_path, dest_sub_path, .{}),
else => {},
}
}
}

/// detect the dir whether exist
fn does_dir_exist(path: []const u8) bool {
const result = blk: {
std.fs.accessAbsolute(path, .{}) catch |err| {
if (err == error.FileNotFound)
break :blk false;
break :blk true;
};
break :blk true;
};
return result;
}

/// detect the dir whether exist
fn does_file_exist(path: []const u8) bool {
const result = blk: {
std.fs.accessAbsolute(path, .{}) catch |err| {
if (err == error.FileNotFound)
break :blk false;
break :blk true;
};
break :blk true;
};
return result;
}

/// verify current zig version
fn verify_zig_version(expected_version: []const u8) !void {
const allocator = tools.get_allocator();

const actual_version = try retrieve_zig_version(allocator);
const actual_version = try tools.get_current_version(allocator, false);
defer allocator.free(actual_version);

assert(actual_version.len > 0);

if (!std.mem.eql(u8, expected_version, actual_version)) {
std.debug.print("Expected Zig version {s}, but currently using {s}. Please check.\n", .{ expected_version, actual_version });
} else {
std.debug.print("Now using Zig version {s}\n", .{expected_version});
}
}

/// try to get zig version
fn retrieve_zig_version(allocator: std.mem.Allocator) ![]u8 {
const home_dir = tools.get_home();
const current_zig_path = try std.fs.path.join(allocator, &.{ home_dir, ".zm", "current", tools.zig_name });
defer allocator.free(current_zig_path);

// 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);

child_process.stdin_behavior = .Close;
child_process.stdout_behavior = .Pipe;
child_process.stderr_behavior = .Close;
/// verify current zig version
fn verify_zls_version(expected_version: []const u8) !void {
const allocator = tools.get_allocator();

try child_process.spawn();
const actual_version = try tools.get_current_version(allocator, true);
defer allocator.free(actual_version);

if (child_process.stdout) |stdout| {
const version = try stdout.reader().readUntilDelimiterOrEofAlloc(allocator, '\n', 100) orelse return error.EmptyVersion;
assert(version.len > 0);
return 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 });
jinzhongjia marked this conversation as resolved.
Show resolved Hide resolved
} else {
std.debug.print("Now using Zls version {s}\n", .{expected_version});
jinzhongjia marked this conversation as resolved.
Show resolved Hide resolved
}

return error.FailedToReadVersion;
}
1 change: 1 addition & 0 deletions src/architecture.zig
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! This file is used to splice os and architecture into the correct file name
const std = @import("std");

pub const DetectParams = struct {
Expand Down
Loading
Loading