예제 #1
0
 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);
 }
예제 #2
0
        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]);
            }
        }
예제 #3
0
        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));
        }
예제 #5
0
 public bool MatchesVersion(VersionIdentifier version)
 {
     foreach (var clause in clauses)
     {
         if (!clause.MatchesVersion(version))
         {
             return(false);
         }
     }
     return(true);
 }
예제 #6
0
 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);
        }
예제 #8
0
 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());
 }
예제 #10
0
        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);
                    }
                }
            }
        }
예제 #11
0
 public int Compare(VersionIdentifier other)
 {
     return(Compare(other, false, false, false));
 }
예제 #12
0
        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);
                        }
                    }
                }
            }
        }
예제 #13
0
        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);
            }
        }
예제 #14
0
        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);
        }
예제 #15
0
        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 */
        }
예제 #16
0
        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));
                    }
                }
            }
        }
예제 #17
0
        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);
                        }
                    }
                }
            }
        }