/// <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)); }
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); }
public bool IsInstalled(PackageIdentity pkg) => LocalPackagesFinder.Exists(pkg, Logger, CancellationToken.None);