public bool CheckDependencies(PythonInstall install, out DistRequirement failed_dependency, Request request) { failed_dependency = new DistRequirement(); if (requires_dist.Count == 0) { return(true); } List <PythonPackage> installed_packages = new List <PythonPackage>(install.FindInstalledPackages(null, null, request)); foreach (var dep in requires_dist) { if (dep.marker != null && !dep.marker.Eval(install)) { continue; } bool satisfied_dependency = false; foreach (var package in installed_packages) { if (package.SatisfiesDependency(install, dep, request)) { satisfied_dependency = true; break; } } if (!satisfied_dependency) { failed_dependency = dep; return(false); } } return(true); }
public static DistRequirement Parse(string requirement) { DistRequirement result = new DistRequirement(); result.raw_string = requirement; if (requirement.Contains(';')) { string[] parts = requirement.Split(new char[] { ';' }, 2); requirement = parts[0].Trim(); result.marker = EnvironmentMarker.ParseEnvironmentMarker(parts[1].Trim()); } if (requirement.Contains('(')) { string[] parts = requirement.TrimEnd(')').Split(new char[] { '(' }, 2); result.name = parts[0].Trim(); result.has_version_specifier = true; result.version_specifier = new VersionSpecifier(parts[1]); } else { result.name = requirement.Trim(); result.has_version_specifier = false; } return(result); }
public static PythonPackage GetPackage(Tuple <string, string> source, string name, string version, Request request) { var detailed_info = GetDetailedPackageInfo(source, name, version, request); PythonPackage package = new PythonPackage(name); package.version = new VersionIdentifier(version); package.summary = detailed_info["info"]["summary"].ToString(); package.source = source.Item1; package.sourceurl = source.Item2; package.search_key = name; package.downloads = ParseUrls(detailed_info["urls"]); JToken requires_dist; if (((JObject)detailed_info["info"]).TryGetValue("requires_dist", out requires_dist)) { foreach (var requirement in requires_dist) { package.requires_dist.Add(DistRequirement.Parse(requirement.ToString())); } } if (((JObject)detailed_info["info"]).TryGetValue("requires", out requires_dist)) { foreach (var requirement in requires_dist) { package.requires_dist.Add(DistRequirement.Parse(requirement.ToString())); } } return(package); }
public void ReadMetadata(Stream stream) { using (var reader = new StreamReader(stream)) { string line; while ((line = reader.ReadLine()) != null) { if (line == "") { break; } if (line.StartsWith(" ")) { // Line continuation continue; } int delim_index = line.IndexOf(": "); if (delim_index != -1) { string name = line.Substring(0, delim_index); string value = line.Substring(delim_index + 2); name = name.ToLowerInvariant(); if (name == "name") { this.name = value; } else if (name == "version") { this.version = new VersionIdentifier(value); } else if (name == "summary") { this.summary = value; } else if (name == "requires-dist") { this.requires_dist.Add(DistRequirement.Parse(value)); } } } } }
public bool SatisfiesDependency(PythonInstall install, DistRequirement dep, Request request) { if (dep.marker != null && !dep.marker.Eval(install)) { // FIXME: handle this, somehow? return(true); } if (!MatchesName(dep.name)) { return(false); } if (dep.has_version_specifier) { if (!dep.version_specifier.MatchesVersion(version)) { return(false); } } return(true); }
private Dictionary <string, PythonPackage> SimpleResolveDependencies(PythonInstall install, out DistRequirement failed_dependency, Request request) { Dictionary <string, PythonPackage> result = new Dictionary <string, PythonPackage>(); Queue <DistRequirement> to_resolve = new Queue <DistRequirement>(); var installed_packages = new Dictionary <string, PythonPackage>(); bool need_recheck = true; // True if we're [up|down]grading a package, and therefore may need to recheck deps foreach (var package in install.FindInstalledPackages(null, null, request)) { installed_packages[package.name] = package; } while (need_recheck) { need_recheck = false; to_resolve.Clear(); foreach (var dep in requires_dist) { request.Debug("Adding dependency {0}", dep.raw_string); to_resolve.Enqueue(dep); } result.Clear(); while (to_resolve.Count != 0) { var dep = to_resolve.Dequeue(); PythonPackage package; request.Debug("Examining dependency {0}", dep.raw_string); if (dep.marker != null && !dep.marker.Eval(install)) { request.Debug("Does not apply to current Python environment"); continue; } if (result.TryGetValue(NormalizeName(dep.name), out package)) { if (!package.SatisfiesDependency(install, dep, request)) { failed_dependency = dep; return(null); } request.Debug("Satisfied by package to install {0} {1}", package.name, package.version.ToString()); } else { if (installed_packages.TryGetValue(NormalizeName(dep.name), out package)) { if (package.SatisfiesDependency(install, dep, request)) { request.Debug("Satisfied by installed package {0} {1}", package.name, package.version.ToString()); continue; } else { request.Debug("Not satisfied by installed package {0} {1}", package.name, package.version.ToString()); need_recheck = true; } } // find newest version of package that satisfies dependency package = null; foreach (var candidate_package in PyPI.ExactSearch(dep.name, request)) { request.Debug("Examining {0} {1}", candidate_package.name, candidate_package.version.ToString()); if (candidate_package.SatisfiesDependency(install, dep, request)) { package = candidate_package; break; } } if (package == null) { request.Debug("Cannot satisfy dependency"); failed_dependency = dep; return(null); } request.Debug("Selecting {0} {1}", package.name, package.version.ToString()); // need to do another request to find dependencies if (package.incomplete_metadata) { package = PyPI.GetPackage(new Tuple <string, string>(package.source, package.sourceurl), package.name, package.version.raw_version_string, request); } // add its dependencies to queue foreach (var dep2 in package.requires_dist) { request.Debug("Adding dependency {0}", dep2.raw_string); to_resolve.Enqueue(dep2); } result[NormalizeName(package.name)] = package; } } } failed_dependency = default(DistRequirement); return(result); }