Example #1
0
        private PackageWrapper EnsurePackageDependencies(IPackage nuGetPackage)
        {
            List <PackageDependencySet> dependencySets = new List <PackageDependencySet>();

            foreach (PackageDependencySet dependencySet in nuGetPackage.DependencySets)
            {
                dependencySets.Add(new PackageDependencySet(dependencySet.TargetFramework, dependencySet.Dependencies.Where(dependency => !_apiPackageRegistry.IsRegistered(dependency.Id))));
            }

            return(new PackageWrapper(nuGetPackage, dependencySets));
        }
Example #2
0
        private async Task <Resolver.PackageResolverContext> ResolveDependenciesAsync(PackageIdentity identity, NuGetFramework targetFramework, IEqualityComparer <PackageIdentity> equalityComparer,
                                                                                      DependencyInfoResourceCollection dependencyInfoResource, SourceCacheContext cacheContext, IExtensibleProject project, bool ignoreMissingPackages = false, CancellationToken cancellationToken = default)
        {
            // The collection of already processed packages
            var packageStore      = new HashSet <SourcePackageDependencyInfo>(equalityComparer);
            var ignoredPackages   = new HashSet <PackageIdentity>();
            var downloadStack     = new Stack <SourcePackageDependencyInfo>();
            var resolvingBehavior = DependencyBehavior.Lowest;

            // get top dependency
            var dependencyInfo = await dependencyInfoResource.ResolvePackageAsync(
                identity, targetFramework, cacheContext, _nugetLogger, cancellationToken);

            if (dependencyInfo is null)
            {
                _nugetLogger.LogError($"Cannot resolve {identity} package for target framework {targetFramework}");
                return(Resolver.PackageResolverContext.Empty);
            }

            downloadStack.Push(dependencyInfo); //and add it to package store

            while (downloadStack.Count > 0)
            {
                var nextPackage = downloadStack.Pop();

                if (packageStore.Contains(nextPackage))
                {
                    continue;
                }
                else
                {
                    packageStore.Add(nextPackage);
                }

                foreach (var dependency in nextPackage.Dependencies)
                {
                    // currently we use specific version during child dependency resolving
                    // but possibly it should be configured in project
                    var dependencyIdentity = new PackageIdentity(dependency.Id, dependency.VersionRange.MinVersion);

                    var isPackageRequiresOwnDependencies = !_apiPackageRegistry.IsRegistered(dependencyIdentity.Id);
                    if (isPackageRequiresOwnDependencies)
                    {
                        // We can't determine the unknown version yet from range, but can exclude min required if it was already processed
                        if (packageStore.Contains(dependencyIdentity))
                        {
                            continue;
                        }

                        var relatedDepInfos = await dependencyInfoResource.ResolvePackagesWithVersionSatisfyRangeAsync(dependencyIdentity, dependency.VersionRange, targetFramework, cacheContext, _nugetLogger, cancellationToken);

                        foreach (var relatedDepedencyInfoResource in relatedDepInfos)
                        {
                            downloadStack.Push(relatedDepedencyInfoResource);
                        }

                        if (relatedDepInfos.Any())
                        {
                            // we found compatible (at least with target framework) packages and leave decision to Package Resolver in the future
                            continue;
                        }
                    }

                    // Determine behavior if package cannot be resolved in any way
                    if (ignoreMissingPackages)
                    {
                        if (_apiPackageRegistry.IsRegistered(dependencyIdentity.Id))
                        {
                            resolvingBehavior = DependencyBehavior.Lowest;

                            if (!packageStore.Contains(dependencyIdentity))
                            {
                                packageStore.Add(new SourcePackageDependencyInfo(dependencyIdentity.Id, dependencyIdentity.Version, Enumerable.Empty <PackageDependency>(), false, null));
                            }

                            if (ignoredPackages.Add(dependencyIdentity))
                            {
                                // Show only for top package, not much effort to see this message multiple times
                                if (nextPackage == dependencyInfo)
                                {
                                    await _nugetLogger.LogAsync(LogLevel.Information, $"The package dependency {dependencyIdentity.Id} listed as part of API and can be safely skipped");
                                }
                            }
                        }
                        else
                        {
                            resolvingBehavior = DependencyBehavior.Ignore;
                            await _nugetLogger.LogAsync(LogLevel.Warning, $"Available sources doesn't contain package {dependencyIdentity}. Package {dependencyIdentity} is missing");
                        }
                    }
                    else
                    {
                        throw new MissingPackageException($"Cannot find package {dependencyIdentity}");
                    }
                }
            }


            // Pass packages.config to resolver
            var nugetPackagesConfigProject = _nuGetProjectConfigurationProvider.GetProjectConfig(project);
            var packagesConfigReferences   = await nugetPackagesConfigProject.GetInstalledPackagesAsync(cancellationToken);

            // Construct context for package resolver
            return(GetResolverContext(identity, resolvingBehavior, packageStore, packagesConfigReferences, ignoredPackages));
        }