From 431c99313c13546052fb687108123f4a84abf954 Mon Sep 17 00:00:00 2001 From: Remi Gelinas Date: Wed, 17 Jul 2024 12:27:12 -0400 Subject: [PATCH] feat(cli): add initial validate-config action --- src/cli/action.zig | 5 ++++ src/cli/validate_config.zig | 59 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/cli/validate_config.zig diff --git a/src/cli/action.zig b/src/cli/action.zig index a7cbabf25..68bcf6448 100644 --- a/src/cli/action.zig +++ b/src/cli/action.zig @@ -9,6 +9,7 @@ const list_keybinds = @import("list_keybinds.zig"); const list_themes = @import("list_themes.zig"); const list_colors = @import("list_colors.zig"); const show_config = @import("show_config.zig"); +const validate_config = @import("validate_config.zig"); /// Special commands that can be invoked via CLI flags. These are all /// invoked by using `+` as a CLI flag. The only exception is @@ -35,6 +36,9 @@ pub const Action = enum { /// Dump the config to stdout @"show-config", + // Validate passed config file + @"validate-config", + pub const Error = error{ /// Multiple actions were detected. You can specify at most one /// action on the CLI otherwise the behavior desired is ambiguous. @@ -124,6 +128,7 @@ pub const Action = enum { .@"list-themes" => try list_themes.run(alloc), .@"list-colors" => try list_colors.run(alloc), .@"show-config" => try show_config.run(alloc), + .@"validate-config" => try validate_config.run(alloc), }; } diff --git a/src/cli/validate_config.zig b/src/cli/validate_config.zig new file mode 100644 index 000000000..7bd8e8032 --- /dev/null +++ b/src/cli/validate_config.zig @@ -0,0 +1,59 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const args = @import("args.zig"); +const Action = @import("action.zig").Action; +const Config = @import("../config.zig").Config; +const cli = @import("../cli.zig"); + +pub const Options = struct { + /// The path of the config file to validate + @"config-file": ?[:0]const u8 = null, + + pub fn deinit(self: Options) void { + _ = self; + } + + /// Enables "-h" and "--help" to work. + pub fn help(self: Options) !void { + _ = self; + return Action.help_error; + } +}; + +/// The `validate-config` command is used to validate a Ghostty config +pub fn run(alloc: std.mem.Allocator) !u8 { + var opts: Options = .{}; + defer opts.deinit(); + + { + var iter = try std.process.argsWithAllocator(alloc); + defer iter.deinit(); + try args.parse(Options, alloc, &opts, &iter); + } + + const stdout = std.io.getStdOut().writer(); + + // If a config path is passed, validate it, otherwise validate usual config options + if (opts.@"config-file") |config_path| { + const cwd = std.fs.cwd(); + + if (cwd.openFile(config_path, .{})) |file| { + defer file.close(); + + var cfg = try Config.default(alloc); + defer cfg.deinit(); + + var buf_reader = std.io.bufferedReader(file.reader()); + var iter = cli.args.lineIterator(buf_reader.reader()); + try cfg.loadIter(alloc, &iter); + try cfg.loadRecursiveFiles(alloc); + try cfg.finalize(); + } else |err| { + try stdout.print("{any}", .{err}); + } + } else { + _ = try Config.load(alloc); + } + + return 0; +}