public static async Task <RemoteMatch> FindLibraryMatchAsync( LibraryRange libraryRange, NuGetFramework framework, string runtimeIdentifier, IEnumerable <IRemoteDependencyProvider> remoteProviders, IEnumerable <IRemoteDependencyProvider> localProviders, IEnumerable <IDependencyProvider> projectProviders, IDictionary <LockFileCacheKey, IList <LibraryIdentity> > lockFileLibraries, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { var projectMatch = await FindProjectMatchAsync(libraryRange, framework, projectProviders, cancellationToken); if (projectMatch != null) { return(projectMatch); } if (libraryRange.VersionRange == null) { return(null); } // The resolution below is only for package types if (!libraryRange.TypeConstraintAllows(LibraryDependencyTarget.Package)) { return(null); } var targetFramework = framework; if (framework is AssetTargetFallbackFramework) { targetFramework = (framework as AssetTargetFallbackFramework).RootFramework; } var key = new LockFileCacheKey(targetFramework, runtimeIdentifier); // This is only applicable when packages has to be resolved from packages.lock.json file if (lockFileLibraries.TryGetValue(key, out var libraries)) { var library = libraries.FirstOrDefault(lib => StringComparer.OrdinalIgnoreCase.Equals(lib.Name, libraryRange.Name)); if (library != null) { // check for the exact library through local repositories var localMatch = await FindLibraryByVersionAsync(library, framework, localProviders, cacheContext, logger, cancellationToken); if (localMatch != null && localMatch.Library.Version.Equals(library.Version)) { return(localMatch); } // if not found in local repositories, then check the remote repositories var remoteMatch = await FindLibraryByVersionAsync(library, framework, remoteProviders, cacheContext, logger, cancellationToken); if (remoteMatch != null && remoteMatch.Library.Version.Equals(library.Version)) { // Only return the result if the version is same as defined in packages.lock.json file return(remoteMatch); } } // it should never come to this, but as a fail-safe if it ever fails to resolve a package from lock file when // it has to... then fail restore. return(null); } return(await FindPackageLibraryMatchAsync(libraryRange, framework, remoteProviders, localProviders, cacheContext, logger, cancellationToken)); }
public static async Task <RemoteMatch> FindLibraryMatchAsync( LibraryRange libraryRange, NuGetFramework framework, string runtimeIdentifier, GraphEdge <RemoteResolveResult> outerEdge, IEnumerable <IRemoteDependencyProvider> remoteProviders, IEnumerable <IRemoteDependencyProvider> localProviders, IEnumerable <IDependencyProvider> projectProviders, IDictionary <LockFileCacheKey, IList <LibraryIdentity> > lockFileLibraries, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { var projectMatch = await FindProjectMatchAsync(libraryRange, framework, outerEdge, projectProviders, cancellationToken); if (projectMatch != null) { return(projectMatch); } if (libraryRange.VersionRange == null) { return(null); } // The resolution below is only for package types if (!libraryRange.TypeConstraintAllows(LibraryDependencyTarget.Package)) { return(null); } var targetFramework = framework; if (framework is AssetTargetFallbackFramework) { targetFramework = (framework as AssetTargetFallbackFramework).RootFramework; } var key = new LockFileCacheKey(targetFramework, runtimeIdentifier); // This is only applicable when packages has to be resolved from packages.lock.json file if (lockFileLibraries.TryGetValue(key, out var libraries)) { var library = libraries.FirstOrDefault(lib => StringComparer.OrdinalIgnoreCase.Equals(lib.Name, libraryRange.Name)); if (library != null) { // check for the exact library through local repositories var localMatch = await FindLibraryByVersionAsync(library, framework, localProviders, cacheContext, logger, cancellationToken); if (localMatch != null) { return(localMatch); } // if not found in local repositories, then check the remote repositories var remoteMatch = await FindLibraryByVersionAsync(library, framework, remoteProviders, cacheContext, logger, cancellationToken); // either found or not, we must return from here since we dont want to resolve to any other version // then defined in packages.lock.json file return(remoteMatch); } // it should never come to this, but as a fail-safe if it ever fails to resolve a package from lock file when // it has to... then fail restore. return(null); } if (libraryRange.VersionRange.IsFloating) { // For snapshot dependencies, get the version remotely first. var remoteMatch = await FindLibraryByVersionAsync(libraryRange, framework, remoteProviders, cacheContext, logger, cancellationToken); if (remoteMatch != null) { // Try to see if the specific version found on the remote exists locally. This avoids any unnecessary // remote access incase we already have it in the cache/local packages folder. var localMatch = await FindLibraryByVersionAsync(remoteMatch.Library, framework, localProviders, cacheContext, logger, cancellationToken); if (localMatch != null && localMatch.Library.Version.Equals(remoteMatch.Library.Version)) { // If we have a local match, and it matches the version *exactly* then use it. return(localMatch); } // We found something locally, but it wasn't an exact match // for the resolved remote match. } return(remoteMatch); } else { // Check for the specific version locally. var localMatch = await FindLibraryByVersionAsync(libraryRange, framework, localProviders, cacheContext, logger, cancellationToken); if (localMatch != null && localMatch.Library.Version.Equals(libraryRange.VersionRange.MinVersion)) { // We have an exact match so use it. return(localMatch); } // Either we found a local match but it wasn't the exact version, or // we didn't find a local match. var remoteMatch = await FindLibraryByVersionAsync(libraryRange, framework, remoteProviders, cacheContext, logger, cancellationToken); if (remoteMatch != null && localMatch == null) { // There wasn't any local match for the specified version but there was a remote match. // See if that version exists locally. localMatch = await FindLibraryByVersionAsync(remoteMatch.Library, framework, remoteProviders, cacheContext, logger, cancellationToken); } if (localMatch != null && remoteMatch != null) { // We found a match locally and remotely, so pick the better version // in relation to the specified version. if (libraryRange.VersionRange.IsBetter( current: localMatch.Library.Version, considering: remoteMatch.Library.Version)) { return(remoteMatch); } else { return(localMatch); } } // Prefer local over remote generally. return(localMatch ?? remoteMatch); } }