Isolate PackageInfo from libsolv (#2340)

* Isolate libsolv from PackageInfo
This commit is contained in:
Antoine Prouvost 2023-03-08 09:15:46 +01:00 committed by GitHub
parent 66c721c220
commit 8c5841cbfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 473 additions and 467 deletions

View File

@ -12,10 +12,6 @@
#include <vector>
#include <nlohmann/json.hpp>
#include <solv/pool.h>
#include <solv/poolid.h>
#include <solv/repo.h>
#include <solv/solvable.h>
namespace mamba
{
@ -26,20 +22,14 @@ namespace mamba
using field_getter = std::function<std::string(const PackageInfo&)>;
using compare_fun = std::function<bool(const PackageInfo&, const PackageInfo&)>;
static field_getter get_field_getter(const std::string& name);
static compare_fun less(const std::string& member);
static compare_fun equal(const std::string& member);
static field_getter get_field_getter(std::string_view field_name);
static compare_fun less(std::string_view member);
static compare_fun equal(std::string_view member);
PackageInfo(Solvable* s);
PackageInfo(nlohmann::json&& j);
PackageInfo(const std::string& name);
PackageInfo(std::string&& name);
PackageInfo(
const std::string& name,
const std::string& version,
const std::string build_string,
std::size_t build_number
);
PackageInfo() = default;
explicit PackageInfo(nlohmann::json&& j);
explicit PackageInfo(std::string name);
PackageInfo(std::string name, std::string version, std::string build_string, std::size_t build_number);
bool operator==(const PackageInfo& other) const;
@ -48,26 +38,26 @@ namespace mamba
std::string str() const;
std::string long_str() const;
std::string name;
std::string version;
std::string build_string;
std::string noarch;
std::string name = {};
std::string version = {};
std::string build_string = {};
std::string noarch = {};
std::size_t build_number = 0;
std::string channel;
std::string url;
std::string subdir;
std::string fn;
std::string license;
std::string channel = {};
std::string url = {};
std::string subdir = {};
std::string fn = {};
std::string license = {};
std::size_t size = 0;
std::size_t timestamp = 0;
std::string md5;
std::string sha256;
std::string track_features;
std::vector<std::string> depends;
std::vector<std::string> constrains;
std::string signatures;
std::string extra_metadata;
std::set<std::string> defaulted_keys;
std::string md5 = {};
std::string sha256 = {};
std::string track_features = {};
std::vector<std::string> depends = {};
std::vector<std::string> constrains = {};
std::string signatures = {};
std::string extra_metadata = {};
std::set<std::string> defaulted_keys = {};
};
} // namespace mamba

View File

@ -32,13 +32,16 @@ namespace mamba
MPool();
~MPool();
std::size_t n_solvables() const;
void set_debuglevel();
void create_whatprovides();
std::vector<Id> select_solvables(Id id, bool sorted = false) const;
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 const Pool*() const;

View File

@ -19,6 +19,7 @@
extern "C"
{
typedef struct s_Repo Repo;
typedef struct s_Repodata Repodata;
}
namespace mamba

View File

@ -95,7 +95,7 @@ namespace mamba
[[nodiscard]] const std::vector<MatchSpec>& neuter_specs() const;
[[nodiscard]] const std::vector<MatchSpec>& pinned_specs() const;
operator const Solver*() const;
operator Solver*();
bool only_deps = false;

View File

@ -35,14 +35,10 @@
namespace mamba
{
void try_add(nlohmann::json& j, const char* key, const char* val);
nlohmann::json solvable_to_json(Solvable* s);
class PackageDownloadExtractTarget
{
public:
PackageDownloadExtractTarget(Solvable* solvable);
PackageDownloadExtractTarget(const PackageInfo& pkg_info);
void write_repodata_record(const fs::u8path& base_path);
@ -126,7 +122,7 @@ namespace mamba
const std::vector<MatchSpec>& specs_to_install,
MultiPackageCache& caches
);
MTransaction(MSolver& solver, MultiPackageCache& caches);
MTransaction(MPool& pool, MSolver& solver, MultiPackageCache& caches);
// Only use if the packages have been solved previously already.
MTransaction(MPool& pool, const std::vector<PackageInfo>& packages, MultiPackageCache& caches);
@ -157,6 +153,8 @@ namespace mamba
private:
MPool m_pool;
FilterType m_filter_type = FilterType::none;
std::set<Id> m_filter_name_ids;

View File

@ -493,10 +493,12 @@ namespace mamba
MRepo::create(pool, prefix_data);
MSolver solver(
std::move(pool),
{ { SOLVER_FLAG_ALLOW_UNINSTALL, ctx.allow_uninstall },
{ SOLVER_FLAG_ALLOW_DOWNGRADE, ctx.allow_downgrade },
{ SOLVER_FLAG_STRICT_REPO_PRIORITY, ctx.channel_priority == ChannelPriority::kStrict } }
pool,
{
{ SOLVER_FLAG_ALLOW_UNINSTALL, ctx.allow_uninstall },
{ SOLVER_FLAG_ALLOW_DOWNGRADE, ctx.allow_downgrade },
{ SOLVER_FLAG_STRICT_REPO_PRIORITY, ctx.channel_priority == ChannelPriority::kStrict },
}
);
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)
{

View File

@ -111,11 +111,13 @@ namespace mamba
else
{
MSolver solver(
std::move(pool),
{ { SOLVER_FLAG_ALLOW_DOWNGRADE, 1 },
{ SOLVER_FLAG_ALLOW_UNINSTALL, 1 },
{ SOLVER_FLAG_STRICT_REPO_PRIORITY,
ctx.channel_priority == ChannelPriority::kStrict } }
pool,
{
{ SOLVER_FLAG_ALLOW_DOWNGRADE, 1 },
{ SOLVER_FLAG_ALLOW_UNINSTALL, 1 },
{ SOLVER_FLAG_STRICT_REPO_PRIORITY,
ctx.channel_priority == ChannelPriority::kStrict },
}
);
History history(ctx.target_prefix);
@ -138,7 +140,7 @@ namespace mamba
solver.add_jobs(specs, solver_flag);
solver.must_solve();
MTransaction transaction(solver, package_caches);
MTransaction transaction(pool, solver, package_caches);
execute_transaction(transaction);
}
}

View File

@ -70,10 +70,12 @@ namespace mamba
MRepo::create(pool, prefix_data);
MSolver solver(
std::move(pool),
{ { SOLVER_FLAG_ALLOW_DOWNGRADE, ctx.allow_downgrade },
{ SOLVER_FLAG_ALLOW_UNINSTALL, ctx.allow_uninstall },
{ SOLVER_FLAG_STRICT_REPO_PRIORITY, ctx.channel_priority == ChannelPriority::kStrict } }
pool,
{
{ SOLVER_FLAG_ALLOW_DOWNGRADE, ctx.allow_downgrade },
{ SOLVER_FLAG_ALLOW_UNINSTALL, ctx.allow_uninstall },
{ SOLVER_FLAG_STRICT_REPO_PRIORITY, ctx.channel_priority == ChannelPriority::kStrict },
}
);
if (update_all)
@ -140,7 +142,7 @@ namespace mamba
}
};
MTransaction transaction(solver, package_caches);
MTransaction transaction(pool, solver, package_caches);
execute_transaction(transaction);
config.operation_teardown();

View File

@ -15,8 +15,6 @@
#include "mamba/core/channel.hpp"
#include "mamba/core/util_string.hpp"
#include "solv-cpp/queue.hpp"
namespace mamba
{
namespace
@ -43,7 +41,7 @@ namespace mamba
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()
{
@ -62,16 +60,16 @@ namespace mamba
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();
return m;
}
} // 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())
{
throw std::runtime_error("field_getter function not found");
@ -79,169 +77,20 @@ namespace mamba
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);
return [getter](const PackageInfo& lhs, const PackageInfo& 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);
return [getter](const PackageInfo& lhs, const PackageInfo& 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)
{
using namespace std::string_literals; // NOLINT(build/namespaces)
@ -289,21 +138,16 @@ namespace mamba
}
}
PackageInfo::PackageInfo(const std::string& n)
: name(n)
{
}
PackageInfo::PackageInfo(std::string&& n)
PackageInfo::PackageInfo(std::string n)
: name(std::move(n))
{
}
PackageInfo::PackageInfo(const std::string& n, const std::string& v, const std::string b, std::size_t bn)
: name(n)
, version(v)
, build_string(b)
, build_number(bn)
PackageInfo::PackageInfo(std::string n, std::string v, std::string b, std::size_t bn)
: name(std::move(n))
, version(std::move(v))
, build_string(std::move(b))
, build_number(std::move(bn))
{
}

View File

@ -6,6 +6,7 @@
#include <list>
#include <fmt/format.h>
#include <solv/evr.h>
#include <solv/pool.h>
#include <solv/selection.h>
@ -19,6 +20,9 @@ extern "C" // Incomplete header
#include "mamba/core/context.hpp"
#include "mamba/core/output.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"
@ -90,6 +94,11 @@ namespace mamba
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()
{
// ensure that debug logging goes to stderr as to not interfere with stdout json output
@ -150,13 +159,147 @@ namespace mamba
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 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)

View File

@ -6,6 +6,8 @@
#include "mamba/core/prefix_data.hpp"
#include <solv/pool.h>
#include <solv/repo.h>
#include <solv/transaction.h>
#include "mamba/core/output.hpp"

View File

@ -27,114 +27,119 @@
namespace mamba
{
void walk_graph(
query_result::dependency_graph& dep_graph,
query_result::dependency_graph::node_id parent,
Solvable* s,
std::map<Solvable*, size_t>& visited,
std::map<std::string, size_t>& not_found,
int depth = -1
)
namespace
{
if (depth == 0)
void walk_graph(
MPool pool,
query_result::dependency_graph& dep_graph,
query_result::dependency_graph::node_id parent,
Solvable* s,
std::map<Solvable*, size_t>& visited,
std::map<std::string, size_t>& not_found,
int depth = -1
)
{
return;
}
depth -= 1;
if (s && s->requires)
{
auto* pool = s->repo->pool;
Id* reqp = s->repo->idarraydata + s->requires;
Id req = *reqp;
while (req != 0)
if (depth == 0)
{
solv::ObjQueue rec_solvables = {};
// the following prints the requested version
solv::ObjQueue job = { SOLVER_SOLVABLE_PROVIDES, req };
selection_solvables(pool, job.raw(), rec_solvables.raw());
return;
}
depth -= 1;
if (rec_solvables.size() != 0)
if (s && s->requires)
{
Id* reqp = s->repo->idarraydata + s->requires;
Id req = *reqp;
while (req != 0)
{
Solvable* rs = nullptr;
for (auto& el : rec_solvables)
solv::ObjQueue rec_solvables = {};
// the following prints the requested version
solv::ObjQueue job = { SOLVER_SOLVABLE_PROVIDES, req };
selection_solvables(pool, job.raw(), rec_solvables.raw());
if (rec_solvables.size() != 0)
{
rs = pool_id2solvable(pool, el);
if (rs->name == req)
Solvable* rs = nullptr;
for (auto& el : rec_solvables)
{
break;
rs = pool_id2solvable(pool, el);
if (rs->name == req)
{
break;
}
}
auto it = visited.find(rs);
if (it == visited.end())
{
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);
visited.insert(std::make_pair(rs, dep_id));
walk_graph(pool, dep_graph, dep_id, rs, visited, not_found, depth);
}
else
{
dep_graph.add_edge(parent, it->second);
}
}
auto it = visited.find(rs);
if (it == visited.end())
{
auto dep_id = dep_graph.add_node(PackageInfo(rs));
dep_graph.add_edge(parent, dep_id);
visited.insert(std::make_pair(rs, dep_id));
walk_graph(dep_graph, dep_id, rs, visited, not_found, depth);
}
else
{
dep_graph.add_edge(parent, it->second);
std::string name = pool_id2str(pool, req);
auto it = not_found.find(name);
if (it == not_found.end())
{
auto dep_id = dep_graph.add_node(
PackageInfo(concat(name, " >>> NOT FOUND <<<"))
);
dep_graph.add_edge(parent, dep_id);
not_found.insert(std::make_pair(name, dep_id));
}
else
{
dep_graph.add_edge(parent, it->second);
}
}
++reqp;
req = *reqp;
}
else
{
std::string name = pool_id2str(pool, req);
auto it = not_found.find(name);
if (it == not_found.end())
{
auto dep_id = dep_graph.add_node(
PackageInfo(concat(name, " >>> NOT FOUND <<<"))
);
dep_graph.add_edge(parent, dep_id);
not_found.insert(std::make_pair(name, dep_id));
}
else
{
dep_graph.add_edge(parent, it->second);
}
}
++reqp;
req = *reqp;
}
}
}
void reverse_walk_graph(
query_result::dependency_graph& dep_graph,
query_result::dependency_graph::node_id parent,
Solvable* s,
std::map<Solvable*, size_t>& visited
)
{
if (s)
void reverse_walk_graph(
MPool& pool,
query_result::dependency_graph& dep_graph,
query_result::dependency_graph::node_id parent,
Solvable* s,
std::map<Solvable*, size_t>& visited
)
{
auto* pool = s->repo->pool;
// figure out who requires `s`
solv::ObjQueue solvables = {};
pool_whatmatchesdep(pool, SOLVABLE_REQUIRES, s->name, solvables.raw(), -1);
if (solvables.size() != 0)
if (s)
{
Solvable* rs;
for (auto& el : solvables)
// figure out who requires `s`
solv::ObjQueue solvables = {};
pool_whatmatchesdep(pool, SOLVABLE_REQUIRES, s->name, solvables.raw(), -1);
if (solvables.size() != 0)
{
rs = pool_id2solvable(pool, el);
auto it = visited.find(rs);
if (it == visited.end())
for (auto& el : solvables)
{
auto dep_id = dep_graph.add_node(PackageInfo(rs));
dep_graph.add_edge(parent, dep_id);
visited.insert(std::make_pair(rs, dep_id));
reverse_walk_graph(dep_graph, dep_id, rs, visited);
}
else
{
dep_graph.add_edge(parent, it->second);
::Solvable* rs = pool_id2solvable(pool, el);
auto it = visited.find(rs);
if (it == visited.end())
{
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);
visited.insert(std::make_pair(rs, dep_id));
reverse_walk_graph(pool, dep_graph, dep_id, rs, visited);
}
else
{
dep_graph.add_edge(parent, it->second);
}
}
}
}
@ -236,8 +241,9 @@ namespace mamba
for (auto& el : solvables)
{
Solvable* s = pool_id2solvable(m_pool.get(), el);
g.add_node(PackageInfo(s));
auto pkg_info = m_pool.get().id2pkginfo(el);
assert(pkg_info.has_value());
g.add_node(std::move(pkg_info).value());
}
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
{
solv::ObjQueue job, solvables;
const Id id = pool_conda_matchspec(m_pool.get(), query.c_str());
if (!id)
{
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;
if (tree)
{
solv::ObjQueue solvables = {};
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]);
const auto node_id = g.add_node(PackageInfo(latest));
auto pkg_info = m_pool.get().id2pkginfo(solvables.front());
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 } };
reverse_walk_graph(g, node_id, latest, visited);
reverse_walk_graph(m_pool, g, node_id, latest, visited);
}
}
else
{
solv::ObjQueue solvables = {};
pool_whatmatchesdep(m_pool.get(), SOLVABLE_REQUIRES, id, solvables.raw(), -1);
for (auto& el : solvables)
{
Solvable* s = pool_id2solvable(m_pool.get(), el);
g.add_node(PackageInfo(s));
auto pkg_info = m_pool.get().id2pkginfo(el);
assert(pkg_info.has_value());
g.add_node(std::move(pkg_info).value());
}
}
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*
{
Solvable* latest = pool_id2solvable(m_pool.get(), lsolvables.front());
for (Id const solv : lsolvables)
::Solvable* latest = pool_id2solvable(m_pool.get(), lsolvables.front());
for (Id const solv : solvables)
{
Solvable* s = pool_id2solvable(m_pool.get(), solv);
if (pool_evrcmp(m_pool.get(), s->evr, latest->evr, 0) > 0)
@ -309,13 +318,16 @@ namespace mamba
return latest;
};
if (solvables.size() > 0)
if (!solvables.empty())
{
Solvable* latest = find_latest_in_non_empty(solvables);
const auto node_id = g.add_node(PackageInfo(latest));
::Solvable* const latest = find_latest_in_non_empty(solvables);
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<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));

View File

@ -126,8 +126,9 @@ namespace mamba
for (const auto& solv_id : m_pool.select_solvables(dep_id))
{
added = true;
PackageInfo pkg_info(pool_id2solvable(m_pool, solv_id));
node_id to_id = add_solvable(solv_id, PackageNode{ std::move(pkg_info) }, false);
auto pkg_info = m_pool.id2pkginfo(solv_id);
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);
}
return added;

View File

@ -171,47 +171,32 @@ namespace mamba
}
}
std::optional<PackageInfo> make_solver_problem_source(::Pool* pool, Id source_id)
{
if (source_id == 0 || source_id >= pool->nsolvables)
{
return std::nullopt;
}
return pool_id2solvable(pool, source_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)
MSolverProblem make_solver_problem(
const MSolver& solver,
const MPool& pool,
SolverRuleinfo type,
Id source_id,
Id target_id,
Id dep_id
)
{
const ::Solver* const solver_ptr = solver;
return {
/* .type= */ type,
/* .source_id= */ source_id,
/* .target_id= */ target_id,
/* .dep_id= */ dep_id,
/* .source= */ make_solver_problem_source(solver->pool, source_id),
/* .target= */ make_solver_problem_target(solver->pool, target_id),
/* .dep= */ make_solver_problem_dep(solver->pool, dep_id),
/* .source= */ pool.id2pkginfo(source_id),
/* .target= */ pool.id2pkginfo(target_id),
/* .dep= */ pool.dep2str(dep_id),
/* .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;
const SolverRuleinfo type = solver_ruleinfo(m_solver.get(), r, &source, &target, &dep);
res.push_back(make_solver_problem(
/* solver= */ m_solver.get(),
/* solver= */ *this,
/* pool= */ m_pool,
/* type= */ type,
/* source_id= */ source,
/* target_id= */ target,
@ -713,6 +699,11 @@ namespace mamba
return problems;
}
MSolver::operator const Solver*() const
{
return m_solver.get();
}
MSolver::operator Solver*()
{
return m_solver.get();

View File

@ -32,20 +32,29 @@ extern "C" // Incomplete header
#include "progress_bar_impl.hpp"
namespace
{
bool need_pkg_download(const mamba::PackageInfo& pkg_info, mamba::MultiPackageCache& caches)
{
return caches.get_extracted_dir_path(pkg_info).empty()
&& caches.get_tarball_path(pkg_info).empty();
}
} // anonymouse namspace
namespace mamba
{
nlohmann::json solvable_to_json(Solvable* s)
namespace
{
return PackageInfo(s).json_record();
bool need_pkg_download(const PackageInfo& pkg_info, MultiPackageCache& caches)
{
return caches.get_extracted_dir_path(pkg_info).empty()
&& caches.get_tarball_path(pkg_info).empty();
}
auto mk_pkginfo(const MPool& pool, Solvable* s) -> PackageInfo
{
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 mk_pkginfo(pool, s).json_record();
}
/********************************
@ -64,11 +73,6 @@ namespace mamba
DownloadExtractSemaphore::semaphore.set_max(value);
}
PackageDownloadExtractTarget::PackageDownloadExtractTarget(Solvable* solvable)
: PackageDownloadExtractTarget(PackageInfo(solvable))
{
}
PackageDownloadExtractTarget::PackageDownloadExtractTarget(const PackageInfo& pkg_info)
: m_finished(false)
, m_package_info(pkg_info)
@ -474,7 +478,8 @@ namespace mamba
const std::vector<MatchSpec>& specs_to_install,
MultiPackageCache& caches
)
: m_multi_cache(caches)
: m_pool(pool)
, m_multi_cache(caches)
{
// auto& ctx = Context::instance();
std::vector<PackageInfo> pi_result;
@ -499,9 +504,9 @@ namespace mamba
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
solv::ObjQueue q, job, decision;
@ -512,12 +517,12 @@ namespace mamba
job.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)
{
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)
{
@ -536,8 +541,8 @@ namespace mamba
throw std::runtime_error("Could not find packages to remove:" + join("", not_found));
}
selection_solvables(pool, job.raw(), q.raw());
const bool remove_success = q.size() >= specs_to_remove.size();
selection_solvables(m_pool, job.raw(), q.raw());
const bool remove_success = size_t(q.size()) >= specs_to_remove.size();
Console::instance().json_write({ { "success", remove_success } });
Id pkg_id;
Solvable* solvable;
@ -548,7 +553,7 @@ namespace mamba
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();
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_multi_cache(caches)
: m_pool(pool)
, m_multi_cache(caches)
{
if (!solver.is_solved())
{
@ -590,8 +596,6 @@ namespace mamba
m_transaction = solver_create_transaction(solver);
transaction_order(m_transaction, 0);
auto* pool = static_cast<Solver*>(solver)->pool;
m_history_entry = History::UserRequest::prefilled();
if (solver.no_deps || solver.only_deps)
@ -599,11 +603,11 @@ namespace mamba
m_filter_type = solver.only_deps ? FilterType::keep_only : FilterType::ignore;
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())
{
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)
@ -612,15 +616,15 @@ namespace mamba
transaction_installedresult(m_transaction, q.raw());
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))
{
// add the dependencies of this selected package to the added specs
Id* reqp;
for (reqp = s->repo->idarraydata + s->requires; *reqp; reqp++)
{
const char* depname = pool_id2str(pool, *reqp);
const char* depevr = pool_id2evr(pool, *reqp);
const char* depname = pool_id2str(m_pool, *reqp);
const char* depevr = pool_id2evr(m_pool, *reqp);
std::string add_spec;
if (depname)
{
@ -670,7 +674,8 @@ namespace mamba
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;
Solvable* s = nullptr;
@ -678,9 +683,9 @@ namespace mamba
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);
@ -714,11 +719,12 @@ namespace mamba
continue;
}
PackageInfo pi(s);
const auto pkg_info = mk_pkginfo(m_pool, s);
const Id id = pool_conda_matchspec(
pool,
fmt::format("{} {} {}", pi.name, pi.version, pi.build_string).c_str()
m_pool,
fmt::format("{} {} {}", pkg_info.name, pkg_info.version, pkg_info.build_string)
.c_str()
);
if (id)
@ -726,13 +732,13 @@ namespace mamba
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;
for (const Id r : q)
{
auto* xid = pool_id2solvable(pool, r);
if (xid->repo != pool->installed)
auto* xid = pool_id2solvable(m_pool, r);
if (xid->repo != pool_ptr->installed)
{
reinstall_id = r;
break;
@ -747,9 +753,9 @@ namespace mamba
"To upgrade python we need to reinstall noarch",
" package {} {} {} but we could not find it in",
" any of the loaded channels.",
pi.name,
pi.version,
pi.build_string
pkg_info.name,
pkg_info.version,
pkg_info.build_string
);
continue;
}
@ -763,7 +769,7 @@ namespace mamba
}
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);
// init everything again...
@ -776,11 +782,12 @@ namespace mamba
const std::vector<PackageInfo>& packages,
MultiPackageCache& caches
)
: m_multi_cache(caches)
: m_pool(pool)
, m_multi_cache(caches)
{
LOG_INFO << "MTransaction::MTransaction - packages already resolved (lockfile)";
MRepo& mrepo = MRepo::create(pool, "__explicit_specs__", packages);
pool.create_whatprovides();
MRepo& mrepo = MRepo::create(m_pool, "__explicit_specs__", packages);
m_pool.create_whatprovides();
solv::ObjQueue decision = {};
@ -792,7 +799,7 @@ namespace mamba
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);
init();
@ -828,7 +835,7 @@ namespace mamba
{
Id p = m_transaction->steps.elements[i];
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))
{
continue;
@ -842,7 +849,7 @@ namespace mamba
{
m_to_remove.push_back(s);
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;
}
@ -871,31 +878,31 @@ namespace mamba
// We need to find the python version that will be there after this
// Transaction is finished in order to compile the noarch packages correctly,
// for example
Pool* pool = m_transaction->pool;
assert(pool != nullptr);
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)
{
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;
break;
}
}
if (pool->installed != nullptr)
::Pool* const pool_ptr = m_pool;
if (pool_ptr->installed != nullptr)
{
Id p;
Solvable* s;
FOR_REPO_SOLVABLES(pool->installed, p, s)
FOR_REPO_SOLVABLES(pool_ptr->installed, p, s)
{
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;
break;
}
@ -985,13 +992,11 @@ namespace mamba
TransactionRollback rollback;
auto* pool = m_transaction->pool;
for (int i = 0; i < m_transaction->steps.count && !is_sig_interrupted(); i++)
{
Id p = m_transaction->steps.elements[i];
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))
{
@ -1005,17 +1010,19 @@ namespace mamba
case SOLVER_TRANSACTION_CHANGED:
case SOLVER_TRANSACTION_REINSTALLED:
{
Solvable* s2 = m_transaction->pool->solvables
Solvable* s2 = static_cast<::Pool*>(m_pool)->solvables
+ 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(
m_multi_cache.get_extracted_dir_path(package_to_unlink)
);
PackageInfo package_to_link(s2);
const fs::u8path l_cache_path(
m_multi_cache.get_extracted_dir_path(package_to_link, false)
);
@ -1035,7 +1042,7 @@ namespace mamba
}
case SOLVER_TRANSACTION_ERASE:
{
PackageInfo package_info(s);
PackageInfo package_info = mk_pkginfo(m_pool, s);
Console::stream() << "Unlinking " << package_info.str();
const fs::u8path cache_path(m_multi_cache.get_extracted_dir_path(package_info));
UnlinkPackage up(package_info, cache_path, &m_transaction_context);
@ -1046,7 +1053,7 @@ namespace mamba
}
case SOLVER_TRANSACTION_INSTALL:
{
PackageInfo package_info(s);
PackageInfo package_info = mk_pkginfo(m_pool, s);
Console::stream() << "Linking " << package_info.str();
const fs::u8path cache_path(
m_multi_cache.get_extracted_dir_path(package_info, false)
@ -1083,7 +1090,7 @@ namespace mamba
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_remove_type to_remove_structured;
@ -1097,7 +1104,7 @@ namespace mamba
for (Solvable* s : m_to_install)
{
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;
if (solvable_lookup_str(s, real_repo_key))
@ -1126,20 +1133,20 @@ namespace mamba
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
{
to_fetch.push_back(solvable_to_json(s));
to_link.push_back(solvable_to_json(s));
to_fetch.push_back(solvable_to_json(m_pool, s));
to_link.push_back(solvable_to_json(m_pool, s));
}
}
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)
@ -1184,9 +1191,7 @@ namespace mamba
if (ctx.experimental && ctx.verify_artifacts)
{
const auto& repo_checker = make_channel(mamba_repo->url()).repo_checker(m_multi_cache);
auto pkg_info = PackageInfo(s);
const auto pkg_info = mk_pkginfo(m_pool, s);
repo_checker.verify_package(
pkg_info.json_signable(),
nlohmann::json::parse(pkg_info.signatures)
@ -1195,7 +1200,8 @@ namespace mamba
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);
if (download_target != nullptr)
{
@ -1450,7 +1456,6 @@ namespace mamba
rows downgraded, upgraded, changed, reinstalled, erased, installed, ignored;
std::size_t total_size = 0;
auto* pool = m_transaction->pool;
enum struct Status
{
@ -1459,7 +1464,7 @@ namespace mamba
remove
};
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);
printers::FormattedString dlsize_s;
@ -1471,7 +1476,7 @@ namespace mamba
}
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.style = ctx.palette.addition;
@ -1490,7 +1495,7 @@ namespace mamba
}
}
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)
{
name.style = ctx.palette.addition;
@ -1506,7 +1511,7 @@ namespace mamba
const char* build_string = solvable_lookup_str(s, SOLVABLE_BUILDFLAVOR);
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))
{
std::string repo_key = solvable_lookup_str(s, real_repo_key);
@ -1529,12 +1534,14 @@ namespace mamba
}
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(cut_repo_name(channel)),
dlsize_s });
};
::Solvable* const solvables = static_cast<::Pool*>(m_pool)->solvables;
int mode = SOLVER_TRANSACTION_SHOW_OBSOLETES | SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE;
transaction_classify(m_transaction, mode, classes.raw());
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)
{
Solvable* s = m_transaction->pool->solvables + p;
Solvable* s = solvables + p;
if (filter(s))
{
@ -1564,7 +1571,7 @@ namespace mamba
format_row(upgraded, s, Status::remove, "-");
format_row(
upgraded,
m_transaction->pool->solvables + transaction_obs_pkg(m_transaction, p),
solvables + transaction_obs_pkg(m_transaction, p),
Status::install,
"+"
);
@ -1573,7 +1580,7 @@ namespace mamba
format_row(changed, s, Status::remove, "-");
format_row(
changed,
m_transaction->pool->solvables + transaction_obs_pkg(m_transaction, p),
solvables + transaction_obs_pkg(m_transaction, p),
Status::install,
"+"
);
@ -1585,7 +1592,7 @@ namespace mamba
format_row(downgraded, s, Status::remove, "-");
format_row(
downgraded,
m_transaction->pool->solvables + transaction_obs_pkg(m_transaction, p),
solvables + transaction_obs_pkg(m_transaction, p),
Status::install,
"+"
);

View File

@ -844,8 +844,6 @@ class MultiPackageCache:
pass
class PackageInfo:
@typing.overload
def __init__(self, arg0: s_Solvable) -> None: ...
@typing.overload
def __init__(self, name: str) -> None: ...
@typing.overload
@ -1398,6 +1396,9 @@ class SubdirData:
pass
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 execute(self, arg0: PrefixData) -> bool: ...
def fetch_extract_packages(self) -> bool: ...

View File

@ -210,7 +210,14 @@ PYBIND11_MODULE(bindings, m)
.def("clear", &MRepo::clear);
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("log_json", &MTransaction::log_json)
.def("print", &MTransaction::print)
@ -565,7 +572,7 @@ PYBIND11_MODULE(bindings, m)
.def_property_readonly("package_records", &PrefixData::records)
.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&, const std::string&, const std::string&, std::size_t>(),

View File

@ -224,7 +224,7 @@ def remove(args, parser):
return exit_code
package_cache = api.MultiPackageCache(context.pkgs_dirs)
transaction = api.Transaction(solver, package_cache)
transaction = api.Transaction(pool, solver, package_cache)
if not transaction.prompt():
exit(0)
@ -562,7 +562,7 @@ def install(args, parser, command="install"):
return exit_code
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()
specs_to_add = [MatchSpec(m) for m in mmb_specs[0]]

View File

@ -141,7 +141,7 @@ def mamba_install(prefix, specs, args, env, dry_run=False, *_, **kwargs):
exit(1)
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()
specs_to_add = [MatchSpec(m) for m in mmb_specs[0]]