Пример #1
0
        /// <summary>
        /// Log upgrade warnings from the graphs.
        /// </summary>
        public static IEnumerable <RestoreLogMessage> GetDependenciesAboveUpperBounds(List <IndexedRestoreTargetGraph> graphs, ILogger logger)
        {
            var messages = new List <RestoreLogMessage>();

            foreach (var indexedGraph in graphs)
            {
                var graph = indexedGraph.Graph;

                foreach (var node in graph.Flattened)
                {
                    var dependencies = node.Data?.Dependencies ?? Enumerable.Empty <LibraryDependency>();

                    foreach (var dependency in dependencies)
                    {
                        // Check if the dependency has an upper bound
                        var dependencyRange = dependency.LibraryRange.VersionRange;
                        var upperBound      = dependencyRange?.MaxVersion;
                        if (upperBound != null)
                        {
                            var dependencyId = dependency.Name;

                            // If the version does not exist then it was not resolved or is a project and should be skipped.
                            var match = indexedGraph.GetItemById(dependencyId, LibraryType.Package);
                            if (match != null)
                            {
                                var actualVersion = match.Key.Version;

                                // If the upper bound is included then require that the version be higher than the upper bound to fail
                                // If the upper bound is not included, then an exact match on the upperbound is a failure
                                var compare = dependencyRange.IsMaxInclusive ? 1 : 0;

                                if (VersionComparer.VersionRelease.Compare(actualVersion, upperBound) >= compare)
                                {
                                    // True if the package already has an NU1107 error, NU1608 would be redundant here.
                                    if (!indexedGraph.HasErrors(dependencyId))
                                    {
                                        var parent = DiagnosticUtility.FormatIdentity(node.Key);
                                        var child  = DiagnosticUtility.FormatDependency(dependencyId, dependencyRange);
                                        var actual = DiagnosticUtility.FormatIdentity(match.Key);

                                        var message = string.Format(CultureInfo.CurrentCulture,
                                                                    Strings.Warning_VersionAboveUpperBound,
                                                                    parent,
                                                                    child,
                                                                    actual);

                                        messages.Add(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1608, message, dependencyId, graph.TargetGraphName));
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Merge log messages
            return(DiagnosticUtility.MergeOnTargetGraph(messages));
        }
Пример #2
0
        /// <summary>
        /// Log downgrade warnings from the graphs.
        /// </summary>
        private static Task LogDowngradeWarningsAsync(IEnumerable <RestoreTargetGraph> graphs, ILogger logger)
        {
            var messages = new List <RestoreLogMessage>();

            foreach (var graph in graphs)
            {
                if (graph.AnalyzeResult.Downgrades.Count > 0)
                {
                    // Find all dependencies in the flattened graph that are not packages.
                    var ignoreIds = new HashSet <string>(
                        graph.Flattened.Where(e => e.Key.Type != LibraryType.Package)
                        .Select(e => e.Key.Name),
                        StringComparer.OrdinalIgnoreCase);

                    foreach (var downgrade in graph.AnalyzeResult.Downgrades)
                    {
                        var downgraded   = downgrade.DowngradedFrom;
                        var downgradedBy = downgrade.DowngradedTo;

                        // Filter out non-package dependencies
                        if (!ignoreIds.Contains(downgraded.Key.Name))
                        {
                            // Not all dependencies have a min version, if one does not exist use 0.0.0
                            var fromVersion = downgraded.GetVersionRange().MinVersion
                                              ?? new NuGetVersion(0, 0, 0);

                            // Use the actual version resolved if it exists
                            var toVersion = downgradedBy.GetVersionOrDefault()
                                            ?? downgradedBy.GetVersionRange().MinVersion
                                            ?? new NuGetVersion(0, 0, 0);

                            var message = string.Format(
                                CultureInfo.CurrentCulture,
                                Strings.Log_DowngradeWarning,
                                downgraded.Key.Name,
                                fromVersion,
                                toVersion)
                                          + $" {Environment.NewLine} {downgraded.GetPathWithLastRange()} {Environment.NewLine} {downgradedBy.GetPathWithLastRange()}";

                            messages.Add(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1605, message, downgraded.Key.Name, graph.TargetGraphName));
                        }
                    }
                }
            }

            // Merge and log messages
            var mergedMessages = DiagnosticUtility.MergeOnTargetGraph(messages);

            return(logger.LogMessagesAsync(mergedMessages));
        }
Пример #3
0
        /// <summary>
        /// Log errors for missing dependencies.
        /// </summary>
        internal static async Task LogAsync(IEnumerable <IRestoreTargetGraph> graphs, RemoteWalkContext context, CancellationToken token)
        {
            var tasks = graphs.SelectMany(graph => graph.Unresolved.Select(e =>
                                                                           GetMessageAsync(
                                                                               graph.TargetGraphName,
                                                                               e,
                                                                               context.FilterDependencyProvidersForLibrary(e),
                                                                               context.PackageSourceMapping.IsEnabled,
                                                                               context.RemoteLibraryProviders,
                                                                               context.CacheContext,
                                                                               context.Logger,
                                                                               token))).ToArray();

            var messages = await Task.WhenAll(tasks);

            await context.Logger.LogMessagesAsync(DiagnosticUtility.MergeOnTargetGraph(messages));
        }
        /// <summary>
        /// Log warnings for all project issues related to unexpected dependencies.
        /// </summary>
        public static async Task LogAsync(IEnumerable <IRestoreTargetGraph> graphs, PackageSpec project, ILogger logger)
        {
            var ignoreIds = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            var graphList = graphs.AsList();

            // Index the flattened graph for faster lookups.
            var indexedGraphs = graphList.Select(IndexedRestoreTargetGraph.Create).ToList();

            // 1. Detect project dependency authoring issues in the current project.
            //    The user can fix these themselves.
            var projectMissingVersions = GetProjectDependenciesMissingVersion(project);

            ignoreIds.UnionWith(projectMissingVersions.Select(e => e.LibraryId));
            await logger.LogMessagesAsync(DiagnosticUtility.MergeOnTargetGraph(projectMissingVersions));

            var projectMissingLowerBounds = GetProjectDependenciesMissingLowerBounds(project);

            ignoreIds.UnionWith(projectMissingLowerBounds.Select(e => e.LibraryId));
            await logger.LogMessagesAsync(DiagnosticUtility.MergeOnTargetGraph(projectMissingLowerBounds));

            // Ignore generating NU1603/NU1602 across entire graph if lock file is enabled. Because
            // lock file enforce a fixed resolved version for all the different requests for the same package ID.
            if (!PackagesLockFileUtilities.IsNuGetLockFileEnabled(project))
            {
                // 2. Detect dependency and source issues across the entire graph
                //    where the minimum version was not matched exactly.
                //    Ignore packages already logged by #1
                var missingMinimums = GetMissingLowerBounds(graphList, ignoreIds);
                ignoreIds.UnionWith(missingMinimums.Select(e => e.LibraryId));
                await logger.LogMessagesAsync(DiagnosticUtility.MergeOnTargetGraph(missingMinimums));
            }

            // 3. Detect top level dependencies that have a version different from the specified version.
            //    Ignore packages already logged in #1 and #2 since those errors are more specific.
            var bumpedUp = GetBumpedUpDependencies(indexedGraphs, project, ignoreIds);
            await logger.LogMessagesAsync(DiagnosticUtility.MergeOnTargetGraph(bumpedUp));

            // 4. Detect dependencies that are higher than the upper bound of a version range.
            var aboveUpperBounds = GetDependenciesAboveUpperBounds(indexedGraphs, logger);
            await logger.LogMessagesAsync(aboveUpperBounds);
        }
Пример #5
0
        public static async Task LogAsync(IList <DownloadDependencyResolutionResult> downloadDependencyResults, IList <IRemoteDependencyProvider> remoteLibraryProviders, SourceCacheContext sourceCacheContext,
                                          ILogger logger, CancellationToken token)
        {
            var messageTasks = new List <Task <RestoreLogMessage> >();

            foreach (var ddi in downloadDependencyResults)
            {
                foreach (var unresolved in ddi.Unresolved)
                {
                    messageTasks.Add(GetMessageAsync(
                                         ddi.Framework.ToString(),
                                         unresolved,
                                         remoteLibraryProviders, sourceCacheContext,
                                         logger,
                                         token));
                }
            }

            var messages = await Task.WhenAll(messageTasks);

            await logger.LogMessagesAsync(DiagnosticUtility.MergeOnTargetGraph(messages));
        }
Пример #6
0
        internal static async Task LogAsync(IList <DownloadDependencyResolutionResult> downloadDependencyResults, RemoteWalkContext context, CancellationToken token)
        {
            var messageTasks = new List <Task <RestoreLogMessage> >();

            foreach (var ddi in downloadDependencyResults)
            {
                foreach (var unresolved in ddi.Unresolved)
                {
                    messageTasks.Add(GetMessageAsync(
                                         ddi.Framework.ToString(),
                                         unresolved,
                                         context.FilterDependencyProvidersForLibrary(unresolved),
                                         context.CacheContext,
                                         context.Logger,
                                         token));
                }
            }

            var messages = await Task.WhenAll(messageTasks);

            await context.Logger.LogMessagesAsync(DiagnosticUtility.MergeOnTargetGraph(messages));
        }