Skip to content

Commit 2a95a08

Browse files
authored
Merge pull request #10 from happystraw/main
fix: print subcommand help on --help/-h and enable LLVM backend
2 parents 7eae454 + 1e06de7 commit 2a95a08

3 files changed

Lines changed: 48 additions & 12 deletions

File tree

build.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ pub fn build(b: *std.Build) void {
3939
.optimize = optimize,
4040
.link_libc = true,
4141
}),
42+
// NOTE: Only for 0.16.0, can be removed in 0.17.0
43+
// See: https://codeberg.org/ziglang/zig/issues/31272#issuecomment-13790015
44+
.use_llvm = true,
4245
});
4346

4447
const options = b.addOptions();

src/cli.zig

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub const ParsedCommand = union(Command) {
8787
shell: ShellType,
8888
},
8989
version,
90-
help,
90+
help: ?Command,
9191
};
9292

9393
/// Global flags that apply before the command (e.g., --color).
@@ -147,7 +147,7 @@ pub fn parse(allocator: std.mem.Allocator, init: std.process.Init.Minimal) !stru
147147
} else if (std.mem.cutPrefix(u8, arg, "--color=")) |val| {
148148
if (parseColorValue(val)) |c| global_flags.color = c;
149149
} else if (std.mem.eql(u8, arg, "--help") or std.mem.eql(u8, arg, "-h")) {
150-
return .{ .global = global_flags, .cmd = .help };
150+
return .{ .global = global_flags, .cmd = .{ .help = null } };
151151
} else if (std.mem.eql(u8, arg, "--version") or std.mem.eql(u8, arg, "-v")) {
152152
return .{ .global = global_flags, .cmd = .version };
153153
} else {
@@ -158,7 +158,7 @@ pub fn parse(allocator: std.mem.Allocator, init: std.process.Init.Minimal) !stru
158158
}
159159
}
160160

161-
const cmd = maybe_cmd orelse return .{ .global = global_flags, .cmd = .help };
161+
const cmd = maybe_cmd orelse return .{ .global = global_flags, .cmd = .{ .help = null } };
162162

163163
// Check if the raw command name implies --all
164164
const auto_all = if (cmd_raw) |raw|
@@ -179,7 +179,7 @@ pub fn parse(allocator: std.mem.Allocator, init: std.process.Init.Minimal) !stru
179179
.proxy => try parseProxy(allocator, &args),
180180
.completion => try parseCompletion(&args),
181181
.version => ParsedCommand.version,
182-
.help => ParsedCommand.help,
182+
.help => ParsedCommand{ .help = null },
183183
};
184184

185185
return .{ .global = global_flags, .cmd = parsed };
@@ -203,11 +203,19 @@ fn parseColorValue(val: []const u8) ?bool {
203203
return null;
204204
}
205205

206+
fn checkHelp(comptime cmd: Command, arg: []const u8) ?ParsedCommand {
207+
if (std.mem.eql(u8, arg, "--help") or std.mem.eql(u8, arg, "-h")) {
208+
return .{ .help = cmd };
209+
}
210+
return null;
211+
}
212+
206213
fn parseInstall(allocator: std.mem.Allocator, args: anytype) !ParsedCommand {
207214
var flags: InstallFlags = .{};
208215
var version: ?[]const u8 = null;
209216

210217
while (args.next()) |arg| {
218+
if (checkHelp(.install, arg)) |h| return h;
211219
if (std.mem.eql(u8, arg, "--force") or std.mem.eql(u8, arg, "-f")) {
212220
flags.force = true;
213221
} else if (std.mem.eql(u8, arg, "--zls")) {
@@ -232,6 +240,7 @@ fn parseUse(allocator: std.mem.Allocator, args: anytype) !ParsedCommand {
232240
var version: ?[]const u8 = null;
233241

234242
while (args.next()) |arg| {
243+
if (checkHelp(.use, arg)) |h| return h;
235244
if (std.mem.eql(u8, arg, "--sync")) {
236245
flags.sync = true;
237246
} else {
@@ -249,6 +258,7 @@ fn parseList(args: anytype, auto_all: bool) ParsedCommand {
249258
var flags: ListFlags = .{ .all = auto_all };
250259

251260
while (args.next()) |arg| {
261+
if (checkHelp(.list, arg)) |h| return h;
252262
if (std.mem.eql(u8, arg, "--all") or std.mem.eql(u8, arg, "-a")) {
253263
flags.all = true;
254264
} else if (std.mem.eql(u8, arg, "--vmu")) {
@@ -261,13 +271,15 @@ fn parseList(args: anytype, auto_all: bool) ParsedCommand {
261271

262272
fn parseUninstall(allocator: std.mem.Allocator, args: anytype) !ParsedCommand {
263273
const version = args.next() orelse return error.MissingArgument;
274+
if (checkHelp(.uninstall, version)) |h| return h;
264275
return .{ .uninstall = .{
265276
.version = try allocator.dupe(u8, version),
266277
} };
267278
}
268279

269280
fn parseRun(allocator: std.mem.Allocator, args: anytype) !ParsedCommand {
270281
const version = args.next() orelse return error.MissingArgument;
282+
if (checkHelp(.run, version)) |h| return h;
271283

272284
var run_args: std.ArrayList([]const u8) = .empty;
273285
errdefer run_args.deinit(allocator);
@@ -284,6 +296,7 @@ fn parseRun(allocator: std.mem.Allocator, args: anytype) !ParsedCommand {
284296

285297
fn parseVmu(allocator: std.mem.Allocator, args: anytype) !ParsedCommand {
286298
const subcmd = args.next() orelse return error.MissingArgument;
299+
if (checkHelp(.vmu, subcmd)) |h| return h;
287300
const value = args.next() orelse return error.MissingArgument;
288301

289302
const target: VmuTarget = if (std.mem.eql(u8, subcmd, "zig"))
@@ -301,20 +314,25 @@ fn parseVmu(allocator: std.mem.Allocator, args: anytype) !ParsedCommand {
301314

302315
fn parseMirrorlist(allocator: std.mem.Allocator, args: anytype) !ParsedCommand {
303316
const url = args.next();
304-
return .{ .mirrorlist = .{
305-
.url = if (url) |u| try allocator.dupe(u8, u) else null,
306-
} };
317+
if (url) |u| {
318+
if (checkHelp(.mirrorlist, u)) |h| return h;
319+
return .{ .mirrorlist = .{ .url = try allocator.dupe(u8, u) } };
320+
}
321+
return .{ .mirrorlist = .{ .url = null } };
307322
}
308323

309324
fn parseProxy(allocator: std.mem.Allocator, args: anytype) !ParsedCommand {
310325
const url = args.next();
311-
return .{ .proxy = .{
312-
.url = if (url) |u| try allocator.dupe(u8, u) else null,
313-
} };
326+
if (url) |u| {
327+
if (checkHelp(.proxy, u)) |h| return h;
328+
return .{ .proxy = .{ .url = try allocator.dupe(u8, u) } };
329+
}
330+
return .{ .proxy = .{ .url = null } };
314331
}
315332

316333
fn parseCompletion(args: anytype) !ParsedCommand {
317334
const shell_str = args.next() orelse return error.MissingArgument;
335+
if (checkHelp(.completion, shell_str)) |h| return h;
318336
const shell: ShellType = if (std.mem.eql(u8, shell_str, "zsh"))
319337
.zsh
320338
else if (std.mem.eql(u8, shell_str, "bash"))
@@ -470,6 +488,17 @@ pub fn printCommandHelp(writer: *std.Io.Writer, cmd: Command) !void {
470488
\\ zvm proxy Show current proxy setting
471489
\\
472490
),
491+
.completion => try writer.writeAll(
492+
\\Generate shell completion script.
493+
\\
494+
\\Usage:
495+
\\ zvm completion <shell>
496+
\\
497+
\\Supported shells:
498+
\\ zsh
499+
\\ bash
500+
\\
501+
),
473502
.version, .help => printHelp(writer) catch {},
474503
}
475504
try writer.flush();

src/main.zig

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,12 @@ pub fn main(init: std.process.Init) !void {
7272

7373
// Dispatch to the appropriate command handler
7474
switch (parsed.cmd) {
75-
.help => {
76-
try cli.printHelp(console.stdout.writer);
75+
.help => |maybe_cmd| {
76+
if (maybe_cmd) |cmd| {
77+
try cli.printCommandHelp(console.stdout.writer, cmd);
78+
} else {
79+
try cli.printHelp(console.stdout.writer);
80+
}
7781
},
7882
.version => {
7983
console.plain("zvm {s}", .{fullVersion()});

0 commit comments

Comments
 (0)