diff --git a/meson.build b/meson.build index d1d6e20..29c747c 100644 --- a/meson.build +++ b/meson.build @@ -46,6 +46,8 @@ lib_dep = declare_dependency( include_directories: lib_inc ) +subdir('src/uenv') + # the uenv executable if uenv_cli uenv_src = [ diff --git a/src/cli/ls.cpp b/src/cli/ls.cpp index a059525..0413c22 100644 --- a/src/cli/ls.cpp +++ b/src/cli/ls.cpp @@ -26,7 +26,8 @@ void image_ls_args::add_cli(CLI::App& cli, "comma separated list of uenv to mount."); ls_cli->add_flag("--no-header", no_header, "print only the matching records, with no header."); - ls_cli->callback([&settings]() { settings.mode = uenv::mode_image_ls; }); + ls_cli->callback( + [&settings]() { settings.mode = uenv::cli_mode::image_ls; }); } int image_ls(const image_ls_args& args, const global_settings& settings) { diff --git a/src/cli/run.cpp b/src/cli/run.cpp index 2b3fcf0..22df5d5 100644 --- a/src/cli/run.cpp +++ b/src/cli/run.cpp @@ -34,7 +34,7 @@ void run_args::add_cli(CLI::App& cli, global_settings& settings) { ->add_option("commands", commands, "the command to run, including with arguments") ->required(); - run_cli->callback([&settings]() { settings.mode = uenv::mode_run; }); + run_cli->callback([&settings]() { settings.mode = uenv::cli_mode::run; }); } int run(const run_args& args, const global_settings& globals) { diff --git a/src/cli/start.cpp b/src/cli/start.cpp index 31130d3..afe6996 100644 --- a/src/cli/start.cpp +++ b/src/cli/start.cpp @@ -31,7 +31,8 @@ void start_args::add_cli(CLI::App& cli, ->add_option("uenv", uenv_description, "comma separated list of uenv to mount") ->required(); - start_cli->callback([&settings]() { settings.mode = uenv::mode_start; }); + start_cli->callback( + [&settings]() { settings.mode = uenv::cli_mode::start; }); } int start(const start_args& args, diff --git a/src/cli/uenv.cpp b/src/cli/uenv.cpp index 38bbda9..dda3dc5 100644 --- a/src/cli/uenv.cpp +++ b/src/cli/uenv.cpp @@ -7,6 +7,7 @@ #include +#include #include #include #include @@ -16,17 +17,15 @@ #include "start.h" #include "uenv.h" -void help() { - fmt::println("usage main"); -} - int main(int argc, char** argv) { uenv::global_settings settings; + bool print_version = false; - CLI::App cli("uenv"); + CLI::App cli(fmt::format("uenv {}", UENV_VERSION)); cli.add_flag("-v,--verbose", settings.verbose, "enable verbose output"); cli.add_flag("--no-color", settings.no_color, "disable color output"); cli.add_flag("--repo", settings.repo_, "the uenv repository"); + cli.add_flag("--version", print_version, "print version"); uenv::start_args start; uenv::run_args run; @@ -50,6 +49,12 @@ int main(int argc, char** argv) { } uenv::init_log(console_log_level, spdlog::level::trace); + // print the version and exit if the --version flag was passed + if (print_version) { + fmt::print("{}\n", UENV_VERSION); + return 0; + } + // if a repo was not provided as a flag, look at environment variables if (!settings.repo_) { if (const auto p = uenv::default_repo_path()) { @@ -73,21 +78,27 @@ int main(int argc, char** argv) { } if (settings.repo) { - spdlog::info("repo is set {}", *settings.repo); + spdlog::info("using repo {}", *settings.repo); } spdlog::info("{}", settings); switch (settings.mode) { - case uenv::mode_start: + case settings.start: return uenv::start(start, settings); - case uenv::mode_run: + case settings.run: return uenv::run(run, settings); - case uenv::mode_image_ls: + case settings.image_ls: return uenv::image_ls(image.ls_args, settings); - case uenv::mode_none: + case settings.unset: + fmt::println("uenv version {}", UENV_VERSION); + fmt::println("call '{} --help' for help", argv[0]); + return 0; default: - help(); + spdlog::warn("{}", (int)settings.mode); + spdlog::error("internal error, missing implementation for mode {}", + settings.mode); + return 1; } return 0; diff --git a/src/cli/uenv.h b/src/cli/uenv.h index 5af1e9e..c4d9ace 100644 --- a/src/cli/uenv.h +++ b/src/cli/uenv.h @@ -1,6 +1,7 @@ // vim: ts=4 sts=4 sw=4 et #pragma once +#include #include #include #include @@ -11,17 +12,15 @@ namespace uenv { -extern int mode; - -constexpr int mode_none = 0; -constexpr int mode_start = 1; -constexpr int mode_run = 2; -constexpr int mode_image_ls = 3; +enum class cli_mode : std::uint32_t { unset, start, run, image_ls }; struct global_settings { + using enum cli_mode; + int verbose = 0; bool no_color = false; - int mode = mode_none; + // int mode = mode_none; + cli_mode mode = unset; // repo_ is the unverified string description of the repo path that is // either read from an environment variable or as a --repo CLI argument. the @@ -33,6 +32,30 @@ struct global_settings { } // namespace uenv +template <> class fmt::formatter { + public: + // parse format specification and store it: + constexpr auto parse(format_parse_context& ctx) { + return ctx.end(); + } + // format a value using stored specification: + template + constexpr auto format(uenv::cli_mode mode, FmtContext& ctx) const { + using enum uenv::cli_mode; + switch (mode) { + case unset: + return format_to(ctx.out(), "unset"); + case start: + return format_to(ctx.out(), "start"); + case run: + return format_to(ctx.out(), "run"); + case image_ls: + return format_to(ctx.out(), "image-ls"); + } + return format_to(ctx.out(), "unknown"); + } +}; + template <> class fmt::formatter { public: // parse format specification and store it: diff --git a/src/uenv/config.h.in b/src/uenv/config.h.in new file mode 100644 index 0000000..2308871 --- /dev/null +++ b/src/uenv/config.h.in @@ -0,0 +1,7 @@ +#pragma once + +#define UENV_VERSION "@version@" +#define UENV_VERSION_MAJOR @version_major@ +#define UENV_VERSION_MINOR @version_minor@ +#define UENV_VERSION_PATCH @version_patch@ +#define UENV_VERSION_PRERELEASE "@version_prerelease@" diff --git a/src/uenv/meson.build b/src/uenv/meson.build new file mode 100644 index 0000000..87e8a1e --- /dev/null +++ b/src/uenv/meson.build @@ -0,0 +1,28 @@ +version_path = meson.current_build_dir()+'config.h' +fs = import('fs') +if not fs.is_file(version_path) + uenv_version = meson.project_version() + uenv_version_array = uenv_version.split('-') + if uenv_version_array.length()==2 + uenv_version_prerelease = uenv_version_array[1] + else + uenv_version_prerelease = '' + endif + uenv_version_array = uenv_version_array[0].split('.') + uenv_version_major = uenv_version_array[0].to_int() + uenv_version_minor = uenv_version_array[1].to_int() + uenv_version_patch = uenv_version_array[2].to_int() + + conf = configuration_data() + + conf.set('version', uenv_version) + conf.set('version_major', uenv_version_major) + conf.set('version_minor', uenv_version_minor) + conf.set('version_patch', uenv_version_patch) + conf.set('version_prerelease', uenv_version_prerelease) + + configure_file(input : 'config.h.in', + output : 'config.h', + configuration : conf) +endif +