config: track the location of CLI argument errors

This commit is contained in:
Mitchell Hashimoto
2024-10-17 07:55:02 -07:00
parent f24098cbd8
commit a12b33662c
2 changed files with 34 additions and 3 deletions

View File

@ -856,6 +856,34 @@ test "parseIntoField: tagged union missing tag" {
);
}
/// An iterator that considers its location to be CLI args. It
/// iterates through an underlying iterator and increments a counter
/// to track the current CLI arg index.
pub fn ArgsIterator(comptime Iterator: type) type {
return struct {
const Self = @This();
/// The underlying args iterator.
iterator: Iterator,
/// Our current index into the iterator. This is 1-indexed.
/// The 0 value is used to indicate that we haven't read any
/// values yet.
index: usize = 0,
pub fn next(self: *Self) ?[]const u8 {
const value = self.iterator.next() orelse return null;
self.index += 1;
return value;
}
/// Returns a location for a diagnostic message.
pub fn location(self: *const Self) ?Diagnostic.Location {
return .{ .cli = self.index };
}
};
}
/// Returns an iterator (implements "next") that reads CLI args by line.
/// Each CLI arg is expected to be a single line. This is used to implement
/// configuration files.
@ -946,8 +974,7 @@ pub fn LineIterator(comptime ReaderType: type) type {
return self.entry[0 .. buf.len + 2];
}
/// Modify the diagnostic so it includes richer context about
/// the location of the error.
/// Returns a location for a diagnostic message.
pub fn location(self: *const Self) ?Diagnostic.Location {
// If we have no filepath then we have no location.
if (self.filepath.len == 0) return null;

View File

@ -2372,7 +2372,11 @@ pub fn loadCliArgs(self: *Config, alloc_gpa: Allocator) !void {
if (iter.next()) |argv0| log.debug("skipping argv0 value={s}", .{argv0});
// Parse the config from the CLI args
try self.loadIter(alloc_gpa, &iter);
{
const ArgsIter = cli.args.ArgsIterator(@TypeOf(iter));
var args_iter: ArgsIter = .{ .iterator = iter };
try self.loadIter(alloc_gpa, &args_iter);
}
// If we are not loading the default files, then we need to
// replay the steps up to this point so that we can rebuild