|
@@ -5,25 +5,69 @@ namespace Usm {
|
|
|
public class Resolver {
|
|
|
|
|
|
private Dictionary<Repository, RepositoryListing> listings = new Dictionary<Repository, RepositoryListing>();
|
|
|
+ private Set<AbstractPackage> supplied = new Set<AbstractPackage>();
|
|
|
+
|
|
|
+ private Enumerable<AbstractPackage> available_packages() {
|
|
|
+ return
|
|
|
+ supplied.concat(listings
|
|
|
+ .select_many<Pair<Repository, RepositoryListingEntry>>(l => l.value.entries.select_pairs<Repository, RepositoryListingEntry>(e => l.key, e => e))
|
|
|
+ .select<AbstractPackage>(p => new AbstractPackage.from_repository(p.value1, p.value2)));
|
|
|
+ }
|
|
|
|
|
|
public void load_listing(Repository repo, RepositoryListing listing) {
|
|
|
listings.set(repo, listing);
|
|
|
}
|
|
|
|
|
|
+ public void supply_package(string path) throws Error {
|
|
|
+ supplied.add(new AbstractPackage.from_package(path));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void load_cache(Paths paths) throws Error {
|
|
|
+ var state = new SystemState(paths);
|
|
|
+ foreach (var package in state.get_cached_packages()) {
|
|
|
+ supply_package(package.package_path);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public AbstractPackage? find_package(string search) {
|
|
|
- return listings
|
|
|
- .select_many<Pair<Repository, RepositoryListingEntry>>(l => l.value.entries.select_pairs<Repository, RepositoryListingEntry>(e => l.key, e => e))
|
|
|
- .where(p => p.value2.manifest.name == search)
|
|
|
- .select<AbstractPackage>(p => new AbstractPackage.from_repository(p.value1, p.value2))
|
|
|
- .first_or_default();
|
|
|
+ return available_packages()
|
|
|
+ .first_or_default(p => p.manifest.name == search);
|
|
|
+ }
|
|
|
+
|
|
|
+ public AbstractPackage? find_resource(ResourceRef resource) {
|
|
|
+ return available_packages()
|
|
|
+ .first_or_default(p => p.manifest.provides.any(r => resource.satisfied_by(r.key)));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void solve_dependencies_for(PackageSet package_set) {
|
|
|
+ var queue = new Fifo<AbstractPackage>();
|
|
|
+ package_set.iterate(i => queue.push(i));
|
|
|
+
|
|
|
+ foreach (var item in queue) {
|
|
|
+ var dependencies = item.manifest.dependencies.build
|
|
|
+ .concat(item.manifest.dependencies.manage)
|
|
|
+ .concat(item.manifest.dependencies.runtime);
|
|
|
+
|
|
|
+ foreach (var dep in dependencies) {
|
|
|
+ if(package_set.provides(dep) || dep.is_satisfied()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ var provider = find_resource(dep);
|
|
|
+ if(provider == null) {
|
|
|
+ error(@"Could not solve dependency $dep");
|
|
|
+ }
|
|
|
+
|
|
|
+ package_set.add(provider);
|
|
|
+ queue.push(provider);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public class PackageSet : Set<AbstractPackage> {
|
|
|
|
|
|
- private Set<ResourceRef> provided_in_set = new Set<ResourceRef>();
|
|
|
-
|
|
|
public void add_from_file(string path) throws Error {
|
|
|
add(new AbstractPackage.from_package(path));
|
|
|
}
|
|
@@ -37,10 +81,14 @@ namespace Usm {
|
|
|
}
|
|
|
|
|
|
private bool check_satisfied(AbstractPackage package) {
|
|
|
- return package.manifest.dependencies.build.all(d => provided_in_set.has(d) || d.is_satisfied()) &&
|
|
|
- package.manifest.dependencies.manage.all(d => provided_in_set.has(d) || d.is_satisfied()) &&
|
|
|
- package.manifest.dependencies.runtime.all(d => provided_in_set.has(d) || d.is_satisfied());
|
|
|
+ return package.manifest.dependencies.build.all(d => provides(d) || d.is_satisfied()) &&
|
|
|
+ package.manifest.dependencies.manage.all(d => provides(d) || d.is_satisfied()) &&
|
|
|
+ package.manifest.dependencies.runtime.all(d => provides(d) || d.is_satisfied());
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
+ public bool provides(ResourceRef resource) {
|
|
|
+ return any(p => p.manifest.provides.any(r => resource.satisfied_by(r.key)));
|
|
|
}
|
|
|
|
|
|
}
|