Porytiles
Loading...
Searching...
No Matches
command_compile_tileset.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4#include <string>
5
6#include "CLI/CLI.hpp"
7
13
14#include "command.hpp"
15#include "option.hpp"
17
18class CompileTilesetCommand final : public Command {
19 public:
20 explicit CompileTilesetCommand(CLI::App &parent_app)
21 : Command{parent_app, command_name, command_desc, command_group}
22 {
23 CLI::App &cmd = get_app();
24 cmd.add_option("<tileset-name>", tileset_name_, "Name of the tileset to compile")->required();
25 project_root_opt_.RegisterOpt(cmd);
26 porytiles::register_config_options(cmd, cli_storage_);
27 }
28
29 private:
30 void Run() override
31 {
32 using namespace porytiles;
33
34 TilesetCommandEnv env{project_root_opt_.project_root(), cli_storage_};
35
36 // Env initialization and schema resolution can fail, so they run first and their failures chain and report
37 // through the unfiltered stderr diagnostics.
38 const auto env_result = env.initialize(tileset_name_);
39 if (!env_result.has_value()) {
40 const auto env_fail_result = ChainableResult<void>{
41 FormattableError{"Failed to compile tileset '{}'.", FormatParam{tileset_name_, Style::bold}},
42 env_result};
43 env.stderr_diag.fatal(env_fail_result);
44 throw CLI::RuntimeError{1};
45 }
46
47 auto attribute_context = resolve_attribute_context(env, tileset_name_);
48 if (!attribute_context.has_value()) {
49 const auto fail_result = ChainableResult<void>{
50 FormattableError{"Failed to compile tileset '{}'.", FormatParam{tileset_name_, Style::bold}},
51 attribute_context};
52 env.diag->fatal(fail_result);
53 throw CLI::RuntimeError{1};
54 }
55 TilesetCommandServices services{env, std::move(attribute_context).value()};
56
57 // Verify the tileset exists in the project before proceeding
58 if (!services.metadata_provider.exists(tileset_name_)) {
59 const auto not_found_err = ChainableResult<void>{FormattableError{
60 "Tileset '{}' does not exist. Create or import it first.", FormatParam{tileset_name_, Style::bold}}};
61 env.diag->fatal(not_found_err);
62 throw CLI::RuntimeError{1};
63 }
64
65 // Detect primary vs secondary and dispatch to the correct use case
66 auto is_secondary_result = services.metadata_provider.is_secondary(tileset_name_);
67 if (!is_secondary_result.has_value()) {
68 const auto fail_result = ChainableResult<void>{
69 FormattableError{"Failed to compile tileset '{}'.", FormatParam{tileset_name_, Style::bold}},
70 is_secondary_result};
71 env.diag->fatal(fail_result);
72 throw CLI::RuntimeError{1};
73 }
74
75 ChainableResult<void> compile_result;
76 if (is_secondary_result.value()) {
77 CompileSecondaryTileset compile_use_case{
78 &services.repo,
79 &services.compiler,
80 &services.metadata_provider,
81 &services.layout_metadata_provider,
82 &services.tileset_manager,
83 &env.config,
84 &env.config,
85 env.diag.get()};
86 compile_result = compile_use_case.compile(tileset_name_);
87 }
88 else {
89 CompilePrimaryTileset compile_use_case{
90 &services.repo,
91 &services.compiler,
92 &services.metadata_provider,
93 &services.tileset_manager,
94 &env.config,
95 &env.config,
96 env.diag.get()};
97 compile_result = compile_use_case.compile(tileset_name_);
98 }
99 if (!compile_result.has_value()) {
100 const auto fail_result = ChainableResult<std::unique_ptr<Tileset>>{
101 FormattableError{"Failed to compile tileset '{}'.", FormatParam{tileset_name_, Style::bold}},
102 compile_result};
103 env.diag->fatal(fail_result);
104 throw CLI::RuntimeError{1};
105 }
106 }
107
108 static constexpr auto command_name = "compile-tileset";
109 static constexpr auto command_desc =
110 "Compile a tileset -- update the Porymap assets to match the Porytiles assets.";
111 static constexpr auto command_group = "COMMANDS";
112 std::string tileset_name_;
113 OptProjectRoot project_root_opt_;
114 porytiles::CliOptionStorage cli_storage_;
115};
Command is an abstract class that provides basic command functionality for the Porytiles CLI driver.
Definition command.hpp:16
CLI::App & get_app() const
Definition command.hpp:42
CompileTilesetCommand(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.
bool has_value() const
Checks whether the result contains a success value.
Use case for compiling a primary Tileset.
Use case for compiling a secondary Tileset.
A text parameter with associated styling for formatted output.
General-purpose error implementation with formatted message support.
Definition error.hpp:57
Bootstrap class so every tileset command can share common config and diagnostic setup.
The schema-driven service graph shared by the compile, create, import, and decompile commands.
void register_config_options(CLI::App &app, CliOptionStorage &storage)
Registers all config options with a CLI11 App.
ChainableResult< ResolvedAttributeContext > resolve_attribute_context(TilesetCommandEnv &env, const std::string &tileset_name)
Resolves the invocation's metatile attribute schema and builds the provider map for its fields.
Storage struct for CLI option values.