Beispiel #1
0
        /// <summary>
        /// Find the list of netstandard Assemblies (if any) for the given package.
        /// Certain System and .NET packages are ignored as the assemblies of these should
        /// be automatically included without package references.
        /// </summary>
        public IEnumerable <AssemblyInfo> GetAssemblies(PackageIdentity pkg)
        {
            // Ignore all SDK packages:
            if (pkg == null || IsSystemPackage(pkg))
            {
                return(Enumerable.Empty <AssemblyInfo>());
            }

            var pkgInfo       = LocalPackagesFinder.GetPackage(pkg, Logger, CancellationToken.None);
            var packageReader = pkgInfo?.GetReader();
            var libs          = packageReader?.GetLibItems();

            // If package contains no dlls:
            if (libs == null)
            {
                Logger.LogWarning($"Could not find any dll for {pkg}");
                return(Enumerable.Empty <AssemblyInfo>());
            }

            var root = Path.GetDirectoryName(pkgInfo.Path);

            string[] CheckOnFramework(NuGetFramework framework)
            {
                var frameworkReducer = new FrameworkReducer();
                var nearest          = frameworkReducer.GetNearest(framework, libs.Select(x => x.TargetFramework));

                if (nearest == null)
                {
                    return(new string[0]);
                }

                var files = libs
                            .Where(x => x.TargetFramework.Equals(nearest))
                            .SelectMany(x => x.Items)
                            .Where(n => n.EndsWith(".dll"))
                            .Select(p => Path.Combine(root, p));

                return(files.ToArray());
            }

            var names = CheckOnFramework(NETCOREAPP2_1);

            Assembly LoadAssembly(string path)
            {
                try
                {
                    return(Assembly.LoadFile(path));
                }
                catch (Exception e)
                {
                    Logger.LogWarning($"Unable to load assembly '{path}' ({e.Message})");
                    return(null);
                }
            }

            return(names
                   .Select(LoadAssembly)
                   .Select(AssemblyInfo.Create)
                   .Where(a => a != null));
        }
Beispiel #2
0
        public IEnumerable <SourcePackageDependencyInfo> ResolveDependencyGraph(PackageIdentity pkgId)
        {
            // We used PackageResolver to flatten the dependency graph. This is the process Nuget uses
            // when adding a package to a project. It takes:
            // - a list of targets, in this case the package we want to add
            // - a list of packages already installed, (i.e. the package that used to be defined in the packages.config)
            //      * in our case, the packages already added to this service
            // - a list of available packages (i.e. the list of packages in the nuget sources).
            //      * in our case, all the dependencies we already found via GetPackageDependencies
            // The resolver will then filter out the list such that only one version of each package
            //  gets installed.
            var resolverContext = new PackageResolverContext(
                dependencyBehavior: DependencyBehavior.Lowest,
                targetIds: new[] { pkgId.Id },
                requiredPackageIds: Enumerable.Empty <string>(),
                packagesConfig: Items.Select(p => new PackageReference(p, NETCOREAPP3_1, true)),
                preferredVersions: Enumerable.Empty <PackageIdentity>(),
                availablePackages: AvailablePackages,
                packageSources: Repositories.Select(s => s.PackageSource),
                log: Logger);

            var resolver = new PackageResolver();

            try
            {
                return(resolver.Resolve(resolverContext, CancellationToken.None)
                       .Select(p => AvailablePackages.Single(x => PackageIdentityComparer.Default.Equals(x, p))));
            }
            catch (NuGetResolverConstraintException exception)
            {
                Logger.LogWarning($"Exception caught when resolving package dependencies: {exception.Message}");
            }

            /*
             *  First we try using the NuGet PackageResolver to resolve all package dependencies.
             *  It's main purpose is to find which version of each package that needs to be loaded
             *  that satisfies all dependencies.
             *  But it may fail trying to find the perfect solution because some deeper package
             *  dependency might not be available, even though that dependency might never be
             *  needed in runtime.
             *  So we are opting to try to load our target package and all the available
             *  dependencies that could be found using the latest versions that are available in
             *  the local folders.
             */
            var uniquePackageIds        = AvailablePackages.Select(pkg => pkg.Id).Distinct();
            var uniqueAvailablePackages = uniquePackageIds.SelectMany(
                pkgId =>
                LocalPackagesFinder.FindPackagesById(pkgId, Logger, CancellationToken.None)
                .OrderByDescending(pkg => pkg.Identity.Version)
                .Take(1)
                .Select(
                    pkg => new SourcePackageDependencyInfo(
                        id: pkg.Identity.Id,
                        version: pkg.Identity.Version,
                        dependencies: AvailablePackages
                        .Where(d => d.Id == pkg.Identity.Id)
                        .OrderByDescending(d => d.Version.Version)
                        .FirstOrDefault()
                        ?.Dependencies ?? new List <PackageDependency>(),
                        listed: true,
                        source: GlobalPackagesSource))
                );

            return(uniqueAvailablePackages);
        }
Beispiel #3
0
 public bool IsInstalled(PackageIdentity pkg) => LocalPackagesFinder.Exists(pkg, Logger, CancellationToken.None);