Merge pull request #2243 from gpanders/push-yvplumostzqp

config: interpret leading ? in config-file as an optional file
This commit is contained in:
Mitchell Hashimoto
2024-09-17 13:04:52 -07:00
committed by GitHub

View File

@ -1087,6 +1087,10 @@ keybind: Keybinds = .{},
/// `config-file` directive. For command-line arguments, paths are relative to /// `config-file` directive. For command-line arguments, paths are relative to
/// the current working directory. /// the current working directory.
/// ///
/// Prepend a ? character to the file path to suppress errors if the file does
/// not exist. If you want to include a file that begins with a literal ?
/// character, surround the file path in double quotes (").
///
/// Cycles are not allowed. If a cycle is detected, an error will be logged and /// Cycles are not allowed. If a cycle is detected, an error will be logged and
/// the configuration file will be ignored. /// the configuration file will be ignored.
@"config-file": RepeatablePath = .{}, @"config-file": RepeatablePath = .{},
@ -2258,12 +2262,20 @@ pub fn loadRecursiveFiles(self: *Config, alloc_gpa: Allocator) !void {
defer loaded.deinit(); defer loaded.deinit();
const cwd = std.fs.cwd(); const cwd = std.fs.cwd();
var i: usize = 0; for (0..self.@"config-file".value.list.items.len) |i| {
while (i < self.@"config-file".value.list.items.len) : (i += 1) { const optional, const path = blk: {
const path = self.@"config-file".value.list.items[i]; const path = self.@"config-file".value.list.items[i];
if (path.len == 0) {
continue;
}
// Error paths break :blk if (path[0] == '?')
if (path.len == 0) continue; .{ true, path[1..] }
else if (path[0] == '"' and path[path.len - 1] == '"')
.{ false, path[1 .. path.len - 1] }
else
.{ false, path };
};
// All paths should already be absolute at this point because // All paths should already be absolute at this point because
// they're fixed up after each load. // they're fixed up after each load.
@ -2282,13 +2294,15 @@ pub fn loadRecursiveFiles(self: *Config, alloc_gpa: Allocator) !void {
} }
var file = cwd.openFile(path, .{}) catch |err| { var file = cwd.openFile(path, .{}) catch |err| {
try self._errors.add(arena_alloc, .{ if (err != error.FileNotFound or !optional) {
.message = try std.fmt.allocPrintZ( try self._errors.add(arena_alloc, .{
arena_alloc, .message = try std.fmt.allocPrintZ(
"error opening config-file {s}: {}", arena_alloc,
.{ path, err }, "error opening config-file {s}: {}",
), .{ path, err },
}); ),
});
}
continue; continue;
}; };
defer file.close(); defer file.close();
@ -3261,14 +3275,37 @@ pub const RepeatablePath = struct {
var dir = try std.fs.cwd().openDir(base, .{}); var dir = try std.fs.cwd().openDir(base, .{});
defer dir.close(); defer dir.close();
for (self.value.list.items, 0..) |path, i| { for (0..self.value.list.items.len) |i| {
const optional, const path = blk: {
const path = self.value.list.items[i];
if (path.len == 0) {
continue;
}
break :blk if (path[0] == '?')
.{ true, path[1..] }
else if (path[0] == '"' and path[path.len - 1] == '"')
.{ false, path[1 .. path.len - 1] }
else
.{ false, path };
};
// If it is already absolute we can ignore it. // If it is already absolute we can ignore it.
if (path.len == 0 or std.fs.path.isAbsolute(path)) continue; if (std.fs.path.isAbsolute(path)) continue;
// If it isn't absolute, we need to make it absolute relative // If it isn't absolute, we need to make it absolute relative
// to the base. // to the base.
var buf: [std.fs.max_path_bytes]u8 = undefined; var buf: [std.fs.max_path_bytes]u8 = undefined;
const abs = dir.realpath(path, &buf) catch |err| { const abs = dir.realpath(path, &buf) catch |err| abs: {
if (err == error.FileNotFound and optional) {
// The file doesn't exist. Try to resolve the relative path
// another way.
const resolved = try std.fs.path.resolve(alloc, &.{ base, path });
defer alloc.free(resolved);
@memcpy(buf[0..resolved.len], resolved);
break :abs buf[0..resolved.len];
}
try errors.add(alloc, .{ try errors.add(alloc, .{
.message = try std.fmt.allocPrintZ( .message = try std.fmt.allocPrintZ(
alloc, alloc,