Example #1
0
        //  This code trims the metadata tree to just include packages that fit within an allowed-version specification.
        //  Packages outside of the range are removed from the tree. That removal should filter up the tree which is what the second
        //  pass is intended to achieve. This notion of allowed versions can trivially be extended for example to include
        //  for example multiple version ranges. (In fact this code could probably be parameterized with an actual trim lambda.)

        public static void TrimByAllowedVersions(RegistrationInfo registrationInfo, IDictionary<string, VersionRange> allowedVersions)
        {
            foreach (KeyValuePair<string, VersionRange> allowedVersion in allowedVersions)
            {
                Execute(registrationInfo, allowedVersion);
            }
        }
        public static async Task<RegistrationInfo> GetTree(HttpClient httpClient, RegistrationInfo registrationInfo, NuGetFramework projectFramework, ConcurrentDictionary<Uri, JObject> sessionCache, Func<IDictionary<NuGetVersion, HashSet<string>>, IDictionary<NuGetVersion, HashSet<string>>> filter = null)
        {
            //ApplyFilter(registrationInfo, filter);

            await InlineDependencies(httpClient, registrationInfo, projectFramework, sessionCache, filter);

            return registrationInfo;
        }
Example #3
0
        /// <summary>
        /// Retrieve a registration blob
        /// </summary>
        /// <returns>Returns Null if the package does not exist</returns>
        public static async Task <RegistrationInfo> GetRegistrationInfo(
            HttpSource httpClient,
            Uri registrationUri,
            VersionRange range,
            NuGetFramework projectTargetFramework,
            ILogger log,
            CancellationToken token)
        {
            var frameworkComparer = new NuGetFrameworkFullComparer();
            var frameworkReducer  = new FrameworkReducer();
            var dependencies      = await GetDependencies(httpClient, registrationUri, range, log, token);

            var result           = new HashSet <RegistrationInfo>();
            var registrationInfo = new RegistrationInfo();

            registrationInfo.IncludePrerelease = true;
            foreach (var item in dependencies)
            {
                var packageInfo = new PackageInfo
                {
                    Listed         = item.Listed,
                    Version        = item.Identity.Version,
                    PackageContent = new Uri(item.ContentUri)
                };

                // only one target framework group will be used at install time, which means
                // we can filter down to that group now by using the project target framework
                var depFrameworks   = item.DependencyGroups.Select(e => e.TargetFramework);
                var targetFramework = frameworkReducer.GetNearest(projectTargetFramework, depFrameworks);

                // If no frameworks are compatible we just ignore them - Should this be an exception?
                if (targetFramework != null)
                {
                    var dependencyGroup = item.DependencyGroups.FirstOrDefault(d => frameworkComparer.Equals(targetFramework, d.TargetFramework));
                    if (dependencyGroup != null)
                    {
                        foreach (var dependency in dependencyGroup.Packages)
                        {
                            var dependencyInfo = new DependencyInfo
                            {
                                Id    = dependency.Id,
                                Range = dependency.VersionRange
                            };

                            packageInfo.Dependencies.Add(dependencyInfo);
                        }
                    }
                }

                registrationInfo.Add(packageInfo);
                registrationInfo.Id = item.Identity.Id;
            }

            return(registrationInfo);
        }
Example #4
0
        static void Execute(RegistrationInfo registrationInfo, KeyValuePair<string, VersionRange> allowedVersion)
        {
            Pass1(registrationInfo, allowedVersion);

            bool updated = true;
            while (updated)
            {
                updated = false;
                Pass2(registrationInfo, ref updated);
            }
        }
Example #5
0
        private static void Execute(RegistrationInfo registrationInfo, KeyValuePair <string, VersionRange> allowedVersion)
        {
            Pass1(registrationInfo, allowedVersion);

            var updated = true;

            while (updated)
            {
                updated = false;
                Pass2(registrationInfo, ref updated);
            }
        }
        private static async Task InlineDependencies(HttpClient httpClient, RegistrationInfo registrationInfo, NuGetFramework projectFramework, ConcurrentDictionary <Uri, JObject> sessionCache, Func <IDictionary <NuGetVersion, HashSet <string> >, IDictionary <NuGetVersion, HashSet <string> > > filter)
        {
            foreach (PackageInfo packageInfo in registrationInfo.Packages)
            {
                foreach (DependencyInfo dependencyInfo in packageInfo.Dependencies)
                {
                    dependencyInfo.RegistrationInfo = await GetRegistrationInfo(httpClient, dependencyInfo.RegistrationUri, dependencyInfo.Range, projectFramework, sessionCache);

                    //ApplyFilter(dependencyInfo.RegistrationInfo, filter);

                    await InlineDependencies(httpClient, dependencyInfo.RegistrationInfo, projectFramework, sessionCache, filter);
                }
            }
        }
        private static async Task InlineDependencies(HttpClient httpClient, RegistrationInfo registrationInfo, NuGetFramework projectFramework, ConcurrentDictionary<Uri, JObject> sessionCache, Func<IDictionary<NuGetVersion, HashSet<string>>, IDictionary<NuGetVersion, HashSet<string>>> filter)
        {
            foreach (PackageInfo packageInfo in registrationInfo.Packages)
            {
                foreach (DependencyInfo dependencyInfo in packageInfo.Dependencies)
                {
                    dependencyInfo.RegistrationInfo = await GetRegistrationInfo(httpClient, dependencyInfo.RegistrationUri, dependencyInfo.Range, projectFramework, sessionCache);

                    //ApplyFilter(dependencyInfo.RegistrationInfo, filter);

                    await InlineDependencies(httpClient, dependencyInfo.RegistrationInfo, projectFramework, sessionCache, filter);
                }
            }
        }
Example #8
0
        private static void Pass1(RegistrationInfo registrationInfo, KeyValuePair <string, VersionRange> allowedVersion)
        {
            if (registrationInfo.Id == allowedVersion.Key)
            {
                IList <PackageInfo> packagesToRemove = registrationInfo.Packages.Where(p => !allowedVersion.Value.Satisfies(p.Version)).ToList();

                foreach (var packageToRemove in packagesToRemove)
                {
                    registrationInfo.Packages.Remove(packageToRemove);
                }
            }

            foreach (var child in registrationInfo.Packages)
            {
                Pass1(child, registrationInfo.Id, allowedVersion);
            }
        }
Example #9
0
        static void Pass1(RegistrationInfo registrationInfo, KeyValuePair<string, VersionRange> allowedVersion)
        {
            if (registrationInfo.Id == allowedVersion.Key)
            {
                IList<PackageInfo> packagesToRemove = registrationInfo.Packages.Where(p => !allowedVersion.Value.Satisfies(p.Version)).ToList();

                foreach (PackageInfo packageToRemove in packagesToRemove)
                {
                    registrationInfo.Packages.Remove(packageToRemove);
                }
            }

            foreach (PackageInfo child in registrationInfo.Packages)
            {
                Pass1(child, registrationInfo.Id, allowedVersion);
            }
        }
Example #10
0
        private static void Pass2(RegistrationInfo registrationInfo, ref bool updated)
        {
            IList <PackageInfo> packagesToRemove = new List <PackageInfo>();

            foreach (var package in registrationInfo.Packages)
            {
                if (!CheckDependenciesExists(package))
                {
                    packagesToRemove.Add(package);
                }
            }

            foreach (var packageToRemove in packagesToRemove)
            {
                registrationInfo.Packages.Remove(packageToRemove);
                updated = true;
            }

            foreach (var child in registrationInfo.Packages)
            {
                Pass2(child, registrationInfo.Id, ref updated);
            }
        }
Example #11
0
        static void Pass2(RegistrationInfo registrationInfo, ref bool updated)
        {
            IList<PackageInfo> packagesToRemove = new List<PackageInfo>();

            foreach (PackageInfo package in registrationInfo.Packages)
            {
                if (!CheckDependenciesExists(package))
                {
                    packagesToRemove.Add(package);
                }
            }

            foreach (PackageInfo packageToRemove in packagesToRemove)
            {
                registrationInfo.Packages.Remove(packageToRemove);
                updated = true;
            }

            foreach (PackageInfo child in registrationInfo.Packages)
            {
                Pass2(child, registrationInfo.Id, ref updated);
            }
        }
        /// <summary>
        /// Walk the RegistrationInfo tree to find all package instances and their dependencies.
        /// </summary>
        private static IEnumerable<PackageDependencyInfo> GetPackagesFromRegistration(RegistrationInfo registration, CancellationToken token)
        {
            foreach (var pkgInfo in registration.Packages)
            {
                var dependencies = pkgInfo.Dependencies.Select(e => new PackageDependency(e.Id, e.Range));
                yield return new PackageDependencyInfo(registration.Id, pkgInfo.Version, dependencies);

                foreach (var dep in pkgInfo.Dependencies)
                {
                    foreach (var depPkg in GetPackagesFromRegistration(dep.RegistrationInfo, token))
                    {
                        // check if we have been cancelled
                        token.ThrowIfCancellationRequested();

                        yield return depPkg;
                    }
                }
            }

            yield break;
        }
        public static async Task <RegistrationInfo> GetRegistrationInfo(HttpClient httpClient, Uri registrationUri, VersionRange range, NuGetFramework projectTargetFramework, ConcurrentDictionary <Uri, JObject> sessionCache = null)
        {
            NuGetFrameworkFullComparer frameworkComparer = new NuGetFrameworkFullComparer();
            FrameworkReducer           frameworkReducer  = new FrameworkReducer();
            JObject index = await LoadResource(httpClient, registrationUri, sessionCache);

            if (index == null)
            {
                throw new ArgumentException(registrationUri.AbsoluteUri);
            }

            VersionRange preFilterRange = Utils.SetIncludePrerelease(range, true);

            IList <Task <JObject> > rangeTasks = new List <Task <JObject> >();

            foreach (JObject item in index["items"])
            {
                NuGetVersion lower = NuGetVersion.Parse(item["lower"].ToString());
                NuGetVersion upper = NuGetVersion.Parse(item["upper"].ToString());

                if (ResolverMetadataClientUtility.IsItemRangeRequired(preFilterRange, lower, upper))
                {
                    JToken items;
                    if (!item.TryGetValue("items", out items))
                    {
                        Uri rangeUri = item["@id"].ToObject <Uri>();

                        rangeTasks.Add(LoadResource(httpClient, rangeUri, sessionCache));
                    }
                    else
                    {
                        rangeTasks.Add(Task.FromResult(item));
                    }
                }
            }

            await Task.WhenAll(rangeTasks.ToArray());

            RegistrationInfo registrationInfo = new RegistrationInfo();

            registrationInfo.IncludePrerelease = range.IncludePrerelease;

            string id = string.Empty;

            foreach (JObject rangeObj in rangeTasks.Select((t) => t.Result))
            {
                if (rangeObj == null)
                {
                    throw new InvalidDataException(registrationUri.AbsoluteUri);
                }

                foreach (JObject packageObj in rangeObj["items"])
                {
                    JObject catalogEntry = (JObject)packageObj["catalogEntry"];

                    NuGetVersion packageVersion = NuGetVersion.Parse(catalogEntry["version"].ToString());

                    id = catalogEntry["id"].ToString();

                    int    publishedDate = 0;
                    JToken publishedValue;

                    if (catalogEntry.TryGetValue("published", out publishedValue))
                    {
                        publishedDate = int.Parse(publishedValue.ToObject <DateTime>().ToString("yyyyMMdd"));
                    }

                    //publishedDate = 0 means the property doesn't exist in index.json
                    //publishedDate = 19000101 means the property exists but the package is unlisted
                    if (range.Satisfies(packageVersion) && (publishedDate != 19000101))
                    {
                        PackageInfo packageInfo = new PackageInfo();
                        packageInfo.Version        = packageVersion;
                        packageInfo.PackageContent = new Uri(packageObj["packageContent"].ToString());

                        JArray dependencyGroupsArray = (JArray)catalogEntry["dependencyGroups"];

                        if (dependencyGroupsArray != null)
                        {
                            // only one target framework group will be used at install time, which means
                            // we can filter down to that group now by using the project target framework
                            var depFrameworks = dependencyGroupsArray.Select(e => GetFramework(e as JObject));

                            var targetFramework = frameworkReducer.GetNearest(projectTargetFramework, depFrameworks);

                            // If no frameworks are compatible we just ignore them - Should this be an exception?
                            if (targetFramework != null)
                            {
                                foreach (JObject dependencyGroupObj in dependencyGroupsArray)
                                {
                                    NuGetFramework currentFramework = GetFramework(dependencyGroupObj);

                                    if (frameworkComparer.Equals(currentFramework, targetFramework))
                                    {
                                        foreach (JObject dependencyObj in dependencyGroupObj["dependencies"])
                                        {
                                            DependencyInfo dependencyInfo = new DependencyInfo();
                                            dependencyInfo.Id              = dependencyObj["id"].ToString();
                                            dependencyInfo.Range           = Utils.CreateVersionRange((string)dependencyObj["range"], range.IncludePrerelease);
                                            dependencyInfo.RegistrationUri = dependencyObj["registration"].ToObject <Uri>();

                                            packageInfo.Dependencies.Add(dependencyInfo);
                                        }
                                    }
                                }
                            }
                        }

                        registrationInfo.Add(packageInfo);
                    }
                }

                registrationInfo.Id = id;
            }

            return(registrationInfo);
        }
        public static async Task<RegistrationInfo> GetRegistrationInfo(HttpClient httpClient, Uri registrationUri, VersionRange range, NuGetFramework projectTargetFramework, ConcurrentDictionary<Uri, JObject> sessionCache = null)
        {
            NuGetFrameworkFullComparer frameworkComparer = new NuGetFrameworkFullComparer();
            FrameworkReducer frameworkReducer = new FrameworkReducer();
            JObject index = await LoadResource(httpClient, registrationUri, sessionCache);

            if (index == null)
            {
                throw new ArgumentException(registrationUri.AbsoluteUri);
            }

            VersionRange preFilterRange = Utils.SetIncludePrerelease(range, true);

            IList<Task<JObject>> rangeTasks = new List<Task<JObject>>();

            foreach (JObject item in index["items"])
            {
                NuGetVersion lower = NuGetVersion.Parse(item["lower"].ToString());
                NuGetVersion upper = NuGetVersion.Parse(item["upper"].ToString());

                if (ResolverMetadataClientUtility.IsItemRangeRequired(preFilterRange, lower, upper))
                {
                    JToken items;
                    if (!item.TryGetValue("items", out items))
                    {
                        Uri rangeUri = item["@id"].ToObject<Uri>();

                        rangeTasks.Add(LoadResource(httpClient, rangeUri, sessionCache));
                    }
                    else
                    {
                        rangeTasks.Add(Task.FromResult(item));
                    }
                }
            }

            await Task.WhenAll(rangeTasks.ToArray());

            RegistrationInfo registrationInfo = new RegistrationInfo();

            registrationInfo.IncludePrerelease = range.IncludePrerelease;

            string id = string.Empty;

            foreach (JObject rangeObj in rangeTasks.Select((t) => t.Result))
            {
                if (rangeObj == null)
                {
                    throw new InvalidDataException(registrationUri.AbsoluteUri);
                }

                foreach (JObject packageObj in rangeObj["items"])
                {
                    JObject catalogEntry = (JObject)packageObj["catalogEntry"];

                    NuGetVersion packageVersion = NuGetVersion.Parse(catalogEntry["version"].ToString());

                    id = catalogEntry["id"].ToString();

                    int publishedDate = 0;
                    JToken publishedValue;

                    if (catalogEntry.TryGetValue("published", out publishedValue))
                    {
                        publishedDate = int.Parse(publishedValue.ToObject<DateTime>().ToString("yyyyMMdd"));
                    }

                    //publishedDate = 0 means the property doesn't exist in index.json
                    //publishedDate = 19000101 means the property exists but the package is unlisted
                    if (range.Satisfies(packageVersion) && (publishedDate!= 19000101))
                    {
                        PackageInfo packageInfo = new PackageInfo();
                        packageInfo.Version = packageVersion;
                        packageInfo.PackageContent = new Uri(packageObj["packageContent"].ToString());

                        JArray dependencyGroupsArray = (JArray)catalogEntry["dependencyGroups"];

                        if (dependencyGroupsArray != null)
                        {
                            // only one target framework group will be used at install time, which means 
                            // we can filter down to that group now by using the project target framework
                            var depFrameworks = dependencyGroupsArray.Select(e => GetFramework(e as JObject));

                            var targetFramework = frameworkReducer.GetNearest(projectTargetFramework, depFrameworks);

                            // If no frameworks are compatible we just ignore them - Should this be an exception?
                            if (targetFramework != null)
                            {
                                foreach (JObject dependencyGroupObj in dependencyGroupsArray)
                                {
                                    NuGetFramework currentFramework = GetFramework(dependencyGroupObj);

                                    if (frameworkComparer.Equals(currentFramework, targetFramework))
                                    {
                                        foreach (JObject dependencyObj in dependencyGroupObj["dependencies"])
                                        {
                                            DependencyInfo dependencyInfo = new DependencyInfo();
                                            dependencyInfo.Id = dependencyObj["id"].ToString();
                                            dependencyInfo.Range = Utils.CreateVersionRange((string)dependencyObj["range"], range.IncludePrerelease);
                                            dependencyInfo.RegistrationUri = dependencyObj["registration"].ToObject<Uri>();

                                            packageInfo.Dependencies.Add(dependencyInfo);
                                        }
                                    }
                                }
                            }
                        }

                        registrationInfo.Add(packageInfo);
                    }
                }

                registrationInfo.Id = id;
            }

            return registrationInfo;
        }
        /// <summary>
        /// Retrieve dependency info from a registration blob
        /// </summary>
        private IEnumerable<SourcePackageDependencyInfo> GetPackagesFromRegistration(RegistrationInfo registration, CancellationToken token)
        {
            foreach (var pkgInfo in registration.Packages)
            {
                var dependencies = pkgInfo.Dependencies.Select(dep => new PackageDependency(dep.Id, dep.Range));
                yield return new SourcePackageDependencyInfo(registration.Id, pkgInfo.Version, dependencies, pkgInfo.Listed, _source);
            }

            yield break;
        }
Example #16
0
        /// <summary>
        /// Retrieve a registration blob
        /// </summary>
        /// <returns>Returns Null if the package does not exist</returns>
        public static async Task<RegistrationInfo> GetRegistrationInfo(
            HttpClient httpClient,
            Uri registrationUri,
            VersionRange range,
            NuGetFramework projectTargetFramework,
            CancellationToken token)
        {
            var frameworkComparer = new NuGetFrameworkFullComparer();
            var frameworkReducer = new FrameworkReducer();
            var dependencies = await GetDependencies(httpClient, registrationUri, range, token);
            
            var registrationInfo = new RegistrationInfo();

            registrationInfo.IncludePrerelease = range.IncludePrerelease;
            foreach (var item in dependencies)
            {
                var packageInfo = new PackageInfo
                    {
                        Listed = item.Listed,
                        Version = item.Identity.Version,
                        PackageContent = new Uri(item.ContentUri)
                    };

                // only one target framework group will be used at install time, which means 
                // we can filter down to that group now by using the project target framework
                var depFrameworks = item.DependencyGroups.Select(e => e.TargetFramework);
                var targetFramework = frameworkReducer.GetNearest(projectTargetFramework, depFrameworks);

                // If no frameworks are compatible we just ignore them - Should this be an exception?
                if (targetFramework != null)
                {
                    var dependencyGroup = item.DependencyGroups.FirstOrDefault(d => frameworkComparer.Equals(targetFramework, d.TargetFramework));
                    if (dependencyGroup != null)
                    {
                        foreach (var dependency in dependencyGroup.Packages)
                        {
                            var dependencyInfo = new DependencyInfo
                                {
                                    Id = dependency.Id,
                                    Range = dependency.VersionRange
                                };

                            packageInfo.Dependencies.Add(dependencyInfo);
                        }
                    }
                }

                registrationInfo.Add(packageInfo);
                registrationInfo.Id = item.Identity.Id;
            }

            return registrationInfo;
        }