1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
const std = @import("std");
const zup = @import("zup");
const Allocator = std.mem.Allocator;
const ArrayList = std.ArrayList;
const Config = zup.Config;
const Installation = zup.Installation;
const Installations = zup.Installations;
pub const params =
\\--active List the active version
\\-a, --all List the active, available, and installed versions
\\-A, --available List available versions
\\-i, --installed List installed versions
;
pub const description = "Lists Zig versions. Default is `--active -i`.";
pub const min_args = 0;
pub const max_args = 0;
pub fn main(comptime Result: type, config: Config, res: Result) !void {
const allocator = config.allocator;
var list_active = res.args.active;
var list_available = res.args.available;
var list_installed = res.args.installed;
if (res.args.all) {
list_active = true;
list_available = true;
list_installed = true;
} else if (!list_active and !list_available and !list_installed) {
list_active = true;
list_installed = true;
}
if (list_active) {
const active = try Installation.getActiveName(allocator);
defer if (active) |s| allocator.free(s);
// TODO: zig-bug should I really need to do this?
try printActive(if (active) |a| a else null);
}
if (list_installed) {
var installed = try Installation.getInstalledList(allocator);
defer Installation.deinitMap(allocator, &installed);
try printInstalledList(allocator, installed);
}
if (list_available) {
var available = try Installation.getAvailableList(config);
defer Installation.deinitMap(allocator, &available);
try printAvailableList(allocator, available);
}
}
fn printActive(active: ?[]const u8) !void {
const writer = std.io.getStdOut().writer();
try writer.writeAll("Active installation: ");
if (active) |act| {
try writer.writeAll(act);
} else {
try writer.writeAll("NONE");
}
try writer.writeByte('\n');
}
fn printAvailableList(allocator: Allocator, avail: Installations) !void {
const writer = std.io.getStdOut().writer();
try writer.writeAll("Available versions:\n");
try printList(allocator, avail);
}
fn printInstalledList(allocator: Allocator, installed: Installations) !void {
const writer = std.io.getStdOut().writer();
try writer.writeAll("Installed versions:\n");
try printList(allocator, installed);
}
fn printList(allocator: Allocator, installations: Installations) !void {
const InstallationAndName = struct {
name: []const u8,
installation: Installation,
const Self = @This();
pub fn lessThan(_: void, lhs: Self, rhs: Self) bool {
return lhs.installation.version.order(rhs.installation.version) == .lt;
}
};
var list = try ArrayList(InstallationAndName).initCapacity(allocator, installations.unmanaged.size);
defer list.deinit();
var it = installations.iterator();
while (it.next()) |kv| {
list.appendAssumeCapacity(.{ .name = kv.key_ptr.*, .installation = kv.value_ptr.* });
}
std.sort.sort(InstallationAndName, list.items, {}, InstallationAndName.lessThan);
const writer = std.io.getStdOut().writer();
for (list.items) |item| {
try writer.print(" {s}: {}\n", .{ item.name, item.installation.version });
}
}
|