summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.zig12
m---------libs/clap0
m---------libs/curl0
-rw-r--r--src/Config.zig68
-rw-r--r--src/Installation.zig48
-rw-r--r--src/list.zig4
-rw-r--r--src/main.zig4
-rw-r--r--src/remove.zig2
-rw-r--r--src/subcommand.zig2
-rw-r--r--src/switch.zig2
-rw-r--r--src/update.zig2
11 files changed, 77 insertions, 67 deletions
diff --git a/build.zig b/build.zig
index 4ff015b..56a5ed3 100644
--- a/build.zig
+++ b/build.zig
@@ -3,21 +3,15 @@ const std = @import("std");
3 3
4const Build = std.Build; 4const Build = std.Build;
5const SemanticVersion = std.SemanticVersion; 5const SemanticVersion = std.SemanticVersion;
6const Version = std.builtin.Version;
7 6
8pub fn build(b: *Build) void { 7pub fn build(b: *Build) void {
9 const target = b.standardTargetOptions(.{}); 8 const target = b.standardTargetOptions(.{});
10 const optimize = b.standardOptimizeOption(.{}); 9 const optimize = b.standardOptimizeOption(.{});
11 10
12 const semanticVersion = getSemanticVersion(b); 11 const version = getVersion(b);
13 const version = Version{
14 .major = @intCast(u32, semanticVersion.major),
15 .minor = @intCast(u32, semanticVersion.minor),
16 .patch = @intCast(u32, semanticVersion.patch),
17 };
18 12
19 const config = b.addOptions(); 13 const config = b.addOptions();
20 config.addOption(SemanticVersion, "version", semanticVersion); 14 config.addOption(SemanticVersion, "version", version);
21 15
22 const exe = b.addExecutable(.{ 16 const exe = b.addExecutable(.{
23 .name = "zup", 17 .name = "zup",
@@ -59,7 +53,7 @@ pub fn build(b: *Build) void {
59 53
60const default_version = SemanticVersion.parse("0.2.1") catch unreachable; 54const default_version = SemanticVersion.parse("0.2.1") catch unreachable;
61 55
62fn getSemanticVersion(b: *Build) SemanticVersion { 56fn getVersion(b: *Build) SemanticVersion {
63 var out_code: u8 = undefined; 57 var out_code: u8 = undefined;
64 const untrimmed = b.execAllowFail( 58 const untrimmed = b.execAllowFail(
65 &.{ "git", "-C", b.build_root.path.?, "describe", "--tags" }, 59 &.{ "git", "-C", b.build_root.path.?, "describe", "--tags" },
diff --git a/libs/clap b/libs/clap
Subproject ab69ef2db44b6c4b7f00283d52d38fbe71d16c4 Subproject bdb5853b678d68f342ec65b04a6785af522ca6c
diff --git a/libs/curl b/libs/curl
Subproject 7f920ec5be3e4b336303e93bb164c33f1e44022 Subproject f6915b7da30b39ced132c4f163ce7f2ec451065
diff --git a/src/Config.zig b/src/Config.zig
index 4eb58cc..e559cad 100644
--- a/src/Config.zig
+++ b/src/Config.zig
@@ -3,6 +3,7 @@ const std = @import("std");
3const xdg = @import("xdg"); 3const xdg = @import("xdg");
4 4
5const Allocator = std.mem.Allocator; 5const Allocator = std.mem.Allocator;
6const ArenaAllocator = std.heap.ArenaAllocator;
6const ArrayList = std.ArrayList; 7const ArrayList = std.ArrayList;
7const Config = @This(); 8const Config = @This();
8const CrossTarget = std.zig.CrossTarget; 9const CrossTarget = std.zig.CrossTarget;
@@ -55,38 +56,49 @@ pub fn deinit(self: *Config) void {
55} 56}
56 57
57fn readConfig(self: *Config, file: File) !void { 58fn readConfig(self: *Config, file: File) !void {
58 const allocator = self.allocator; 59 var arena = ArenaAllocator.init(self.allocator);
59 const reader = file.reader(); 60 defer arena.deinit();
60 61
61 var json_str = try reader.readAllAlloc(allocator, std.math.maxInt(u64)); 62 const allocator = arena.allocator();
62 defer allocator.free(json_str);
63 63
64 var parser = std.json.Parser.init(allocator, false); 64 const ConfigJson = struct {
65 defer parser.deinit(); 65 supported_targets: [][]u8,
66 66 };
67 var vt = try parser.parse(json_str);
68 defer vt.deinit();
69
70 if (vt.root != .Object) {
71 std.log.warn("Failed at reading config, root isn't object.", .{});
72 return;
73 }
74 67
75 if (vt.root.Object.get("supported_targets")) |supported_targets| blk: { 68 var reader = std.json.reader(allocator, file.reader());
76 if (supported_targets != .Array) { 69 defer reader.deinit();
77 break :blk; 70
78 } 71 const parsed = try std.json.parseFromTokenSourceLeaky(
72 ConfigJson,
73 allocator,
74 &reader,
75 .{
76 .duplicate_field_behavior = .use_last,
77 .ignore_unknown_fields = true,
78 },
79 );
80
81 try self.supported_targets.ensureUnusedCapacity(parsed.supported_targets.len);
82
83 for (parsed.supported_targets) |target| {
84 const ct = CrossTarget.parse(.{
85 .arch_os_abi = target,
86 }) catch |e| {
87 std.log.warn(
88 "Failed to parse '{s}' as a target string: {}",
89 .{ target, e },
90 );
91 continue;
92 };
79 93
80 for (supported_targets.Array.items) |supported_target| { 94 const nti = NativeTargetInfo.detect(ct) catch |e| {
81 if (supported_target != .String) { 95 std.log.warn(
82 continue; 96 "Failed to detect NativeTargetInfo from '{s}': {}",
83 } 97 .{ target, e },
98 );
99 continue;
100 };
84 101
85 const cross_target = try CrossTarget.parse(.{ 102 self.supported_targets.appendAssumeCapacity(nti.target);
86 .arch_os_abi = supported_target.String,
87 });
88 const native_target_info = try NativeTargetInfo.detect(cross_target);
89 try self.supported_targets.append(native_target_info.target);
90 }
91 } 103 }
92} 104}
diff --git a/src/Installation.zig b/src/Installation.zig
index 3ff65ea..54b870c 100644
--- a/src/Installation.zig
+++ b/src/Installation.zig
@@ -4,6 +4,7 @@ const xdg = @import("xdg");
4const zup = @import("root"); 4const zup = @import("root");
5 5
6const Allocator = std.mem.Allocator; 6const Allocator = std.mem.Allocator;
7const ArenaAllocator = std.heap.ArenaAllocator;
7const Config = zup.Config; 8const Config = zup.Config;
8const ChildProcess = std.ChildProcess; 9const ChildProcess = std.ChildProcess;
9const JsonValue = std.json.Value; 10const JsonValue = std.json.Value;
@@ -84,7 +85,7 @@ pub fn getInstalledList(allocator: Allocator) !Installations {
84 85
85 var it = zup_data_iterable.iterate(); 86 var it = zup_data_iterable.iterate();
86 while (try it.next()) |item| { 87 while (try it.next()) |item| {
87 if (item.kind != .Directory) { 88 if (item.kind != .directory) {
88 continue; 89 continue;
89 } 90 }
90 91
@@ -133,32 +134,35 @@ pub fn isInstalled(allocator: Allocator, name: []const u8) !bool {
133} 134}
134 135
135pub fn getAvailableList(config: Config) !Installations { 136pub fn getAvailableList(config: Config) !Installations {
136 const allocator = config.allocator; 137 var arena = ArenaAllocator.init(config.allocator);
138 defer arena.deinit();
137 139
138 var json_str = try curl.easyDownload(allocator, "https://ziglang.org/download/index.json"); 140 const allocator = arena.allocator();
139 defer allocator.free(json_str);
140 141
141 var parser = std.json.Parser.init(allocator, false); 142 const json_str = try curl.easyDownload(allocator, "https://ziglang.org/download/index.json");
142 defer parser.deinit();
143 143
144 var vt = try parser.parse(json_str); 144 const parsed = try std.json.parseFromSliceLeaky(
145 defer vt.deinit(); 145 JsonValue,
146 allocator,
147 json_str,
148 .{},
149 );
146 150
147 if (vt.root != .Object) { 151 if (parsed != .object) {
148 return error.JsonSchema; 152 return error.JsonSchema;
149 } 153 }
150 154
151 var installations = Installations.init(allocator); 155 var installations = Installations.init(config.allocator);
152 errdefer Installation.deinitMap(allocator, &installations); 156 errdefer Installation.deinitMap(config.allocator, &installations);
153 157
154 var it = vt.root.Object.iterator(); 158 var it = parsed.object.iterator();
155 while (it.next()) |kv| { 159 while (it.next()) |kv| {
156 var installation_opt = try parseInstallation(config, kv.key_ptr.*, kv.value_ptr.*); 160 var installation_opt = try parseInstallation(config, kv.key_ptr.*, kv.value_ptr.*);
157 if (installation_opt) |*installation| { 161 if (installation_opt) |*installation| {
158 errdefer installation.deinit(); 162 errdefer installation.deinit();
159 163
160 var name = try allocator.dupe(u8, kv.key_ptr.*); 164 var name = try config.allocator.dupe(u8, kv.key_ptr.*);
161 errdefer allocator.free(name); 165 errdefer config.allocator.free(name);
162 166
163 try installations.putNoClobber(name, installation.*); 167 try installations.putNoClobber(name, installation.*);
164 } 168 }
@@ -170,10 +174,10 @@ pub fn getAvailableList(config: Config) !Installations {
170fn parseInstallation(config: Config, name: []const u8, value: JsonValue) !?Installation { 174fn parseInstallation(config: Config, name: []const u8, value: JsonValue) !?Installation {
171 const allocator = config.allocator; 175 const allocator = config.allocator;
172 176
173 if (value != .Object) { 177 if (value != .object) {
174 return error.JsonSchema; 178 return error.JsonSchema;
175 } 179 }
176 const map = value.Object; 180 const map = value.object;
177 181
178 const url_root = url_root: { 182 const url_root = url_root: {
179 for (config.supported_targets.items) |target| { 183 for (config.supported_targets.items) |target| {
@@ -190,23 +194,23 @@ fn parseInstallation(config: Config, name: []const u8, value: JsonValue) !?Insta
190 194
191 return null; 195 return null;
192 }; 196 };
193 if (url_root != .Object) { 197 if (url_root != .object) {
194 return error.JsonSchema; 198 return error.JsonSchema;
195 } 199 }
196 const url_src = url_root.Object.get("tarball") orelse { 200 const url_src = url_root.object.get("tarball") orelse {
197 return error.JsonSchema; 201 return error.JsonSchema;
198 }; 202 };
199 if (url_src != .String) { 203 if (url_src != .string) {
200 return error.JsonSchema; 204 return error.JsonSchema;
201 } 205 }
202 var url = try allocator.dupeZ(u8, url_src.String); 206 var url = try allocator.dupeZ(u8, url_src.string);
203 errdefer allocator.free(url); 207 errdefer allocator.free(url);
204 208
205 const version_src = if (map.get("version")) |ver| blk: { 209 const version_src = if (map.get("version")) |ver| blk: {
206 if (ver != .String) { 210 if (ver != .string) {
207 return error.JsonSchema; 211 return error.JsonSchema;
208 } else { 212 } else {
209 break :blk ver.String; 213 break :blk ver.string;
210 } 214 }
211 } else blk: { 215 } else blk: {
212 break :blk name; 216 break :blk name;
diff --git a/src/list.zig b/src/list.zig
index 0a0fee9..9ff26c2 100644
--- a/src/list.zig
+++ b/src/list.zig
@@ -19,7 +19,7 @@ pub const max_args = 0;
19 19
20pub fn main(comptime Result: type, config: Config, res: Result) !void { 20pub fn main(comptime Result: type, config: Config, res: Result) !void {
21 const allocator = config.allocator; 21 const allocator = config.allocator;
22 22
23 var list_active = res.args.active != 0; 23 var list_active = res.args.active != 0;
24 var list_available = res.args.available != 0; 24 var list_available = res.args.available != 0;
25 var list_installed = res.args.installed != 0; 25 var list_installed = res.args.installed != 0;
@@ -96,7 +96,7 @@ fn printList(allocator: Allocator, installations: Installations) !void {
96 list.appendAssumeCapacity(.{ .name = kv.key_ptr.*, .installation = kv.value_ptr.* }); 96 list.appendAssumeCapacity(.{ .name = kv.key_ptr.*, .installation = kv.value_ptr.* });
97 } 97 }
98 98
99 std.sort.sort(InstallationAndName, list.items, {}, InstallationAndName.lessThan); 99 std.mem.sort(InstallationAndName, list.items, {}, InstallationAndName.lessThan);
100 100
101 const writer = std.io.getStdOut().writer(); 101 const writer = std.io.getStdOut().writer();
102 for (list.items) |item| { 102 for (list.items) |item| {
diff --git a/src/main.zig b/src/main.zig
index 93356d6..93cd5d4 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -60,7 +60,7 @@ const CommandMap = blk: {
60 map_data[1] = .{ "--version", .version }; 60 map_data[1] = .{ "--version", .version };
61 var idx: usize = 2; 61 var idx: usize = 2;
62 inline for (commands) |command| { 62 inline for (commands) |command| {
63 map_data[idx] = .{ command.name, @intToEnum(Command, command.value) }; 63 map_data[idx] = .{ command.name, @as(Command, @enumFromInt(command.value)) };
64 idx += 1; 64 idx += 1;
65 } 65 }
66 66
@@ -78,7 +78,7 @@ fn dispatch(
78 const cmd_enum = CommandMap.get(cmd) orelse return @call(.auto, default_fn, args); 78 const cmd_enum = CommandMap.get(cmd) orelse return @call(.auto, default_fn, args);
79 const commands = @typeInfo(Command).Enum.fields; 79 const commands = @typeInfo(Command).Enum.fields;
80 inline for (commands) |command| { 80 inline for (commands) |command| {
81 if (@enumToInt(cmd_enum) == command.value) { 81 if (@intFromEnum(cmd_enum) == command.value) {
82 const fun = @field(@field(@This(), command.name), fn_name); 82 const fun = @field(@field(@This(), command.name), fn_name);
83 return @call(.auto, fun, args); 83 return @call(.auto, fun, args);
84 } 84 }
diff --git a/src/remove.zig b/src/remove.zig
index 2d868fb..bc5b06a 100644
--- a/src/remove.zig
+++ b/src/remove.zig
@@ -15,7 +15,7 @@ pub const max_args = 1;
15 15
16pub fn main(comptime Result: type, config: Config, res: Result) !void { 16pub fn main(comptime Result: type, config: Config, res: Result) !void {
17 const allocator = config.allocator; 17 const allocator = config.allocator;
18 18
19 const name = res.positionals[0]; 19 const name = res.positionals[0];
20 20
21 if (!try Installation.isInstalled(allocator, name)) { 21 if (!try Installation.isInstalled(allocator, name)) {
diff --git a/src/subcommand.zig b/src/subcommand.zig
index 09f1b4f..8fde170 100644
--- a/src/subcommand.zig
+++ b/src/subcommand.zig
@@ -37,7 +37,7 @@ pub fn SubCommand(comptime template: type) type {
37 37
38 pub fn main(name: []const u8, config: Config, args: *ArgIterator) !void { 38 pub fn main(name: []const u8, config: Config, args: *ArgIterator) !void {
39 const allocator = config.allocator; 39 const allocator = config.allocator;
40 40
41 var diag = clap.Diagnostic{}; 41 var diag = clap.Diagnostic{};
42 var res = clap.parseEx(clap.Help, &params, parsers, args, .{ 42 var res = clap.parseEx(clap.Help, &params, parsers, args, .{
43 .allocator = allocator, 43 .allocator = allocator,
diff --git a/src/switch.zig b/src/switch.zig
index f90f7d7..3323332 100644
--- a/src/switch.zig
+++ b/src/switch.zig
@@ -12,7 +12,7 @@ pub const max_args = 1;
12 12
13pub fn main(comptime Result: type, config: Config, res: Result) !void { 13pub fn main(comptime Result: type, config: Config, res: Result) !void {
14 const allocator = config.allocator; 14 const allocator = config.allocator;
15 15
16 const name = res.positionals[0]; 16 const name = res.positionals[0];
17 if (!try Installation.isInstalled(allocator, name)) { 17 if (!try Installation.isInstalled(allocator, name)) {
18 std.log.err( 18 std.log.err(
diff --git a/src/update.zig b/src/update.zig
index 55e6847..fc1ab51 100644
--- a/src/update.zig
+++ b/src/update.zig
@@ -13,7 +13,7 @@ pub const max_args = 0;
13 13
14pub fn main(comptime Result: type, config: Config, _: Result) !void { 14pub fn main(comptime Result: type, config: Config, _: Result) !void {
15 const allocator = config.allocator; 15 const allocator = config.allocator;
16 16
17 var installed = try Installation.getInstalledList(allocator); 17 var installed = try Installation.getInstalledList(allocator);
18 defer Installation.deinitMap(allocator, &installed); 18 defer Installation.deinitMap(allocator, &installed);
19 19