public bool TryGetAssembly(string name, NuGetFramework targetFramework, out string path, out Version version) { path = null; version = null; var information = _cache.GetOrAdd(targetFramework, GetFrameworkInformation); if (information == null || !information.Exists) { return false; } lock (information.Assemblies) { AssemblyEntry entry; if (information.Assemblies.TryGetValue(name, out entry)) { if (string.IsNullOrEmpty(entry.Path)) { entry.Path = GetAssemblyPath(information.SearchPaths, name); } if (!string.IsNullOrEmpty(entry.Path) && entry.Version == null) { // This code path should only run on mono entry.Version = VersionUtility.GetAssemblyVersion(entry.Path).Version; } path = entry.Path; version = entry.Version; } } return !string.IsNullOrEmpty(path); }
public Library GetLibrary(LibraryRange libraryRange, NuGetFramework targetFramework) { var key = Tuple.Create(targetFramework, libraryRange.Name); LockFileTargetLibrary library = null; // Determine if we have a library for this target if (_targetLibraries.TryGetValue(key, out library) && libraryRange.VersionRange.IsBetter(current: null, considering: library.Version)) { var dependencies = GetDependencies(library, targetFramework); var description = new Library { LibraryRange = libraryRange, Identity = new LibraryIdentity { Name = library.Name, Version = library.Version, Type = LibraryTypes.Package }, Resolved = true, Dependencies = dependencies, [KnownLibraryProperties.LockFileLibrary] = _libraries[Tuple.Create(library.Name, library.Version)], [KnownLibraryProperties.LockFileTargetLibrary] = library }; return description; } return null; }
public static CommandSpec TryResolveCommandSpec(string commandName, string args, NuGetFramework framework = null) { return ResolveFromRootedCommand(commandName, args) ?? ResolveFromProjectDependencies(commandName, args, framework) ?? ResolveFromProjectTools(commandName, args) ?? ResolveFromPath(commandName, args); }
public Library GetLibrary(LibraryRange libraryRange, NuGetFramework targetFramework) { var package = FindCandidate(libraryRange.Name, libraryRange.VersionRange); if (package != null) { NuspecReader nuspecReader = null; using (var stream = File.OpenRead(package.ManifestPath)) { nuspecReader = new NuspecReader(stream); } var description = new Library { LibraryRange = libraryRange, Identity = new LibraryIdentity { Name = package.Id, Version = package.Version, Type = LibraryTypes.Package }, Path = package.ManifestPath, Dependencies = GetDependencies(nuspecReader, targetFramework) }; description.Items["package"] = package; description.Items["metadata"] = nuspecReader; return description; } return null; }
/// <summary> /// Retrieve dependency info for a single package. /// </summary> /// <param name="package">package id and version</param> /// <param name="projectFramework">project target framework. This is used for finding the dependency group</param> /// <param name="token">cancellation token</param> /// <returns> /// Returns dependency info for the given package if it exists. If the package is not found null is /// returned. /// </returns> public override async Task<SourcePackageDependencyInfo> ResolvePackage(PackageIdentity package, NuGetFramework projectFramework, CancellationToken token) { try { SourcePackageDependencyInfo result = null; // Construct the registration index url var uri = _regResource.GetUri(package.Id); // Retrieve the registration blob var singleVersion = new VersionRange(minVersion: package.Version, includeMinVersion: true, maxVersion: package.Version, includeMaxVersion: true); var regInfo = await ResolverMetadataClient.GetRegistrationInfo(_client, uri, singleVersion, projectFramework, token); // regInfo is null if the server returns a 404 for the package to indicate that it does not exist if (regInfo != null) { // Parse package and dependeny info from the blob result = GetPackagesFromRegistration(regInfo, token).FirstOrDefault(); } return result; } catch (Exception ex) { // Wrap exceptions coming from the server with a user friendly message var error = String.Format(CultureInfo.CurrentUICulture, Strings.Protocol_PackageMetadataError, package, _source); throw new NuGetProtocolException(error, ex); } }
/// <summary> /// Gives the smallest set of frameworks from the table that cover everything the given framework would cover. /// </summary> public IEnumerable<NuGetFramework> GetNearest(NuGetFramework framework) { // start with everything compatible with the framework var allCompatible = _table.Keys.Where(f => _compat.IsCompatible(framework, f)); return _reducer.ReduceUpwards(allCompatible); }
public LibraryExporter( NuGetFramework targetFramework, PackagePathResolver packagePathResolver) { _targetFramework = targetFramework; _packagePathResolver = packagePathResolver; }
public static ICommand Create( string project, string configuration, NuGetFramework framework, string buildBasePath, string output) { var args = new List<string>() { project, "--configuration", configuration, "--framework", framework.GetShortFolderName() }; if (buildBasePath != null) { args.Add("--build-base-path"); args.Add(buildBasePath); } if (output != null) { args.Add("--output"); args.Add(output); } return Command.CreateDotNet( "build", args, framework, configuration); }
public void Generations_MatchesInbox() { FrameworkSet fxs = FrameworkSet.Load("FrameworkLists"); Version maxVersion = new Version(int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue); foreach (var fxGroup in fxs.Frameworks) { foreach (var fx in fxGroup.Value) { var thisFx = new NuGetFramework(fx.FrameworkName.Identifier, fx.FrameworkName.Version); var fxGeneration = Generations.DetermineGenerationForFramework(thisFx, false); foreach (var assembly in fx.Assemblies.Where(a => !s_classicAssemblies.Contains(a.Key) && a.Value != maxVersion)) { _log.Reset(); Version assmGeneration = _generations.DetermineGenerationFromSeeds(assembly.Key, assembly.Value, _log); Version effectiveFxGeneration; if (!s_generationException.TryGetValue(Tuple.Create(fx.FrameworkName, assembly.Key), out effectiveFxGeneration)) { effectiveFxGeneration = fxGeneration; } Assert.Equal(0, _log.ErrorsLogged); Assert.Equal(0, _log.WarningsLogged); Assert.True(null != assmGeneration, $"{assembly.Key},{assembly.Value} should be tracked by generations"); Assert.True(assmGeneration.Major >= 1 && assmGeneration.Minor >= 0); Assert.True(assmGeneration <= effectiveFxGeneration, $"Generation {assmGeneration} of {assembly.Key}, {assembly.Value} must be less than or equal to {fxGeneration} since this assembly is inbox in {fx.FrameworkName} which is mapped to generation {effectiveFxGeneration}."); } } } }
private CommandSpec ResolveFromProjectDependencies( string projectDirectory, NuGetFramework framework, string configuration, string commandName, IEnumerable<string> commandArguments, string outputPath) { var allowedExtensions = GetAllowedCommandExtensionsFromEnvironment(_environment); var projectContext = GetProjectContextFromDirectory( projectDirectory, framework); if (projectContext == null) { return null; } var depsFilePath = projectContext.GetOutputPaths(configuration, outputPath: outputPath).RuntimeFiles.Deps; var dependencyLibraries = GetAllDependencyLibraries(projectContext); return ResolveFromDependencyLibraries( dependencyLibraries, depsFilePath, commandName, allowedExtensions, commandArguments, projectContext); }
public DependencyContext Build(CommonCompilerOptions compilerOptions, IEnumerable<LibraryExport> compilationExports, IEnumerable<LibraryExport> runtimeExports, bool portable, NuGetFramework target, string runtime) { if (compilationExports == null) { compilationExports = Enumerable.Empty<LibraryExport>(); } var dependencyLookup = compilationExports .Concat(runtimeExports) .Select(export => export.Library.Identity) .Distinct() .Select(identity => new Dependency(identity.Name, identity.Version.ToString())) .ToDictionary(dependency => dependency.Name); var compilationOptions = compilerOptions != null ? GetCompilationOptions(compilerOptions) : CompilationOptions.Default; var runtimeSignature = GenerateRuntimeSignature(runtimeExports); return new DependencyContext( new TargetInfo(target.DotNetFrameworkName, runtime, runtimeSignature, portable), compilationOptions, GetLibraries(compilationExports, dependencyLookup, runtime: false).Cast<CompilationLibrary>(), GetLibraries(runtimeExports, dependencyLookup, runtime: true).Cast<RuntimeLibrary>(), new RuntimeFallbacks[] {}); }
public Library GetDescription(LibraryRange libraryRange, NuGetFramework targetFramework) { Debug.Assert(SupportsType(libraryRange.TypeConstraint)); var name = libraryRange.Name; var version = libraryRange.VersionRange?.MinVersion; string path; NuGetVersion assemblyVersion; if (!FrameworkResolver.TryGetAssembly(name, targetFramework, out path, out assemblyVersion)) { Log.LogWarning($"Unable to resolve requested assembly {libraryRange.Name}"); return null; } if (version == null || version == assemblyVersion) { return new Library { LibraryRange = libraryRange, Identity = new LibraryIdentity { Name = name, Version = assemblyVersion, Type = LibraryTypes.Reference }, Dependencies = Enumerable.Empty<LibraryDependency>(), [KnownLibraryProperties.AssemblyPath] = path }; } return null; }
public PackageAssemblyLoader(NuGetFramework runtimeFramework, IAssemblyLoadContextAccessor loadContextAccessor, IEnumerable<Library> libraries, PackagePathResolver pathResolver) { Log = RuntimeLogging.Logger<PackageAssemblyLoader>(); _loadContextAccessor = loadContextAccessor; _assemblyLookupTable = InitializeAssemblyLookupTable(libraries, runtimeFramework, pathResolver); }
public Package(NuGetFramework currentFramework, string packageId, IReadOnlyList<SourceRepository> sourceRepositories, string versionRange, bool getLatest, bool allowPrereleaseVersions, bool allowUnlisted, bool exclusive) { if (packageId == null) { throw new ArgumentNullException(nameof(packageId)); } if (string.IsNullOrWhiteSpace(packageId)) { throw new ArgumentException(nameof(packageId)); } if (getLatest && !string.IsNullOrEmpty(versionRange)) { throw new ArgumentException("Can not specify both a version and the latest package"); } _currentFramework = currentFramework; _packageId = packageId; _sourceRepositories = sourceRepositories; if (!string.IsNullOrEmpty(versionRange) && !VersionRange.TryParse(versionRange, out _versionRange)) { throw new ArgumentException(nameof(versionRange)); } _getLatest = getLatest; _allowPrereleaseVersions = allowPrereleaseVersions; _allowUnlisted = allowUnlisted; _exclusive = exclusive; }
private void PopulateDependencies( List<LibraryRange> dependencies, LockFileTargetLibrary targetLibrary, NuGetFramework targetFramework) { foreach (var dependency in targetLibrary.Dependencies) { dependencies.Add(new LibraryRange( dependency.Id, dependency.VersionRange, LibraryType.Unspecified, LibraryDependencyType.Default)); } if (!targetFramework.IsPackageBased) { // Only add framework assemblies for non-package based frameworks. foreach (var frameworkAssembly in targetLibrary.FrameworkAssemblies) { dependencies.Add(new LibraryRange( frameworkAssembly, LibraryType.ReferenceAssembly, LibraryDependencyType.Default)); } } }
public MSBuildProjectDescription GetDescription(NuGetFramework targetFramework, LockFileProjectLibrary projectLibrary, LockFileTargetLibrary targetLibrary) { var compatible = targetLibrary.FrameworkAssemblies.Any() || targetLibrary.CompileTimeAssemblies.Any() || targetLibrary.RuntimeAssemblies.Any(); var dependencies = new List<LibraryRange>(targetLibrary.Dependencies.Count + targetLibrary.FrameworkAssemblies.Count); PopulateDependencies(dependencies, targetLibrary, targetFramework); var msbuildProjectFilePath = GetMSBuildProjectFilePath(projectLibrary); var msbuildProjectDirectoryPath = Path.GetDirectoryName(msbuildProjectFilePath); var exists = Directory.Exists(msbuildProjectDirectoryPath); var projectFile = projectLibrary.Path == null ? null : _projectResolver(projectLibrary.Path); var msbuildPackageDescription = new MSBuildProjectDescription( msbuildProjectDirectoryPath, msbuildProjectFilePath, projectLibrary, targetLibrary, projectFile, dependencies, compatible, resolved: compatible && exists); return msbuildPackageDescription; }
private IList<LibraryDependency> GetDependencies(LockFileTargetLibrary library, NuGetFramework targetFramework) { var libraryDependencies = new List<LibraryDependency>(); foreach (var d in library.Dependencies) { libraryDependencies.Add(new LibraryDependency { LibraryRange = new LibraryRange { Name = d.Id, VersionRange = d.VersionRange } }); } foreach (var name in library.FrameworkAssemblies) { libraryDependencies.Add(new LibraryDependency { LibraryRange = new LibraryRange { Name = name, TypeConstraint = LibraryTypes.Reference } }); } return libraryDependencies; }
public ICommand Create( string commandName, IEnumerable<string> args, NuGetFramework framework = null, string configuration = Constants.DefaultConfiguration) { if (string.IsNullOrEmpty(configuration)) { configuration = _configuration; } if (framework == null) { framework = _nugetFramework; } var commandSpec = FindProjectDependencyCommands( commandName, args, configuration, framework, _outputPath, _buildBasePath, _projectDirectory); return Command.Create(commandSpec); }
public static AssemblyInfoOptions CreateForProject(ProjectContext context) { var project = context.ProjectFile; NuGetFramework targetFramework = null; // force .NETFramework instead of DNX if (context.TargetFramework.IsDesktop()) { targetFramework = new NuGetFramework(FrameworkConstants.FrameworkIdentifiers.Net, context.TargetFramework.Version); } else { targetFramework = context.TargetFramework; } return new AssemblyInfoOptions() { AssemblyVersion = project.Version?.Version.ToString(), AssemblyFileVersion = project.AssemblyFileVersion.ToString(), InformationalVersion = project.Version.ToString(), Copyright = project.Copyright, Description = project.Description, Title = project.Title, NeutralLanguage = project.Language, TargetFramework = targetFramework.DotNetFrameworkName }; }
private CommandSpec FindProjectDependencyCommands( string commandName, IEnumerable<string> commandArgs, string configuration, NuGetFramework framework, string outputPath, string buildBasePath, string projectDirectory) { var commandResolverArguments = new CommandResolverArguments { CommandName = commandName, CommandArguments = commandArgs, Framework = framework, Configuration = configuration, OutputPath = outputPath, BuildBasePath = buildBasePath, ProjectDirectory = projectDirectory }; var commandResolver = GetProjectDependenciesCommandResolver(); var commandSpec = commandResolver.Resolve(commandResolverArguments); if (commandSpec == null) { throw new CommandUnknownException(commandName); } return commandSpec; }
public IEnumerable<string> GetCompatibleAssemblyPaths() { List<string> assemblyPaths = new List<string>(); FrameworkReducer reducer = new FrameworkReducer(); NuGetFramework targetFramework = new NuGetFramework(".NETFramework", Version.Parse("4.5")); // If alternate versions of Wyam are developed (I.e., for DNX), this will need to be switched NuGetFrameworkFullComparer frameworkComparer = new NuGetFrameworkFullComparer(); IPackageRepository packageRepository = PackageRepositoryFactory.Default.CreateRepository(Path); PackageManager packageManager = new PackageManager(packageRepository, Path); foreach (IPackage package in packageManager.LocalRepository.GetPackages()) { List<KeyValuePair<IPackageFile, NuGetFramework>> filesAndFrameworks = package.GetLibFiles() .Select(x => new KeyValuePair<IPackageFile, NuGetFramework>(x, new NuGetFramework(x.TargetFramework.Identifier, x.TargetFramework.Version, x.TargetFramework.Profile))) .ToList(); NuGetFramework targetPackageFramework = reducer.GetNearest(targetFramework, filesAndFrameworks.Select(x => x.Value)); if (targetPackageFramework != null) { assemblyPaths.AddRange(filesAndFrameworks .Where(x => frameworkComparer.Equals(targetPackageFramework, x.Value)) .Select(x => System.IO.Path.Combine(Path, String.Format(CultureInfo.InvariantCulture, "{0}.{1}", package.Id, package.Version), x.Key.Path)) .Where(x => System.IO.Path.GetExtension(x) == ".dll")); } } return assemblyPaths; }
public LibraryDescription GetDescription(LibraryRange libraryRange, NuGetFramework targetFramework) { if (!LibraryType.ReferenceAssembly.CanSatisfyConstraint(libraryRange.Target)) { return null; } var name = libraryRange.Name; var version = libraryRange.VersionRange?.MinVersion; string path; Version assemblyVersion; if (!FrameworkResolver.TryGetAssembly(name, targetFramework, out path, out assemblyVersion)) { return null; } return new LibraryDescription( new LibraryIdentity(libraryRange.Name, new NuGetVersion(assemblyVersion), LibraryType.ReferenceAssembly), string.Empty, // Framework assemblies don't have hashes path, Enumerable.Empty<LibraryRange>(), targetFramework, resolved: true, compatible: true); }
public ProjectContext GetTarget(NuGetFramework targetFramework, string runtimeIdentifier) { return ProjectContexts .FirstOrDefault(c => Equals(c.TargetFramework, targetFramework) && string.Equals(c.RuntimeIdentifier ?? string.Empty, runtimeIdentifier ?? string.Empty)); }
public PackageDescription GetDescription(NuGetFramework targetFramework, LockFilePackageLibrary package, LockFileTargetLibrary targetLibrary) { // If a NuGet dependency is supposed to provide assemblies but there is no assembly compatible with // current target framework, we should mark this dependency as unresolved var containsAssembly = package.Files .Any(x => x.StartsWith($"ref{Path.DirectorySeparatorChar}") || x.StartsWith($"lib{Path.DirectorySeparatorChar}")); var compatible = targetLibrary.FrameworkAssemblies.Any() || targetLibrary.CompileTimeAssemblies.Any() || targetLibrary.RuntimeAssemblies.Any() || !containsAssembly; var dependencies = new List<LibraryRange>(targetLibrary.Dependencies.Count + targetLibrary.FrameworkAssemblies.Count); PopulateDependencies(dependencies, targetLibrary, targetFramework); var path = _packagePathResolver.GetInstallPath(package.Name, package.Version); // If the package's compile time assemblies is for a portable profile then, read the assembly metadata // and turn System.* references into reference assembly dependencies PopulateLegacyPortableDependencies(targetFramework, dependencies, path, targetLibrary); var packageDescription = new PackageDescription( path, package, targetLibrary, dependencies, compatible); return packageDescription; }
/// <summary> /// Dependency walk /// </summary> public override async Task<IEnumerable<PackageDependencyInfo>> ResolvePackages(IEnumerable<PackageIdentity> packages, NuGetFramework projectFramework, bool includePrerelease, CancellationToken token) { if (projectFramework == null) { throw new ArgumentNullException("projectFramework"); } if (packages == null) { throw new ArgumentNullException("packages"); } HashSet<PackageDependencyInfo> results = new HashSet<PackageDependencyInfo>(PackageIdentityComparer.Default); foreach (PackageIdentity package in packages) { VersionRange range = package.HasVersion ? new VersionRange(package.Version, true, package.Version, true) : VersionRange.All; var target = new NuGet.Packaging.Core.PackageDependency(package.Id, range); results.UnionWith(await Seek(target, projectFramework, includePrerelease, Enumerable.Empty<string>(), token)); } // pre-release should not be in the final set, but filter again just to be sure return results.Where(e => includePrerelease || !e.Version.IsPrerelease); }
/// <summary> /// Actual compatibility check without caching /// </summary> private bool? IsCompatibleCore(NuGetFramework target, NuGetFramework candidate) { bool? result = null; // check if they are the exact same if (_fullComparer.Equals(target, candidate)) { return true; } // special cased frameworks if (!target.IsSpecificFramework || !candidate.IsSpecificFramework) { result = IsSpecialFrameworkCompatible(target, candidate); } if (result == null) { // PCL compat logic if (target.IsPCL || candidate.IsPCL) { result = IsPCLCompatible(target, candidate); } else { // regular framework compat check result = IsCompatibleWithTarget(target, candidate); } } return result; }
private static IEnumerable<Library> GetLibraries(IEnumerable<LibraryExport> dependencies, IDictionary<string, Dependency> dependencyLookup, NuGetFramework target, string configuration, bool runtime) { return dependencies.Select(export => GetLibrary(export, target, configuration, runtime, dependencyLookup)); }
public string GetBestLockFilePath(string packageId, VersionRange versionRange, NuGetFramework framework) { var availableToolVersions = GetAvailableToolVersions(packageId); var bestVersion = versionRange.FindBestMatch(availableToolVersions); return GetLockFilePath(packageId, bestVersion, framework); }
public string GetLockFilePath(string packageId, NuGetVersion version, NuGetFramework framework) { return Path.Combine( GetBaseToolPath(packageId), version.ToNormalizedString(), framework.GetShortFolderName(), "project.lock.json"); }
public PackageManifest GetManifest(PackageKey key, NuGet.Frameworks.NuGetFramework projectFramework) { Guard.NotNull(projectFramework, nameof(projectFramework)); var packageIdentity = new NuGet.Packaging.Core.PackageIdentity(key.PackageId, key.Version); var packagesResource = _sourceRepository.GetResource <PackageMetadataResource>(); var packageInfo = packagesResource.GetMetadataAsync(packageIdentity, NullSourceCacheContext.Instance, NullLogger.Instance, CancellationToken.None).Result; NuGet.Packaging.PackageDependencyGroup dependencies = null; if (packageInfo.DependencySets.Count() == 1 && packageInfo.DependencySets.First().TargetFramework.IsUnsupported) { dependencies = packageInfo.DependencySets.First(); } else if (packageInfo.DependencySets.Any()) { dependencies = NuGetFrameworkUtility.GetNearest(packageInfo.DependencySets, projectFramework); if (dependencies == null) { throw new ApplicationException($"Could not find compatible dependencies for '{packageInfo.Identity}' and framework '{projectFramework}'"); } } var manifest = new PackageManifest { PackageId = packageInfo.Identity.Id, Version = packageInfo.Identity.Version, Dependencies = new List <PackageDependency>() }; if (dependencies == null) { return(manifest); } foreach (var dependency in dependencies.Packages) { manifest.Dependencies.Add(new PackageDependency(dependency.Id, dependency.VersionRange)); } return(manifest); }
/// <summary> /// True if the Framework is .NETFramework /// </summary> public static bool IsDesktop(this NuGetFramework framework) { return(framework.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.Net, StringComparison.OrdinalIgnoreCase) || framework.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.AspNet, StringComparison.OrdinalIgnoreCase) || framework.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.Dnx, StringComparison.OrdinalIgnoreCase)); }
/// <summary> /// Creates a NuGetFramework from a folder name using the given mappings. /// </summary> public static NuGetFramework ParseFolder(string folderName, IFrameworkNameProvider mappings) { if (folderName == null) { throw new ArgumentNullException("folderName"); } if (folderName.IndexOf('%') > -1) { folderName = Uri.UnescapeDataString(folderName); } NuGetFramework result = null; // first check if we have a special or common framework if (!TryParseSpecialFramework(folderName, out result) && !TryParseCommonFramework(folderName, out result)) { // assume this is unsupported unless we find a match result = UnsupportedFramework; Tuple <string, string, string> parts = RawParse(folderName); if (parts != null) { string framework = null; if (mappings.TryGetIdentifier(parts.Item1, out framework)) { Version version = FrameworkConstants.EmptyVersion; if (parts.Item2 == null || mappings.TryGetVersion(parts.Item2, out version)) { string profileShort = parts.Item3; string profile = null; if (!mappings.TryGetProfile(framework, profileShort, out profile)) { profile = profileShort ?? string.Empty; } if (StringComparer.OrdinalIgnoreCase.Equals(FrameworkConstants.FrameworkIdentifiers.Portable, framework)) { IEnumerable <NuGetFramework> clientFrameworks = null; mappings.TryGetPortableFrameworks(profileShort, out clientFrameworks); int profileNumber = -1; if (mappings.TryGetPortableProfile(clientFrameworks, out profileNumber)) { string portableProfileNumber = FrameworkNameHelpers.GetPortableProfileNumberString(profileNumber); result = new NuGetFramework(framework, version, portableProfileNumber); } else { // TODO: should this be unsupported? result = new NuGetFramework(framework, version, profileShort); } } else { result = new NuGetFramework(framework, version, profile); } } } } else { // If the framework was not recognized check if it is a deprecated framework NuGetFramework deprecated = null; if (TryParseDeprecatedFramework(folderName, out deprecated)) { result = deprecated; } } } return(result); }
/// <summary> /// Sort PCLs using these criteria /// 1. Lowest number of frameworks (highest surface area) wins first /// 2. Profile with the highest version numbers wins next /// 3. String compare is used as a last resort /// </summary> private bool IsBetterPCL(NuGetFramework current, NuGetFramework considering) { Debug.Assert(considering.IsPCL && current.IsPCL, "This method should be used only to compare PCLs"); // Find all frameworks in the profile var consideringFrameworks = ExplodePortableFramework(considering, false); var currentFrameworks = ExplodePortableFramework(current, false); // The PCL with the least frameworks (highest surface area) goes first if (consideringFrameworks.Count() < currentFrameworks.Count()) { return(true); } else if (currentFrameworks.Count() < consideringFrameworks.Count()) { return(false); } // If both frameworks have the same number of frameworks take the framework that has the highest // overall set of framework versions // Find Frameworks that both profiles have in common var sharedFrameworkIds = consideringFrameworks.Select(f => f.Framework) .Where(f => currentFrameworks.Any(consideringFramework => StringComparer.OrdinalIgnoreCase.Equals(f, consideringFramework.Framework))); var consideringHighest = 0; var currentHighest = 0; // Determine which framework has the highest version of each shared framework foreach (var sharedId in sharedFrameworkIds) { var consideringFramework = consideringFrameworks.First(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, sharedId)); var currentFramework = currentFrameworks.First(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, sharedId)); if (consideringFramework.Version < currentFramework.Version) { currentHighest++; } else if (currentFramework.Version < consideringFramework.Version) { consideringHighest++; } } // Prefer the highest count if (currentHighest < consideringHighest) { return(true); } else if (consideringHighest < currentHighest) { return(false); } // Take the highest version of .NET if no winner could be determined, this is usually a good indicator of which is newer var consideringNet = consideringFrameworks.FirstOrDefault(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, FrameworkConstants.FrameworkIdentifiers.Net)); var currentNet = currentFrameworks.FirstOrDefault(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, FrameworkConstants.FrameworkIdentifiers.Net)); // Compare using .NET only if both frameworks have it. PCLs should always have .NET, but since users can make these strings up we should // try to handle that as best as possible. if (consideringNet != null && currentNet != null) { if (currentNet.Version < consideringNet.Version) { return(true); } else if (consideringNet.Version < currentNet.Version) { return(false); } } // In the very rare case that both frameworks are still equal, we have to pick one. // There is nothing but we need to be deterministic, so compare the profiles as strings. if (StringComparer.OrdinalIgnoreCase.Compare(considering.GetShortFolderName(_mappings), current.GetShortFolderName(_mappings)) < 0) { return(true); } return(false); }
private NuGetFramework GetNearestInternal(NuGetFramework framework, IEnumerable <NuGetFramework> possibleFrameworks) { NuGetFramework nearest = null; // Unsupported frameworks always lose, throw them out unless it's all we were given if (possibleFrameworks.Any(e => e != NuGetFramework.UnsupportedFramework)) { possibleFrameworks = possibleFrameworks.Where(e => e != NuGetFramework.UnsupportedFramework); } // Try exact matches first nearest = possibleFrameworks.Where(f => _fullComparer.Equals(framework, f)).FirstOrDefault(); if (nearest == null) { // Elimate non-compatible frameworks var compatible = possibleFrameworks.Where(f => _compat.IsCompatible(framework, f)); // Remove lower versions of compatible frameworks var reduced = ReduceUpwards(compatible); bool isNet6Era = framework.IsNet5Era && framework.Version.Major >= 6; // Reduce to the same framework name if possible, with an exception for Xamarin, MonoAndroid and Tizen when net6.0+ if (reduced.Count() > 1 && reduced.Any(f => _fwNameComparer.Equals(f, framework))) { reduced = reduced.Where(f => { if (isNet6Era && framework.HasPlatform && ( f.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.MonoAndroid, StringComparison.OrdinalIgnoreCase) || f.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.Tizen, StringComparison.OrdinalIgnoreCase) )) { return(true); } else { return(_fwNameComparer.Equals(f, framework)); } }); } // PCL reduce if (reduced.Count() > 1) { // if we have a pcl and non-pcl mix, throw out the pcls if (reduced.Any(f => f.IsPCL) && reduced.Any(f => !f.IsPCL)) { reduced = reduced.Where(f => !f.IsPCL); } else if (reduced.All(f => f.IsPCL)) { // decide between PCLs if (framework.IsPCL) { reduced = GetNearestPCLtoPCL(framework, reduced); } else { reduced = GetNearestNonPCLtoPCL(framework, reduced); } if (reduced.Count() > 1) { // For scenarios where we are unable to decide between PCLs, choose the PCL with the // least frameworks. Less frameworks means less compatibility which means it is nearer to the target. reduced = new NuGetFramework[] { GetBestPCL(reduced) }; } } } // Packages based framework reduce, only if the project is not packages based if (reduced.Count() > 1 && !framework.IsPackageBased && reduced.Any(f => f.IsPackageBased) && reduced.Any(f => !f.IsPackageBased)) { // If we have a packages based and non-packages based mix, throw out the packages based frameworks. // This situation is unlikely but it could happen with framework mappings that do not provide // a relationship between the frameworks and the compatible packages based frameworks. // Ex: net46, dotnet -> net46 reduced = reduced.Where(f => !f.IsPackageBased); } // Profile reduce if (reduced.Count() > 1 && !reduced.Any(f => f.IsPCL)) { // Prefer the same framework and profile if (framework.HasProfile) { var sameProfile = reduced.Where(f => _fwNameComparer.Equals(framework, f) && StringComparer.OrdinalIgnoreCase.Equals(framework.Profile, f.Profile)); if (sameProfile.Any()) { reduced = sameProfile; } } // Prefer frameworks without profiles if (reduced.Count() > 1 && reduced.Any(f => f.HasProfile) && reduced.Any(f => !f.HasProfile)) { reduced = reduced.Where(f => !f.HasProfile); } } // Platforms reduce if (reduced.Count() > 1 && framework.HasPlatform) { if (!isNet6Era || reduced.Any(f => _fwNameComparer.Equals(framework, f) && f.Version.Major >= 6)) { // Prefer the highest framework version, likely to be the non-platform specific option. reduced = reduced.Where(f => _fwNameComparer.Equals(framework, f)).GroupBy(f => f.Version).OrderByDescending(f => f.Key).First(); } else if (isNet6Era && reduced.Any(f => { return(f.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.MonoAndroid, StringComparison.OrdinalIgnoreCase) || f.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.Tizen, StringComparison.OrdinalIgnoreCase)); })) { // We have a special case for *some* Xamarin-related frameworks here. For specific precedence rules, please see: // https://github.com/dotnet/designs/blob/main/accepted/2021/net6.0-tfms/net6.0-tfms.md#compatibility-rules reduced = reduced.GroupBy(f => f.Framework).OrderByDescending(f => f.Key).First(f => { NuGetFramework first = f.First(); return(first.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.MonoAndroid, StringComparison.OrdinalIgnoreCase) || first.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.Tizen, StringComparison.OrdinalIgnoreCase)); }); } } // if we have reduced down to a single framework, use that if (reduced.Count() == 1) { nearest = reduced.Single(); } // this should be a very rare occurrence // at this point we are unable to decide between the remaining frameworks in any useful way // just take the first one by rev alphabetical order if we can't narrow it down at all if (nearest == null && reduced.Any()) { // Sort by precedence rules, then by name in the case of a tie nearest = reduced .OrderBy(f => f, new FrameworkPrecedenceSorter(_mappings, false)) .ThenByDescending(f => f, new NuGetFrameworkSorter()) .ThenBy(f => f.GetHashCode()) .First(); } } return(nearest); }
/// <summary> /// Return the item with the target framework nearest the project framework /// </summary> public static T GetNearest <T>(this IEnumerable <T> items, NuGetFramework projectFramework) where T : class, IFrameworkSpecific { return(NuGetFrameworkUtility.GetNearest(items, projectFramework, e => e.TargetFramework)); }
public IEnumerable <PackageDependency> DependenciesForPackage(PackageIdentity identity, NuGet.Frameworks.NuGetFramework framework) { foreach (DependencyInfoResource dependencyInfoResource in DependencyInfoResourceList) { try { var context = new SourceCacheContext(); var infoTask = dependencyInfoResource.ResolvePackage(identity, framework, cacheContext: context, log: new NugetLogger(), token: CancellationToken.None); var result = infoTask.Result; return(result.Dependencies); } catch (Exception e) { Console.WriteLine("A dependency resource was unable to load for package: " + identity); if (e.InnerException != null) { Console.WriteLine(e.InnerException.Message); } } } return(new List <PackageDependency>()); }
private ProjectContext GetProjectContextFromDirectory(string directory, NuGetFramework framework) { if (directory == null || framework == null) { return null; } var projectRootPath = directory; if (!File.Exists(Path.Combine(projectRootPath, Project.FileName))) { return null; } var projectContext = ProjectContext.Create( projectRootPath, framework, PlatformServices.Default.Runtime.GetAllCandidateRuntimeIdentifiers()); if (projectContext.RuntimeIdentifier == null) { return null; } return projectContext; }