build: allow CLI actions to have enum option values (#2987)

A typo in the fish completions (that was likely copied to the zsh and
bash completions) prevented CLI actions from using enums as option
values because the completions tried to access non-existent fields from
type introspection. This doesn't cause any problems _now_ because no CLI
action uses an enum as an option value. However as soon as you try and
add one the completions fail to compile.

This patch fixes the incorrect field reference. It also adds the ability
to have _optional_ enums as option values.

cc @jparise @anund @anmolw
This commit is contained in:
Mitchell Hashimoto
2024-12-16 21:05:34 -08:00
committed by GitHub
3 changed files with 50 additions and 3 deletions

View File

@ -181,12 +181,29 @@ fn writeBashCompletions(writer: anytype) !void {
.Bool => try writer.writeAll("return ;;"), .Bool => try writer.writeAll("return ;;"),
.Enum => |info| { .Enum => |info| {
try writer.writeAll(compgenPrefix); try writer.writeAll(compgenPrefix);
for (info.opts, 0..) |f, i| { for (info.fields, 0..) |f, i| {
if (i > 0) try writer.writeAll(" "); if (i > 0) try writer.writeAll(" ");
try writer.writeAll(f.name); try writer.writeAll(f.name);
} }
try writer.writeAll(compgenSuffix); try writer.writeAll(compgenSuffix);
}, },
.Optional => |optional| {
switch (@typeInfo(optional.child)) {
.Enum => |info| {
try writer.writeAll(compgenPrefix);
for (info.fields, 0..) |f, i| {
if (i > 0) try writer.writeAll(" ");
try writer.writeAll(f.name);
}
try writer.writeAll(compgenSuffix);
},
else => {
if (std.mem.eql(u8, "config-file", opt.name)) {
try writer.writeAll("return ;;");
} else try writer.writeAll("return;;");
},
}
},
else => { else => {
if (std.mem.eql(u8, "config-file", opt.name)) { if (std.mem.eql(u8, "config-file", opt.name)) {
try writer.writeAll("return ;;"); try writer.writeAll("return ;;");

View File

@ -117,7 +117,17 @@ fn writeFishCompletions(writer: anytype) !void {
.Bool => try writer.writeAll(" -a \"true false\""), .Bool => try writer.writeAll(" -a \"true false\""),
.Enum => |info| { .Enum => |info| {
try writer.writeAll(" -a \""); try writer.writeAll(" -a \"");
for (info.opts, 0..) |f, i| { for (info.fields, 0..) |f, i| {
if (i > 0) try writer.writeAll(" ");
try writer.writeAll(f.name);
}
try writer.writeAll("\"");
},
.Optional => |optional| {
switch (@typeInfo(optional.child)) {
.Enum => |info| {
try writer.writeAll(" -a \"");
for (info.fields, 0..) |f, i| {
if (i > 0) try writer.writeAll(" "); if (i > 0) try writer.writeAll(" ");
try writer.writeAll(f.name); try writer.writeAll(f.name);
} }
@ -125,6 +135,9 @@ fn writeFishCompletions(writer: anytype) !void {
}, },
else => {}, else => {},
} }
},
else => {},
}
try writer.writeAll("\n"); try writer.writeAll("\n");
} }
} }

View File

@ -175,12 +175,29 @@ fn writeZshCompletions(writer: anytype) !void {
.Bool => try writer.writeAll("(true false)"), .Bool => try writer.writeAll("(true false)"),
.Enum => |info| { .Enum => |info| {
try writer.writeAll("("); try writer.writeAll("(");
for (info.opts, 0..) |f, i| { for (info.fields, 0..) |f, i| {
if (i > 0) try writer.writeAll(" "); if (i > 0) try writer.writeAll(" ");
try writer.writeAll(f.name); try writer.writeAll(f.name);
} }
try writer.writeAll(")"); try writer.writeAll(")");
}, },
.Optional => |optional| {
switch (@typeInfo(optional.child)) {
.Enum => |info| {
try writer.writeAll("(");
for (info.fields, 0..) |f, i| {
if (i > 0) try writer.writeAll(" ");
try writer.writeAll(f.name);
}
try writer.writeAll(")");
},
else => {
if (std.mem.eql(u8, "config-file", opt.name)) {
try writer.writeAll("_files");
} else try writer.writeAll("( )");
},
}
},
else => { else => {
if (std.mem.eql(u8, "config-file", opt.name)) { if (std.mem.eql(u8, "config-file", opt.name)) {
try writer.writeAll("_files"); try writer.writeAll("_files");