Porytiles
Loading...
Searching...
No Matches
command_dump_tileset_config.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <filesystem>
4#include <iostream>
5#include <memory>
6#include <string>
7#include <unistd.h>
8
9#include "CLI/CLI.hpp"
10#include "fruit/fruit.h"
11
13
26
27#include "command.hpp"
28#include "option.hpp"
29
30class DumpTilesetConfigCommand final : public Command {
31 public:
32 explicit DumpTilesetConfigCommand(CLI::App &parent_app)
33 : Command{parent_app, kCommandName, kCommandDesc, kCommandGroup}
34 {
35 CLI::App &cmd = get_app();
36 cmd.add_option("<tileset-name>", tileset_name_, "Name of the tileset to dump config for")->required();
37 project_root_opt_.RegisterOpt(cmd);
38 porytiles::register_config_options(cmd, cli_storage_);
39 }
40
41 void Run() override
42 {
43 using namespace porytiles;
44
45 // Use Fruit DI to inject TextFormatter based on no_color flag
46 const bool no_color = !isatty(STDERR_FILENO);
47 fruit::Injector injector{di::get_formatter_component, no_color};
48 auto text_formatter = injector.get<TextFormatter *>();
49
50 // Create unfiltered diag for config bootstrapping (so config-loading warnings always show)
51 auto stderr_diag = std::make_unique<StderrStyledUserDiagnostics>(text_formatter);
52
53 std::filesystem::path project_root = project_root_opt_.project_root();
54 std::filesystem::path fieldmap_header_root_relative{"include/fieldmap.h"};
55
56 // Setup layered configuration (CLI options have highest priority)
57 std::vector<std::unique_ptr<ConfigProvider>> providers{};
58 providers.push_back(std::make_unique<CliOptionProvider>(cli_storage_));
59 auto yaml_provider = std::make_unique<YamlFileProvider>(text_formatter, stderr_diag.get(), project_root);
60 auto *yaml_provider_ptr = yaml_provider.get();
61 providers.push_back(std::move(yaml_provider));
62 providers.push_back(
63 std::make_unique<HeaderDefineProvider>(project_root, fieldmap_header_root_relative, text_formatter));
64 providers.push_back(std::make_unique<MetatilesHeaderProvider>(project_root, text_formatter));
65 providers.push_back(std::make_unique<DefaultProvider>());
66 LazyLayeredConfig config{text_formatter, std::move(providers)};
67
68 // Eagerly validate all YAML config files for unknown keys
69 if (yaml_provider_ptr->preload_and_validate(ConfigScopeType::tileset, tileset_name_)) {
70 const auto validation_err = ChainableResult<void>{FormattableError{
71 "Configuration validation failed for tileset '{}'.", FormatParam{tileset_name_, Style::bold}}};
72 stderr_diag->fatal(validation_err);
73 throw CLI::RuntimeError{1};
74 }
75
76 config.dump_config(std::cout, ConfigScopeType::tileset, tileset_name_);
77 }
78
79 private:
80 static constexpr auto kCommandName = "dump-tileset-config";
81 static constexpr auto kCommandDesc = "Dump the full configuration provenance chain for a tileset.";
82 static constexpr auto kCommandGroup = "UTILITIES";
83 std::string tileset_name_;
84 OptProjectRoot project_root_opt_;
85 porytiles::CliOptionStorage cli_storage_;
86};
Command is an abstract class that provides basic command functionality for the Porytiles CLI driver.
Definition command.hpp:18
CLI::App & get_app() const
Definition command.hpp:44
DumpTilesetConfigCommand(CLI::App &parent_app)
std::filesystem::path project_root() const
Definition option.hpp:58
void RegisterOpt(CLI::App &app) override
Definition option.hpp:46
A result type that maintains a chainable sequence of errors for debugging and error reporting.
A text parameter with associated styling for formatted output.
General-purpose error implementation with formatted message support.
Definition error.hpp:63
A Config implementation that lazily pulls a config value by consulting multiple priority-ordered back...
Abstract base class for applying text styling with context-aware formatting.
void register_config_options(CLI::App &app, CliOptionStorage &storage)
Registers all config options with a CLI11 App.
Storage struct for CLI option values.