Skip to content

Commit 6ef4841

Browse files
authored
Config command (#57)
1 parent be8defc commit 6ef4841

File tree

5 files changed

+149
-0
lines changed

5 files changed

+149
-0
lines changed

cli/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ cc_binary(
1010
deps = [
1111
"//cli/commands:codegen",
1212
"//cli/commands:command",
13+
"//cli/commands:config",
1314
],
1415
)
1516

cli/cli.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "./commands/command.hh"
77
#include "./commands/codegen.hh"
8+
#include "./commands/config.hh"
89

910
namespace fs = std::filesystem;
1011

@@ -24,6 +25,7 @@ int main(int argc, char* argv[]) {
2425

2526
const std::unordered_map<std::string, command_fn_t> commands{
2627
{"codegen", &ecsact::cli::detail::codegen_command},
28+
{"config", &ecsact::cli::detail::config_command},
2729
};
2830

2931
for(int i=1; argc > i; ++i) {

cli/commands/BUILD.bazel

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,15 @@ cc_library(
2626
"@ecsact_runtime//:meta",
2727
],
2828
)
29+
30+
cc_library(
31+
name = "config",
32+
srcs = ["config.cc"],
33+
hdrs = ["config.hh"],
34+
copts = copts,
35+
deps = [
36+
":command",
37+
"//executable_path",
38+
"@bazelregistry_docopt_cpp//:docopt",
39+
],
40+
)

cli/commands/config.cc

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#include "./config.hh"
2+
3+
#include <iostream>
4+
#include <filesystem>
5+
#include <map>
6+
#include <string>
7+
#include "docopt.h"
8+
9+
#include "executable_path/executable_path.hh"
10+
11+
namespace fs = std::filesystem;
12+
13+
constexpr auto USAGE = R"(Ecsact Config Command
14+
15+
Usage:
16+
ecsact config [--include_dir] [--plugin_dir] [--builtin_plugins]
17+
18+
Options:
19+
--include_dir
20+
Prints the include directory containing Ecsact headers.
21+
--plugin_dir
22+
Prints the directory containing all built-in Ecsact codegen plugins.
23+
--builtin_plugins
24+
Prints a list of built-in Ecsact codegen plugins available.
25+
)";
26+
27+
constexpr auto CANNOT_FIND_INCLUDE_DIR = R"(
28+
[ERROR] Cannot find Ecsact include directory.
29+
Expected include directory next to bin directory. Make sure you're using a
30+
standard Ecsact SDK installation.
31+
If you believe this is a mistake please file an issue at
32+
https://github.com/ecsact-dev/ecsact_sdk/issues
33+
)";
34+
35+
constexpr auto CANNOT_FIND_PLUGIN_DIR = R"(
36+
[ERROR] Cannot find Ecsact built-in plugin directory.
37+
Make sure you're using a standard Ecsact SDK installation.
38+
If you believe this is a mistake please file an issue at
39+
https://github.com/ecsact-dev/ecsact_sdk/issues
40+
)";
41+
42+
int ecsact::cli::detail::config_command(int argc, char* argv[]) {
43+
using namespace std::string_literals;
44+
using executable_path::executable_path;
45+
46+
auto args = docopt::docopt(USAGE, {argv + 1, argv + argc});
47+
auto exec_path = executable_path();
48+
if(exec_path.empty()) {
49+
exec_path = fs::path{argv[0]};
50+
std::error_code ec;
51+
exec_path = fs::canonical(exec_path, ec);
52+
if(ec) {
53+
exec_path = fs::weakly_canonical(fs::path{argv[0]});
54+
}
55+
}
56+
57+
auto install_prefix = exec_path.parent_path().parent_path();
58+
auto plugin_dir = install_prefix / "share" / "ecsact" / "plugins";
59+
std::map<std::string, std::string> output;
60+
61+
if(args.at("--include_dir").asBool()) {
62+
auto includedir = install_prefix / "include";
63+
auto core_hdr = includedir / "ecsact" / "runtime" / "core.h";
64+
65+
if(fs::exists(core_hdr)) {
66+
output["include_dir"] = includedir.string();
67+
} else {
68+
std::cerr << CANNOT_FIND_INCLUDE_DIR;
69+
return 1;
70+
}
71+
}
72+
73+
if(args.at("--plugin_dir").asBool()) {
74+
if(fs::exists(plugin_dir)) {
75+
output["plugin_dir"] = plugin_dir.string();
76+
} else {
77+
std::cerr << CANNOT_FIND_PLUGIN_DIR;
78+
return 1;
79+
}
80+
}
81+
82+
if(args.at("--builtin_plugins").asBool()) {
83+
if(fs::exists(plugin_dir)) {
84+
auto& builtin_plugins_str = output["builtin_plugins"];
85+
std::vector<std::string> builtin_plugins;
86+
for(auto& entry : fs::directory_iterator(plugin_dir)) {
87+
auto filename = entry.path().filename().replace_extension("").string();
88+
const auto prefix = "ecsact_"s;
89+
const auto suffix = "_codegen"s;
90+
if(filename.starts_with(prefix) && filename.ends_with(suffix)) {
91+
builtin_plugins.emplace_back() = filename.substr(
92+
prefix.size(),
93+
filename.size() - prefix.size() - suffix.size()
94+
);
95+
}
96+
}
97+
98+
if(!builtin_plugins.empty()) {
99+
auto& builtin_plugins_str = output["builtin_plugins"];
100+
for(auto i=0; builtin_plugins.size() - 1 > i; ++i) {
101+
builtin_plugins_str += builtin_plugins[i] + "\n";
102+
}
103+
builtin_plugins_str += builtin_plugins.back();
104+
}
105+
} else {
106+
std::cerr << CANNOT_FIND_PLUGIN_DIR;
107+
return 1;
108+
}
109+
}
110+
111+
if(output.empty()) {
112+
return 1;
113+
}
114+
115+
if(output.size() == 1) {
116+
std::cout << output.begin()->second << "\n";
117+
} else {
118+
for(auto&& [key, value] : output) {
119+
std::cout << key << ": " << value << "\n";
120+
}
121+
}
122+
123+
return 0;
124+
}

cli/commands/config.hh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#pragma once
2+
3+
#include <type_traits>
4+
5+
#include "./command.hh"
6+
7+
namespace ecsact::cli::detail {
8+
int config_command(int argc, char* argv[]);
9+
static_assert(std::is_same_v<command_fn_t, decltype(&config_command)>);
10+
}

0 commit comments

Comments
 (0)