Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uenv repo mode #10

Merged
merged 6 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@

subprojects/Catch2-*
subprojects/CLI11-*
subprojects/curl-*
subprojects/fmt-*
subprojects/packagecache
subprojects/spdlog-*
subprojects/sqlite-amalgamation-*
subprojects/nlohmann_json-*

install
9 changes: 5 additions & 4 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ fmt_dep = subproject('fmt', default_options: ['werror=false', 'warning_level=0
json_dep = subproject('nlohmann_json', default_options: ['werror=false', 'warning_level=0']).get_variable('nlohmann_json_dep')
spdlog_dep = subproject('spdlog', default_options: ['werror=false', 'warning_level=0','std_format=disabled','external_fmt=enabled']).get_variable('spdlog_dep')
sqlite3_dep = subproject('sqlite3', default_options: ['werror=false', 'warning_level=0']).get_variable('sqlite3_dep')
subproject('curl', default_options: ['werror=false', 'warning_level=0'])

curl_dep = dependency('libcurl', required: true)

# the lib dependency is all of the common funtionality shared between the CLI
# and the slurm plugin.
Expand All @@ -42,7 +45,7 @@ lib_inc = include_directories('src')

lib_dep = declare_dependency(
sources: lib_src,
dependencies: [sqlite3_dep, fmt_dep, spdlog_dep, json_dep],
dependencies: [curl_dep, sqlite3_dep, fmt_dep, spdlog_dep, json_dep],
include_directories: lib_inc
)

Expand All @@ -55,6 +58,7 @@ if uenv_cli
'src/cli/help.cpp',
'src/cli/image.cpp',
'src/cli/ls.cpp',
'src/cli/repo.cpp',
'src/cli/run.cpp',
'src/cli/start.cpp',
'src/cli/uenv.cpp',
Expand Down Expand Up @@ -86,6 +90,3 @@ unit = executable('unit',
if uenv_slurm_plugin
subdir('src/slurm')
endif

# install the license
#install_data('LICENSE', install_mode : 'rw-r--r--', install_dir : 'license')
97 changes: 97 additions & 0 deletions src/cli/repo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// vim: ts=4 sts=4 sw=4 et
#include <string>

#include <fmt/core.h>
#include <fmt/std.h>
#include <spdlog/spdlog.h>

#include <uenv/parse.h>
#include <uenv/repository.h>
#include <util/expected.h>

#include "repo.h"
#include "uenv.h"

namespace uenv {

void repo_args::add_cli(CLI::App& cli,
[[maybe_unused]] global_settings& settings) {
auto* repo_cli =
cli.add_subcommand("repo", "manage and query uenv image repositories");

// add the create command, i.e. `uenv repo create ...`
auto* create_cli =
repo_cli->add_subcommand("create", "create a new uenv repository");

create_cli->add_option("path", create_args.path,
"path of the repo to create");
create_cli->callback(
[&settings]() { settings.mode = uenv::cli_mode::repo_create; });

// add the status command, i.e. `uenv repo status ...`
auto* status_cli = repo_cli->add_subcommand(
"status", "status of an existing uenv repository");
status_cli->add_option("path", status_args.path, "path of the repo");
status_cli->callback(
[&settings]() { settings.mode = uenv::cli_mode::repo_status; });
}

// inspect the repo path that is optionally passed as an argument.
// if no argument is provided, fall back to the value passed using
// the --repo argument, which in turn falls back to the default value.
util::expected<std::string, std::string>
resolve_repo_path(std::optional<std::string> path,
const global_settings& settings) {
if (path) {
if (auto result = parse_path(*path); !result) {
return util::unexpected(result.error().message());
}
return *path;
}
if (settings.repo) {
return *(settings.repo);
}
return util::unexpected("no path provided");
}

int repo_create(const repo_create_args& args, const global_settings& settings) {
auto path = resolve_repo_path(args.path, settings);
if (!path) {
spdlog::error("invalid repository path: {}", path.error());
return 1;
}
spdlog::info("attempting to create uenv repo at {}", *path);
auto x = create_repository(*path);
if (!x) {
spdlog::error("{}", x.error());
return 1;
}
return 0;
}

int repo_status(const repo_status_args& args, const global_settings& settings) {
using enum repo_state;

auto path = resolve_repo_path(args.path, settings);
if (!path) {
spdlog::error("invalid repository path: {}", path.error());
return 1;
}
auto status = validate_repository(*path);
if (status == readonly) {
fmt::print("the repository at {} is read only\n", *path);
}
if (status == readwrite) {
fmt::print("the repository at {} is read-write\n", *path);
}
if (status == no_exist) {
fmt::print("no repository at {}\n", *path);
}
if (status == invalid) {
fmt::print("the repository at {} is in invalid state\n", *path);
}

return 0;
}

} // namespace uenv
34 changes: 34 additions & 0 deletions src/cli/repo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// vim: ts=4 sts=4 sw=4 et
#pragma once

#include <CLI/CLI.hpp>
#include <fmt/core.h>

#include "uenv.h"

namespace uenv {

/*
uenv repo create <repo>
uenv repo status <repo>
*/

struct repo_create_args {
std::optional<std::string> path;
};
struct repo_status_args {
std::optional<std::string> path;
};

void repo_help();

struct repo_args {
repo_create_args create_args;
repo_status_args status_args;
void add_cli(CLI::App&, global_settings& settings);
};

int repo_create(const repo_create_args& args, const global_settings& settings);
int repo_status(const repo_status_args& args, const global_settings& settings);

} // namespace uenv
11 changes: 9 additions & 2 deletions src/cli/uenv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "color.h"
#include "help.h"
#include "image.h"
#include "repo.h"
#include "run.h"
#include "start.h"
#include "uenv.h"
Expand Down Expand Up @@ -44,10 +45,12 @@ int main(int argc, char** argv) {
uenv::start_args start;
uenv::run_args run;
uenv::image_args image;
uenv::repo_args repo;

start.add_cli(cli, settings);
run.add_cli(cli, settings);
image.add_cli(cli, settings);
repo.add_cli(cli, settings);

CLI11_PARSE(cli, argc, argv);

Expand All @@ -74,7 +77,7 @@ int main(int argc, char** argv) {
// if a repo was not provided as a flag, look at environment variables
if (!settings.repo_) {
if (const auto p = uenv::default_repo_path()) {
settings.repo_ = *uenv::default_repo_path();
settings.repo_ = *p;
} else {
spdlog::warn("ignoring the default repo path: {}", p.error());
}
Expand All @@ -94,7 +97,7 @@ int main(int argc, char** argv) {
}

if (settings.repo) {
spdlog::info("using repo {}", *settings.repo);
spdlog::info("the repo {}", *settings.repo);
}

spdlog::info("{}", settings);
Expand All @@ -106,6 +109,10 @@ int main(int argc, char** argv) {
return uenv::run(run, settings);
case settings.image_ls:
return uenv::image_ls(image.ls_args, settings);
case settings.repo_create:
return uenv::repo_create(repo.create_args, settings);
case settings.repo_status:
return uenv::repo_status(repo.status_args, settings);
case settings.unset:
fmt::println("uenv version {}", UENV_VERSION);
fmt::println("call '{} --help' for help", argv[0]);
Expand Down
13 changes: 12 additions & 1 deletion src/cli/uenv.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@

namespace uenv {

enum class cli_mode : std::uint32_t { unset, start, run, image_ls };
enum class cli_mode : std::uint32_t {
unset,
start,
run,
image_ls,
repo_create,
repo_status
};

struct global_settings {
using enum cli_mode;
Expand Down Expand Up @@ -49,6 +56,10 @@ template <> class fmt::formatter<uenv::cli_mode> {
return format_to(ctx.out(), "run");
case image_ls:
return format_to(ctx.out(), "image-ls");
case repo_create:
return format_to(ctx.out(), "repo-create");
case repo_status:
return format_to(ctx.out(), "repo-status");
}
return format_to(ctx.out(), "unknown");
}
Expand Down
Loading