Skip to content

Commit

Permalink
Merge branch 'master' into add/bigsur-ci
Browse files Browse the repository at this point in the history
  • Loading branch information
ken-matsui authored Dec 13, 2020
2 parents 9290380 + 2df1c09 commit b5bb0b9
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 114 deletions.
14 changes: 11 additions & 3 deletions include/poac/core/resolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ namespace poac::core::resolver {

using termcolor2::color_literals::operator""_green;
PLOG_INFO << fmt::format(
"{:>21} {} v{}", "Downloaded"_green, package.first, package.second
"{:>21} {} v{}", "Downloaded"_green,
resolve::get_name(package),
resolve::get_version(package)
);
}
return mitama::success();
Expand All @@ -57,8 +59,14 @@ namespace poac::core::resolver {
try {
const auto duplicate_deps = MITAMA_TRY(resolve::gather_all_deps(deps));
if (!resolve::duplicate_loose(duplicate_deps)) {
// When all dependencies are one package and one version,
// backtrack is not needed.
// When all dependencies are composed of one package and one version,
// a backtrack is not needed. Therefore, the duplicate_loose
// function just needs to check whether the gathered dependencies
// have multiple packages with the same name. If found multiple
// packages with the same name, then it means this package trying
// building depends on multiple versions of the same package.
// At the condition (the else clause), gathered dependencies
// should be in the backtrack loop.
return mitama::success(resolve::activated_to_backtracked(duplicate_deps));
} else {
return mitama::success(resolve::backtrack_loop(duplicate_deps));
Expand Down
110 changes: 62 additions & 48 deletions include/poac/core/resolver/resolve.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,36 @@ namespace poac::core::resolver::resolve {
std::string // version or interval
>;

package_t::first_type&
inline package_t::first_type&
get_name(package_t& package) noexcept {
return package.first;
}

const package_t::first_type&
inline const package_t::first_type&
get_name(const package_t& package) noexcept {
return package.first;
}

package_t::first_type&
inline package_t::second_type&
get_version(package_t& package) noexcept {
return package.second;
}

const package_t::first_type&
inline const package_t::second_type&
get_version(const package_t& package) noexcept {
return package.second;
}

inline package_t::second_type&
get_interval(package_t& package) noexcept {
return get_version(package);
}

inline const package_t::second_type&
get_interval(const package_t& package) noexcept {
return get_version(package);
}

using deps_t = std::optional<duplicate_deps_t<without_deps>>;

template <>
Expand All @@ -107,6 +117,11 @@ namespace poac::core::resolver::resolve {
std::string // version or interval
>>;

inline const package_t&
get_package(const unique_deps_t<with_deps>::value_type& deps) noexcept {
return deps.first;
}

std::string to_binary_numbers(const int& x, const std::size_t& digit) {
return fmt::format(FMT_STRING("{:0{}b}"), x, digit);
}
Expand Down Expand Up @@ -235,7 +250,7 @@ namespace poac::core::resolver::resolve {
PLOG_DEBUG <<
fmt::format(
"{}-{}: {}, ",
package.first, package.second, l
get_name(package), get_version(package), l
);
}
PLOG_DEBUG << "";
Expand All @@ -259,7 +274,7 @@ namespace poac::core::resolver::resolve {
const auto last = std::end(rng);
return std::find_if(first, last, [&](const auto& x){
return std::count_if(first, last, [&](const auto& y) {
return x.first == y.first;
return get_name(get_package(x)) == get_name(get_package(y));
}) > 1;
}) != last;
}
Expand All @@ -269,11 +284,11 @@ namespace poac::core::resolver::resolve {
// `latest` -> { 2.5.0 }
// name is boost/config, no boost-config
std::vector<std::string>
get_versions_satisfy_interval(const std::string& name, const std::string& interval) {
get_versions_satisfy_interval(const package_t& package) {
// TODO: (`>1.2 and <=1.3.2` -> NG,`>1.2.0-alpha and <=1.3.2` -> OK)
const std::vector<std::string> versions =
io::net::api::versions(name).unwrap();
if (interval == "latest") {
io::net::api::versions(get_name(package)).unwrap();
if (get_interval(package) == "latest") {
return {
*std::max_element(
versions.cbegin(),
Expand All @@ -285,7 +300,7 @@ namespace poac::core::resolver::resolve {
};
} else { // `2.0.0` specific version or `>=0.1.2 and <3.4.0` version interval
std::vector<std::string> res;
semver::Interval i(name, interval);
semver::Interval i(get_interval(package));
std::copy_if(
versions.cbegin(),
versions.cend(),
Expand All @@ -296,7 +311,7 @@ namespace poac::core::resolver::resolve {
throw except::error(
fmt::format(
"`{}: {}` not found. seem dependencies are broken",
name, interval
get_name(package), get_interval(package)
)
);
} else {
Expand All @@ -308,81 +323,89 @@ namespace poac::core::resolver::resolve {
using interval_cache_t =
std::vector<
std::tuple<
std::string, // name
std::string, // interval
package_t,
std::vector<std::string> // versions in the interval
>>;

inline const package_t&
get_package(const interval_cache_t::value_type& cache) noexcept {
return std::get<0>(cache);
}

inline const std::vector<std::string>&
get_versions(const interval_cache_t::value_type& cache) noexcept {
return std::get<1>(cache);
}

duplicate_deps_t<without_deps>
gather_deps_of_deps(
const unique_deps_t<without_deps>& deps_api_res,
interval_cache_t& interval_cache)
{
duplicate_deps_t<without_deps> cur_deps_deps;
for (const auto& [name, interval] : deps_api_res) {
for (const auto& package : deps_api_res) {
// Check if node package is resolved dependency (by interval)
const auto itr =
boost::range::find_if(
interval_cache,
[&name=name, &interval=interval](const auto& d) {
return std::get<0>(d) == name &&
std::get<1>(d) == interval;
[&package](const auto& cache) {
return get_name(get_package(cache)) == get_name(package) &&
get_interval(get_package(cache)) == get_interval(package);
}
);
if (itr != interval_cache.cend()) { // cache found
for (const auto& dep_version : std::get<2>(*itr)) {
cur_deps_deps.emplace_back(name, dep_version);
for (const auto& dep_version : get_versions(*itr)) {
cur_deps_deps.emplace_back(get_name(package), dep_version);
}
} else {
const auto dep_versions =
get_versions_satisfy_interval(name, interval);
const auto dep_versions = get_versions_satisfy_interval(package);
// Cache interval and versions pair
interval_cache.emplace_back(name, interval, dep_versions);
interval_cache.emplace_back(package, dep_versions);
for (const auto& dep_version : dep_versions) {
cur_deps_deps.emplace_back(name, dep_version);
cur_deps_deps.emplace_back(get_name(package), dep_version);
}
}
}
return cur_deps_deps;
}

void gather_deps(
const std::string& name,
const std::string& version,
const package_t& package,
duplicate_deps_t<with_deps>& new_deps,
interval_cache_t& interval_cache)
{
// Check if root package resolved dependency
// (whether the specific version is the same),
// and check circulating
if (util::meta::find_if(new_deps, [&](const auto& d) {
return d.first.first == name && d.first.second == version;
return get_name(get_package(d)) == get_name(package) &&
get_version(get_package(d)) == get_version(package);
})) {
return;
}

// Get dependencies of dependencies
const unique_deps_t<without_deps> deps_api_res =
io::net::api::deps(name, version).unwrap();
io::net::api::deps(get_name(package), get_version(package)).unwrap();
if (deps_api_res.empty()) {
new_deps.emplace_back(std::make_pair(name, version), std::nullopt);
new_deps.emplace_back(package, std::nullopt);
} else {
const auto deps_of_deps = gather_deps_of_deps(deps_api_res, interval_cache);

// Store dependency and the dependency's dependencies.
new_deps.emplace_back(std::make_pair(name, version), deps_of_deps);
new_deps.emplace_back(package, deps_of_deps);

// Gather dependencies of dependencies of dependencies. lol
for (const auto& [name, version] : deps_of_deps) {
gather_deps(name, version, new_deps, interval_cache);
for (const auto& dep_package : deps_of_deps) {
gather_deps(dep_package, new_deps, interval_cache);
}
}
}

[[nodiscard]] mitama::result<duplicate_deps_t<with_deps>, std::string>
gather_all_deps(const unique_deps_t<without_deps>& deps) {
duplicate_deps_t<with_deps> duplicate_deps{};
interval_cache_t interval_cache{};
duplicate_deps_t<with_deps> duplicate_deps;
interval_cache_t interval_cache;

// Activate the root of dependencies
for (const auto& package : deps) {
Expand All @@ -392,31 +415,22 @@ namespace poac::core::resolver::resolve {
// by checking whether package's interval is the same.
if (util::meta::find_if(
interval_cache,
[&package=package](const auto& cache){
return get_name(package) == std::get<0>(cache) &&
get_version(package) == std::get<1>(cache);
[&package](const auto& cache){
return get_name(package) == get_name(get_package(cache)) &&
get_interval(package) == get_interval(get_package(cache));
}
)) {
continue;
}

// Get versions using interval
// FIXME: versions API and deps API are received the almost same responses
const auto versions =
get_versions_satisfy_interval(
get_name(package),
get_version(package)
);
const auto versions = get_versions_satisfy_interval(package);
// Cache interval and versions pair
interval_cache.emplace_back(
get_name(package),
get_version(package),
versions
);
interval_cache.emplace_back(package, versions);
for (const auto& version : versions) {
gather_deps(
get_name(package),
version,
std::make_pair(get_name(package), version),
duplicate_deps,
interval_cache
);
Expand Down
Loading

0 comments on commit b5bb0b9

Please sign in to comment.