private ITaskItem AssignNearestFrameworkForSingleReference(
            ITaskItem project,
            NuGetFramework projectNuGetFramework,
            IList <NuGetFramework> fallbackNuGetFrameworks,
            MSBuildLogger logger)
        {
            var itemWithProperties = new TaskItem(project);
            var referencedProjectFrameworkString = project.GetMetadata(TARGET_FRAMEWORKS);
            var referenceTargetFrameworkMonikers = project.GetMetadata(TARGET_FRAMEWORK_MONIKERS);
            var referencedProjectPlatformString  = project.GetMetadata(TARGET_PLATFORM_MONIKERS);

            var referencedProjectFile = project.GetMetadata(MSBUILD_SOURCE_PROJECT_FILE);

            if (string.IsNullOrEmpty(referencedProjectFrameworkString))
            {
                // No target frameworks set, nothing to do.
                return(itemWithProperties);
            }

            var referencedProjectFrameworks = MSBuildStringUtility.Split(referencedProjectFrameworkString);
            var referencedProjectTargetFrameworkMonikers = MSBuildStringUtility.Split(referenceTargetFrameworkMonikers);
            var referencedProjectTargetPlatformMonikers  = MSBuildStringUtility.Split(referencedProjectPlatformString);

            if (referencedProjectTargetFrameworkMonikers.Length > 0 &&
                (referencedProjectTargetFrameworkMonikers.Length != referencedProjectTargetPlatformMonikers.Length ||
                 referencedProjectTargetFrameworkMonikers.Length != referencedProjectFrameworks.Length))
            {
                logger.LogError($"Internal error for {CurrentProjectName}." +
                                $" Expected {TARGET_FRAMEWORKS}:{referencedProjectFrameworks}, " +
                                $"{TARGET_FRAMEWORK_MONIKERS}:{referenceTargetFrameworkMonikers}, " +
                                $"{TARGET_PLATFORM_MONIKERS}:{referencedProjectPlatformString} to have the same number of elements.");
                return(itemWithProperties);
            }
            // TargetFrameworks, TargetFrameworkMoniker, TargetPlatforMoniker
            var targetFrameworkInformations = new List <TargetFrameworkInformation>();
            var useTargetMonikers           = referencedProjectTargetFrameworkMonikers.Length > 0;

            for (int i = 0; i < referencedProjectFrameworks.Length; i++)
            {
                targetFrameworkInformations.Add(new TargetFrameworkInformation(
                                                    referencedProjectFrameworks[i],
                                                    useTargetMonikers ? referencedProjectTargetFrameworkMonikers[i] : null,
                                                    useTargetMonikers ? referencedProjectTargetPlatformMonikers[i] : null));
            }

            // try project framework
            var nearestNuGetFramework = NuGetFrameworkUtility.GetNearest(targetFrameworkInformations, projectNuGetFramework, GetNuGetFramework);

            if (nearestNuGetFramework != null)
            {
                itemWithProperties.SetMetadata(NEAREST_TARGET_FRAMEWORK, nearestNuGetFramework._targetFrameworkAlias);
                return(itemWithProperties);
            }

            // try project fallback frameworks
            foreach (var currentProjectTargetFramework in fallbackNuGetFrameworks)
            {
                nearestNuGetFramework = NuGetFrameworkUtility.GetNearest(targetFrameworkInformations, currentProjectTargetFramework, GetNuGetFramework);

                if (nearestNuGetFramework != null)
                {
                    var message = string.Format(CultureInfo.CurrentCulture,
                                                Strings.ImportsFallbackWarning,
                                                referencedProjectFile,
                                                currentProjectTargetFramework.DotNetFrameworkName,
                                                projectNuGetFramework.DotNetFrameworkName);

                    var warning = RestoreLogMessage.CreateWarning(NuGetLogCode.NU1702, message);
                    warning.LibraryId   = referencedProjectFile;
                    warning.ProjectPath = CurrentProjectName;

                    // log NU1702 for ATF on project reference
                    logger.Log(warning);

                    itemWithProperties.SetMetadata(NEAREST_TARGET_FRAMEWORK, nearestNuGetFramework._targetFrameworkAlias);
                    return(itemWithProperties);
                }
            }

            // no match found
            logger.LogError(string.Format(CultureInfo.CurrentCulture, Strings.NoCompatibleTargetFramework, project.ItemSpec, projectNuGetFramework.DotNetFrameworkName, referencedProjectFrameworkString));
            return(itemWithProperties);
        }
Example #2
0
        public LockFile CreateLockFile(LockFile previousLockFile,
                                       PackageSpec project,
                                       IEnumerable <RestoreTargetGraph> targetGraphs,
                                       IReadOnlyList <NuGetv3LocalRepository> localRepositories,
                                       RemoteWalkContext context)
        {
            var lockFile = new LockFile()
            {
                Version = _lockFileVersion
            };

            var previousLibraries = previousLockFile?.Libraries.ToDictionary(l => Tuple.Create(l.Name, l.Version));

            if (project.RestoreMetadata?.ProjectStyle == ProjectStyle.PackageReference ||
                project.RestoreMetadata?.ProjectStyle == ProjectStyle.DotnetToolReference)
            {
                AddProjectFileDependenciesForPackageReference(project, lockFile, targetGraphs);
            }
            else
            {
                AddProjectFileDependenciesForSpec(project, lockFile);
            }

            // Record all libraries used
            foreach (var item in targetGraphs.SelectMany(g => g.Flattened).Distinct()
                     .OrderBy(x => x.Data.Match.Library))
            {
                var library = item.Data.Match.Library;

                if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase))
                {
                    // Do not include the project itself as a library.
                    continue;
                }

                if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject)
                {
                    // Project
                    var localMatch = (LocalMatch)item.Data.Match;

                    var projectLib = new LockFileLibrary()
                    {
                        Name    = library.Name,
                        Version = library.Version,
                        Type    = LibraryType.Project,
                    };

                    // Set the relative path if a path exists
                    // For projects without project.json this will be empty
                    if (!string.IsNullOrEmpty(localMatch.LocalLibrary.Path))
                    {
                        projectLib.Path = PathUtility.GetRelativePath(
                            project.FilePath,
                            localMatch.LocalLibrary.Path,
                            '/');
                    }

                    // The msbuild project path if it exists
                    object msbuildPath;
                    if (localMatch.LocalLibrary.Items.TryGetValue(KnownLibraryProperties.MSBuildProjectPath, out msbuildPath))
                    {
                        var msbuildRelativePath = PathUtility.GetRelativePath(
                            project.FilePath,
                            (string)msbuildPath,
                            '/');

                        projectLib.MSBuildProject = msbuildRelativePath;
                    }

                    lockFile.Libraries.Add(projectLib);
                }
                else if (library.Type == LibraryType.Package)
                {
                    // Packages
                    var packageInfo = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, library.Name, library.Version);

                    // Add the library if it was resolved, unresolved packages are not added to the assets file.
                    if (packageInfo != null)
                    {
                        var package  = packageInfo.Package;
                        var resolver = packageInfo.Repository.PathResolver;

                        var             sha512          = package.Sha512;
                        var             path            = PathUtility.GetPathWithForwardSlashes(resolver.GetPackageDirectory(package.Id, package.Version));
                        LockFileLibrary lockFileLib     = null;
                        LockFileLibrary previousLibrary = null;

                        if (previousLibraries?.TryGetValue(Tuple.Create(package.Id, package.Version), out previousLibrary) == true)
                        {
                            // Check that the previous library is still valid
                            if (previousLibrary != null &&
                                StringComparer.Ordinal.Equals(path, previousLibrary.Path) &&
                                StringComparer.Ordinal.Equals(sha512, previousLibrary.Sha512))
                            {
                                // We mutate this previous library so we must take a clone of it. This is
                                // important because later, when deciding whether the lock file has changed,
                                // we compare the new lock file to the previous (in-memory) lock file.
                                lockFileLib = previousLibrary.Clone();
                            }
                        }

                        // Create a new lock file library if one doesn't exist already.
                        if (lockFileLib == null)
                        {
                            lockFileLib = CreateLockFileLibrary(package, sha512, path);
                        }

                        // Create a new lock file library
                        lockFile.Libraries.Add(lockFileLib);
                    }
                }
            }

            var libraries = lockFile.Libraries.ToDictionary(lib => Tuple.Create(lib.Name, lib.Version));

            var librariesWithWarnings = new HashSet <LibraryIdentity>();

            var rootProjectStyle = project.RestoreMetadata?.ProjectStyle ?? ProjectStyle.Unknown;

            // Cache package data and selection criteria across graphs.
            var builderCache = new LockFileBuilderCache();

            // Add the targets
            foreach (var targetGraph in targetGraphs
                     .OrderBy(graph => graph.Framework.ToString(), StringComparer.Ordinal)
                     .ThenBy(graph => graph.RuntimeIdentifier, StringComparer.Ordinal))
            {
                var target = new LockFileTarget
                {
                    TargetFramework   = targetGraph.Framework,
                    RuntimeIdentifier = targetGraph.RuntimeIdentifier
                };

                var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, project, targetGraph);

                // Check if warnings should be displayed for the current framework.
                var tfi = project.GetTargetFramework(targetGraph.Framework);

                var warnForImportsOnGraph = tfi.Warn &&
                                            (target.TargetFramework is FallbackFramework ||
                                             target.TargetFramework is AssetTargetFallbackFramework);

                foreach (var graphItem in targetGraph.Flattened.OrderBy(x => x.Key))
                {
                    var library = graphItem.Key;

                    // include flags
                    LibraryIncludeFlags includeFlags;
                    if (!flattenedFlags.TryGetValue(library.Name, out includeFlags))
                    {
                        includeFlags = ~LibraryIncludeFlags.ContentFiles;
                    }

                    if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject)
                    {
                        if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            // Do not include the project itself as a library.
                            continue;
                        }

                        var projectLib = LockFileUtils.CreateLockFileTargetProject(
                            graphItem,
                            library,
                            includeFlags,
                            targetGraph,
                            rootProjectStyle);

                        target.Libraries.Add(projectLib);
                        continue;
                    }
                    else if (library.Type == LibraryType.Package)
                    {
                        var packageInfo = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, library.Name, library.Version);

                        if (packageInfo == null)
                        {
                            continue;
                        }

                        var package = packageInfo.Package;

                        var developmentDependency = package.Nuspec.GetDevelopmentDependency();

                        // check if package is development dependency and include flags are not overwritten
                        if (developmentDependency && includeFlags == LibraryIncludeFlags.All)
                        {
                            var dependency = tfi.Dependencies.FirstOrDefault(dep => dep.Name.Equals(package.Id, StringComparison.OrdinalIgnoreCase));

                            // make sure new resolved dependency still have default PrivateAssets as well as IncludeAssets
                            if (dependency?.SuppressParent == LibraryIncludeFlagUtils.DefaultSuppressParent &&
                                dependency?.IncludeType == LibraryIncludeFlags.All)
                            {
                                includeFlags = LibraryIncludeFlags.All & ~LibraryIncludeFlags.Compile;
                            }
                        }

                        var targetLibrary = LockFileUtils.CreateLockFileTargetLibrary(
                            libraries[Tuple.Create(library.Name, library.Version)],
                            package,
                            targetGraph,
                            dependencyType: includeFlags,
                            targetFrameworkOverride: null,
                            dependencies: graphItem.Data.Dependencies,
                            cache: builderCache);

                        target.Libraries.Add(targetLibrary);

                        // Log warnings if the target library used the fallback framework
                        if (warnForImportsOnGraph && !librariesWithWarnings.Contains(library))
                        {
                            var nonFallbackFramework = new NuGetFramework(target.TargetFramework);

                            var targetLibraryWithoutFallback = LockFileUtils.CreateLockFileTargetLibrary(
                                libraries[Tuple.Create(library.Name, library.Version)],
                                package,
                                targetGraph,
                                targetFrameworkOverride: nonFallbackFramework,
                                dependencyType: includeFlags,
                                dependencies: graphItem.Data.Dependencies,
                                cache: builderCache);

                            if (!targetLibrary.Equals(targetLibraryWithoutFallback))
                            {
                                var libraryName = DiagnosticUtility.FormatIdentity(library);

                                var message = string.Format(CultureInfo.CurrentCulture,
                                                            Strings.Log_ImportsFallbackWarning,
                                                            libraryName,
                                                            GetFallbackFrameworkString(target.TargetFramework),
                                                            nonFallbackFramework);

                                var logMessage = RestoreLogMessage.CreateWarning(
                                    NuGetLogCode.NU1701,
                                    message,
                                    library.Name,
                                    targetGraph.TargetGraphName);

                                _logger.Log(logMessage);

                                // only log the warning once per library
                                librariesWithWarnings.Add(library);
                            }
                        }
                    }
                }

                lockFile.Targets.Add(target);
            }

            PopulatePackageFolders(localRepositories.Select(repo => repo.RepositoryRoot).Distinct(), lockFile);

            // Add the original package spec to the lock file.
            lockFile.PackageSpec = project;

            return(lockFile);
        }
Example #3
0
        /// <summary>
        /// This method verifies that the assets files, props/targets files and all the packages written out in the assets file are present on disk
        /// When the project has opted into packages lock file, it also verified that the lock file is present on disk.
        /// This does not account if the files were manually modified since the last restore
        /// </summary>
        internal static bool VerifyRestoreOutput(RestoreRequest request, CacheFile cacheFile)
        {
            if (!string.IsNullOrWhiteSpace(request.LockFilePath) && !File.Exists(request.LockFilePath))
            {
                request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_AssetsFileNotOnDisk, request.Project.Name));
                return(false);
            }

            if (request.ProjectStyle == ProjectStyle.PackageReference || request.ProjectStyle == ProjectStyle.Standalone)
            {
                var targetsFilePath = BuildAssetsUtils.GetMSBuildFilePath(request.Project, BuildAssetsUtils.TargetsExtension);
                if (!File.Exists(targetsFilePath))
                {
                    request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_TargetsFileNotOnDisk, request.Project.Name, targetsFilePath));
                    return(false);
                }
                var propsFilePath = BuildAssetsUtils.GetMSBuildFilePath(request.Project, BuildAssetsUtils.PropsExtension);
                if (!File.Exists(propsFilePath))
                {
                    request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_PropsFileNotOnDisk, request.Project.Name, propsFilePath));
                    return(false);
                }
                if (PackagesLockFileUtilities.IsNuGetLockFileEnabled(request.Project))
                {
                    var packageLockFilePath = PackagesLockFileUtilities.GetNuGetLockFilePath(request.Project);
                    if (!File.Exists(packageLockFilePath))
                    {
                        request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_LockFileNotOnDisk, request.Project.Name, packageLockFilePath));
                        return(false);
                    }
                }
            }

            if (cacheFile.HasAnyMissingPackageFiles)
            {
                request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_MissingPackagesOnDisk, request.Project.Name));
                return(false);
            }

            if (request.UpdatePackageLastAccessTime)
            {
                foreach (var package in cacheFile.ExpectedPackageFilePaths)
                {
                    if (!package.StartsWith(request.PackagesDirectory, StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    var packageDirectory = Path.GetDirectoryName(package);
                    var metadataFile     = Path.Combine(packageDirectory, PackagingCoreConstants.NupkgMetadataFileExtension);

                    try
                    {
                        request.DependencyProviders.PackageFileCache.UpdateLastAccessTime(metadataFile);
                    }
                    catch (Exception ex)
                    {
                        request.Log.Log(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1802,
                                                                        string.Format(CultureInfo.InvariantCulture, Strings.Error_CouldNotUpdateMetadataLastAccessTime,
                                                                                      metadataFile, ex.Message)));
                    }
                }
            }

            return(true);
        }
Example #4
0
        private async Task <IEnumerable <RestoreTargetGraph> > ExecuteRestoreAsync(
            NuGetv3LocalRepository userPackageFolder,
            IReadOnlyList <NuGetv3LocalRepository> fallbackPackageFolders,
            RemoteWalkContext context,
            CancellationToken token,
            TelemetryActivity telemetryActivity)
        {
            if (_request.Project.TargetFrameworks.Count == 0)
            {
                var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_ProjectDoesNotSpecifyTargetFrameworks, _request.Project.Name, _request.Project.FilePath);
                await _logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1001, message));

                _success = false;
                return(Enumerable.Empty <RestoreTargetGraph>());
            }

            _logger.LogMinimal(string.Format(CultureInfo.CurrentCulture, Strings.Log_RestoringPackages, _request.Project.FilePath));

            // Get external project references
            // If the top level project already exists, update the package spec provided
            // with the RestoreRequest spec.
            var updatedExternalProjects = GetProjectReferences(context);

            // Determine if the targets and props files should be written out.
            context.IsMsBuildBased = _request.ProjectStyle != ProjectStyle.DotnetCliTool;

            // Load repositories
            // the external project provider is specific to the current restore project
            context.ProjectLibraryProviders.Add(
                new PackageSpecReferenceDependencyProvider(updatedExternalProjects, _logger));

            var remoteWalker = new RemoteDependencyWalker(context);

            var projectRange = new LibraryRange()
            {
                Name           = _request.Project.Name,
                VersionRange   = new VersionRange(_request.Project.Version),
                TypeConstraint = LibraryDependencyTarget.Project | LibraryDependencyTarget.ExternalProject
            };

            // Resolve dependency graphs
            var allGraphs  = new List <RestoreTargetGraph>();
            var runtimeIds = RequestRuntimeUtility.GetRestoreRuntimes(_request);
            var projectFrameworkRuntimePairs = CreateFrameworkRuntimePairs(_request.Project, runtimeIds);
            var hasSupports = _request.Project.RuntimeGraph.Supports.Count > 0;

            var projectRestoreRequest = new ProjectRestoreRequest(
                _request,
                _request.Project,
                _request.ExistingLockFile,
                _logger)
            {
                ParentId = _operationId
            };

            var projectRestoreCommand = new ProjectRestoreCommand(projectRestoreRequest);

            Tuple <bool, List <RestoreTargetGraph>, RuntimeGraph> result = null;

            using (var tryRestoreTelemetry = TelemetryActivity.CreateTelemetryActivityWithNewOperationIdAndEvent(telemetryActivity.OperationId, CreateRestoreTargetGraph))
            {
                result = await projectRestoreCommand.TryRestoreAsync(
                    projectRange,
                    projectFrameworkRuntimePairs,
                    userPackageFolder,
                    fallbackPackageFolders,
                    remoteWalker,
                    context,
                    forceRuntimeGraphCreation : hasSupports,
                    token : token,
                    telemetryActivity : tryRestoreTelemetry);
            }

            var success = result.Item1;

            allGraphs.AddRange(result.Item2);
            _success = success;

            // Calculate compatibility profiles to check by merging those defined in the project with any from the command line
            foreach (var profile in _request.Project.RuntimeGraph.Supports)
            {
                var runtimes = result.Item3;

                CompatibilityProfile compatProfile;
                if (profile.Value.RestoreContexts.Any())
                {
                    // Just use the contexts from the project definition
                    compatProfile = profile.Value;
                }
                else if (!runtimes.Supports.TryGetValue(profile.Value.Name, out compatProfile))
                {
                    // No definition of this profile found, so just continue to the next one
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_UnknownCompatibilityProfile, profile.Key);

                    await _logger.LogAsync(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1502, message));

                    continue;
                }

                foreach (var pair in compatProfile.RestoreContexts)
                {
                    _logger.LogDebug($" {profile.Value.Name} -> +{pair}");
                    _request.CompatibilityProfiles.Add(pair);
                }
            }

            // Walk additional runtime graphs for supports checks
            if (_success && _request.CompatibilityProfiles.Any())
            {
                Tuple <bool, List <RestoreTargetGraph>, RuntimeGraph> compatibilityResult = null;
                using (var runtimeTryRestoreTelemetry = TelemetryActivity.CreateTelemetryActivityWithNewOperationIdAndEvent(telemetryActivity.OperationId, RestoreAdditionalCompatCheck))
                {
                    compatibilityResult = await projectRestoreCommand.TryRestoreAsync(
                        projectRange,
                        _request.CompatibilityProfiles,
                        userPackageFolder,
                        fallbackPackageFolders,
                        remoteWalker,
                        context,
                        forceRuntimeGraphCreation : true,
                        token : token,
                        telemetryActivity : runtimeTryRestoreTelemetry);
                }

                _success = compatibilityResult.Item1;

                // TryRestore may contain graphs that are already in allGraphs if the
                // supports section contains the same TxM as the project framework.
                var currentGraphs = new HashSet <KeyValuePair <NuGetFramework, string> >(
                    allGraphs.Select(graph => new KeyValuePair <NuGetFramework, string>(
                                         graph.Framework,
                                         graph.RuntimeIdentifier))
                    );

                foreach (var graph in compatibilityResult.Item2)
                {
                    var key = new KeyValuePair <NuGetFramework, string>(
                        graph.Framework,
                        graph.RuntimeIdentifier);

                    if (currentGraphs.Add(key))
                    {
                        allGraphs.Add(graph);
                    }
                }
            }


            return(allGraphs);
        }
        /// <summary>
        /// Asynchronously gets a package downloader.
        /// </summary>
        /// <param name="packageIdentity">A package identity.</param>
        /// <param name="cacheContext">A source cache context.</param>
        /// <param name="logger">A logger.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A task that represents the asynchronous operation.
        /// The task result (<see cref="Task{TResult}.Result" />) returns a <see cref="IPackageDownloader" />
        /// instance.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="packageIdentity" />
        /// is either <c>null</c> or empty.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="cacheContext" />
        /// is either <c>null</c> or empty.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="logger" />
        /// is either <c>null</c> or empty.</exception>
        /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" />
        /// is cancelled.</exception>
        public async Task <IPackageDownloader> GetPackageDownloaderAsync(
            PackageIdentity packageIdentity,
            SourceCacheContext cacheContext,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            if (packageIdentity == null)
            {
                throw new ArgumentNullException(nameof(packageIdentity));
            }

            if (cacheContext == null)
            {
                throw new ArgumentNullException(nameof(cacheContext));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            cancellationToken.ThrowIfCancellationRequested();

            await EnsureResource();

            try
            {
                if (_throttle != null)
                {
                    await _throttle.WaitAsync();
                }

                cancellationToken.ThrowIfCancellationRequested();

                var packageDownloader = await _findPackagesByIdResource.GetPackageDownloaderAsync(
                    packageIdentity,
                    cacheContext,
                    logger,
                    cancellationToken);

                packageDownloader.SetThrottle(_throttle);
                packageDownloader.SetExceptionHandler(async exception =>
                {
                    if (exception is FatalProtocolException && _ignoreFailedSources)
                    {
                        if (!_ignoreWarning)
                        {
                            await _logger.LogAsync(
                                RestoreLogMessage.CreateWarning(
                                    NuGetLogCode.NU1801,
                                    exception.Message,
                                    packageIdentity.Id));
                        }

                        return(true);
                    }

                    return(false);
                });

                return(packageDownloader);
            }
            catch (FatalProtocolException e) when(_ignoreFailedSources)
            {
                if (!_ignoreWarning)
                {
                    await _logger.LogAsync(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1801, e.Message, packageIdentity.Id));
                }
            }
            finally
            {
                _throttle?.Release();
            }

            return(null);
        }