Skip to content

Commit

Permalink
correctly handle null description in uenv meta; add basic test
Browse files Browse the repository at this point in the history
  • Loading branch information
bcumming committed Sep 4, 2024
1 parent eb8f42f commit c51e510
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 45 deletions.
4 changes: 2 additions & 2 deletions src/uenv/env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ concretise_env(const std::string& uenv_args,
spdlog::info("{}: loaded meta (name {}, mount {})", desc, name,
mount_meta);
} else {
spdlog::error("{} opening the uenv meta data {}: {}", desc,
*env_meta_path, result.error());
spdlog::warn("{} opening the uenv meta data {}: {}", desc,
*env_meta_path, result.error());
}
} else {
spdlog::debug("{} no meta file found at expected location {}", desc,
Expand Down
105 changes: 62 additions & 43 deletions src/uenv/meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <fmt/core.h>
#include <fmt/std.h>
#include <nlohmann/json.hpp>
#include <spdlog/spdlog.h>

#include <util/expected.h>

Expand All @@ -18,59 +19,77 @@ namespace uenv {
util::expected<meta, std::string> load_meta(const std::filesystem::path& file) {
using json = nlohmann::json;

if (!std::filesystem::is_regular_file(file)) {
return util::unexpected(fmt::format(
"the uenv meta data file {} does not exist", file.string()));
}

auto fid = std::ifstream(file);
spdlog::debug("uenv::load_meta attempting to open uenv meta data file {}",
file.string());

nlohmann::json raw;
try {
raw = json::parse(fid);
} catch (std::exception& e) {
return util::unexpected(
fmt::format("error parsing meta data file for uenv {}: {}",
file.string(), e.what()));
}
if (!std::filesystem::is_regular_file(file)) {
return util::unexpected(fmt::format(
"the uenv meta data file {} does not exist", file.string()));
}
spdlog::debug("uenv::load_meta file opened");

auto fid = std::ifstream(file);

nlohmann::json raw;
try {
raw = json::parse(fid);
} catch (std::exception& e) {
return util::unexpected(
fmt::format("error parsing meta data file for uenv {}: {}",
file.string(), e.what()));
}
spdlog::debug("uenv::load_meta raw json read");

const std::string name = raw.contains("name") ? raw["name"] : "unnamed";
using ostring = std::optional<std::string>;
const ostring description =
raw.contains("description") ? ostring(raw["description"]) : ostring{};
const ostring mount =
raw.contains("mount") ? ostring(raw["mount"]) : ostring{};
const std::string name = raw.contains("name") ? raw["name"] : "unnamed";
using ostring = std::optional<std::string>;
const ostring description =
(raw.contains("description") && !raw["description"].is_null())
? ostring(raw["description"])
: ostring{};
const ostring mount =
raw.contains("mount") ? ostring(raw["mount"]) : ostring{};

std::unordered_map<std::string, concrete_view> views;
if (auto& jviews = raw["views"]; jviews.is_object()) {
for (auto& [name, desc] : jviews.items()) {
uenv::envvarset envvars;
if (auto& list = desc["env"]["values"]["list"]; list.is_object()) {
for (auto& [var_name, updates] : list.items()) {
for (auto& u : updates) {
const uenv::update_kind op =
u["op"] == "append" ? uenv::update_kind::append
: u["op"] == "prepend" ? uenv::update_kind::prepend
: uenv::update_kind::set;
std::vector<std::string> paths = u["value"];
envvars.update_prefix_path(var_name, {op, paths});
spdlog::debug("uenv::load_meta name '{}' mount {} description '{}'",
name, mount, description);

std::unordered_map<std::string, concrete_view> views;
if (auto& jviews = raw["views"]; jviews.is_object()) {
for (auto& [name, desc] : jviews.items()) {
uenv::envvarset envvars;
if (auto& list = desc["env"]["values"]["list"];
list.is_object()) {
for (auto& [var_name, updates] : list.items()) {
for (auto& u : updates) {
const uenv::update_kind op =
u["op"] == "append" ? uenv::update_kind::append
: u["op"] == "prepend"
? uenv::update_kind::prepend
: uenv::update_kind::set;
std::vector<std::string> paths = u["value"];
envvars.update_prefix_path(var_name, {op, paths});
}
}
}
}
if (auto& scalar = desc["env"]["values"]["scalar"];
scalar.is_object()) {
for (auto& [var_name, val] : scalar.items()) {
envvars.update_scalar(var_name, val);
if (auto& scalar = desc["env"]["values"]["scalar"];
scalar.is_object()) {
for (auto& [var_name, val] : scalar.items()) {
envvars.update_scalar(var_name, val);
}
}
}

const std::string description =
desc.contains("description") ? desc["description"] : "";
views[name] = concrete_view{name, description, envvars};
const std::string description =
desc.contains("description") ? desc["description"] : "";
views[name] = concrete_view{name, description, envvars};
}
}
}

return meta{name, description, mount, views};
return meta{name, description, mount, views};
} catch (json::exception& e) {
return util::unexpected(
fmt::format("internal error parsing uenv meta data in {}: {}",
file.string(), e.what()));
}
}

} // namespace uenv
7 changes: 7 additions & 0 deletions test/unit/env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,10 @@
#include <fmt/core.h>

#include <uenv/env.h>
#include <uenv/log.h>
#include <uenv/meta.h>

TEST_CASE("load_meta", "[env]") {
REQUIRE(uenv::load_meta("/home/bcumming/software/uenv2/test/data/env-files/"
"cp2k-2024.2-v1.json"));
}

0 comments on commit c51e510

Please sign in to comment.