mirror of https://github.com/mamba-org/mamba.git
added static create method to PrefixData + error handling
This commit is contained in:
parent
3f6bfb59bf
commit
d5da2b3bf9
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "tl/expected.hpp"
|
||||
|
||||
#include "history.hpp"
|
||||
#include "package_info.hpp"
|
||||
|
@ -16,12 +17,21 @@
|
|||
|
||||
namespace mamba
|
||||
{
|
||||
enum class prefixdata_error
|
||||
{
|
||||
unknown,
|
||||
load
|
||||
};
|
||||
|
||||
class PrefixData
|
||||
{
|
||||
public:
|
||||
using package_map = std::unordered_map<std::string, PackageInfo>;
|
||||
|
||||
PrefixData(const fs::path& prefix_path);
|
||||
template <class T>
|
||||
using expected = tl::expected<T, mamba_error<prefixdata_error>>;
|
||||
|
||||
static expected<PrefixData> create(const fs::path& prefix_path);
|
||||
|
||||
void add_packages(const std::vector<PackageInfo>& packages);
|
||||
const package_map& records() const;
|
||||
|
@ -32,6 +42,7 @@ namespace mamba
|
|||
std::vector<PackageInfo> sorted_records() const;
|
||||
|
||||
private:
|
||||
PrefixData(const fs::path& prefix_path);
|
||||
void load();
|
||||
|
||||
History m_history;
|
||||
|
|
|
@ -33,17 +33,10 @@ namespace decompress
|
|||
namespace mamba
|
||||
{
|
||||
|
||||
class subdirdata_error
|
||||
enum class subdirdata_error
|
||||
{
|
||||
public:
|
||||
|
||||
subdirdata_error(const char* msg);
|
||||
subdirdata_error(const std::string& msg);
|
||||
const std::string& what() const noexcept;
|
||||
|
||||
private:
|
||||
|
||||
std::string m_message;
|
||||
unknown,
|
||||
load
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -55,7 +48,7 @@ namespace mamba
|
|||
{
|
||||
public:
|
||||
template <class T>
|
||||
using expected = tl::expected<T, subdirdata_error>;
|
||||
using expected = tl::expected<T, mamba_error<subdirdata_error>>;
|
||||
|
||||
static expected<MSubdirData> create(const Channel& channel,
|
||||
const std::string& platform,
|
||||
|
|
|
@ -52,12 +52,6 @@ namespace mamba
|
|||
const static std::regex token_re("/t/([a-zA-Z0-9-_]{0,2}[a-zA-Z0-9-]*)");
|
||||
const static std::regex http_basicauth_re("://([^\\s]+):([^\\s]+)@");
|
||||
|
||||
class mamba_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
bool is_package_file(const std::string_view& fn);
|
||||
|
||||
bool lexists(const fs::path& p);
|
||||
|
@ -117,6 +111,26 @@ namespace mamba
|
|||
return result;
|
||||
}
|
||||
|
||||
enum class unspecified_error
|
||||
{
|
||||
unkown
|
||||
};
|
||||
|
||||
template <class error_type>
|
||||
class mamba_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
using base_type = std::runtime_error;
|
||||
|
||||
mamba_error(const std::string& msg, error_type ec);
|
||||
mamba_error(const char* msg, error_type ec);
|
||||
|
||||
error_type error_code() const noexcept;
|
||||
|
||||
private:
|
||||
error_type m_error_code;
|
||||
};
|
||||
|
||||
class TemporaryDirectory
|
||||
{
|
||||
public:
|
||||
|
@ -467,6 +481,30 @@ namespace mamba
|
|||
std::tuple<std::vector<std::string>, std::unique_ptr<TemporaryFile>> prepare_wrapped_call(
|
||||
const fs::path& prefix, const std::vector<std::string>& cmd);
|
||||
|
||||
/******************************
|
||||
* mamba_error implementation *
|
||||
******************************/
|
||||
|
||||
template <class ET>
|
||||
mamba_error<ET>::mamba_error(const std::string& msg, ET ec)
|
||||
: base_type(msg)
|
||||
, m_error_code(ec)
|
||||
{
|
||||
}
|
||||
|
||||
template <class ET>
|
||||
mamba_error<ET>::mamba_error(const char* msg, ET ec)
|
||||
: base_type(msg)
|
||||
, m_error_code(ec)
|
||||
{
|
||||
}
|
||||
|
||||
template <class ET>
|
||||
ET mamba_error<ET>::error_code() const noexcept
|
||||
{
|
||||
return m_error_code;
|
||||
}
|
||||
|
||||
} // namespace mamba
|
||||
|
||||
#endif // MAMBA_UTIL_HPP
|
||||
|
|
|
@ -14,9 +14,15 @@ namespace mamba
|
|||
{
|
||||
if (!fs::exists(pkgs_dir))
|
||||
{
|
||||
// TODO : us tl::expected mechanis
|
||||
throw std::runtime_error("Specified pkgs_dir does not exist\n");
|
||||
}
|
||||
PrefixData prefix_data(pkgs_dir);
|
||||
auto sprefix_data = PrefixData::create(pkgs_dir);
|
||||
if (!sprefix_data)
|
||||
{
|
||||
throw std::runtime_error("Specified pkgs_dir does not exist\n");
|
||||
}
|
||||
PrefixData& prefix_data = sprefix_data.value();
|
||||
for (const auto& entry : fs::directory_iterator(pkgs_dir))
|
||||
{
|
||||
fs::path repodata_record_json = entry.path() / "info" / "repodata_record.json";
|
||||
|
@ -59,7 +65,8 @@ namespace mamba
|
|||
// TODO: error handling
|
||||
continue;
|
||||
}
|
||||
//auto sdir = std::make_shared<MSubdirData>(*channel, platform, url, package_caches);
|
||||
// auto sdir = std::make_shared<MSubdirData>(*channel, platform, url,
|
||||
// package_caches);
|
||||
auto sdir = std::move(sdires).value();
|
||||
|
||||
multi_dl.add(sdir.target());
|
||||
|
|
|
@ -358,8 +358,13 @@ namespace mamba
|
|||
|
||||
MPool pool;
|
||||
load_channels(pool, package_caches, is_retry);
|
||||
|
||||
PrefixData prefix_data(ctx.target_prefix);
|
||||
auto sprefix_data = PrefixData::create(ctx.target_prefix);
|
||||
if (!sprefix_data)
|
||||
{
|
||||
// TODO: propagate tl::expected mechanism
|
||||
throw std::runtime_error("could not load prefix data");
|
||||
}
|
||||
PrefixData& prefix_data = sprefix_data.value();
|
||||
|
||||
std::vector<std::string> prefix_pkgs;
|
||||
for (auto& it : prefix_data.records())
|
||||
|
@ -463,7 +468,14 @@ namespace mamba
|
|||
{
|
||||
MPool pool;
|
||||
auto& ctx = Context::instance();
|
||||
PrefixData prefix_data(ctx.target_prefix);
|
||||
auto sprefix_data = PrefixData::create(ctx.target_prefix);
|
||||
if (!sprefix_data)
|
||||
{
|
||||
// TODO: propagate tl::expected mechanism
|
||||
throw std::runtime_error("could not load prefix data");
|
||||
}
|
||||
PrefixData& prefix_data = sprefix_data.value();
|
||||
|
||||
fs::path pkgs_dirs(Context::instance().root_prefix / "pkgs");
|
||||
MultiPackageCache pkg_caches({ pkgs_dirs });
|
||||
|
||||
|
|
|
@ -46,7 +46,13 @@ namespace mamba
|
|||
{
|
||||
auto& ctx = Context::instance();
|
||||
|
||||
PrefixData prefix_data(ctx.target_prefix);
|
||||
auto sprefix_data = PrefixData::create(ctx.target_prefix);
|
||||
if (!sprefix_data)
|
||||
{
|
||||
// TODO: propagate tl::expected mechanism
|
||||
throw std::runtime_error("could not load prefix data");
|
||||
}
|
||||
PrefixData& prefix_data = sprefix_data.value();
|
||||
|
||||
std::regex spec_pat(regex);
|
||||
|
||||
|
|
|
@ -35,8 +35,13 @@ namespace mamba
|
|||
|
||||
if (remove_all)
|
||||
{
|
||||
PrefixData prefix_data(ctx.target_prefix);
|
||||
|
||||
auto sprefix_data = PrefixData::create(ctx.target_prefix);
|
||||
if (!sprefix_data)
|
||||
{
|
||||
// TODO: propagate tl::expected mechanism
|
||||
throw std::runtime_error("could not load prefix data");
|
||||
}
|
||||
PrefixData& prefix_data = sprefix_data.value();
|
||||
for (const auto& package : prefix_data.records())
|
||||
{
|
||||
remove_specs.push_back(package.second.name);
|
||||
|
@ -67,7 +72,13 @@ namespace mamba
|
|||
throw std::runtime_error("Aborted.");
|
||||
}
|
||||
|
||||
PrefixData prefix_data(ctx.target_prefix);
|
||||
auto sprefix_data = PrefixData::create(ctx.target_prefix);
|
||||
if (!sprefix_data)
|
||||
{
|
||||
// TODO: propagate tl::expected mechanism
|
||||
throw std::runtime_error("could not load prefix data");
|
||||
}
|
||||
PrefixData& prefix_data = sprefix_data.value();
|
||||
|
||||
MPool pool;
|
||||
MRepo::create(pool, prefix_data);
|
||||
|
|
|
@ -29,7 +29,13 @@ namespace mamba
|
|||
MultiPackageCache package_caches(ctx.pkgs_dirs);
|
||||
if (use_local)
|
||||
{
|
||||
auto prefix_data = PrefixData(ctx.target_prefix);
|
||||
auto sprefix_data = PrefixData::create(ctx.target_prefix);
|
||||
if (!sprefix_data)
|
||||
{
|
||||
// TODO: propagate tl::expected mechanism
|
||||
throw std::runtime_error("could not load prefix data");
|
||||
}
|
||||
PrefixData& prefix_data = sprefix_data.value();
|
||||
MRepo::create(pool, prefix_data);
|
||||
Console::stream() << "Loaded current active prefix: " << ctx.target_prefix << std::endl;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,13 @@ namespace mamba
|
|||
|
||||
load_channels(pool, package_caches, 0);
|
||||
|
||||
PrefixData prefix_data(ctx.target_prefix);
|
||||
auto sprefix_data = PrefixData::create(ctx.target_prefix);
|
||||
if (!sprefix_data)
|
||||
{
|
||||
// TODO: propagate tl::expected mechanism
|
||||
throw std::runtime_error("could not load prefix data");
|
||||
}
|
||||
PrefixData& prefix_data = sprefix_data.value();
|
||||
|
||||
std::vector<std::string> prefix_pkgs;
|
||||
for (auto& it : prefix_data.records())
|
||||
|
|
|
@ -185,7 +185,7 @@ namespace mamba
|
|||
{
|
||||
rhs.m_handle = nullptr;
|
||||
rhs.m_headers = nullptr;
|
||||
std::copy(rhs.m_errbuf, rhs.m_errbuf+CURL_ERROR_SIZE, m_errbuf);
|
||||
std::copy(rhs.m_errbuf, rhs.m_errbuf + CURL_ERROR_SIZE, m_errbuf);
|
||||
}
|
||||
|
||||
DownloadTarget& DownloadTarget::operator=(DownloadTarget&& rhs)
|
||||
|
|
|
@ -14,6 +14,24 @@
|
|||
|
||||
namespace mamba
|
||||
{
|
||||
auto PrefixData::create(const fs::path& prefix_path) -> expected<PrefixData>
|
||||
{
|
||||
try
|
||||
{
|
||||
return PrefixData(prefix_path);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
return tl::make_unexpected(mamba_error(e.what(), prefixdata_error::load));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return tl::make_unexpected(mamba_error("Unkown error when trying to load prefix data "
|
||||
+ std::string(prefix_path),
|
||||
prefixdata_error::unknown));
|
||||
}
|
||||
}
|
||||
|
||||
PrefixData::PrefixData(const fs::path& prefix_path)
|
||||
: m_history(prefix_path)
|
||||
, m_prefix_path(prefix_path)
|
||||
|
|
|
@ -707,7 +707,7 @@ namespace mamba
|
|||
: p_bar(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool ProgressProxy::defined() const
|
||||
{
|
||||
return p_bar != nullptr;
|
||||
|
|
|
@ -160,21 +160,6 @@ namespace mamba
|
|||
|
||||
}
|
||||
|
||||
subdirdata_error::subdirdata_error(const char* msg)
|
||||
: m_message(msg)
|
||||
{
|
||||
}
|
||||
|
||||
subdirdata_error::subdirdata_error(const std::string& msg)
|
||||
: m_message(msg)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string& subdirdata_error::what() const noexcept
|
||||
{
|
||||
return m_message;
|
||||
}
|
||||
|
||||
auto MSubdirData::create(const Channel& channel,
|
||||
const std::string& platform,
|
||||
const std::string& url,
|
||||
|
@ -185,13 +170,14 @@ namespace mamba
|
|||
{
|
||||
return MSubdirData(channel, platform, url, caches, repodata_fn);
|
||||
}
|
||||
catch(std::exception& e)
|
||||
catch (std::exception& e)
|
||||
{
|
||||
return tl::make_unexpected(e.what());
|
||||
return tl::make_unexpected(mamba_error(e.what(), subdirdata_error::load));
|
||||
}
|
||||
catch(...)
|
||||
catch (...)
|
||||
{
|
||||
return tl::make_unexpected("Unkown error when trying to load subdir data " + url);
|
||||
return tl::make_unexpected(mamba_error(
|
||||
"Unkown error when trying to load subdir data " + url, subdirdata_error::unknown));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,14 @@ namespace mamba
|
|||
{
|
||||
std::vector<std::string> specs;
|
||||
std::string pin;
|
||||
PrefixData prefix_data("");
|
||||
|
||||
auto sprefix_data = PrefixData::create("");
|
||||
if (!sprefix_data)
|
||||
{
|
||||
// TODO: propagate tl::expected mechanism
|
||||
throw std::runtime_error("could not load prefix data");
|
||||
}
|
||||
PrefixData& prefix_data = sprefix_data.value();
|
||||
ASSERT_EQ(prefix_data.records().size(), 0);
|
||||
|
||||
specs = { "python" };
|
||||
|
|
|
@ -13,7 +13,10 @@ namespace mamba
|
|||
const mamba::Channel& c = mamba::make_channel("conda-forge");
|
||||
mamba::MultiDownloadTarget multi_dl;
|
||||
mamba::MultiPackageCache pkg_cache({ "/tmp/" });
|
||||
mamba::MSubdirData cf = mamba::MSubdirData::create(c, "linux-64", "file:///nonexistent/repodata.json", pkg_cache).value();
|
||||
mamba::MSubdirData cf
|
||||
= mamba::MSubdirData::create(
|
||||
c, "linux-64", "file:///nonexistent/repodata.json", pkg_cache)
|
||||
.value();
|
||||
multi_dl.add(cf.target());
|
||||
|
||||
// file:// url should not retry
|
||||
|
@ -28,7 +31,9 @@ namespace mamba
|
|||
const mamba::Channel& c = mamba::make_channel("conda-forge");
|
||||
mamba::MultiDownloadTarget multi_dl;
|
||||
mamba::MultiPackageCache pkg_cache({ "/tmp/" });
|
||||
mamba::MSubdirData cf = mamba::MSubdirData::create(c, "noarch", "file:///nonexistent/repodata.json", pkg_cache).value();
|
||||
mamba::MSubdirData cf = mamba::MSubdirData::create(
|
||||
c, "noarch", "file:///nonexistent/repodata.json", pkg_cache)
|
||||
.value();
|
||||
multi_dl.add(cf.target());
|
||||
EXPECT_THROW(multi_dl.download(MAMBA_DOWNLOAD_FAILFAST), std::runtime_error);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ PYBIND11_MODULE(bindings, m)
|
|||
|
||||
py::class_<mamba::LockFile>(m, "LockFile").def(py::init<fs::path>());
|
||||
|
||||
py::register_exception<mamba_error>(m, "MambaNativeException");
|
||||
py::register_exception<mamba_error<unspecified_error>>(m, "MambaNativeException");
|
||||
|
||||
py::add_ostream_redirect(m, "ostream_redirect");
|
||||
|
||||
|
@ -225,12 +225,15 @@ PYBIND11_MODULE(bindings, m)
|
|||
return res_stream.str();
|
||||
});
|
||||
|
||||
py::register_exception<mamba_error<subdirdata_error>>(m, "SubdirDataError");
|
||||
|
||||
py::class_<MSubdirData>(m, "SubdirData")
|
||||
.def(py::init([](const Channel& channel,
|
||||
const std::string& platform,
|
||||
const std::string& url,
|
||||
MultiPackageCache& caches,
|
||||
const std::string& repodata_fn) -> MSubdirData
|
||||
.def(py::init(
|
||||
[](const Channel& channel,
|
||||
const std::string& platform,
|
||||
const std::string& url,
|
||||
MultiPackageCache& caches,
|
||||
const std::string& repodata_fn) -> MSubdirData
|
||||
{
|
||||
auto sres = MSubdirData::create(channel, platform, url, caches, repodata_fn);
|
||||
if (sres.has_value())
|
||||
|
@ -239,7 +242,7 @@ PYBIND11_MODULE(bindings, m)
|
|||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error(sres.error().what());
|
||||
throw sres.error();
|
||||
}
|
||||
}))
|
||||
.def("create_repo", &MSubdirData::create_repo, py::return_value_policy::reference)
|
||||
|
@ -306,7 +309,19 @@ PYBIND11_MODULE(bindings, m)
|
|||
.def("set_log_level", &Context::set_log_level);
|
||||
|
||||
py::class_<PrefixData>(m, "PrefixData")
|
||||
.def(py::init<const fs::path&>())
|
||||
.def(py::init(
|
||||
[](const fs::path& prefix_path) -> PrefixData
|
||||
{
|
||||
auto sres = PrefixData::create(prefix_path);
|
||||
if (sres.has_value())
|
||||
{
|
||||
return std::move(sres.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw sres.error();
|
||||
}
|
||||
}))
|
||||
.def_property_readonly("package_records", &PrefixData::records)
|
||||
.def("add_packages", &PrefixData::add_packages);
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ set_env_command(CLI::App* com)
|
|||
|
||||
if (explicit_format)
|
||||
{
|
||||
PrefixData pd(ctx.target_prefix);
|
||||
// TODO: handle error
|
||||
auto pd = PrefixData::create(ctx.target_prefix).value();
|
||||
auto records = pd.sorted_records();
|
||||
std::cout << "# This file may be used to create an environment using:\n"
|
||||
<< "# $ conda create --name <env> --file <this file>\n"
|
||||
|
@ -87,7 +88,7 @@ set_env_command(CLI::App* com)
|
|||
}
|
||||
else
|
||||
{
|
||||
PrefixData pd(ctx.target_prefix);
|
||||
auto pd = PrefixData::create(ctx.target_prefix).value();
|
||||
History& hist = pd.history();
|
||||
|
||||
auto versions_map = pd.records();
|
||||
|
|
Loading…
Reference in New Issue