public static PythonInstall FromPath(string installpath, Request request) { try { PythonInstall result = new PythonInstall(); if (Directory.Exists(installpath)) { result.install_path = installpath; result.exe_path = Path.Combine(installpath, "python.exe"); } else { result.install_path = Path.GetDirectoryName(installpath); result.exe_path = installpath; } result.ReadInterpreterInfo(request); string requested_version_str = request.GetOptionValue("PythonVersion"); if (!string.IsNullOrEmpty(requested_version_str)) { VersionIdentifier requested_version = new VersionIdentifier(requested_version_str); if (!requested_version.IsPrefix(result.version)) { return(null); } } return(result); } catch (Exception e) { request.Debug("Python at {0} isn't usable: {1}", installpath, e); } return(null); }
private void ReadInterpreterInfo(Request request) { string info; if (!interpreter_info_cache.TryGetValue(exe_path, out info)) { info = QueryPython(string.Format("\"{0}\"", FindPythonScript("get_info.py")), request); interpreter_info_cache.TryAdd(exe_path, info); } string[] parts = info.Split(new char[] { '\0' }, 15); if (parts.Length != 14) { throw new Exception(string.Format("Bad output from python interpreter at {0}", exe_path)); } version = GetPythonVersion(parts[0]); global_site_folder = parts[1]; is_64bit = (parts[2] == "8"); supported_tags = parts[3].Split('.'); int i; string_marker_variables = new string[6]; for (i = 0; i < 6; i++) { string_marker_variables[i] = parts[4 + i]; } version_marker_variables = new VersionIdentifier[4]; for (i = 0; i < 4; i++) { version_marker_variables[i] = new VersionIdentifier(parts[10 + i]); } }
private VersionIdentifier GetPythonVersion(string version_str) { string[] version_parts = version_str.Split(new char[] { '.' }, 6); if (version_parts.Length != 5) { return(null); } VersionIdentifier result = new VersionIdentifier("0.0.0"); int part; if (!int.TryParse(version_parts[0], out part) || part < 0) { return(null); } result.release[0] = part; if (!int.TryParse(version_parts[1], out part) || part < 0) { return(null); } result.release[1] = part; if (!int.TryParse(version_parts[2], out part) || part < 0) { return(null); } result.release[2] = part; switch (version_parts[3]) { case "alpha": result.prerelease_type = VersionIdentifier.PrereleaseType.Alpha; break; case "beta": result.prerelease_type = VersionIdentifier.PrereleaseType.Beta; break; case "candidate": result.prerelease_type = VersionIdentifier.PrereleaseType.ReleaseCandidate; break; case "final": result.prerelease_type = VersionIdentifier.PrereleaseType.Final; break; default: return(null); } if (!int.TryParse(version_parts[4], out part) || part < 0) { return(null); } result.prerelease_version = part; return(result); }
public override bool Equals(object obj) { VersionIdentifier id = obj as VersionIdentifier; if (id != null) { return(Compare(id) == 0); } return(base.Equals(obj)); }
public bool MatchesVersion(VersionIdentifier version) { foreach (var clause in clauses) { if (!clause.MatchesVersion(version)) { return(false); } } return(true); }
private static bool BetterVersion(VersionIdentifier current, VersionIdentifier candidate) { if (current.IsPrerelease && !candidate.IsPrerelease) { return(true); } if (!current.IsPrerelease && candidate.IsPrerelease) { return(false); } return(candidate.Compare(current) > 0); }
public bool IsPrefix(VersionIdentifier other) { if (epoch != other.epoch) { return(false); } for (int i = 0; i < release.Length; i++) { if ((other.release.Length > i ? other.release[i] : 0) != release[i]) { return(false); } } return(true); }
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 override int GetHashCode() { if (!is_valid) { return(raw_version_string.GetHashCode()); } else if (release.Length > 1 && release[release.Length - 1] == 0) { var trimmed_version = new VersionIdentifier(this.ToString()); int i = release.Length - 1; while (i > 1 && release[i] == 0) { i--; } trimmed_version.release = new int[i]; for (int j = 0; j < i; j++) { trimmed_version.release[j] = release[j]; } return(trimmed_version.ToString().GetHashCode()); } return(this.ToString().GetHashCode()); }
public void GetInstalledPackages(string name, string requiredVersion, string minimumVersion, string maximumVersion, Request request) { request.Debug("Calling '{0}::GetInstalledPackages({1},{2},{3},{4})'", ProviderName, name, requiredVersion, minimumVersion, maximumVersion); VersionIdentifier required = string.IsNullOrEmpty(requiredVersion) ? null : new VersionIdentifier(requiredVersion); VersionIdentifier minimum = string.IsNullOrEmpty(minimumVersion) ? null : new VersionIdentifier(minimumVersion); VersionIdentifier maximum = string.IsNullOrEmpty(maximumVersion) ? null : new VersionIdentifier(maximumVersion); foreach (var install in PythonInstall.FindEnvironments(request)) { if (string.IsNullOrEmpty(name) || name == "Python") { install.YieldSelf(request); } foreach (var package in install.FindInstalledPackages(name, requiredVersion, request)) { if ((required == null || required.Compare(package.version) == 0) && (minimum == null || minimum.Compare(package.version) <= 0) && (maximum == null || maximum.Compare(package.version) >= 0)) { package.YieldSelf(request); } } } }
public int Compare(VersionIdentifier other) { return(Compare(other, false, false, false)); }
private static IEnumerable <PythonPackage> ContainsSearch(string name, string requiredVersion, string minimumVersion, string maximumVersion, Request request) { VersionIdentifier required = null, minimum = null, maximum = null; if (!string.IsNullOrWhiteSpace(requiredVersion)) { required = new VersionIdentifier(requiredVersion); } if (!string.IsNullOrWhiteSpace(minimumVersion)) { minimum = new VersionIdentifier(minimumVersion); } if (!string.IsNullOrWhiteSpace(maximumVersion)) { maximum = new VersionIdentifier(maximumVersion); } MemoryStream call_ms = new MemoryStream(); XmlWriter writer = XmlWriter.Create(call_ms); writer.WriteStartElement("methodCall"); writer.WriteElementString("methodName", "search"); writer.WriteStartElement("params"); writer.WriteStartElement("param"); //spec writer.WriteStartElement("value"); writer.WriteStartElement("struct"); if (!string.IsNullOrEmpty(name)) { writer.WriteStartElement("member"); writer.WriteElementString("name", "name"); writer.WriteStartElement("value"); writer.WriteElementString("string", name); writer.WriteEndElement(); //value writer.WriteEndElement(); //member } // FIXME: Provide request options to also search summary, description, and keywords? writer.WriteEndElement(); //struct writer.WriteEndElement(); //value writer.WriteEndElement(); //param writer.WriteEndElement(); //params writer.WriteEndElement(); //methodCall writer.Close(); byte[] call = call_ms.ToArray(); foreach (var source in GetSources(request)) { if (request.IsCanceled) { break; } request.Debug("Python::ContainsSearch asking {0}", source.Item1); using (var response = DoWebRequest(source, call, request)) { var search_response = ParseResponse(response.GetResponseStream(), request) as List <object>; if (search_response == null) { request.Debug("search returned unexpected value"); continue; } string package_name = null; HashSet <string> nonhidden_versions = new HashSet <string>(); foreach (var package_info_obj in search_response) { if (request.IsCanceled) { break; } var package_info = package_info_obj as Dictionary <string, object>; if (package_info == null) { request.Debug("search returned unexpected value in array"); continue; } request.Debug("Python::ContainsSearch got {0} {1}", package_info["name"].ToString(), package_info["version"].ToString()); if (package_name != null && package_name != package_info["name"].ToString()) { foreach (var package in FilterPackageVersions(source, name, package_name, nonhidden_versions, required, minimum, maximum, false, request)) { yield return(package); } nonhidden_versions.Clear(); } package_name = package_info["name"].ToString(); nonhidden_versions.Add(package_info["version"].ToString()); } if (package_name != null) { foreach (var package in FilterPackageVersions(source, name, package_name, nonhidden_versions, required, minimum, maximum, false, request)) { yield return(package); } } } } }
public bool MatchesVersion(VersionIdentifier version) { switch (type) { case VersionClauseType.Compatible: if (version.Compare(this.version) < 0) { return(false); } VersionIdentifier version_prefix = new VersionIdentifier("1"); version_prefix.release = new int[this.version.release.Length - 1]; for (int i = 0; i < this.version.release.Length - 1; i++) { version_prefix.release[i] = this.version.release[i]; } return(version_prefix.IsPrefix(version)); case VersionClauseType.Matching: if (this.version.is_wildcard) { return(this.version.IsPrefix(version)); } else { return(this.version.Compare(version, !this.version.is_localversion, false, false) == 0); } case VersionClauseType.Exclusion: if (this.version.is_wildcard) { return(!this.version.IsPrefix(version)); } else { return(this.version.Compare(version, !this.version.is_localversion, false, false) != 0); } case VersionClauseType.GTE: return(this.version.Compare(version) <= 0); case VersionClauseType.LTE: return(this.version.Compare(version) >= 0); case VersionClauseType.GT: if (!this.version.is_postrelease && version.is_postrelease && this.version.Compare(version, false, false, true) == 0) { return(false); } if (version.is_localversion) { return(false); } return(this.version.Compare(version) < 0); case VersionClauseType.LT: if (!this.version.IsPrerelease && version.IsPrerelease && this.version.Compare(version, false, true, false) == 0) { return(false); } return(this.version.Compare(version) > 0); case VersionClauseType.ArbitraryEquality: return(this.version.raw_version_string == version.raw_version_string); default: return(false); } }
public int Compare(VersionIdentifier other, bool ignore_local, bool ignore_pre, bool ignore_post) { int res = cmp(epoch, other.epoch); if (res != 0) { return(res); } int common_segments = release.Length < other.release.Length ? release.Length : other.release.Length; for (int i = 0; i < common_segments; i++) { res = cmp(release[i], other.release[i]); if (res != 0) { return(res); } } if (common_segments < release.Length) { for (int i = common_segments; i < release.Length; i++) { if (release[i] != 0) { return(1); } } } if (common_segments < other.release.Length) { for (int i = common_segments; i < other.release.Length; i++) { if (other.release[i] != 0) { return(-1); } } } if (!ignore_pre) { if (is_plain_devrelease() && !other.is_plain_devrelease()) { return(-1); } if (!is_plain_devrelease() && other.is_plain_devrelease()) { return(1); } res = cmp((int)prerelease_type, (int)other.prerelease_type); if (res != 0) { return(res); } res = cmp(prerelease_version, other.prerelease_version); if (res != 0) { return(res); } } if (!ignore_post) { if (is_postrelease && !other.is_postrelease) { return(1); } if (!is_postrelease && other.is_postrelease) { return(-1); } res = cmp(postrelease_version, other.postrelease_version); if (res != 0) { return(res); } if (is_devrelease && !other.is_devrelease) { return(-1); } if (!is_devrelease && other.is_devrelease) { return(1); } res = cmp(devrelease_version, other.devrelease_version); if (res != 0) { return(res); } } if (!ignore_local) { if (is_localversion && !other.is_localversion) { return(1); } if (!is_localversion && other.is_localversion) { return(-1); } if (is_localversion) { common_segments = localversion_segments.Length < other.localversion_segments.Length ? localversion_segments.Length : other.localversion_segments.Length; for (int i = 0; i < common_segments; i++) { string this_str = localversion_segments[i] as string; if (this_str != null) { string other_str = other.localversion_segments[i] as string; if (other_str == null) { // any string < any int return(-1); } else { res = cmp(this_str, other_str); if (res != 0) { return(res); } } } else { int this_int = (int)localversion_segments[i]; string other_string = other.localversion_segments[i] as string; if (other_string != null) { // any int > any string return(1); } else { res = cmp(this_int, (int)other.localversion_segments[i]); if (res != 0) { return(res); } } } } res = cmp(localversion_segments.Length, other.localversion_segments.Length); } } return(res); }
private static IEnumerable <PythonPackage> FilterPackageVersions(Tuple <string, string> source, string search_name, string package_name, HashSet <string> nonhidden_versions, VersionIdentifier required, VersionIdentifier minimum, VersionIdentifier maximum, bool no_filter, Request request) { JObject detailed_info; try { detailed_info = GetDetailedPackageInfo(source, package_name, null, request); } catch (WebException) { /* Sometimes the search API lists things that 404 */ goto end; } bool list_all_versions = (no_filter || request.GetOptionValue("AllVersions") == "True"); var release_listing = detailed_info.GetValue("releases") as JObject; List <string> sorted_versions = new List <string>(); foreach (var release in release_listing) { sorted_versions.Add(release.Key); } sorted_versions.Sort(delegate(string a, string b) { // sort nonhidden versions first if (nonhidden_versions.Contains(a)) { if (!nonhidden_versions.Contains(b)) { return(-1); } } else if (!nonhidden_versions.Contains(a)) { if (nonhidden_versions.Contains(b)) { return(1); } } // sort non-prerelease versions first VersionIdentifier va = new VersionIdentifier(a); VersionIdentifier vb = new VersionIdentifier(b); if (va.IsPrerelease && !vb.IsPrerelease) { return(1); } if (!va.IsPrerelease && vb.IsPrerelease) { return(-1); } // newer versions first return(vb.Compare(va)); }); foreach (var version in sorted_versions) { VersionIdentifier candidate_version = new VersionIdentifier(version); var uris = release_listing[version] as JArray; if (uris == null || uris.Count == 0) { continue; } if (required != null && required.Compare(candidate_version) != 0) { continue; } if (minimum != null && minimum.Compare(candidate_version) > 0) { continue; } if (maximum != null && maximum.Compare(candidate_version) < 0) { continue; } PythonPackage package = new PythonPackage(package_name); package.version = new VersionIdentifier(version); package.summary = detailed_info["info"]["summary"].ToString(); package.source = source.Item1; package.sourceurl = source.Item2; package.search_key = search_name; package.downloads = ParseUrls(uris); package.incomplete_metadata = true; yield return(package); if (!list_all_versions) { break; } } end : do { } while (false); /* labels require a statement */ }
public static IEnumerable <PythonPackage> Search(string name, string requiredVersion, string minimumVersion, string maximumVersion, bool list_all_versions, Request request) { if (string.IsNullOrWhiteSpace(name) || name.ToLowerInvariant() == "python") { VersionIdentifier required = string.IsNullOrEmpty(requiredVersion) ? null : new VersionIdentifier(requiredVersion); VersionIdentifier minimum = string.IsNullOrEmpty(minimumVersion) ? null : new VersionIdentifier(minimumVersion); VersionIdentifier maximum = string.IsNullOrEmpty(maximumVersion) ? null : new VersionIdentifier(maximumVersion); string pythonVersionStr = request.GetOptionValue("PythonVersion"); VersionIdentifier pythonVersion = string.IsNullOrEmpty(pythonVersionStr) ? null : new VersionIdentifier(pythonVersionStr); Dictionary <string, VersionIdentifier> best_versions = new Dictionary <string, VersionIdentifier>(); Dictionary <string, JObject> best_releases = new Dictionary <string, JObject>(); int filter_version = -1; if (required != null) { filter_version = required.release[0]; } string version_query_string = filter_version == -1 ? "" : string.Format("&version={0}", filter_version); string url = string.Format("{0}/downloads/release/?limit=0{1}", api_url, version_query_string); JObject result = DoWebRequest(url, request); foreach (JObject release in result["objects"]) { string release_name = release["name"].ToString(); if (!release_name.StartsWith("Python ")) { continue; } var release_version = new VersionIdentifier(release_name.Substring(7)); if ((required == null || required.Compare(release_version) == 0) && (minimum == null || minimum.Compare(release_version) <= 0) && (maximum == null || maximum.Compare(release_version) >= 0) && (pythonVersion == null || pythonVersion.IsPrefix(release_version))) { if (list_all_versions) { yield return(FromReleaseRes(release, request)); } else { string major_version = release["version"].ToString(); VersionIdentifier current_best; if (!best_versions.TryGetValue(major_version, out current_best) || BetterVersion(current_best, release_version)) { best_versions[major_version] = release_version; best_releases[major_version] = release; } } } } if (!list_all_versions) { foreach (var release in best_releases) { yield return(FromReleaseRes(release.Value, request)); } } } }
private static IEnumerable <PythonPackage> ExactSearch(IEnumerable <string> names, string requiredVersion, string minimumVersion, string maximumVersion, bool no_filter, Request request) { VersionIdentifier required = null, minimum = null, maximum = null; if (!string.IsNullOrWhiteSpace(requiredVersion)) { required = new VersionIdentifier(requiredVersion); } if (!string.IsNullOrWhiteSpace(minimumVersion)) { minimum = new VersionIdentifier(minimumVersion); } if (!string.IsNullOrWhiteSpace(maximumVersion)) { maximum = new VersionIdentifier(maximumVersion); } foreach (var source in GetSources(request)) { foreach (string exact_name in names) { JObject detailed_info; try { detailed_info = GetDetailedPackageInfo(source, exact_name, null, request); } catch (WebException) { continue; } string package_name = detailed_info["info"]["name"].ToString(); if (!package_name.Equals(exact_name, StringComparison.InvariantCultureIgnoreCase)) { request.Debug("Python::ExactSearch got package named {0} but we're looking for {1}", package_name, exact_name); } MemoryStream call_ms = new MemoryStream(); XmlWriter writer = XmlWriter.Create(call_ms); writer.WriteStartElement("methodCall"); writer.WriteElementString("methodName", "package_releases"); writer.WriteStartElement("params"); writer.WriteStartElement("param"); //package_name writer.WriteStartElement("value"); writer.WriteElementString("string", package_name); writer.WriteEndElement(); //value writer.WriteEndElement(); //param writer.WriteEndElement(); //params writer.WriteEndElement(); //methodCall writer.Close(); byte[] call = call_ms.ToArray(); using (var response = DoWebRequest(source, call, request)) { request.Debug("Python::ExactSearch asking {0} about {1}", source.Item1, package_name); var search_response = ParseResponse(response.GetResponseStream(), request) as List <object>; if (search_response == null || search_response.Count == 0) { //FIXME: Check for non-hidden versions if this fails? continue; } HashSet <string> versions = new HashSet <string>(); foreach (var version in search_response) { versions.Add((string)version); } foreach (var package in FilterPackageVersions(source, package_name, package_name, versions, required, minimum, maximum, no_filter, request)) { yield return(package); } } } } }