mirror of https://github.com/mamba-org/mamba.git
Isolate PackageInfo from libsolv (#2340)
* Isolate libsolv from PackageInfo
This commit is contained in:
parent
66c721c220
commit
8c5841cbfc
|
@ -12,10 +12,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <solv/pool.h>
|
|
||||||
#include <solv/poolid.h>
|
|
||||||
#include <solv/repo.h>
|
|
||||||
#include <solv/solvable.h>
|
|
||||||
|
|
||||||
namespace mamba
|
namespace mamba
|
||||||
{
|
{
|
||||||
|
@ -26,20 +22,14 @@ namespace mamba
|
||||||
using field_getter = std::function<std::string(const PackageInfo&)>;
|
using field_getter = std::function<std::string(const PackageInfo&)>;
|
||||||
using compare_fun = std::function<bool(const PackageInfo&, const PackageInfo&)>;
|
using compare_fun = std::function<bool(const PackageInfo&, const PackageInfo&)>;
|
||||||
|
|
||||||
static field_getter get_field_getter(const std::string& name);
|
static field_getter get_field_getter(std::string_view field_name);
|
||||||
static compare_fun less(const std::string& member);
|
static compare_fun less(std::string_view member);
|
||||||
static compare_fun equal(const std::string& member);
|
static compare_fun equal(std::string_view member);
|
||||||
|
|
||||||
PackageInfo(Solvable* s);
|
PackageInfo() = default;
|
||||||
PackageInfo(nlohmann::json&& j);
|
explicit PackageInfo(nlohmann::json&& j);
|
||||||
PackageInfo(const std::string& name);
|
explicit PackageInfo(std::string name);
|
||||||
PackageInfo(std::string&& name);
|
PackageInfo(std::string name, std::string version, std::string build_string, std::size_t build_number);
|
||||||
PackageInfo(
|
|
||||||
const std::string& name,
|
|
||||||
const std::string& version,
|
|
||||||
const std::string build_string,
|
|
||||||
std::size_t build_number
|
|
||||||
);
|
|
||||||
|
|
||||||
bool operator==(const PackageInfo& other) const;
|
bool operator==(const PackageInfo& other) const;
|
||||||
|
|
||||||
|
@ -48,26 +38,26 @@ namespace mamba
|
||||||
std::string str() const;
|
std::string str() const;
|
||||||
std::string long_str() const;
|
std::string long_str() const;
|
||||||
|
|
||||||
std::string name;
|
std::string name = {};
|
||||||
std::string version;
|
std::string version = {};
|
||||||
std::string build_string;
|
std::string build_string = {};
|
||||||
std::string noarch;
|
std::string noarch = {};
|
||||||
std::size_t build_number = 0;
|
std::size_t build_number = 0;
|
||||||
std::string channel;
|
std::string channel = {};
|
||||||
std::string url;
|
std::string url = {};
|
||||||
std::string subdir;
|
std::string subdir = {};
|
||||||
std::string fn;
|
std::string fn = {};
|
||||||
std::string license;
|
std::string license = {};
|
||||||
std::size_t size = 0;
|
std::size_t size = 0;
|
||||||
std::size_t timestamp = 0;
|
std::size_t timestamp = 0;
|
||||||
std::string md5;
|
std::string md5 = {};
|
||||||
std::string sha256;
|
std::string sha256 = {};
|
||||||
std::string track_features;
|
std::string track_features = {};
|
||||||
std::vector<std::string> depends;
|
std::vector<std::string> depends = {};
|
||||||
std::vector<std::string> constrains;
|
std::vector<std::string> constrains = {};
|
||||||
std::string signatures;
|
std::string signatures = {};
|
||||||
std::string extra_metadata;
|
std::string extra_metadata = {};
|
||||||
std::set<std::string> defaulted_keys;
|
std::set<std::string> defaulted_keys = {};
|
||||||
};
|
};
|
||||||
} // namespace mamba
|
} // namespace mamba
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,16 @@ namespace mamba
|
||||||
MPool();
|
MPool();
|
||||||
~MPool();
|
~MPool();
|
||||||
|
|
||||||
|
std::size_t n_solvables() const;
|
||||||
|
|
||||||
void set_debuglevel();
|
void set_debuglevel();
|
||||||
void create_whatprovides();
|
void create_whatprovides();
|
||||||
|
|
||||||
std::vector<Id> select_solvables(Id id, bool sorted = false) const;
|
std::vector<Id> select_solvables(Id id, bool sorted = false) const;
|
||||||
Id matchspec2id(const std::string& ms);
|
Id matchspec2id(const std::string& ms);
|
||||||
|
|
||||||
std::optional<PackageInfo> id2pkginfo(Id id);
|
std::optional<PackageInfo> id2pkginfo(Id solv_id) const;
|
||||||
|
std::optional<std::string> dep2str(Id dep_id) const;
|
||||||
|
|
||||||
operator Pool*();
|
operator Pool*();
|
||||||
operator const Pool*() const;
|
operator const Pool*() const;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
typedef struct s_Repo Repo;
|
typedef struct s_Repo Repo;
|
||||||
|
typedef struct s_Repodata Repodata;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace mamba
|
namespace mamba
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace mamba
|
||||||
[[nodiscard]] const std::vector<MatchSpec>& neuter_specs() const;
|
[[nodiscard]] const std::vector<MatchSpec>& neuter_specs() const;
|
||||||
[[nodiscard]] const std::vector<MatchSpec>& pinned_specs() const;
|
[[nodiscard]] const std::vector<MatchSpec>& pinned_specs() const;
|
||||||
|
|
||||||
|
operator const Solver*() const;
|
||||||
operator Solver*();
|
operator Solver*();
|
||||||
|
|
||||||
bool only_deps = false;
|
bool only_deps = false;
|
||||||
|
|
|
@ -35,14 +35,10 @@
|
||||||
|
|
||||||
namespace mamba
|
namespace mamba
|
||||||
{
|
{
|
||||||
void try_add(nlohmann::json& j, const char* key, const char* val);
|
|
||||||
nlohmann::json solvable_to_json(Solvable* s);
|
|
||||||
|
|
||||||
class PackageDownloadExtractTarget
|
class PackageDownloadExtractTarget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PackageDownloadExtractTarget(Solvable* solvable);
|
|
||||||
PackageDownloadExtractTarget(const PackageInfo& pkg_info);
|
PackageDownloadExtractTarget(const PackageInfo& pkg_info);
|
||||||
|
|
||||||
void write_repodata_record(const fs::u8path& base_path);
|
void write_repodata_record(const fs::u8path& base_path);
|
||||||
|
@ -126,7 +122,7 @@ namespace mamba
|
||||||
const std::vector<MatchSpec>& specs_to_install,
|
const std::vector<MatchSpec>& specs_to_install,
|
||||||
MultiPackageCache& caches
|
MultiPackageCache& caches
|
||||||
);
|
);
|
||||||
MTransaction(MSolver& solver, MultiPackageCache& caches);
|
MTransaction(MPool& pool, MSolver& solver, MultiPackageCache& caches);
|
||||||
|
|
||||||
// Only use if the packages have been solved previously already.
|
// Only use if the packages have been solved previously already.
|
||||||
MTransaction(MPool& pool, const std::vector<PackageInfo>& packages, MultiPackageCache& caches);
|
MTransaction(MPool& pool, const std::vector<PackageInfo>& packages, MultiPackageCache& caches);
|
||||||
|
@ -157,6 +153,8 @@ namespace mamba
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
MPool m_pool;
|
||||||
|
|
||||||
FilterType m_filter_type = FilterType::none;
|
FilterType m_filter_type = FilterType::none;
|
||||||
std::set<Id> m_filter_name_ids;
|
std::set<Id> m_filter_name_ids;
|
||||||
|
|
||||||
|
|
|
@ -493,10 +493,12 @@ namespace mamba
|
||||||
MRepo::create(pool, prefix_data);
|
MRepo::create(pool, prefix_data);
|
||||||
|
|
||||||
MSolver solver(
|
MSolver solver(
|
||||||
std::move(pool),
|
pool,
|
||||||
{ { SOLVER_FLAG_ALLOW_UNINSTALL, ctx.allow_uninstall },
|
{
|
||||||
|
{ SOLVER_FLAG_ALLOW_UNINSTALL, ctx.allow_uninstall },
|
||||||
{ SOLVER_FLAG_ALLOW_DOWNGRADE, ctx.allow_downgrade },
|
{ SOLVER_FLAG_ALLOW_DOWNGRADE, ctx.allow_downgrade },
|
||||||
{ SOLVER_FLAG_STRICT_REPO_PRIORITY, ctx.channel_priority == ChannelPriority::kStrict } }
|
{ SOLVER_FLAG_STRICT_REPO_PRIORITY, ctx.channel_priority == ChannelPriority::kStrict },
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
solver.set_postsolve_flags({ { MAMBA_NO_DEPS, no_deps },
|
solver.set_postsolve_flags({ { MAMBA_NO_DEPS, no_deps },
|
||||||
|
@ -560,7 +562,7 @@ namespace mamba
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
MTransaction trans(solver, package_caches);
|
MTransaction trans(pool, solver, package_caches);
|
||||||
|
|
||||||
if (ctx.json)
|
if (ctx.json)
|
||||||
{
|
{
|
||||||
|
|
|
@ -111,11 +111,13 @@ namespace mamba
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MSolver solver(
|
MSolver solver(
|
||||||
std::move(pool),
|
pool,
|
||||||
{ { SOLVER_FLAG_ALLOW_DOWNGRADE, 1 },
|
{
|
||||||
|
{ SOLVER_FLAG_ALLOW_DOWNGRADE, 1 },
|
||||||
{ SOLVER_FLAG_ALLOW_UNINSTALL, 1 },
|
{ SOLVER_FLAG_ALLOW_UNINSTALL, 1 },
|
||||||
{ SOLVER_FLAG_STRICT_REPO_PRIORITY,
|
{ SOLVER_FLAG_STRICT_REPO_PRIORITY,
|
||||||
ctx.channel_priority == ChannelPriority::kStrict } }
|
ctx.channel_priority == ChannelPriority::kStrict },
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
History history(ctx.target_prefix);
|
History history(ctx.target_prefix);
|
||||||
|
@ -138,7 +140,7 @@ namespace mamba
|
||||||
solver.add_jobs(specs, solver_flag);
|
solver.add_jobs(specs, solver_flag);
|
||||||
solver.must_solve();
|
solver.must_solve();
|
||||||
|
|
||||||
MTransaction transaction(solver, package_caches);
|
MTransaction transaction(pool, solver, package_caches);
|
||||||
execute_transaction(transaction);
|
execute_transaction(transaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,10 +70,12 @@ namespace mamba
|
||||||
MRepo::create(pool, prefix_data);
|
MRepo::create(pool, prefix_data);
|
||||||
|
|
||||||
MSolver solver(
|
MSolver solver(
|
||||||
std::move(pool),
|
pool,
|
||||||
{ { SOLVER_FLAG_ALLOW_DOWNGRADE, ctx.allow_downgrade },
|
{
|
||||||
|
{ SOLVER_FLAG_ALLOW_DOWNGRADE, ctx.allow_downgrade },
|
||||||
{ SOLVER_FLAG_ALLOW_UNINSTALL, ctx.allow_uninstall },
|
{ SOLVER_FLAG_ALLOW_UNINSTALL, ctx.allow_uninstall },
|
||||||
{ SOLVER_FLAG_STRICT_REPO_PRIORITY, ctx.channel_priority == ChannelPriority::kStrict } }
|
{ SOLVER_FLAG_STRICT_REPO_PRIORITY, ctx.channel_priority == ChannelPriority::kStrict },
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (update_all)
|
if (update_all)
|
||||||
|
@ -140,7 +142,7 @@ namespace mamba
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MTransaction transaction(solver, package_caches);
|
MTransaction transaction(pool, solver, package_caches);
|
||||||
execute_transaction(transaction);
|
execute_transaction(transaction);
|
||||||
|
|
||||||
config.operation_teardown();
|
config.operation_teardown();
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include "mamba/core/channel.hpp"
|
#include "mamba/core/channel.hpp"
|
||||||
#include "mamba/core/util_string.hpp"
|
#include "mamba/core/util_string.hpp"
|
||||||
|
|
||||||
#include "solv-cpp/queue.hpp"
|
|
||||||
|
|
||||||
namespace mamba
|
namespace mamba
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
|
@ -43,7 +41,7 @@ namespace mamba
|
||||||
return std::bind(get_package_info_field<T>, std::placeholders::_1, field);
|
return std::bind(get_package_info_field<T>, std::placeholders::_1, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
using field_getter_map = std::map<std::string, PackageInfo::field_getter>;
|
using field_getter_map = std::map<std::string_view, PackageInfo::field_getter>;
|
||||||
|
|
||||||
field_getter_map build_field_getter_map()
|
field_getter_map build_field_getter_map()
|
||||||
{
|
{
|
||||||
|
@ -62,16 +60,16 @@ namespace mamba
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
field_getter_map& get_field_getter_map()
|
const field_getter_map& get_field_getter_map()
|
||||||
{
|
{
|
||||||
static field_getter_map m = build_field_getter_map();
|
static field_getter_map m = build_field_getter_map();
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
PackageInfo::field_getter PackageInfo::get_field_getter(const std::string& name)
|
PackageInfo::field_getter PackageInfo::get_field_getter(std::string_view field_name)
|
||||||
{
|
{
|
||||||
auto it = get_field_getter_map().find(name);
|
auto it = get_field_getter_map().find(field_name);
|
||||||
if (it == get_field_getter_map().end())
|
if (it == get_field_getter_map().end())
|
||||||
{
|
{
|
||||||
throw std::runtime_error("field_getter function not found");
|
throw std::runtime_error("field_getter function not found");
|
||||||
|
@ -79,169 +77,20 @@ namespace mamba
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageInfo::compare_fun PackageInfo::less(const std::string& member)
|
PackageInfo::compare_fun PackageInfo::less(std::string_view member)
|
||||||
{
|
{
|
||||||
auto getter = get_field_getter(member);
|
auto getter = get_field_getter(member);
|
||||||
return [getter](const PackageInfo& lhs, const PackageInfo& rhs)
|
return [getter](const PackageInfo& lhs, const PackageInfo& rhs)
|
||||||
{ return getter(lhs) < getter(rhs); };
|
{ return getter(lhs) < getter(rhs); };
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageInfo::compare_fun PackageInfo::equal(const std::string& member)
|
PackageInfo::compare_fun PackageInfo::equal(std::string_view member)
|
||||||
{
|
{
|
||||||
auto getter = get_field_getter(member);
|
auto getter = get_field_getter(member);
|
||||||
return [getter](const PackageInfo& lhs, const PackageInfo& rhs)
|
return [getter](const PackageInfo& lhs, const PackageInfo& rhs)
|
||||||
{ return getter(lhs) == getter(rhs); };
|
{ return getter(lhs) == getter(rhs); };
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageInfo::PackageInfo(Solvable* s)
|
|
||||||
{
|
|
||||||
// Note: this function (especially the checksum part) is NOT YET threadsafe!
|
|
||||||
Pool* pool = s->repo->pool;
|
|
||||||
Id check_type;
|
|
||||||
|
|
||||||
name = pool_id2str(pool, s->name);
|
|
||||||
version = pool_id2str(pool, s->evr);
|
|
||||||
const char* str = solvable_lookup_str(s, SOLVABLE_BUILDFLAVOR);
|
|
||||||
if (str)
|
|
||||||
{
|
|
||||||
build_string = str;
|
|
||||||
}
|
|
||||||
str = solvable_lookup_str(s, SOLVABLE_BUILDVERSION);
|
|
||||||
if (str)
|
|
||||||
{
|
|
||||||
build_number = std::stoull(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Id real_repo_key = pool_str2id(pool, "solvable:real_repo_url", 1);
|
|
||||||
if (solvable_lookup_str(s, real_repo_key))
|
|
||||||
{
|
|
||||||
url = solvable_lookup_str(s, real_repo_key);
|
|
||||||
channel = make_channel(url).canonical_name();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!s->repo || strcmp(s->repo->name, "__explicit_specs__") == 0)
|
|
||||||
{
|
|
||||||
url = solvable_lookup_location(s, 0);
|
|
||||||
channel = make_channel(url).canonical_name();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
channel = s->repo->name; // note this can and should be <unknown> when e.g.
|
|
||||||
// installing from a tarball
|
|
||||||
url = channel + "/" + raw_str_or_empty(solvable_lookup_str(s, SOLVABLE_MEDIAFILE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subdir = raw_str_or_empty(solvable_lookup_str(s, SOLVABLE_MEDIADIR));
|
|
||||||
fn = raw_str_or_empty(solvable_lookup_str(s, SOLVABLE_MEDIAFILE));
|
|
||||||
str = raw_str_or_empty(solvable_lookup_str(s, SOLVABLE_LICENSE));
|
|
||||||
if (str)
|
|
||||||
{
|
|
||||||
license = str;
|
|
||||||
}
|
|
||||||
size = solvable_lookup_num(s, SOLVABLE_DOWNLOADSIZE, 0);
|
|
||||||
timestamp = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0);
|
|
||||||
str = solvable_lookup_checksum(s, SOLVABLE_PKGID, &check_type);
|
|
||||||
if (str)
|
|
||||||
{
|
|
||||||
md5 = str;
|
|
||||||
}
|
|
||||||
str = solvable_lookup_checksum(s, SOLVABLE_CHECKSUM, &check_type);
|
|
||||||
if (str)
|
|
||||||
{
|
|
||||||
sha256 = str;
|
|
||||||
}
|
|
||||||
signatures = raw_str_or_empty(solvable_lookup_str(s, SIGNATURE_DATA));
|
|
||||||
if (signatures.empty())
|
|
||||||
{
|
|
||||||
signatures = "{}";
|
|
||||||
}
|
|
||||||
|
|
||||||
solv::ObjQueue q = {};
|
|
||||||
|
|
||||||
if (!solvable_lookup_deparray(s, SOLVABLE_REQUIRES, q.raw(), -1))
|
|
||||||
{
|
|
||||||
defaulted_keys.insert("depends");
|
|
||||||
}
|
|
||||||
depends.reserve(q.size());
|
|
||||||
std::transform(
|
|
||||||
q.begin(),
|
|
||||||
q.end(),
|
|
||||||
std::back_inserter(depends),
|
|
||||||
[&pool](Id id) { return pool_dep2str(pool, id); }
|
|
||||||
);
|
|
||||||
|
|
||||||
q.clear();
|
|
||||||
if (!solvable_lookup_deparray(s, SOLVABLE_CONSTRAINS, q.raw(), -1))
|
|
||||||
{
|
|
||||||
defaulted_keys.insert("constrains");
|
|
||||||
}
|
|
||||||
constrains.reserve(q.size());
|
|
||||||
std::transform(
|
|
||||||
q.begin(),
|
|
||||||
q.end(),
|
|
||||||
std::back_inserter(constrains),
|
|
||||||
[&pool](Id id) { return pool_dep2str(pool, id); }
|
|
||||||
);
|
|
||||||
|
|
||||||
q.clear();
|
|
||||||
solvable_lookup_idarray(s, SOLVABLE_TRACK_FEATURES, q.raw());
|
|
||||||
for (auto iter = q.begin(), end = q.end(); iter < end; ++iter)
|
|
||||||
{
|
|
||||||
track_features += pool_id2str(pool, *iter);
|
|
||||||
if (iter < end - 1)
|
|
||||||
{
|
|
||||||
track_features += ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Id extra_keys_id = pool_str2id(pool, "solvable:extra_keys", 0);
|
|
||||||
Id extra_values_id = pool_str2id(pool, "solvable:extra_values", 0);
|
|
||||||
|
|
||||||
if (extra_keys_id && extra_values_id)
|
|
||||||
{
|
|
||||||
// Get extra signed keys
|
|
||||||
q.clear();
|
|
||||||
solvable_lookup_idarray(s, extra_keys_id, q.raw());
|
|
||||||
std::vector<std::string> extra_keys = {};
|
|
||||||
extra_keys.reserve(q.size());
|
|
||||||
std::transform(
|
|
||||||
q.begin(),
|
|
||||||
q.end(),
|
|
||||||
std::back_inserter(extra_keys),
|
|
||||||
[&pool](Id id) { return pool_dep2str(pool, id); }
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get extra signed values
|
|
||||||
q.clear();
|
|
||||||
solvable_lookup_idarray(s, extra_values_id, q.raw());
|
|
||||||
std::vector<std::string> extra_values = {};
|
|
||||||
extra_values.reserve(q.size());
|
|
||||||
std::transform(
|
|
||||||
q.begin(),
|
|
||||||
q.end(),
|
|
||||||
std::back_inserter(extra_values),
|
|
||||||
[&pool](Id id) { return pool_dep2str(pool, id); }
|
|
||||||
);
|
|
||||||
|
|
||||||
// Build a JSON string for extra signed metadata
|
|
||||||
if (!extra_keys.empty() && (extra_keys.size() == extra_values.size()))
|
|
||||||
{
|
|
||||||
std::vector<std::string> extra;
|
|
||||||
for (std::size_t i = 0; i < extra_keys.size(); ++i)
|
|
||||||
{
|
|
||||||
extra.push_back("\"" + extra_keys[i] + "\":" + extra_values[i]);
|
|
||||||
}
|
|
||||||
extra_metadata = "{" + join(",", extra) + "}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
extra_metadata = "{}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PackageInfo::PackageInfo(nlohmann::json&& j)
|
PackageInfo::PackageInfo(nlohmann::json&& j)
|
||||||
{
|
{
|
||||||
using namespace std::string_literals; // NOLINT(build/namespaces)
|
using namespace std::string_literals; // NOLINT(build/namespaces)
|
||||||
|
@ -289,21 +138,16 @@ namespace mamba
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageInfo::PackageInfo(const std::string& n)
|
PackageInfo::PackageInfo(std::string n)
|
||||||
: name(n)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PackageInfo::PackageInfo(std::string&& n)
|
|
||||||
: name(std::move(n))
|
: name(std::move(n))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageInfo::PackageInfo(const std::string& n, const std::string& v, const std::string b, std::size_t bn)
|
PackageInfo::PackageInfo(std::string n, std::string v, std::string b, std::size_t bn)
|
||||||
: name(n)
|
: name(std::move(n))
|
||||||
, version(v)
|
, version(std::move(v))
|
||||||
, build_string(b)
|
, build_string(std::move(b))
|
||||||
, build_number(bn)
|
, build_number(std::move(bn))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
#include <solv/evr.h>
|
#include <solv/evr.h>
|
||||||
#include <solv/pool.h>
|
#include <solv/pool.h>
|
||||||
#include <solv/selection.h>
|
#include <solv/selection.h>
|
||||||
|
@ -19,6 +20,9 @@ extern "C" // Incomplete header
|
||||||
#include "mamba/core/context.hpp"
|
#include "mamba/core/context.hpp"
|
||||||
#include "mamba/core/output.hpp"
|
#include "mamba/core/output.hpp"
|
||||||
#include "mamba/core/pool.hpp"
|
#include "mamba/core/pool.hpp"
|
||||||
|
#include "mamba/core/util_cast.hpp"
|
||||||
|
#include "mamba/core/util_compare.hpp"
|
||||||
|
#include "mamba/core/util_string.hpp"
|
||||||
|
|
||||||
#include "solv-cpp/queue.hpp"
|
#include "solv-cpp/queue.hpp"
|
||||||
|
|
||||||
|
@ -90,6 +94,11 @@ namespace mamba
|
||||||
return m_data->pool.get();
|
return m_data->pool.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t MPool::n_solvables() const
|
||||||
|
{
|
||||||
|
return util::safe_num_cast<std::size_t>(pool()->nsolvables);
|
||||||
|
}
|
||||||
|
|
||||||
void MPool::set_debuglevel()
|
void MPool::set_debuglevel()
|
||||||
{
|
{
|
||||||
// ensure that debug logging goes to stderr as to not interfere with stdout json output
|
// ensure that debug logging goes to stderr as to not interfere with stdout json output
|
||||||
|
@ -150,13 +159,147 @@ namespace mamba
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<PackageInfo> MPool::id2pkginfo(Id id)
|
namespace
|
||||||
{
|
{
|
||||||
if (id == 0 || id >= pool()->nsolvables)
|
auto make_package_info(::Solvable& s) -> PackageInfo
|
||||||
|
{
|
||||||
|
// Note: this function (especially the checksum part) is NOT YET threadsafe!
|
||||||
|
Pool* pool = s.repo->pool;
|
||||||
|
Id check_type;
|
||||||
|
|
||||||
|
PackageInfo out = {};
|
||||||
|
|
||||||
|
out.name = pool_id2str(pool, s.name);
|
||||||
|
out.version = pool_id2str(pool, s.evr);
|
||||||
|
out.build_string = raw_str_or_empty(solvable_lookup_str(&s, SOLVABLE_BUILDFLAVOR));
|
||||||
|
if (const char* str = solvable_lookup_str(&s, SOLVABLE_BUILDVERSION); str != nullptr)
|
||||||
|
{
|
||||||
|
out.build_number = std::stoull(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ::Id real_repo_key = pool_str2id(pool, "solvable:real_repo_url", 1);
|
||||||
|
if (const char* str = solvable_lookup_str(&s, real_repo_key); str != nullptr)
|
||||||
|
{
|
||||||
|
out.url = str;
|
||||||
|
out.channel = make_channel(out.url).canonical_name();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!s.repo || strcmp(s.repo->name, "__explicit_specs__") == 0)
|
||||||
|
{
|
||||||
|
out.url = solvable_lookup_location(&s, 0);
|
||||||
|
out.channel = make_channel(out.url).canonical_name();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.channel = s.repo->name; // note this can and should be <unknown> when e.g.
|
||||||
|
// installing from a tarball
|
||||||
|
out.url = fmt::format(
|
||||||
|
"{}/{}",
|
||||||
|
out.channel,
|
||||||
|
raw_str_or_empty(solvable_lookup_str(&s, SOLVABLE_MEDIAFILE))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.subdir = raw_str_or_empty(solvable_lookup_str(&s, SOLVABLE_MEDIADIR));
|
||||||
|
out.fn = raw_str_or_empty(solvable_lookup_str(&s, SOLVABLE_MEDIAFILE));
|
||||||
|
out.license = raw_str_or_empty(solvable_lookup_str(&s, SOLVABLE_LICENSE));
|
||||||
|
out.size = solvable_lookup_num(&s, SOLVABLE_DOWNLOADSIZE, 0);
|
||||||
|
out.timestamp = solvable_lookup_num(&s, SOLVABLE_BUILDTIME, 0);
|
||||||
|
out.md5 = raw_str_or_empty(solvable_lookup_checksum(&s, SOLVABLE_PKGID, &check_type));
|
||||||
|
out.sha256 = raw_str_or_empty(solvable_lookup_checksum(&s, SOLVABLE_CHECKSUM, &check_type)
|
||||||
|
);
|
||||||
|
out.signatures = raw_str_or_empty(solvable_lookup_str(&s, SIGNATURE_DATA));
|
||||||
|
if (out.signatures.empty())
|
||||||
|
{
|
||||||
|
out.signatures = "{}";
|
||||||
|
}
|
||||||
|
|
||||||
|
solv::ObjQueue q = {};
|
||||||
|
auto dep2str = [&pool](Id id) { return pool_dep2str(pool, id); };
|
||||||
|
if (!solvable_lookup_deparray(&s, SOLVABLE_REQUIRES, q.raw(), -1))
|
||||||
|
{
|
||||||
|
out.defaulted_keys.insert("depends");
|
||||||
|
}
|
||||||
|
out.depends.reserve(q.size());
|
||||||
|
std::transform(q.begin(), q.end(), std::back_inserter(out.depends), dep2str);
|
||||||
|
|
||||||
|
q.clear();
|
||||||
|
if (!solvable_lookup_deparray(&s, SOLVABLE_CONSTRAINS, q.raw(), -1))
|
||||||
|
{
|
||||||
|
out.defaulted_keys.insert("constrains");
|
||||||
|
}
|
||||||
|
out.constrains.reserve(q.size());
|
||||||
|
std::transform(q.begin(), q.end(), std::back_inserter(out.constrains), dep2str);
|
||||||
|
|
||||||
|
q.clear();
|
||||||
|
solvable_lookup_idarray(&s, SOLVABLE_TRACK_FEATURES, q.raw());
|
||||||
|
for (::Id const id : q)
|
||||||
|
{
|
||||||
|
out.track_features += pool_id2str(pool, id);
|
||||||
|
out.track_features += ',';
|
||||||
|
}
|
||||||
|
if (!out.track_features.empty())
|
||||||
|
{
|
||||||
|
out.track_features.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ::Id extra_keys_id = pool_str2id(pool, "solvable:extra_keys", 0);
|
||||||
|
const ::Id extra_values_id = pool_str2id(pool, "solvable:extra_values", 0);
|
||||||
|
if (extra_keys_id && extra_values_id)
|
||||||
|
{
|
||||||
|
// Get extra signed keys
|
||||||
|
q.clear();
|
||||||
|
solvable_lookup_idarray(&s, extra_keys_id, q.raw());
|
||||||
|
std::vector<std::string> extra_keys = {};
|
||||||
|
extra_keys.reserve(q.size());
|
||||||
|
std::transform(q.begin(), q.end(), std::back_inserter(extra_keys), dep2str);
|
||||||
|
|
||||||
|
// Get extra signed values
|
||||||
|
q.clear();
|
||||||
|
solvable_lookup_idarray(&s, extra_values_id, q.raw());
|
||||||
|
std::vector<std::string> extra_values = {};
|
||||||
|
extra_values.reserve(q.size());
|
||||||
|
std::transform(q.begin(), q.end(), std::back_inserter(extra_values), dep2str);
|
||||||
|
|
||||||
|
// Build a JSON string for extra signed metadata
|
||||||
|
if (!extra_keys.empty() && (extra_keys.size() == extra_values.size()))
|
||||||
|
{
|
||||||
|
std::vector<std::string> extra = {};
|
||||||
|
extra.reserve(extra_keys.size());
|
||||||
|
for (std::size_t i = 0; i < extra_keys.size(); ++i)
|
||||||
|
{
|
||||||
|
extra.push_back(fmt::format(R"("{}":{})", extra_keys[i], extra_values[i]));
|
||||||
|
}
|
||||||
|
out.extra_metadata = fmt::format("{{{}}}", fmt::join(extra, ","));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.extra_metadata = "{}";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<PackageInfo> MPool::id2pkginfo(Id solv_id) const
|
||||||
|
{
|
||||||
|
if (solv_id == 0 || util::cmp_greater_equal(solv_id, n_solvables()))
|
||||||
{
|
{
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return pool_id2solvable(pool(), id);
|
return { make_package_info(*pool_id2solvable(pool(), solv_id)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> MPool::dep2str(Id dep_id) const
|
||||||
|
{
|
||||||
|
if (!dep_id)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
// Not const because might alloctmp space
|
||||||
|
return pool_dep2str(const_cast<::Pool*>(pool()), dep_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
MRepo& MPool::add_repo(MRepo&& repo)
|
MRepo& MPool::add_repo(MRepo&& repo)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "mamba/core/prefix_data.hpp"
|
#include "mamba/core/prefix_data.hpp"
|
||||||
|
|
||||||
|
#include <solv/pool.h>
|
||||||
|
#include <solv/repo.h>
|
||||||
#include <solv/transaction.h>
|
#include <solv/transaction.h>
|
||||||
|
|
||||||
#include "mamba/core/output.hpp"
|
#include "mamba/core/output.hpp"
|
||||||
|
|
|
@ -26,8 +26,11 @@
|
||||||
#include "solv-cpp/queue.hpp"
|
#include "solv-cpp/queue.hpp"
|
||||||
|
|
||||||
namespace mamba
|
namespace mamba
|
||||||
|
{
|
||||||
|
namespace
|
||||||
{
|
{
|
||||||
void walk_graph(
|
void walk_graph(
|
||||||
|
MPool pool,
|
||||||
query_result::dependency_graph& dep_graph,
|
query_result::dependency_graph& dep_graph,
|
||||||
query_result::dependency_graph::node_id parent,
|
query_result::dependency_graph::node_id parent,
|
||||||
Solvable* s,
|
Solvable* s,
|
||||||
|
@ -44,8 +47,6 @@ namespace mamba
|
||||||
|
|
||||||
if (s && s->requires)
|
if (s && s->requires)
|
||||||
{
|
{
|
||||||
auto* pool = s->repo->pool;
|
|
||||||
|
|
||||||
Id* reqp = s->repo->idarraydata + s->requires;
|
Id* reqp = s->repo->idarraydata + s->requires;
|
||||||
Id req = *reqp;
|
Id req = *reqp;
|
||||||
|
|
||||||
|
@ -70,10 +71,12 @@ namespace mamba
|
||||||
auto it = visited.find(rs);
|
auto it = visited.find(rs);
|
||||||
if (it == visited.end())
|
if (it == visited.end())
|
||||||
{
|
{
|
||||||
auto dep_id = dep_graph.add_node(PackageInfo(rs));
|
auto pkg_info = pool.id2pkginfo(pool_solvable2id(pool, rs));
|
||||||
|
assert(pkg_info.has_value());
|
||||||
|
auto dep_id = dep_graph.add_node(std::move(pkg_info).value());
|
||||||
dep_graph.add_edge(parent, dep_id);
|
dep_graph.add_edge(parent, dep_id);
|
||||||
visited.insert(std::make_pair(rs, dep_id));
|
visited.insert(std::make_pair(rs, dep_id));
|
||||||
walk_graph(dep_graph, dep_id, rs, visited, not_found, depth);
|
walk_graph(pool, dep_graph, dep_id, rs, visited, not_found, depth);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -104,6 +107,7 @@ namespace mamba
|
||||||
}
|
}
|
||||||
|
|
||||||
void reverse_walk_graph(
|
void reverse_walk_graph(
|
||||||
|
MPool& pool,
|
||||||
query_result::dependency_graph& dep_graph,
|
query_result::dependency_graph& dep_graph,
|
||||||
query_result::dependency_graph::node_id parent,
|
query_result::dependency_graph::node_id parent,
|
||||||
Solvable* s,
|
Solvable* s,
|
||||||
|
@ -112,7 +116,6 @@ namespace mamba
|
||||||
{
|
{
|
||||||
if (s)
|
if (s)
|
||||||
{
|
{
|
||||||
auto* pool = s->repo->pool;
|
|
||||||
// figure out who requires `s`
|
// figure out who requires `s`
|
||||||
solv::ObjQueue solvables = {};
|
solv::ObjQueue solvables = {};
|
||||||
|
|
||||||
|
@ -120,17 +123,18 @@ namespace mamba
|
||||||
|
|
||||||
if (solvables.size() != 0)
|
if (solvables.size() != 0)
|
||||||
{
|
{
|
||||||
Solvable* rs;
|
|
||||||
for (auto& el : solvables)
|
for (auto& el : solvables)
|
||||||
{
|
{
|
||||||
rs = pool_id2solvable(pool, el);
|
::Solvable* rs = pool_id2solvable(pool, el);
|
||||||
auto it = visited.find(rs);
|
auto it = visited.find(rs);
|
||||||
if (it == visited.end())
|
if (it == visited.end())
|
||||||
{
|
{
|
||||||
auto dep_id = dep_graph.add_node(PackageInfo(rs));
|
auto pkg_info = pool.id2pkginfo(el);
|
||||||
|
assert(pkg_info.has_value());
|
||||||
|
auto dep_id = dep_graph.add_node(std::move(pkg_info).value());
|
||||||
dep_graph.add_edge(parent, dep_id);
|
dep_graph.add_edge(parent, dep_id);
|
||||||
visited.insert(std::make_pair(rs, dep_id));
|
visited.insert(std::make_pair(rs, dep_id));
|
||||||
reverse_walk_graph(dep_graph, dep_id, rs, visited);
|
reverse_walk_graph(pool, dep_graph, dep_id, rs, visited);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -140,6 +144,7 @@ namespace mamba
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
* Query implementation *
|
* Query implementation *
|
||||||
|
@ -236,8 +241,9 @@ namespace mamba
|
||||||
|
|
||||||
for (auto& el : solvables)
|
for (auto& el : solvables)
|
||||||
{
|
{
|
||||||
Solvable* s = pool_id2solvable(m_pool.get(), el);
|
auto pkg_info = m_pool.get().id2pkginfo(el);
|
||||||
g.add_node(PackageInfo(s));
|
assert(pkg_info.has_value());
|
||||||
|
g.add_node(std::move(pkg_info).value());
|
||||||
}
|
}
|
||||||
|
|
||||||
return query_result(QueryType::kSEARCH, query, std::move(g));
|
return query_result(QueryType::kSEARCH, query, std::move(g));
|
||||||
|
@ -245,35 +251,38 @@ namespace mamba
|
||||||
|
|
||||||
query_result Query::whoneeds(const std::string& query, bool tree) const
|
query_result Query::whoneeds(const std::string& query, bool tree) const
|
||||||
{
|
{
|
||||||
solv::ObjQueue job, solvables;
|
|
||||||
|
|
||||||
const Id id = pool_conda_matchspec(m_pool.get(), query.c_str());
|
const Id id = pool_conda_matchspec(m_pool.get(), query.c_str());
|
||||||
if (!id)
|
if (!id)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Could not generate query for " + query);
|
throw std::runtime_error("Could not generate query for " + query);
|
||||||
}
|
}
|
||||||
job.push_back(SOLVER_SOLVABLE_PROVIDES, id);
|
|
||||||
|
|
||||||
|
solv::ObjQueue job = { SOLVER_SOLVABLE_PROVIDES, id };
|
||||||
query_result::dependency_graph g;
|
query_result::dependency_graph g;
|
||||||
|
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
|
solv::ObjQueue solvables = {};
|
||||||
selection_solvables(m_pool.get(), job.raw(), solvables.raw());
|
selection_solvables(m_pool.get(), job.raw(), solvables.raw());
|
||||||
if (solvables.size() > 0)
|
if (!solvables.empty())
|
||||||
{
|
{
|
||||||
Solvable* latest = pool_id2solvable(m_pool.get(), solvables[0]);
|
auto pkg_info = m_pool.get().id2pkginfo(solvables.front());
|
||||||
const auto node_id = g.add_node(PackageInfo(latest));
|
assert(pkg_info.has_value());
|
||||||
|
const auto node_id = g.add_node(std::move(pkg_info).value());
|
||||||
|
Solvable* const latest = pool_id2solvable(m_pool.get(), solvables.front());
|
||||||
std::map<Solvable*, size_t> visited = { { latest, node_id } };
|
std::map<Solvable*, size_t> visited = { { latest, node_id } };
|
||||||
reverse_walk_graph(g, node_id, latest, visited);
|
reverse_walk_graph(m_pool, g, node_id, latest, visited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
solv::ObjQueue solvables = {};
|
||||||
pool_whatmatchesdep(m_pool.get(), SOLVABLE_REQUIRES, id, solvables.raw(), -1);
|
pool_whatmatchesdep(m_pool.get(), SOLVABLE_REQUIRES, id, solvables.raw(), -1);
|
||||||
for (auto& el : solvables)
|
for (auto& el : solvables)
|
||||||
{
|
{
|
||||||
Solvable* s = pool_id2solvable(m_pool.get(), el);
|
auto pkg_info = m_pool.get().id2pkginfo(el);
|
||||||
g.add_node(PackageInfo(s));
|
assert(pkg_info.has_value());
|
||||||
|
g.add_node(std::move(pkg_info).value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return query_result(QueryType::kWHONEEDS, query, std::move(g));
|
return query_result(QueryType::kWHONEEDS, query, std::move(g));
|
||||||
|
@ -297,8 +306,8 @@ namespace mamba
|
||||||
|
|
||||||
auto find_latest_in_non_empty = [&](solv::ObjQueue& lsolvables) -> Solvable*
|
auto find_latest_in_non_empty = [&](solv::ObjQueue& lsolvables) -> Solvable*
|
||||||
{
|
{
|
||||||
Solvable* latest = pool_id2solvable(m_pool.get(), lsolvables.front());
|
::Solvable* latest = pool_id2solvable(m_pool.get(), lsolvables.front());
|
||||||
for (Id const solv : lsolvables)
|
for (Id const solv : solvables)
|
||||||
{
|
{
|
||||||
Solvable* s = pool_id2solvable(m_pool.get(), solv);
|
Solvable* s = pool_id2solvable(m_pool.get(), solv);
|
||||||
if (pool_evrcmp(m_pool.get(), s->evr, latest->evr, 0) > 0)
|
if (pool_evrcmp(m_pool.get(), s->evr, latest->evr, 0) > 0)
|
||||||
|
@ -309,13 +318,16 @@ namespace mamba
|
||||||
return latest;
|
return latest;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (solvables.size() > 0)
|
if (!solvables.empty())
|
||||||
{
|
{
|
||||||
Solvable* latest = find_latest_in_non_empty(solvables);
|
::Solvable* const latest = find_latest_in_non_empty(solvables);
|
||||||
const auto node_id = g.add_node(PackageInfo(latest));
|
auto pkg_info = m_pool.get().id2pkginfo(pool_solvable2id(m_pool.get(), latest));
|
||||||
|
assert(pkg_info.has_value());
|
||||||
|
const auto node_id = g.add_node(std::move(pkg_info).value());
|
||||||
|
|
||||||
std::map<Solvable*, size_t> visited = { { latest, node_id } };
|
std::map<Solvable*, size_t> visited = { { latest, node_id } };
|
||||||
std::map<std::string, size_t> not_found;
|
std::map<std::string, size_t> not_found;
|
||||||
walk_graph(g, node_id, latest, visited, not_found, depth);
|
walk_graph(m_pool, g, node_id, latest, visited, not_found, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
return query_result(QueryType::kDEPENDS, query, std::move(g));
|
return query_result(QueryType::kDEPENDS, query, std::move(g));
|
||||||
|
|
|
@ -126,8 +126,9 @@ namespace mamba
|
||||||
for (const auto& solv_id : m_pool.select_solvables(dep_id))
|
for (const auto& solv_id : m_pool.select_solvables(dep_id))
|
||||||
{
|
{
|
||||||
added = true;
|
added = true;
|
||||||
PackageInfo pkg_info(pool_id2solvable(m_pool, solv_id));
|
auto pkg_info = m_pool.id2pkginfo(solv_id);
|
||||||
node_id to_id = add_solvable(solv_id, PackageNode{ std::move(pkg_info) }, false);
|
assert(pkg_info.has_value());
|
||||||
|
node_id to_id = add_solvable(solv_id, PackageNode{ std::move(pkg_info).value() }, false);
|
||||||
m_graph.add_edge(from_id, to_id, edge);
|
m_graph.add_edge(from_id, to_id, edge);
|
||||||
}
|
}
|
||||||
return added;
|
return added;
|
||||||
|
|
|
@ -171,47 +171,32 @@ namespace mamba
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<PackageInfo> make_solver_problem_source(::Pool* pool, Id source_id)
|
MSolverProblem make_solver_problem(
|
||||||
{
|
const MSolver& solver,
|
||||||
if (source_id == 0 || source_id >= pool->nsolvables)
|
const MPool& pool,
|
||||||
{
|
SolverRuleinfo type,
|
||||||
return std::nullopt;
|
Id source_id,
|
||||||
}
|
Id target_id,
|
||||||
return pool_id2solvable(pool, source_id);
|
Id dep_id
|
||||||
}
|
)
|
||||||
|
|
||||||
std::optional<PackageInfo> make_solver_problem_target(::Pool* pool, Id target_id)
|
|
||||||
{
|
|
||||||
if (target_id == 0 || target_id >= pool->nsolvables)
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
return pool_id2solvable(pool, target_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::optional<std::string> make_solver_problem_dep(::Pool* pool, Id dep_id)
|
|
||||||
{
|
|
||||||
if (!dep_id)
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
return pool_dep2str(pool, dep_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
MSolverProblem
|
|
||||||
make_solver_problem(::Solver* solver, SolverRuleinfo type, Id source_id, Id target_id, Id dep_id)
|
|
||||||
{
|
{
|
||||||
|
const ::Solver* const solver_ptr = solver;
|
||||||
return {
|
return {
|
||||||
/* .type= */ type,
|
/* .type= */ type,
|
||||||
/* .source_id= */ source_id,
|
/* .source_id= */ source_id,
|
||||||
/* .target_id= */ target_id,
|
/* .target_id= */ target_id,
|
||||||
/* .dep_id= */ dep_id,
|
/* .dep_id= */ dep_id,
|
||||||
/* .source= */ make_solver_problem_source(solver->pool, source_id),
|
/* .source= */ pool.id2pkginfo(source_id),
|
||||||
/* .target= */ make_solver_problem_target(solver->pool, target_id),
|
/* .target= */ pool.id2pkginfo(target_id),
|
||||||
/* .dep= */ make_solver_problem_dep(solver->pool, dep_id),
|
/* .dep= */ pool.dep2str(dep_id),
|
||||||
/* .description= */
|
/* .description= */
|
||||||
solver_problemruleinfo2str(solver, type, source_id, target_id, dep_id),
|
solver_problemruleinfo2str(
|
||||||
|
const_cast<::Solver*>(solver_ptr), // Not const because might alloctmp space
|
||||||
|
type,
|
||||||
|
source_id,
|
||||||
|
target_id,
|
||||||
|
dep_id
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,7 +608,8 @@ namespace mamba
|
||||||
Id source, target, dep;
|
Id source, target, dep;
|
||||||
const SolverRuleinfo type = solver_ruleinfo(m_solver.get(), r, &source, &target, &dep);
|
const SolverRuleinfo type = solver_ruleinfo(m_solver.get(), r, &source, &target, &dep);
|
||||||
res.push_back(make_solver_problem(
|
res.push_back(make_solver_problem(
|
||||||
/* solver= */ m_solver.get(),
|
/* solver= */ *this,
|
||||||
|
/* pool= */ m_pool,
|
||||||
/* type= */ type,
|
/* type= */ type,
|
||||||
/* source_id= */ source,
|
/* source_id= */ source,
|
||||||
/* target_id= */ target,
|
/* target_id= */ target,
|
||||||
|
@ -713,6 +699,11 @@ namespace mamba
|
||||||
return problems;
|
return problems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MSolver::operator const Solver*() const
|
||||||
|
{
|
||||||
|
return m_solver.get();
|
||||||
|
}
|
||||||
|
|
||||||
MSolver::operator Solver*()
|
MSolver::operator Solver*()
|
||||||
{
|
{
|
||||||
return m_solver.get();
|
return m_solver.get();
|
||||||
|
|
|
@ -32,20 +32,29 @@ extern "C" // Incomplete header
|
||||||
|
|
||||||
#include "progress_bar_impl.hpp"
|
#include "progress_bar_impl.hpp"
|
||||||
|
|
||||||
|
namespace mamba
|
||||||
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
bool need_pkg_download(const mamba::PackageInfo& pkg_info, mamba::MultiPackageCache& caches)
|
bool need_pkg_download(const PackageInfo& pkg_info, MultiPackageCache& caches)
|
||||||
{
|
{
|
||||||
return caches.get_extracted_dir_path(pkg_info).empty()
|
return caches.get_extracted_dir_path(pkg_info).empty()
|
||||||
&& caches.get_tarball_path(pkg_info).empty();
|
&& caches.get_tarball_path(pkg_info).empty();
|
||||||
}
|
}
|
||||||
} // anonymouse namspace
|
|
||||||
|
|
||||||
namespace mamba
|
auto mk_pkginfo(const MPool& pool, Solvable* s) -> PackageInfo
|
||||||
{
|
{
|
||||||
nlohmann::json solvable_to_json(Solvable* s)
|
assert(s != nullptr);
|
||||||
|
const auto pkginfo = pool.id2pkginfo(pool_solvable2id(pool, s));
|
||||||
|
assert(pkginfo.has_value()); // There is Solvable so the optional must no be empty
|
||||||
|
return std::move(pkginfo).value();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json solvable_to_json(const MPool& pool, Solvable* s)
|
||||||
{
|
{
|
||||||
return PackageInfo(s).json_record();
|
return mk_pkginfo(pool, s).json_record();
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************
|
/********************************
|
||||||
|
@ -64,11 +73,6 @@ namespace mamba
|
||||||
DownloadExtractSemaphore::semaphore.set_max(value);
|
DownloadExtractSemaphore::semaphore.set_max(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageDownloadExtractTarget::PackageDownloadExtractTarget(Solvable* solvable)
|
|
||||||
: PackageDownloadExtractTarget(PackageInfo(solvable))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PackageDownloadExtractTarget::PackageDownloadExtractTarget(const PackageInfo& pkg_info)
|
PackageDownloadExtractTarget::PackageDownloadExtractTarget(const PackageInfo& pkg_info)
|
||||||
: m_finished(false)
|
: m_finished(false)
|
||||||
, m_package_info(pkg_info)
|
, m_package_info(pkg_info)
|
||||||
|
@ -474,7 +478,8 @@ namespace mamba
|
||||||
const std::vector<MatchSpec>& specs_to_install,
|
const std::vector<MatchSpec>& specs_to_install,
|
||||||
MultiPackageCache& caches
|
MultiPackageCache& caches
|
||||||
)
|
)
|
||||||
: m_multi_cache(caches)
|
: m_pool(pool)
|
||||||
|
, m_multi_cache(caches)
|
||||||
{
|
{
|
||||||
// auto& ctx = Context::instance();
|
// auto& ctx = Context::instance();
|
||||||
std::vector<PackageInfo> pi_result;
|
std::vector<PackageInfo> pi_result;
|
||||||
|
@ -499,9 +504,9 @@ namespace mamba
|
||||||
pi_result.push_back(p);
|
pi_result.push_back(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
MRepo& mrepo = MRepo::create(pool, "__explicit_specs__", pi_result);
|
MRepo& mrepo = MRepo::create(m_pool, "__explicit_specs__", pi_result);
|
||||||
|
|
||||||
pool.create_whatprovides();
|
m_pool.create_whatprovides();
|
||||||
|
|
||||||
// Just add the packages we want to remove directly to the transaction
|
// Just add the packages we want to remove directly to the transaction
|
||||||
solv::ObjQueue q, job, decision;
|
solv::ObjQueue q, job, decision;
|
||||||
|
@ -512,12 +517,12 @@ namespace mamba
|
||||||
job.clear();
|
job.clear();
|
||||||
q.clear();
|
q.clear();
|
||||||
|
|
||||||
const Id id = pool_conda_matchspec(pool, s.conda_build_form().c_str());
|
const Id id = pool_conda_matchspec(m_pool, s.conda_build_form().c_str());
|
||||||
if (id)
|
if (id)
|
||||||
{
|
{
|
||||||
job.push_back(SOLVER_SOLVABLE_PROVIDES, id);
|
job.push_back(SOLVER_SOLVABLE_PROVIDES, id);
|
||||||
}
|
}
|
||||||
selection_solvables(pool, job.raw(), q.raw());
|
selection_solvables(m_pool, job.raw(), q.raw());
|
||||||
|
|
||||||
if (q.size() == 0)
|
if (q.size() == 0)
|
||||||
{
|
{
|
||||||
|
@ -536,8 +541,8 @@ namespace mamba
|
||||||
throw std::runtime_error("Could not find packages to remove:" + join("", not_found));
|
throw std::runtime_error("Could not find packages to remove:" + join("", not_found));
|
||||||
}
|
}
|
||||||
|
|
||||||
selection_solvables(pool, job.raw(), q.raw());
|
selection_solvables(m_pool, job.raw(), q.raw());
|
||||||
const bool remove_success = q.size() >= specs_to_remove.size();
|
const bool remove_success = size_t(q.size()) >= specs_to_remove.size();
|
||||||
Console::instance().json_write({ { "success", remove_success } });
|
Console::instance().json_write({ { "success", remove_success } });
|
||||||
Id pkg_id;
|
Id pkg_id;
|
||||||
Solvable* solvable;
|
Solvable* solvable;
|
||||||
|
@ -548,7 +553,7 @@ namespace mamba
|
||||||
decision.push_back(pkg_id);
|
decision.push_back(pkg_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_transaction = transaction_create_decisionq(pool, decision.raw(), nullptr);
|
m_transaction = transaction_create_decisionq(m_pool, decision.raw(), nullptr);
|
||||||
init();
|
init();
|
||||||
|
|
||||||
m_history_entry = History::UserRequest::prefilled();
|
m_history_entry = History::UserRequest::prefilled();
|
||||||
|
@ -577,9 +582,10 @@ namespace mamba
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTransaction::MTransaction(MPool& pool, MSolver& solver, MultiPackageCache& caches)
|
||||||
|
|
||||||
MTransaction::MTransaction(MSolver& solver, MultiPackageCache& caches)
|
: m_pool(pool)
|
||||||
: m_multi_cache(caches)
|
, m_multi_cache(caches)
|
||||||
{
|
{
|
||||||
if (!solver.is_solved())
|
if (!solver.is_solved())
|
||||||
{
|
{
|
||||||
|
@ -590,8 +596,6 @@ namespace mamba
|
||||||
m_transaction = solver_create_transaction(solver);
|
m_transaction = solver_create_transaction(solver);
|
||||||
transaction_order(m_transaction, 0);
|
transaction_order(m_transaction, 0);
|
||||||
|
|
||||||
auto* pool = static_cast<Solver*>(solver)->pool;
|
|
||||||
|
|
||||||
m_history_entry = History::UserRequest::prefilled();
|
m_history_entry = History::UserRequest::prefilled();
|
||||||
|
|
||||||
if (solver.no_deps || solver.only_deps)
|
if (solver.no_deps || solver.only_deps)
|
||||||
|
@ -599,11 +603,11 @@ namespace mamba
|
||||||
m_filter_type = solver.only_deps ? FilterType::keep_only : FilterType::ignore;
|
m_filter_type = solver.only_deps ? FilterType::keep_only : FilterType::ignore;
|
||||||
for (auto& s : solver.install_specs())
|
for (auto& s : solver.install_specs())
|
||||||
{
|
{
|
||||||
m_filter_name_ids.insert(pool_str2id(pool, s.name.c_str(), 0));
|
m_filter_name_ids.insert(pool_str2id(m_pool, s.name.c_str(), 0));
|
||||||
}
|
}
|
||||||
for (auto& s : solver.remove_specs())
|
for (auto& s : solver.remove_specs())
|
||||||
{
|
{
|
||||||
m_filter_name_ids.insert(pool_str2id(pool, s.name.c_str(), 0));
|
m_filter_name_ids.insert(pool_str2id(m_pool, s.name.c_str(), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (solver.only_deps)
|
if (solver.only_deps)
|
||||||
|
@ -612,15 +616,15 @@ namespace mamba
|
||||||
transaction_installedresult(m_transaction, q.raw());
|
transaction_installedresult(m_transaction, q.raw());
|
||||||
for (const Id r : q)
|
for (const Id r : q)
|
||||||
{
|
{
|
||||||
Solvable* s = pool_id2solvable(pool, r);
|
Solvable* s = pool_id2solvable(m_pool, r);
|
||||||
if (m_filter_name_ids.count(s->name))
|
if (m_filter_name_ids.count(s->name))
|
||||||
{
|
{
|
||||||
// add the dependencies of this selected package to the added specs
|
// add the dependencies of this selected package to the added specs
|
||||||
Id* reqp;
|
Id* reqp;
|
||||||
for (reqp = s->repo->idarraydata + s->requires; *reqp; reqp++)
|
for (reqp = s->repo->idarraydata + s->requires; *reqp; reqp++)
|
||||||
{
|
{
|
||||||
const char* depname = pool_id2str(pool, *reqp);
|
const char* depname = pool_id2str(m_pool, *reqp);
|
||||||
const char* depevr = pool_id2evr(pool, *reqp);
|
const char* depevr = pool_id2evr(m_pool, *reqp);
|
||||||
std::string add_spec;
|
std::string add_spec;
|
||||||
if (depname)
|
if (depname)
|
||||||
{
|
{
|
||||||
|
@ -670,7 +674,8 @@ namespace mamba
|
||||||
solver.install_specs()
|
solver.install_specs()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (m_transaction_context.relink_noarch && pool->installed != nullptr)
|
::Pool* const pool_ptr = static_cast<::Pool* const>(m_pool);
|
||||||
|
if (m_transaction_context.relink_noarch && pool_ptr->installed != nullptr)
|
||||||
{
|
{
|
||||||
Id p = 0;
|
Id p = 0;
|
||||||
Solvable* s = nullptr;
|
Solvable* s = nullptr;
|
||||||
|
@ -678,9 +683,9 @@ namespace mamba
|
||||||
|
|
||||||
solver_get_decisionqueue(solver, decision.raw());
|
solver_get_decisionqueue(solver, decision.raw());
|
||||||
|
|
||||||
const Id noarch_repo_key = pool_str2id(pool, "solvable:noarch_type", 1);
|
const Id noarch_repo_key = pool_str2id(m_pool, "solvable:noarch_type", 1);
|
||||||
|
|
||||||
FOR_REPO_SOLVABLES(pool->installed, p, s)
|
FOR_REPO_SOLVABLES(pool_ptr->installed, p, s)
|
||||||
{
|
{
|
||||||
const char* noarch_type = solvable_lookup_str(s, noarch_repo_key);
|
const char* noarch_type = solvable_lookup_str(s, noarch_repo_key);
|
||||||
|
|
||||||
|
@ -714,11 +719,12 @@ namespace mamba
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageInfo pi(s);
|
|
||||||
|
|
||||||
|
const auto pkg_info = mk_pkginfo(m_pool, s);
|
||||||
const Id id = pool_conda_matchspec(
|
const Id id = pool_conda_matchspec(
|
||||||
pool,
|
m_pool,
|
||||||
fmt::format("{} {} {}", pi.name, pi.version, pi.build_string).c_str()
|
fmt::format("{} {} {}", pkg_info.name, pkg_info.version, pkg_info.build_string)
|
||||||
|
.c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (id)
|
if (id)
|
||||||
|
@ -726,13 +732,13 @@ namespace mamba
|
||||||
job.push_back(SOLVER_SOLVABLE_PROVIDES, id);
|
job.push_back(SOLVER_SOLVABLE_PROVIDES, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
selection_solvables(pool, job.raw(), q.raw());
|
selection_solvables(m_pool, job.raw(), q.raw());
|
||||||
|
|
||||||
Id reinstall_id = -1;
|
Id reinstall_id = -1;
|
||||||
for (const Id r : q)
|
for (const Id r : q)
|
||||||
{
|
{
|
||||||
auto* xid = pool_id2solvable(pool, r);
|
auto* xid = pool_id2solvable(m_pool, r);
|
||||||
if (xid->repo != pool->installed)
|
if (xid->repo != pool_ptr->installed)
|
||||||
{
|
{
|
||||||
reinstall_id = r;
|
reinstall_id = r;
|
||||||
break;
|
break;
|
||||||
|
@ -747,9 +753,9 @@ namespace mamba
|
||||||
"To upgrade python we need to reinstall noarch",
|
"To upgrade python we need to reinstall noarch",
|
||||||
" package {} {} {} but we could not find it in",
|
" package {} {} {} but we could not find it in",
|
||||||
" any of the loaded channels.",
|
" any of the loaded channels.",
|
||||||
pi.name,
|
pkg_info.name,
|
||||||
pi.version,
|
pkg_info.version,
|
||||||
pi.build_string
|
pkg_info.build_string
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -763,7 +769,7 @@ namespace mamba
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction_free(m_transaction);
|
transaction_free(m_transaction);
|
||||||
m_transaction = transaction_create_decisionq(pool, decision.raw(), nullptr);
|
m_transaction = transaction_create_decisionq(m_pool, decision.raw(), nullptr);
|
||||||
transaction_order(m_transaction, 0);
|
transaction_order(m_transaction, 0);
|
||||||
|
|
||||||
// init everything again...
|
// init everything again...
|
||||||
|
@ -776,11 +782,12 @@ namespace mamba
|
||||||
const std::vector<PackageInfo>& packages,
|
const std::vector<PackageInfo>& packages,
|
||||||
MultiPackageCache& caches
|
MultiPackageCache& caches
|
||||||
)
|
)
|
||||||
: m_multi_cache(caches)
|
: m_pool(pool)
|
||||||
|
, m_multi_cache(caches)
|
||||||
{
|
{
|
||||||
LOG_INFO << "MTransaction::MTransaction - packages already resolved (lockfile)";
|
LOG_INFO << "MTransaction::MTransaction - packages already resolved (lockfile)";
|
||||||
MRepo& mrepo = MRepo::create(pool, "__explicit_specs__", packages);
|
MRepo& mrepo = MRepo::create(m_pool, "__explicit_specs__", packages);
|
||||||
pool.create_whatprovides();
|
m_pool.create_whatprovides();
|
||||||
|
|
||||||
solv::ObjQueue decision = {};
|
solv::ObjQueue decision = {};
|
||||||
|
|
||||||
|
@ -792,7 +799,7 @@ namespace mamba
|
||||||
decision.push_back(pkg_id);
|
decision.push_back(pkg_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_transaction = transaction_create_decisionq(pool, decision.raw(), nullptr);
|
m_transaction = transaction_create_decisionq(m_pool, decision.raw(), nullptr);
|
||||||
transaction_order(m_transaction, 0);
|
transaction_order(m_transaction, 0);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
@ -828,7 +835,7 @@ namespace mamba
|
||||||
{
|
{
|
||||||
Id p = m_transaction->steps.elements[i];
|
Id p = m_transaction->steps.elements[i];
|
||||||
Id ttype = transaction_type(m_transaction, p, SOLVER_TRANSACTION_SHOW_ALL);
|
Id ttype = transaction_type(m_transaction, p, SOLVER_TRANSACTION_SHOW_ALL);
|
||||||
Solvable* s = pool_id2solvable(m_transaction->pool, p);
|
Solvable* s = pool_id2solvable(m_pool, p);
|
||||||
if (filter(s))
|
if (filter(s))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -842,7 +849,7 @@ namespace mamba
|
||||||
{
|
{
|
||||||
m_to_remove.push_back(s);
|
m_to_remove.push_back(s);
|
||||||
m_to_install.push_back(
|
m_to_install.push_back(
|
||||||
m_transaction->pool->solvables + transaction_obs_pkg(m_transaction, p)
|
static_cast<::Pool*>(m_pool)->solvables + transaction_obs_pkg(m_transaction, p)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -871,31 +878,31 @@ namespace mamba
|
||||||
// We need to find the python version that will be there after this
|
// We need to find the python version that will be there after this
|
||||||
// Transaction is finished in order to compile the noarch packages correctly,
|
// Transaction is finished in order to compile the noarch packages correctly,
|
||||||
// for example
|
// for example
|
||||||
Pool* pool = m_transaction->pool;
|
|
||||||
assert(pool != nullptr);
|
|
||||||
|
|
||||||
std::string installed_py_ver, new_py_ver;
|
std::string installed_py_ver, new_py_ver;
|
||||||
Id python = pool_str2id(pool, "python", 0);
|
Id python = pool_str2id(m_pool, "python", 0);
|
||||||
|
|
||||||
for (Solvable* s : m_to_install)
|
for (Solvable* s : m_to_install)
|
||||||
{
|
{
|
||||||
if (s->name == python)
|
if (s->name == python)
|
||||||
{
|
{
|
||||||
new_py_ver = pool_id2str(pool, s->evr);
|
new_py_ver = pool_id2str(m_pool, s->evr);
|
||||||
LOG_INFO << "Found python version in packages to be installed " << new_py_ver;
|
LOG_INFO << "Found python version in packages to be installed " << new_py_ver;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pool->installed != nullptr)
|
|
||||||
|
::Pool* const pool_ptr = m_pool;
|
||||||
|
if (pool_ptr->installed != nullptr)
|
||||||
{
|
{
|
||||||
Id p;
|
Id p;
|
||||||
Solvable* s;
|
Solvable* s;
|
||||||
|
|
||||||
FOR_REPO_SOLVABLES(pool->installed, p, s)
|
FOR_REPO_SOLVABLES(pool_ptr->installed, p, s)
|
||||||
{
|
{
|
||||||
if (s->name == python)
|
if (s->name == python)
|
||||||
{
|
{
|
||||||
installed_py_ver = pool_id2str(pool, s->evr);
|
installed_py_ver = pool_id2str(m_pool, s->evr);
|
||||||
LOG_INFO << "Found python in installed packages " << installed_py_ver;
|
LOG_INFO << "Found python in installed packages " << installed_py_ver;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -985,13 +992,11 @@ namespace mamba
|
||||||
|
|
||||||
TransactionRollback rollback;
|
TransactionRollback rollback;
|
||||||
|
|
||||||
auto* pool = m_transaction->pool;
|
|
||||||
|
|
||||||
for (int i = 0; i < m_transaction->steps.count && !is_sig_interrupted(); i++)
|
for (int i = 0; i < m_transaction->steps.count && !is_sig_interrupted(); i++)
|
||||||
{
|
{
|
||||||
Id p = m_transaction->steps.elements[i];
|
Id p = m_transaction->steps.elements[i];
|
||||||
Id ttype = transaction_type(m_transaction, p, SOLVER_TRANSACTION_SHOW_ALL);
|
Id ttype = transaction_type(m_transaction, p, SOLVER_TRANSACTION_SHOW_ALL);
|
||||||
Solvable* s = pool_id2solvable(pool, p);
|
Solvable* s = pool_id2solvable(m_pool, p);
|
||||||
|
|
||||||
if (filter(s))
|
if (filter(s))
|
||||||
{
|
{
|
||||||
|
@ -1005,17 +1010,19 @@ namespace mamba
|
||||||
case SOLVER_TRANSACTION_CHANGED:
|
case SOLVER_TRANSACTION_CHANGED:
|
||||||
case SOLVER_TRANSACTION_REINSTALLED:
|
case SOLVER_TRANSACTION_REINSTALLED:
|
||||||
{
|
{
|
||||||
Solvable* s2 = m_transaction->pool->solvables
|
Solvable* s2 = static_cast<::Pool*>(m_pool)->solvables
|
||||||
+ transaction_obs_pkg(m_transaction, p);
|
+ transaction_obs_pkg(m_transaction, p);
|
||||||
Console::stream()
|
|
||||||
<< "Changing " << PackageInfo(s).str() << " ==> " << PackageInfo(s2).str();
|
|
||||||
|
|
||||||
PackageInfo package_to_unlink(s);
|
const PackageInfo package_to_unlink = mk_pkginfo(m_pool, s);
|
||||||
|
const PackageInfo package_to_link = mk_pkginfo(m_pool, s2);
|
||||||
|
|
||||||
|
Console::stream() << "Changing " << package_to_unlink.str() << " ==> "
|
||||||
|
<< package_to_link.str();
|
||||||
|
|
||||||
const fs::u8path ul_cache_path(
|
const fs::u8path ul_cache_path(
|
||||||
m_multi_cache.get_extracted_dir_path(package_to_unlink)
|
m_multi_cache.get_extracted_dir_path(package_to_unlink)
|
||||||
);
|
);
|
||||||
|
|
||||||
PackageInfo package_to_link(s2);
|
|
||||||
const fs::u8path l_cache_path(
|
const fs::u8path l_cache_path(
|
||||||
m_multi_cache.get_extracted_dir_path(package_to_link, false)
|
m_multi_cache.get_extracted_dir_path(package_to_link, false)
|
||||||
);
|
);
|
||||||
|
@ -1035,7 +1042,7 @@ namespace mamba
|
||||||
}
|
}
|
||||||
case SOLVER_TRANSACTION_ERASE:
|
case SOLVER_TRANSACTION_ERASE:
|
||||||
{
|
{
|
||||||
PackageInfo package_info(s);
|
PackageInfo package_info = mk_pkginfo(m_pool, s);
|
||||||
Console::stream() << "Unlinking " << package_info.str();
|
Console::stream() << "Unlinking " << package_info.str();
|
||||||
const fs::u8path cache_path(m_multi_cache.get_extracted_dir_path(package_info));
|
const fs::u8path cache_path(m_multi_cache.get_extracted_dir_path(package_info));
|
||||||
UnlinkPackage up(package_info, cache_path, &m_transaction_context);
|
UnlinkPackage up(package_info, cache_path, &m_transaction_context);
|
||||||
|
@ -1046,7 +1053,7 @@ namespace mamba
|
||||||
}
|
}
|
||||||
case SOLVER_TRANSACTION_INSTALL:
|
case SOLVER_TRANSACTION_INSTALL:
|
||||||
{
|
{
|
||||||
PackageInfo package_info(s);
|
PackageInfo package_info = mk_pkginfo(m_pool, s);
|
||||||
Console::stream() << "Linking " << package_info.str();
|
Console::stream() << "Linking " << package_info.str();
|
||||||
const fs::u8path cache_path(
|
const fs::u8path cache_path(
|
||||||
m_multi_cache.get_extracted_dir_path(package_info, false)
|
m_multi_cache.get_extracted_dir_path(package_info, false)
|
||||||
|
@ -1083,7 +1090,7 @@ namespace mamba
|
||||||
|
|
||||||
auto MTransaction::to_conda() -> to_conda_type
|
auto MTransaction::to_conda() -> to_conda_type
|
||||||
{
|
{
|
||||||
Id real_repo_key = pool_str2id(m_transaction->pool, "solvable:real_repo_url", 1);
|
const Id real_repo_key = pool_str2id(m_pool, "solvable:real_repo_url", 1);
|
||||||
|
|
||||||
to_install_type to_install_structured;
|
to_install_type to_install_structured;
|
||||||
to_remove_type to_remove_structured;
|
to_remove_type to_remove_structured;
|
||||||
|
@ -1097,7 +1104,7 @@ namespace mamba
|
||||||
for (Solvable* s : m_to_install)
|
for (Solvable* s : m_to_install)
|
||||||
{
|
{
|
||||||
const char* mediafile = solvable_lookup_str(s, SOLVABLE_MEDIAFILE);
|
const char* mediafile = solvable_lookup_str(s, SOLVABLE_MEDIAFILE);
|
||||||
std::string s_json = solvable_to_json(s).dump(4);
|
std::string s_json = solvable_to_json(m_pool, s).dump(4);
|
||||||
|
|
||||||
std::string channel;
|
std::string channel;
|
||||||
if (solvable_lookup_str(s, real_repo_key))
|
if (solvable_lookup_str(s, real_repo_key))
|
||||||
|
@ -1126,20 +1133,20 @@ namespace mamba
|
||||||
|
|
||||||
for (Solvable* s : m_to_install)
|
for (Solvable* s : m_to_install)
|
||||||
{
|
{
|
||||||
if (!need_pkg_download(s, m_multi_cache))
|
if (!need_pkg_download(mk_pkginfo(m_pool, s), m_multi_cache))
|
||||||
{
|
{
|
||||||
to_link.push_back(solvable_to_json(s));
|
to_link.push_back(solvable_to_json(m_pool, s));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
to_fetch.push_back(solvable_to_json(s));
|
to_fetch.push_back(solvable_to_json(m_pool, s));
|
||||||
to_link.push_back(solvable_to_json(s));
|
to_link.push_back(solvable_to_json(m_pool, s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Solvable* s : m_to_remove)
|
for (Solvable* s : m_to_remove)
|
||||||
{
|
{
|
||||||
to_unlink.push_back(solvable_to_json(s));
|
to_unlink.push_back(solvable_to_json(m_pool, s));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto add_json = [](const auto& jlist, const char* s)
|
auto add_json = [](const auto& jlist, const char* s)
|
||||||
|
@ -1184,9 +1191,7 @@ namespace mamba
|
||||||
if (ctx.experimental && ctx.verify_artifacts)
|
if (ctx.experimental && ctx.verify_artifacts)
|
||||||
{
|
{
|
||||||
const auto& repo_checker = make_channel(mamba_repo->url()).repo_checker(m_multi_cache);
|
const auto& repo_checker = make_channel(mamba_repo->url()).repo_checker(m_multi_cache);
|
||||||
|
const auto pkg_info = mk_pkginfo(m_pool, s);
|
||||||
auto pkg_info = PackageInfo(s);
|
|
||||||
|
|
||||||
repo_checker.verify_package(
|
repo_checker.verify_package(
|
||||||
pkg_info.json_signable(),
|
pkg_info.json_signable(),
|
||||||
nlohmann::json::parse(pkg_info.signatures)
|
nlohmann::json::parse(pkg_info.signatures)
|
||||||
|
@ -1195,7 +1200,8 @@ namespace mamba
|
||||||
LOG_DEBUG << "'" << pkg_info.name << "' trusted from '" << mamba_repo->url() << "'";
|
LOG_DEBUG << "'" << pkg_info.name << "' trusted from '" << mamba_repo->url() << "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
targets.emplace_back(std::make_unique<PackageDownloadExtractTarget>(s));
|
targets.emplace_back(std::make_unique<PackageDownloadExtractTarget>(mk_pkginfo(m_pool, s))
|
||||||
|
);
|
||||||
DownloadTarget* download_target = targets.back()->target(m_multi_cache);
|
DownloadTarget* download_target = targets.back()->target(m_multi_cache);
|
||||||
if (download_target != nullptr)
|
if (download_target != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1450,7 +1456,6 @@ namespace mamba
|
||||||
|
|
||||||
rows downgraded, upgraded, changed, reinstalled, erased, installed, ignored;
|
rows downgraded, upgraded, changed, reinstalled, erased, installed, ignored;
|
||||||
std::size_t total_size = 0;
|
std::size_t total_size = 0;
|
||||||
auto* pool = m_transaction->pool;
|
|
||||||
|
|
||||||
enum struct Status
|
enum struct Status
|
||||||
{
|
{
|
||||||
|
@ -1459,7 +1464,7 @@ namespace mamba
|
||||||
remove
|
remove
|
||||||
};
|
};
|
||||||
auto format_row =
|
auto format_row =
|
||||||
[this, &ctx, pool, &total_size](rows& r, Solvable* s, Status status, std::string diff)
|
[this, &ctx, &total_size](rows& r, Solvable* s, Status status, std::string diff)
|
||||||
{
|
{
|
||||||
std::size_t dlsize = solvable_lookup_num(s, SOLVABLE_DOWNLOADSIZE, SIZE_MAX);
|
std::size_t dlsize = solvable_lookup_num(s, SOLVABLE_DOWNLOADSIZE, SIZE_MAX);
|
||||||
printers::FormattedString dlsize_s;
|
printers::FormattedString dlsize_s;
|
||||||
|
@ -1471,7 +1476,7 @@ namespace mamba
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!need_pkg_download(s, m_multi_cache))
|
if (!need_pkg_download(mk_pkginfo(m_pool, s), m_multi_cache))
|
||||||
{
|
{
|
||||||
dlsize_s.s = "Cached";
|
dlsize_s.s = "Cached";
|
||||||
dlsize_s.style = ctx.palette.addition;
|
dlsize_s.style = ctx.palette.addition;
|
||||||
|
@ -1490,7 +1495,7 @@ namespace mamba
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printers::FormattedString name;
|
printers::FormattedString name;
|
||||||
name.s = fmt::format("{} {}", diff, pool_id2str(pool, s->name));
|
name.s = fmt::format("{} {}", diff, pool_id2str(m_pool, s->name));
|
||||||
if (status == Status::install)
|
if (status == Status::install)
|
||||||
{
|
{
|
||||||
name.style = ctx.palette.addition;
|
name.style = ctx.palette.addition;
|
||||||
|
@ -1506,7 +1511,7 @@ namespace mamba
|
||||||
const char* build_string = solvable_lookup_str(s, SOLVABLE_BUILDFLAVOR);
|
const char* build_string = solvable_lookup_str(s, SOLVABLE_BUILDFLAVOR);
|
||||||
|
|
||||||
std::string channel;
|
std::string channel;
|
||||||
Id real_repo_key = pool_str2id(pool, "solvable:real_repo_url", 1);
|
Id real_repo_key = pool_str2id(m_pool, "solvable:real_repo_url", 1);
|
||||||
if (solvable_lookup_str(s, real_repo_key))
|
if (solvable_lookup_str(s, real_repo_key))
|
||||||
{
|
{
|
||||||
std::string repo_key = solvable_lookup_str(s, real_repo_key);
|
std::string repo_key = solvable_lookup_str(s, real_repo_key);
|
||||||
|
@ -1529,12 +1534,14 @@ namespace mamba
|
||||||
}
|
}
|
||||||
|
|
||||||
r.push_back({ name,
|
r.push_back({ name,
|
||||||
printers::FormattedString(pool_id2str(pool, s->evr)),
|
printers::FormattedString(pool_id2str(m_pool, s->evr)),
|
||||||
printers::FormattedString(build_string ? build_string : ""),
|
printers::FormattedString(build_string ? build_string : ""),
|
||||||
printers::FormattedString(cut_repo_name(channel)),
|
printers::FormattedString(cut_repo_name(channel)),
|
||||||
dlsize_s });
|
dlsize_s });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
::Solvable* const solvables = static_cast<::Pool*>(m_pool)->solvables;
|
||||||
int mode = SOLVER_TRANSACTION_SHOW_OBSOLETES | SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE;
|
int mode = SOLVER_TRANSACTION_SHOW_OBSOLETES | SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE;
|
||||||
transaction_classify(m_transaction, mode, classes.raw());
|
transaction_classify(m_transaction, mode, classes.raw());
|
||||||
for (std::size_t n_classes = classes.size(), i = 0; i < n_classes; i += 4)
|
for (std::size_t n_classes = classes.size(), i = 0; i < n_classes; i += 4)
|
||||||
|
@ -1551,7 +1558,7 @@ namespace mamba
|
||||||
|
|
||||||
for (const Id p : pkgs)
|
for (const Id p : pkgs)
|
||||||
{
|
{
|
||||||
Solvable* s = m_transaction->pool->solvables + p;
|
Solvable* s = solvables + p;
|
||||||
|
|
||||||
if (filter(s))
|
if (filter(s))
|
||||||
{
|
{
|
||||||
|
@ -1564,7 +1571,7 @@ namespace mamba
|
||||||
format_row(upgraded, s, Status::remove, "-");
|
format_row(upgraded, s, Status::remove, "-");
|
||||||
format_row(
|
format_row(
|
||||||
upgraded,
|
upgraded,
|
||||||
m_transaction->pool->solvables + transaction_obs_pkg(m_transaction, p),
|
solvables + transaction_obs_pkg(m_transaction, p),
|
||||||
Status::install,
|
Status::install,
|
||||||
"+"
|
"+"
|
||||||
);
|
);
|
||||||
|
@ -1573,7 +1580,7 @@ namespace mamba
|
||||||
format_row(changed, s, Status::remove, "-");
|
format_row(changed, s, Status::remove, "-");
|
||||||
format_row(
|
format_row(
|
||||||
changed,
|
changed,
|
||||||
m_transaction->pool->solvables + transaction_obs_pkg(m_transaction, p),
|
solvables + transaction_obs_pkg(m_transaction, p),
|
||||||
Status::install,
|
Status::install,
|
||||||
"+"
|
"+"
|
||||||
);
|
);
|
||||||
|
@ -1585,7 +1592,7 @@ namespace mamba
|
||||||
format_row(downgraded, s, Status::remove, "-");
|
format_row(downgraded, s, Status::remove, "-");
|
||||||
format_row(
|
format_row(
|
||||||
downgraded,
|
downgraded,
|
||||||
m_transaction->pool->solvables + transaction_obs_pkg(m_transaction, p),
|
solvables + transaction_obs_pkg(m_transaction, p),
|
||||||
Status::install,
|
Status::install,
|
||||||
"+"
|
"+"
|
||||||
);
|
);
|
||||||
|
|
|
@ -844,8 +844,6 @@ class MultiPackageCache:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class PackageInfo:
|
class PackageInfo:
|
||||||
@typing.overload
|
|
||||||
def __init__(self, arg0: s_Solvable) -> None: ...
|
|
||||||
@typing.overload
|
@typing.overload
|
||||||
def __init__(self, name: str) -> None: ...
|
def __init__(self, name: str) -> None: ...
|
||||||
@typing.overload
|
@typing.overload
|
||||||
|
@ -1398,6 +1396,9 @@ class SubdirData:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Transaction:
|
class Transaction:
|
||||||
|
@typing.overload
|
||||||
|
def __init__(self, arg0: Pool, arg1: Solver, arg2: MultiPackageCache) -> None: ...
|
||||||
|
@typing.overload
|
||||||
def __init__(self, arg0: Solver, arg1: MultiPackageCache) -> None: ...
|
def __init__(self, arg0: Solver, arg1: MultiPackageCache) -> None: ...
|
||||||
def execute(self, arg0: PrefixData) -> bool: ...
|
def execute(self, arg0: PrefixData) -> bool: ...
|
||||||
def fetch_extract_packages(self) -> bool: ...
|
def fetch_extract_packages(self) -> bool: ...
|
||||||
|
|
|
@ -210,7 +210,14 @@ PYBIND11_MODULE(bindings, m)
|
||||||
.def("clear", &MRepo::clear);
|
.def("clear", &MRepo::clear);
|
||||||
|
|
||||||
py::class_<MTransaction>(m, "Transaction")
|
py::class_<MTransaction>(m, "Transaction")
|
||||||
.def(py::init<MSolver&, MultiPackageCache&>())
|
.def(py::init<>(
|
||||||
|
[](MSolver& solver, MultiPackageCache& mpc)
|
||||||
|
{
|
||||||
|
deprecated("Use Transaction(Pool, Solver, MultiPackageCache) instead");
|
||||||
|
return std::make_unique<MTransaction>(solver.pool(), solver, mpc);
|
||||||
|
}
|
||||||
|
))
|
||||||
|
.def(py::init<MPool&, MSolver&, MultiPackageCache&>())
|
||||||
.def("to_conda", &MTransaction::to_conda)
|
.def("to_conda", &MTransaction::to_conda)
|
||||||
.def("log_json", &MTransaction::log_json)
|
.def("log_json", &MTransaction::log_json)
|
||||||
.def("print", &MTransaction::print)
|
.def("print", &MTransaction::print)
|
||||||
|
@ -565,7 +572,7 @@ PYBIND11_MODULE(bindings, m)
|
||||||
.def_property_readonly("package_records", &PrefixData::records)
|
.def_property_readonly("package_records", &PrefixData::records)
|
||||||
.def("add_packages", &PrefixData::add_packages);
|
.def("add_packages", &PrefixData::add_packages);
|
||||||
|
|
||||||
pyPackageInfo.def(py::init<Solvable*>())
|
pyPackageInfo //
|
||||||
.def(py::init<const std::string&>(), py::arg("name"))
|
.def(py::init<const std::string&>(), py::arg("name"))
|
||||||
.def(
|
.def(
|
||||||
py::init<const std::string&, const std::string&, const std::string&, std::size_t>(),
|
py::init<const std::string&, const std::string&, const std::string&, std::size_t>(),
|
||||||
|
|
|
@ -224,7 +224,7 @@ def remove(args, parser):
|
||||||
return exit_code
|
return exit_code
|
||||||
|
|
||||||
package_cache = api.MultiPackageCache(context.pkgs_dirs)
|
package_cache = api.MultiPackageCache(context.pkgs_dirs)
|
||||||
transaction = api.Transaction(solver, package_cache)
|
transaction = api.Transaction(pool, solver, package_cache)
|
||||||
|
|
||||||
if not transaction.prompt():
|
if not transaction.prompt():
|
||||||
exit(0)
|
exit(0)
|
||||||
|
@ -562,7 +562,7 @@ def install(args, parser, command="install"):
|
||||||
return exit_code
|
return exit_code
|
||||||
|
|
||||||
package_cache = api.MultiPackageCache(context.pkgs_dirs)
|
package_cache = api.MultiPackageCache(context.pkgs_dirs)
|
||||||
transaction = api.Transaction(solver, package_cache)
|
transaction = api.Transaction(pool, solver, package_cache)
|
||||||
mmb_specs, to_link, to_unlink = transaction.to_conda()
|
mmb_specs, to_link, to_unlink = transaction.to_conda()
|
||||||
|
|
||||||
specs_to_add = [MatchSpec(m) for m in mmb_specs[0]]
|
specs_to_add = [MatchSpec(m) for m in mmb_specs[0]]
|
||||||
|
|
|
@ -141,7 +141,7 @@ def mamba_install(prefix, specs, args, env, dry_run=False, *_, **kwargs):
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
package_cache = api.MultiPackageCache(context.pkgs_dirs)
|
package_cache = api.MultiPackageCache(context.pkgs_dirs)
|
||||||
transaction = api.Transaction(solver, package_cache)
|
transaction = api.Transaction(pool, solver, package_cache)
|
||||||
mmb_specs, to_link, to_unlink = transaction.to_conda()
|
mmb_specs, to_link, to_unlink = transaction.to_conda()
|
||||||
|
|
||||||
specs_to_add = [MatchSpec(m) for m in mmb_specs[0]]
|
specs_to_add = [MatchSpec(m) for m in mmb_specs[0]]
|
||||||
|
|
Loading…
Reference in New Issue