Skip to content

Commit

Permalink
feat: Add recipes to CLI config and add builtin recipe shortcuts (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kelwan authored Jul 5, 2024
1 parent 7a71935 commit cdda706
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 7 deletions.
42 changes: 38 additions & 4 deletions ecsact/cli/commands/build.cc
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "ecsact/cli/commands/build.hh"

#include <memory>
#include <iostream>
#include <format>
#include <filesystem>
#include <array>
Expand Down Expand Up @@ -58,6 +57,33 @@ constexpr auto allowed_recipe_extensions = std::array{
".json"sv, // json works since yaml is a superset
};

auto resolve_builtin_recipe( //
std::string recipe_str,
const char* argv[]
) -> std::optional<fs::path> {
using namespace std::string_literals;

auto exec_path = ecsact::cli::detail::canon_argv0(argv[0]);
auto install_prefix = exec_path.parent_path().parent_path();
auto recipes_dir = install_prefix / "share" / "ecsact" / "recipes";

if(fs::exists(recipes_dir)) {
for(auto& entry : fs::directory_iterator(recipes_dir)) {
auto filename = entry.path().filename().replace_extension("").string();
const auto prefix = "ecsact_"s;

auto stripped_filename = filename.substr(prefix.size(), filename.size());

if(recipe_str == stripped_filename) {
auto path = fs::path(filename);
path.replace_extension(".ecsact-recipe-bundle");
return recipes_dir / path;
}
}
}
return std::nullopt;
}

auto ecsact::cli::detail::build_command( //
int argc,
const char* argv[]
Expand All @@ -82,7 +108,15 @@ auto ecsact::cli::detail::build_command( //
auto recipe_composite = std::optional<build_recipe>{};
auto recipe_paths = args.at("--recipe").asStringList();
for(auto& recipe_path_str : recipe_paths) {
auto recipe_path = fs::path{recipe_path_str};
auto builtin_path = resolve_builtin_recipe(recipe_path_str, argv);

fs::path recipe_path;
if(builtin_path) {
recipe_path = *builtin_path;
} else {
recipe_path = fs::path{recipe_path_str};
}

if(std::ranges::find(allowed_recipe_extensions, recipe_path.extension()) ==
allowed_recipe_extensions.end()) {
ecsact::cli::report_error(
Expand Down Expand Up @@ -168,8 +202,8 @@ auto ecsact::cli::detail::build_command( //
}
ecsact::cli::report_error(
"Build recipes do not resolve all imports. Make sure all imported "
"functions in provided recipes are also exported by another recipe. If "
"you would like to allow unresolved imports you may provide the "
"functions in provided recipes are also exported by another recipe. "
"If you would like to allow unresolved imports you may provide the "
"--allow-unresolved-imports flag to suppress this error."
);
return 1;
Expand Down
40 changes: 37 additions & 3 deletions ecsact/cli/commands/config.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "./config.hh"

#include <iostream>
#include <filesystem>
#include <map>
Expand All @@ -24,8 +23,9 @@ constexpr auto USAGE = R"(Ecsact Config Command
Available config keys:
install_dir directory Ecsact SDK was installed to
include_dir directory containing Ecsact headers
plugin_dir directory containing built-in Ecsact codegen plugins
builtin_plugins list of built-in Ecsact codegen plugins available.
plugin_dir directory containing built-in Ecsact codegen plugins
builtin_plugins list of built-in Ecsact codegen plugins available
recipe_bundles directory containing runtime recipe bundles
)";

Expand All @@ -44,13 +44,21 @@ constexpr auto CANNOT_FIND_PLUGIN_DIR = R"(
https://github.com/ecsact-dev/ecsact_sdk/issues
)";

constexpr auto CANNOT_FIND_RECIPES_DIR = R"(
[ERROR] Cannot find Ecsact recipes directory.
Make sure you're using a standard Ecsact SDK installation.
If you believe this is a mistake please file an issue at
https://github.com/ecsact-dev/ecsact_sdk/issues
)";

int ecsact::cli::detail::config_command(int argc, const char* argv[]) {
using namespace std::string_literals;

auto args = docopt::docopt(USAGE, {argv + 1, argv + argc});
auto exec_path = canon_argv0(argv[0]);
auto install_prefix = exec_path.parent_path().parent_path();
auto plugin_dir = install_prefix / "share" / "ecsact" / "plugins";
auto recipes_dir = install_prefix / "share" / "ecsact" / "recipes";
auto output = "{}"_json;

std::unordered_map<std::string, std::function<int()>> key_handlers{
Expand Down Expand Up @@ -117,6 +125,32 @@ int ecsact::cli::detail::config_command(int argc, const char* argv[]) {
return 0;
},
},
{
"recipe_bundles",
[&] {
if(fs::exists(recipes_dir)) {
std::vector<std::string> recipe_bundles;

for(auto& entry : fs::directory_iterator(recipes_dir)) {
auto filename =
entry.path().filename().replace_extension("").string();
const auto prefix = "ecsact_"s;

if(filename.starts_with(prefix)) {
recipe_bundles.emplace_back(
filename.substr(prefix.size(), filename.size())
);
}
}
output["recipes_dir"] = recipe_bundles;
} else {
std::cerr << CANNOT_FIND_RECIPES_DIR;
return 1;
}
return 0;
},
},

};

auto keys = args.at("<keys>").asStringList();
Expand Down

0 comments on commit cdda706

Please sign in to comment.