config: re-expand relative paths correctly when reloading config

Fixes #1366

When we use `loadTheme`, we "replay" the configuration so that the theme
is the base configuration and everything else can override everything
the theme sets. During this process, we were not properly re-expanding
all the relative paths.

This fix works by changing our input tracking from solely tracking args
to tracking operations such as expansion as well. When we "replay" the
configuration we also replay operations such as path expansion with the
correct base path.

This also removes the `_inputs` special mechanism `cli/args.zig` had
because we can already do that ourselves using `parseManuallyHook`.
This commit is contained in:
Mitchell Hashimoto
2024-01-23 21:49:16 -08:00
parent 3beae1a4c4
commit 0f133ae4a7
2 changed files with 65 additions and 38 deletions

View File

@@ -67,11 +67,6 @@ pub fn parse(comptime T: type, alloc: Allocator, dst: *T, iter: anytype) !void {
};
while (iter.next()) |arg| {
// If an _inputs fields exist we keep track of the inputs.
if (@hasField(T, "_inputs")) {
try dst._inputs.append(arena_alloc, try arena_alloc.dupe(u8, arg));
}
// Do manual parsing if we have a hook for it.
if (@hasDecl(T, "parseManuallyHook")) {
if (!try dst.parseManuallyHook(arena_alloc, arg, iter)) return;
@@ -433,30 +428,6 @@ test "parse: error tracking" {
try testing.expect(!data._errors.empty());
}
test "parse: input tracking" {
const testing = std.testing;
var data: struct {
a: []const u8 = "",
b: enum { one } = .one,
_arena: ?ArenaAllocator = null,
_errors: ErrorList = .{},
_inputs: std.ArrayListUnmanaged([]const u8) = .{},
} = .{};
defer if (data._arena) |arena| arena.deinit();
var iter = try std.process.ArgIteratorGeneral(.{}).init(
testing.allocator,
"--what --a=42",
);
defer iter.deinit();
try parse(@TypeOf(data), testing.allocator, &data, &iter);
try testing.expect(data._arena != null);
try testing.expect(data._inputs.items.len == 2);
try testing.expectEqualStrings("--what", data._inputs.items[0]);
try testing.expectEqualStrings("--a=42", data._inputs.items[1]);
}
test "parseIntoField: ignore underscore-prefixed fields" {
const testing = std.testing;
var arena = ArenaAllocator.init(testing.allocator);