Example #1
0
        /// <summary>
        /// Fetches the latest versions for all of the packages that are
        /// to be listed
        /// </summary>
        /// <param name="packages">The packages found in a project</param>
        /// <param name="listPackageArgs">List args for the token and source provider</param>
        /// <returns>A data structure like packages, but includes the latest versions</returns>
        private async Task AddLatestVersionsAsync(
            IEnumerable <FrameworkPackages> packages,
            ListPackageArgs listPackageArgs)
        {
            //Unique Dictionary for packages and list of latest versions to handle different sources
            var packagesVersionsDict = new Dictionary <string, IList <IPackageSearchMetadata> >();

            AddPackagesToDict(packages, packagesVersionsDict);

            //Prepare requests for each of the packages
            var providers = Repository.Provider.GetCoreV3();
            var getLatestVersionsRequests = new List <Task>();

            foreach (var package in packagesVersionsDict)
            {
                getLatestVersionsRequests.AddRange(
                    PrepareLatestVersionsRequests(
                        package.Key,
                        listPackageArgs,
                        providers,
                        packagesVersionsDict));
            }

            // Make requests in parallel.
            await RequestNuGetResourcesInParallelAsync(getLatestVersionsRequests);

            //Save latest versions within the InstalledPackageReference
            await GetVersionsFromDictAsync(packages, packagesVersionsDict, listPackageArgs);
        }
        /// <summary>
        /// Get last versions for every package from the unique packages
        /// </summary>
        /// <param name="packages"> Project packages to get filled with latest versions </param>
        /// <param name="packagesVersionsDict"> Unique packages that are mapped to latest versions
        /// from different sources </param>
        /// <param name="listPackageArgs">Arguments for list package to get the right latest version</param>
        private async Task GetVersionsFromDictAsync(
            IEnumerable <FrameworkPackages> packages,
            Dictionary <string, IList <IPackageSearchMetadata> > packagesVersionsDict,
            ListPackageArgs listPackageArgs)
        {
            foreach (var frameworkPackages in packages)
            {
                foreach (var topLevelPackage in frameworkPackages.TopLevelPackages)
                {
                    var matchingPackage = packagesVersionsDict.Where(p => p.Key.Equals(topLevelPackage.Name, StringComparison.OrdinalIgnoreCase)).First();

                    if (!listPackageArgs.IncludeDeprecated && matchingPackage.Value.Count > 0)
                    {
                        var latestVersion = matchingPackage.Value.Where(newVersion => MeetsConstraints(newVersion.Identity.Version, topLevelPackage, listPackageArgs)).Max(i => i.Identity.Version);

                        topLevelPackage.LatestPackageMetadata = matchingPackage.Value.First(p => p.Identity.Version == latestVersion);
                        topLevelPackage.UpdateLevel           = GetUpdateLevel(topLevelPackage.ResolvedPackageMetadata.Identity.Version, topLevelPackage.LatestPackageMetadata.Identity.Version);
                    }

                    var matchingPackagesWithDeprecationMetadata = await Task.WhenAll(
                        matchingPackage.Value.Select(async v => new { SearchMetadata = v, DeprecationMetadata = await v.GetDeprecationMetadataAsync() }));

                    // Update resolved version with deprecated information returned by the server.
                    var resolvedVersionFromServer = matchingPackagesWithDeprecationMetadata
                                                    .Where(v => v.SearchMetadata.Identity.Version == topLevelPackage.ResolvedPackageMetadata.Identity.Version && v.DeprecationMetadata != null)
                                                    .FirstOrDefault();

                    if (resolvedVersionFromServer != null)
                    {
                        topLevelPackage.ResolvedPackageMetadata = resolvedVersionFromServer.SearchMetadata;
                    }
                }

                foreach (var transitivePackage in frameworkPackages.TransitivePackages)
                {
                    var matchingPackage = packagesVersionsDict.Where(p => p.Key.Equals(transitivePackage.Name, StringComparison.OrdinalIgnoreCase)).First();

                    if (!listPackageArgs.IncludeDeprecated && matchingPackage.Value.Count > 0)
                    {
                        var latestVersion = matchingPackage.Value.Where(newVersion => MeetsConstraints(newVersion.Identity.Version, transitivePackage, listPackageArgs)).Max(i => i.Identity.Version);

                        transitivePackage.LatestPackageMetadata = matchingPackage.Value.First(p => p.Identity.Version == latestVersion);
                        transitivePackage.UpdateLevel           = GetUpdateLevel(transitivePackage.ResolvedPackageMetadata.Identity.Version, transitivePackage.LatestPackageMetadata.Identity.Version);
                    }

                    var matchingPackagesWithDeprecationMetadata = await Task.WhenAll(
                        matchingPackage.Value.Select(async v => new { SearchMetadata = v, DeprecationMetadata = await v.GetDeprecationMetadataAsync() }));

                    // Update resolved version with deprecated information returned by the server.
                    var resolvedVersionFromServer = matchingPackagesWithDeprecationMetadata
                                                    .Where(v => v.SearchMetadata.Identity.Version == transitivePackage.ResolvedPackageMetadata.Identity.Version && v.DeprecationMetadata != null)
                                                    .FirstOrDefault();

                    if (resolvedVersionFromServer != null)
                    {
                        transitivePackage.ResolvedPackageMetadata = resolvedVersionFromServer.SearchMetadata;
                    }
                }
            }
        }
Example #3
0
        public static bool FilterPackages(IEnumerable <FrameworkPackages> packages, ListPackageArgs listPackageArgs)
        {
            switch (listPackageArgs.ReportType)
            {
            case ReportType.Default: break;     // No filtering in this case

            case ReportType.Outdated:
                FilterPackages(
                    packages,
                    ListPackageHelper.TopLevelPackagesFilterForOutdated,
                    ListPackageHelper.TransitivePackagesFilterForOutdated);
                break;

            case ReportType.Deprecated:
                FilterPackages(
                    packages,
                    ListPackageHelper.PackagesFilterForDeprecated,
                    ListPackageHelper.PackagesFilterForDeprecated);
                break;

            case ReportType.Vulnerable:
                FilterPackages(
                    packages,
                    ListPackageHelper.PackagesFilterForVulnerable,
                    ListPackageHelper.PackagesFilterForVulnerable);
                break;
            }

            return(packages.Any(p => p.TopLevelPackages.Any() ||
                                listPackageArgs.IncludeTransitive && p.TransitivePackages.Any()));
        }
Example #4
0
        /// <summary>
        /// Gets the requested version of a package from a specific source
        /// </summary>
        /// <param name="packageSource">The source to look for packages at</param>
        /// <param name="listPackageArgs">The list args for the cancellation token</param>
        /// <param name="packageId">Package to look for</param>
        /// <param name="requestedVersion">Requested package version</param>
        /// <param name="packagesVersionsDict">A reference to the unique packages in the project
        /// to be able to handle different sources having different latest versions</param>
        /// <returns>An updated package with the resolved version metadata from a single source</returns>
        private async Task GetPackageMetadataFromSourceAsync(
            PackageSource packageSource,
            ListPackageArgs listPackageArgs,
            string packageId,
            NuGetVersion requestedVersion,
            Dictionary <string, IList <IPackageSearchMetadata> > packagesVersionsDict)
        {
            SourceRepository sourceRepository = _sourceRepositoryCache[packageSource];
            var packageMetadataResource       = await sourceRepository
                                                .GetResourceAsync <PackageMetadataResource>(listPackageArgs.CancellationToken);

            using var sourceCacheContext = new SourceCacheContext();
            var packages = await packageMetadataResource.GetMetadataAsync(
                packageId,
                includePrerelease : true,
                includeUnlisted : true, // Include unlisted because deprecated packages may be unlisted.
                sourceCacheContext : sourceCacheContext,
                log : listPackageArgs.Logger,
                token : listPackageArgs.CancellationToken);

            var resolvedVersionsForPackage = packagesVersionsDict
                                             .Where(p => p.Key.Equals(packageId, StringComparison.OrdinalIgnoreCase))
                                             .Single()
                                             .Value;

            var resolvedPackageVersionMetadata = packages.SingleOrDefault(p => p.Identity.Version.Equals(requestedVersion));

            if (resolvedPackageVersionMetadata != null)
            {
                // Package version metadata found on source
                resolvedVersionsForPackage.Add(resolvedPackageVersionMetadata);
            }
        }
Example #5
0
        /// <summary>
        /// Fetches additional info (e.g. deprecation, vulnerability) for all of the packages found in a project.
        /// </summary>
        /// <param name="packages">The packages found in a project.</param>
        /// <param name="listPackageArgs">List args for the token and source provider</param>
        private async Task GetRegistrationMetadataAsync(
            IEnumerable <FrameworkPackages> packages,
            ListPackageArgs listPackageArgs)
        {
            // Unique dictionary for packages and list of versions to handle different sources
            var packagesVersionsDict = new Dictionary <string, IList <IPackageSearchMetadata> >();

            AddPackagesToDict(packages, packagesVersionsDict);

            // Clone and filter package versions to avoid duplicate requests
            // and to avoid collection being enumerated to be modified.
            var distinctPackageVersionsDict = GetUniqueResolvedPackages(packages);

            // Prepare requests for each of the packages
            var resourceRequestTasks = new List <Task>();

            foreach (var packageIdAndVersions in distinctPackageVersionsDict)
            {
                foreach (var packageVersion in packageIdAndVersions.Value)
                {
                    resourceRequestTasks.AddRange(
                        PrepareCurrentVersionsRequests(
                            packageIdAndVersions.Key,
                            packageVersion,
                            listPackageArgs,
                            packagesVersionsDict));
                }
            }

            // Make requests in parallel.
            await RequestNuGetResourcesInParallelAsync(resourceRequestTasks);

            // Save resolved versions within the InstalledPackageReference
            await GetVersionsFromDictAsync(packages, packagesVersionsDict, listPackageArgs);
        }
        /// <summary>
        /// Gets the requested version of a package from a specific source
        /// </summary>
        /// <param name="packageSource">The source to look for packages at</param>
        /// <param name="listPackageArgs">The list args for the cancellation token</param>
        /// <param name="packageId">Package to look for</param>
        /// <param name="requestedVersion">Requested package version</param>
        /// <param name="providers">The providers to use when looking at sources</param>
        /// <param name="packagesVersionsDict">A reference to the unique packages in the project
        /// to be able to handle different sources having different latest versions</param>
        /// <returns>An updated package with the resolved version metadata from a single source</returns>
        private async Task GetPackageMetadataFromSourceAsync(
            PackageSource packageSource,
            ListPackageArgs listPackageArgs,
            string packageId,
            NuGetVersion requestedVersion,
            IEnumerable <Lazy <INuGetResourceProvider> > providers,
            Dictionary <string, IList <IPackageSearchMetadata> > packagesVersionsDict)
        {
            var sourceRepository        = Repository.CreateSource(providers, packageSource, FeedType.Undefined);
            var packageMetadataResource = await sourceRepository
                                          .GetResourceAsync <PackageMetadataResource>(listPackageArgs.CancellationToken);

            var packages = await packageMetadataResource.GetMetadataAsync(
                packageId,
                includePrerelease : true,
                includeUnlisted : true, // Include unlisted because deprecated packages may be unlisted.
                sourceCacheContext : new SourceCacheContext(),
                log : NullLogger.Instance,
                token : listPackageArgs.CancellationToken);

            var resolvedVersionsForPackage = packagesVersionsDict
                                             .Where(p => p.Key.Equals(packageId, StringComparison.OrdinalIgnoreCase))
                                             .Single()
                                             .Value;

            var resolvedPackageVersionMetadata = packages.SingleOrDefault(p => p.Identity.Version.Equals(requestedVersion));

            if (resolvedPackageVersionMetadata != null)
            {
                // Package version metadata found on source
                resolvedVersionsForPackage.Add(resolvedPackageVersionMetadata);
            }
        }
 private static void DisplayMessages(ListPackageArgs packageRefArgs)
 {
     if (packageRefArgs.ReportType != ReportType.Outdated &&
         (packageRefArgs.Prerelease || packageRefArgs.HighestMinor || packageRefArgs.HighestPatch))
     {
         Console.WriteLine(Strings.ListPkg_VulnerableIgnoredOptions);
     }
 }
Example #8
0
        /// <summary>
        /// Pre-populate _sourceRepositoryCache so source repository can be reused between different calls.
        /// </summary>
        /// <param name="listPackageArgs">List args for the token and source provider</param>
        private void PopulateSourceRepositoryCache(ListPackageArgs listPackageArgs)
        {
            IEnumerable <Lazy <INuGetResourceProvider> > providers = Repository.Provider.GetCoreV3();
            IEnumerable <PackageSource> sources = listPackageArgs.PackageSources;

            foreach (PackageSource source in sources)
            {
                SourceRepository sourceRepository = Repository.CreateSource(providers, source, FeedType.Undefined);
                _sourceRepositoryCache[source] = sourceRepository;
            }
        }
Example #9
0
        /// <summary>
        /// Prepares the calls to sources for latest versions and updates
        /// the list of tasks with the requests
        /// </summary>
        /// <param name="package">The package to get the latest version for</param>
        /// <param name="listPackageArgs">List args for the token and source provider></param>
        /// <param name="providers">The providers to use when looking at sources</param>
        /// <param name="packagesVersionsDict">A reference to the unique packages in the project
        /// to be able to handle different sources having different latest versions</param>
        /// <returns>A list of tasks for all latest versions for packages from all sources</returns>
        private IList <Task> PrepareLatestVersionsRequests(
            string package,
            ListPackageArgs listPackageArgs,
            IEnumerable <Lazy <INuGetResourceProvider> > providers,
            Dictionary <string, IList <IPackageSearchMetadata> > packagesVersionsDict)
        {
            var latestVersionsRequests = new List <Task>();
            var sources = listPackageArgs.PackageSources;

            foreach (var packageSource in sources)
            {
                latestVersionsRequests.Add(GetLatestVersionPerSourceAsync(packageSource, listPackageArgs, package, providers, packagesVersionsDict));
            }
            return(latestVersionsRequests);
        }
        /// <summary>
        /// Gets the highest version of a package from a specific source
        /// </summary>
        /// <param name="packageSource">The source to look for packages at</param>
        /// <param name="listPackageArgs">The list args for the cancellation token</param>
        /// <param name="package">Package to look for updates for</param>
        /// <param name="providers">The providers to use when looking at sources</param>
        /// <param name="packagesVersionsDict">A reference to the unique packages in the project
        /// to be able to handle different sources having different latest versions</param>
        /// <returns>An updated package with the highest version at a single source</returns>
        private async Task GetLatestVersionPerSourceAsync(
            PackageSource packageSource,
            ListPackageArgs listPackageArgs,
            string package,
            IEnumerable <Lazy <INuGetResourceProvider> > providers,
            Dictionary <string, IList <IPackageSearchMetadata> > packagesVersionsDict)
        {
            var sourceRepository        = Repository.CreateSource(providers, packageSource, FeedType.Undefined);
            var packageMetadataResource = await sourceRepository.GetResourceAsync <PackageMetadataResource>(listPackageArgs.CancellationToken);

            var packages = (await packageMetadataResource.GetMetadataAsync(package, true, false, new SourceCacheContext(), NullLogger.Instance, listPackageArgs.CancellationToken));

            var latestVersionsForPackage = packagesVersionsDict.Where(p => p.Key.Equals(package, StringComparison.OrdinalIgnoreCase)).Single().Value;

            latestVersionsForPackage.AddRange(packages);
        }
        /// <summary>
        /// Get last versions for every package from the unqiue packages
        /// </summary>
        /// <param name="packages"> Project packages to get filled with latest versions </param>
        /// <param name="packagesVersionsDict"> Unique packages that are mapped to latest versions
        /// from different sources </param>
        /// <param name="listPackageArgs">Arguments for list package to get the right latest version</param>
        private void GetVersionsFromDict(IEnumerable <FrameworkPackages> packages,
                                         Dictionary <string, IList <NuGetVersion> > packagesVersionsDict,
                                         ListPackageArgs listPackageArgs)
        {
            foreach (var frameworkPackages in packages)
            {
                foreach (var topLevelPackage in frameworkPackages.TopLevelPackages)
                {
                    var matchingPackage = packagesVersionsDict.Where(p => p.Key.Equals(topLevelPackage.Name, StringComparison.OrdinalIgnoreCase)).First();
                    topLevelPackage.LatestVersion = matchingPackage.Value.Where(newVersion => MeetsConstraints(newVersion, topLevelPackage, listPackageArgs)).Max();
                    topLevelPackage.UpdateLevel   = GetUpdateLevel(topLevelPackage.ResolvedVersion, topLevelPackage.LatestVersion);
                }

                foreach (var transitivePackage in frameworkPackages.TransitivePackages)
                {
                    var matchingPackage = packagesVersionsDict.Where(p => p.Key.Equals(transitivePackage.Name, StringComparison.OrdinalIgnoreCase)).First();
                    transitivePackage.LatestVersion = matchingPackage.Value.Where(newVersion => MeetsConstraints(newVersion, transitivePackage, listPackageArgs)).Max();
                    transitivePackage.UpdateLevel   = GetUpdateLevel(transitivePackage.ResolvedVersion, transitivePackage.LatestVersion);
                }
            }
        }
Example #12
0
        /// <summary>
        /// Prepares the calls to sources for current versions and updates
        /// the list of tasks with the requests
        /// </summary>
        /// <param name="packageId">The package ID to get the current version metadata for</param>
        /// <param name="requestedVersion">The version of the requested package</param>
        /// <param name="listPackageArgs">List args for the token and source provider></param>
        /// <param name="packagesVersionsDict">A reference to the unique packages in the project
        /// to be able to handle different sources having different latest versions</param>
        /// <returns>A list of tasks for all current versions for packages from all sources</returns>
        private IList <Task> PrepareCurrentVersionsRequests(
            string packageId,
            NuGetVersion requestedVersion,
            ListPackageArgs listPackageArgs,
            Dictionary <string, IList <IPackageSearchMetadata> > packagesVersionsDict)
        {
            var requests = new List <Task>();
            var sources  = listPackageArgs.PackageSources;

            foreach (var packageSource in sources)
            {
                requests.Add(
                    GetPackageMetadataFromSourceAsync(
                        packageSource,
                        listPackageArgs,
                        packageId,
                        requestedVersion,
                        packagesVersionsDict));
            }

            return(requests);
        }
        /// <summary>
        /// Fetches the latest versions for all of the packages that are
        /// to be listed
        /// </summary>
        /// <param name="packages">The packages found in a project</param>
        /// <param name="listPackageArgs">List args for the token and source provider</param>
        /// <returns>A data structure like packages, but includes the latest versions</returns>
        private async Task AddLatestVersionsAsync(
            IEnumerable <FrameworkPackages> packages, ListPackageArgs listPackageArgs)
        {
            var providers = Repository.Provider.GetCoreV3();

            //Handling concurrency and throttling variables
            var maxTasks = Environment.ProcessorCount;
            var contactSourcesRunningTasks = new List <Task>();
            var latestVersionsRequests     = new List <Task>();

            //Unique Dictionary for packages and list of latest versions to handle different sources
            var packagesVersionsDict = new Dictionary <string, IList <NuGetVersion> >();

            AddPackagesToDict(packages, packagesVersionsDict);

            //Prepare requests for each of the packages
            foreach (var package in packagesVersionsDict)
            {
                latestVersionsRequests.AddRange(PrepareLatestVersionsRequests(package.Key, listPackageArgs, providers, packagesVersionsDict));
            }

            //Make the calls to the sources
            foreach (var latestVersionTask in latestVersionsRequests)
            {
                contactSourcesRunningTasks.Add(Task.Run(() => latestVersionTask));
                //Throttle if needed
                if (maxTasks <= contactSourcesRunningTasks.Count)
                {
                    var finishedTask = await Task.WhenAny(contactSourcesRunningTasks);

                    contactSourcesRunningTasks.Remove(finishedTask);
                }
            }
            await Task.WhenAll(contactSourcesRunningTasks);

            //Save latest versions within the InstalledPackageReference
            GetVersionsFromDict(packages, packagesVersionsDict, listPackageArgs);
        }
Example #14
0
        private static void WarnForHttpSources(ListPackageArgs listPackageArgs)
        {
            List <PackageSource> httpPackageSources = null;

            foreach (PackageSource packageSource in listPackageArgs.PackageSources)
            {
                if (packageSource.IsHttp && !packageSource.IsHttps)
                {
                    if (httpPackageSources == null)
                    {
                        httpPackageSources = new();
                    }
                    httpPackageSources.Add(packageSource);
                }
            }

            if (httpPackageSources != null && httpPackageSources.Count != 0)
            {
                if (httpPackageSources.Count == 1)
                {
                    listPackageArgs.Logger.LogWarning(
                        string.Format(CultureInfo.CurrentCulture,
                                      Strings.Warning_HttpServerUsage,
                                      "list package",
                                      httpPackageSources[0]));
                }
                else
                {
                    listPackageArgs.Logger.LogWarning(
                        string.Format(CultureInfo.CurrentCulture,
                                      Strings.Warning_HttpServerUsage_MultipleSources,
                                      "list package",
                                      Environment.NewLine + string.Join(Environment.NewLine, httpPackageSources.Select(e => e.Name))));
                }
            }
        }
Example #15
0
        /// <summary>
        /// Given a found version from a source and the current version and the args
        /// of list package, this function checks if the found version meets the required
        /// highest-patch, highest-minor or prerelease
        /// </summary>
        /// <param name="newVersion">Version from a source</param>
        /// <param name="package">The required package with its current version</param>
        /// <param name="listPackageArgs">Used to get the constraints</param>
        /// <returns>Whether the new version meets the constraints or not</returns>
        private bool MeetsConstraints(NuGetVersion newVersion, InstalledPackageReference package, ListPackageArgs listPackageArgs)
        {
            var result = !newVersion.IsPrerelease || listPackageArgs.Prerelease || package.ResolvedPackageMetadata.Identity.Version.IsPrerelease;

            if (listPackageArgs.HighestPatch)
            {
                result = newVersion.Minor.Equals(package.ResolvedPackageMetadata.Identity.Version.Minor) && newVersion.Major.Equals(package.ResolvedPackageMetadata.Identity.Version.Major) && result;
            }

            if (listPackageArgs.HighestMinor)
            {
                result = newVersion.Major.Equals(package.ResolvedPackageMetadata.Identity.Version.Major) && result;
            }

            return(result);
        }
        public static void Register(
            CommandLineApplication app,
            Func <ILogger> getLogger,
            Action <LogLevel> setLogLevel,
            Func <IListPackageCommandRunner> getCommandRunner)
        {
            app.Command("list", listpkg =>
            {
                listpkg.Description = Strings.ListPkg_Description;
                listpkg.HelpOption(XPlatUtility.HelpOption);

                listpkg.Option(
                    CommandConstants.ForceEnglishOutputOption,
                    Strings.ForceEnglishOutput_Description,
                    CommandOptionType.NoValue);

                var path = listpkg.Argument(
                    "<PROJECT | SOLUTION>",
                    Strings.ListPkg_PathDescription,
                    multipleValues: false);

                var framework = listpkg.Option(
                    "--framework",
                    Strings.ListPkg_FrameworkDescription,
                    CommandOptionType.MultipleValue);

                var deprecatedReport = listpkg.Option(
                    "--deprecated",
                    Strings.ListPkg_DeprecatedDescription,
                    CommandOptionType.NoValue);

                var outdatedReport = listpkg.Option(
                    "--outdated",
                    Strings.ListPkg_OutdatedDescription,
                    CommandOptionType.NoValue);

                var vulnerableReport = listpkg.Option(
                    "--vulnerable",
                    Strings.ListPkg_VulnerableDescription,
                    CommandOptionType.NoValue);

                var includeTransitive = listpkg.Option(
                    "--include-transitive",
                    Strings.ListPkg_TransitiveDescription,
                    CommandOptionType.NoValue);

                var prerelease = listpkg.Option(
                    "--include-prerelease",
                    Strings.ListPkg_PrereleaseDescription,
                    CommandOptionType.NoValue);

                var highestPatch = listpkg.Option(
                    "--highest-patch",
                    Strings.ListPkg_HighestPatchDescription,
                    CommandOptionType.NoValue);

                var highestMinor = listpkg.Option(
                    "--highest-minor",
                    Strings.ListPkg_HighestMinorDescription,
                    CommandOptionType.NoValue);

                var source = listpkg.Option(
                    "--source",
                    Strings.ListPkg_SourceDescription,
                    CommandOptionType.MultipleValue);

                var config = listpkg.Option(
                    "--config",
                    Strings.ListPkg_ConfigDescription,
                    CommandOptionType.SingleValue);

                var interactive = listpkg.Option(
                    "--interactive",
                    Strings.NuGetXplatCommand_Interactive,
                    CommandOptionType.NoValue);

                var verbosity = listpkg.Option(
                    "-v|--verbosity",
                    Strings.Verbosity_Description,
                    CommandOptionType.SingleValue);

                listpkg.OnExecute(async() =>
                {
                    var logger = getLogger();

                    setLogLevel(XPlatUtility.MSBuildVerbosityToNuGetLogLevel(verbosity.Value()));

                    var settings = ProcessConfigFile(config.Value(), path.Value);
                    var sources  = source.Values;

                    var packageSources = GetPackageSources(settings, sources, config);

                    VerifyValidFrameworks(framework);

                    var reportType = GetReportType(
                        isOutdated: outdatedReport.HasValue(),
                        isDeprecated: deprecatedReport.HasValue(),
                        isVulnerable: vulnerableReport.HasValue());

                    var packageRefArgs = new ListPackageArgs(
                        path.Value,
                        packageSources,
                        framework.Values,
                        reportType,
                        includeTransitive.HasValue(),
                        prerelease.HasValue(),
                        highestPatch.HasValue(),
                        highestMinor.HasValue(),
                        logger,
                        CancellationToken.None);

                    DisplayMessages(packageRefArgs);

                    DefaultCredentialServiceUtility.SetupDefaultCredentialService(getLogger(), !interactive.HasValue());

                    var listPackageCommandRunner = getCommandRunner();
                    await listPackageCommandRunner.ExecuteCommandAsync(packageRefArgs);
                    return(0);
                });
            });
        }
Example #17
0
        public static void Register(CommandLineApplication app, Func <ILogger> getLogger,
                                    Func <IListPackageCommandRunner> getCommandRunner)
        {
            app.Command("list", listpkg =>
            {
                listpkg.Description = Strings.ListPkg_Description;
                listpkg.HelpOption(XPlatUtility.HelpOption);

                listpkg.Option(
                    CommandConstants.ForceEnglishOutputOption,
                    Strings.ForceEnglishOutput_Description,
                    CommandOptionType.NoValue);

                var path = listpkg.Argument(
                    "<PROJECT | SOLUTION>",
                    Strings.ListPkg_PathDescription,
                    multipleValues: false);

                var framework = listpkg.Option(
                    "--framework",
                    Strings.ListPkg_FrameworkDescription,
                    CommandOptionType.MultipleValue);

                var includeOutdated = listpkg.Option(
                    "--outdated",
                    Strings.ListPkg_OutdatedDescription,
                    CommandOptionType.NoValue);

                var includeDeprecated = listpkg.Option(
                    "--deprecated",
                    Strings.ListPkg_DeprecatedDescription,
                    CommandOptionType.NoValue);

                var includeTransitive = listpkg.Option(
                    "--include-transitive",
                    Strings.ListPkg_TransitiveDescription,
                    CommandOptionType.NoValue);

                var prerelease = listpkg.Option(
                    "--include-prerelease",
                    Strings.ListPkg_PrereleaseDescription,
                    CommandOptionType.NoValue);

                var highestPatch = listpkg.Option(
                    "--highest-patch",
                    Strings.ListPkg_HighestPatchDescription,
                    CommandOptionType.NoValue);

                var highestMinor = listpkg.Option(
                    "--highest-minor",
                    Strings.ListPkg_HighestMinorDescription,
                    CommandOptionType.NoValue);

                var source = listpkg.Option(
                    "--source",
                    Strings.ListPkg_SourceDescription,
                    CommandOptionType.MultipleValue);

                var config = listpkg.Option(
                    "--config",
                    Strings.ListPkg_ConfigDescription,
                    CommandOptionType.SingleValue);

                listpkg.OnExecute(async() =>
                {
                    var logger = getLogger();

                    var settings = ProcessConfigFile(config.Value(), path.Value);
                    var sources  = source.Values;

                    var packageSources = GetPackageSources(settings, sources, config);

                    VerifyValidFrameworks(framework);

                    var packageRefArgs = new ListPackageArgs(
                        path.Value,
                        packageSources,
                        framework.Values,
                        includeOutdated.HasValue(),
                        includeDeprecated.HasValue(),
                        includeTransitive.HasValue(),
                        prerelease.HasValue(),
                        highestPatch.HasValue(),
                        highestMinor.HasValue(),
                        logger,
                        CancellationToken.None);

                    var listPackageCommandRunner = getCommandRunner();
                    await listPackageCommandRunner.ExecuteCommandAsync(packageRefArgs);
                    return(0);
                });
            });
        }
        public async Task ExecuteCommandAsync(ListPackageArgs listPackageArgs)
        {
            if (!File.Exists(listPackageArgs.Path))
            {
                Console.Error.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                                      Strings.ListPkg_ErrorFileNotFound,
                                                      listPackageArgs.Path));
                return;
            }
            //If the given file is a solution, get the list of projects
            //If not, then it's a project, which is put in a list
            var projectsPaths = Path.GetExtension(listPackageArgs.Path).Equals(".sln") ?
                                MSBuildAPIUtility.GetProjectsFromSolution(listPackageArgs.Path).Where(f => File.Exists(f)) :
                                new List <string>(new string[] { listPackageArgs.Path });

            var autoReferenceFound = false;
            var deprecatedFound    = false;

            var msBuild = new MSBuildAPIUtility(listPackageArgs.Logger);

            //Print sources
            if (listPackageArgs.IncludeOutdated || listPackageArgs.IncludeDeprecated)
            {
                Console.WriteLine();
                Console.WriteLine(Strings.ListPkg_SourcesUsedDescription);
                ProjectPackagesPrintUtility.PrintSources(listPackageArgs.PackageSources);
                Console.WriteLine();
            }

            foreach (var projectPath in projectsPaths)
            {
                //Open project to evaluate properties for the assets
                //file and the name of the project
                var project = MSBuildAPIUtility.GetProject(projectPath);

                if (!MSBuildAPIUtility.IsPackageReferenceProject(project))
                {
                    Console.Error.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                                          Strings.Error_NotPRProject,
                                                          projectPath));
                    Console.WriteLine();
                    continue;
                }

                var projectName = project.GetPropertyValue(ProjectName);

                var assetsPath = project.GetPropertyValue(ProjectAssetsFile);

                // If the file was not found, print an error message and continue to next project
                if (!File.Exists(assetsPath))
                {
                    Console.Error.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                                          Strings.Error_AssetsFileNotFound,
                                                          projectPath));
                    Console.WriteLine();
                }
                else
                {
                    var lockFileFormat = new LockFileFormat();
                    var assetsFile     = lockFileFormat.Read(assetsPath);

                    // Assets file validation
                    if (assetsFile.PackageSpec != null &&
                        assetsFile.Targets != null &&
                        assetsFile.Targets.Count != 0)
                    {
                        // Get all the packages that are referenced in a project
                        var packages = msBuild.GetResolvedVersions(project.FullPath, listPackageArgs.Frameworks, assetsFile, listPackageArgs.IncludeTransitive);

                        // If packages equals null, it means something wrong happened
                        // with reading the packages and it was handled and message printed
                        // in MSBuildAPIUtility function, but we need to move to the next project
                        if (packages != null)
                        {
                            // No packages means that no package references at all were found
                            if (!packages.Any())
                            {
                                Console.WriteLine(string.Format(Strings.ListPkg_NoPackagesFoundForFrameworks, projectName));
                            }
                            else
                            {
                                var printPackages = true;

                                // Handle --outdated
                                if (listPackageArgs.IncludeOutdated)
                                {
                                    await AddLatestVersionsAsync(packages, listPackageArgs);

                                    printPackages = await FilterOutdatedPackagesAsync(packages);

                                    // If after filtering, all packages were found up to date, inform the user
                                    // and do not print anything
                                    if (!printPackages)
                                    {
                                        Console.WriteLine(string.Format(Strings.ListPkg_NoUpdatesForProject, projectName));
                                    }
                                }
                                // Handle --deprecated
                                else if (listPackageArgs.IncludeDeprecated)
                                {
                                    await GetDeprecationInfoAsync(packages, listPackageArgs);

                                    printPackages = await FilterDeprecatedPackagesAsync(packages);

                                    // If after filtering, no packages were found to be deprecated, inform the user
                                    // and do not print anything
                                    if (!printPackages)
                                    {
                                        Console.WriteLine(string.Format(Strings.ListPkg_NoDeprecatedPackagesForProject, projectName));
                                    }
                                }

                                // Make sure print is still needed, which may be changed in case
                                // outdated filtered all packages out
                                if (printPackages)
                                {
                                    var printPackagesResult = await ProjectPackagesPrintUtility.PrintPackagesAsync(
                                        packages,
                                        projectName,
                                        listPackageArgs.IncludeTransitive,
                                        listPackageArgs.IncludeOutdated,
                                        listPackageArgs.IncludeDeprecated);

                                    autoReferenceFound = autoReferenceFound || printPackagesResult.AutoReferenceFound;
                                    deprecatedFound    = deprecatedFound || printPackagesResult.DeprecatedFound;
                                }
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine(string.Format(Strings.ListPkg_ErrorReadingAssetsFile, assetsPath));
                    }

                    // Unload project
                    ProjectCollection.GlobalProjectCollection.UnloadProject(project);
                }
            }

            // If any auto-references were found, a line is printed
            // explaining what (A) means
            if (autoReferenceFound)
            {
                Console.WriteLine(Strings.ListPkg_AutoReferenceDescription);
            }

            // If any deprecated packages were found as part of the --outdated command,
            // a line is printed explaining what (D) means.
            if (listPackageArgs.IncludeOutdated && deprecatedFound)
            {
                Console.WriteLine(Strings.ListPkg_DeprecatedPkgDescription);
            }
        }
Example #19
0
        public async Task ExecuteCommandAsync(ListPackageArgs listPackageArgs)
        {
            if (!File.Exists(listPackageArgs.Path))
            {
                Console.Error.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                                      Strings.ListPkg_ErrorFileNotFound,
                                                      listPackageArgs.Path));
                return;
            }
            //If the given file is a solution, get the list of projects
            //If not, then it's a project, which is put in a list
            var projectsPaths = Path.GetExtension(listPackageArgs.Path).Equals(".sln") ?
                                MSBuildAPIUtility.GetProjectsFromSolution(listPackageArgs.Path).Where(f => File.Exists(f)) :
                                new List <string>(new string[] { listPackageArgs.Path });

            var autoReferenceFound = false;
            var msBuild            = new MSBuildAPIUtility(listPackageArgs.Logger);

            //Print sources, but not for generic list (which is offline)
            if (listPackageArgs.ReportType != ReportType.Default)
            {
                Console.WriteLine();
                Console.WriteLine(Strings.ListPkg_SourcesUsedDescription);
                ProjectPackagesPrintUtility.PrintSources(listPackageArgs.PackageSources);
                Console.WriteLine();
            }

            foreach (var projectPath in projectsPaths)
            {
                //Open project to evaluate properties for the assets
                //file and the name of the project
                var project = MSBuildAPIUtility.GetProject(projectPath);

                if (!MSBuildAPIUtility.IsPackageReferenceProject(project))
                {
                    Console.Error.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                                          Strings.Error_NotPRProject,
                                                          projectPath));
                    Console.WriteLine();
                    continue;
                }

                var projectName = project.GetPropertyValue(ProjectName);

                var assetsPath = project.GetPropertyValue(ProjectAssetsFile);

                // If the file was not found, print an error message and continue to next project
                if (!File.Exists(assetsPath))
                {
                    Console.Error.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                                          Strings.Error_AssetsFileNotFound,
                                                          projectPath));
                    Console.WriteLine();
                }
                else
                {
                    var lockFileFormat = new LockFileFormat();
                    var assetsFile     = lockFileFormat.Read(assetsPath);

                    // Assets file validation
                    if (assetsFile.PackageSpec != null &&
                        assetsFile.Targets != null &&
                        assetsFile.Targets.Count != 0)
                    {
                        // Get all the packages that are referenced in a project
                        var packages = msBuild.GetResolvedVersions(project.FullPath, listPackageArgs.Frameworks, assetsFile, listPackageArgs.IncludeTransitive, includeProjects: listPackageArgs.ReportType == ReportType.Default);

                        // If packages equals null, it means something wrong happened
                        // with reading the packages and it was handled and message printed
                        // in MSBuildAPIUtility function, but we need to move to the next project
                        if (packages != null)
                        {
                            // No packages means that no package references at all were found in the current framework
                            if (!packages.Any())
                            {
                                Console.WriteLine(string.Format(Strings.ListPkg_NoPackagesFoundForFrameworks, projectName));
                            }
                            else
                            {
                                if (listPackageArgs.ReportType != ReportType.Default)  // generic list package is offline -- no server lookups
                                {
                                    PopulateSourceRepositoryCache(listPackageArgs);
                                    await GetRegistrationMetadataAsync(packages, listPackageArgs);
                                    await AddLatestVersionsAsync(packages, listPackageArgs);
                                }

                                bool printPackages = FilterPackages(packages, listPackageArgs);

                                // Filter packages for dedicated reports, inform user if none
                                if (listPackageArgs.ReportType != ReportType.Default && !printPackages)
                                {
                                    switch (listPackageArgs.ReportType)
                                    {
                                    case ReportType.Outdated:
                                        Console.WriteLine(string.Format(Strings.ListPkg_NoUpdatesForProject, projectName));
                                        break;

                                    case ReportType.Deprecated:
                                        Console.WriteLine(string.Format(Strings.ListPkg_NoDeprecatedPackagesForProject, projectName));
                                        break;

                                    case ReportType.Vulnerable:
                                        Console.WriteLine(string.Format(Strings.ListPkg_NoVulnerablePackagesForProject, projectName));
                                        break;
                                    }
                                }

                                printPackages = printPackages || ReportType.Default == listPackageArgs.ReportType;
                                if (printPackages)
                                {
                                    var hasAutoReference = false;
                                    ProjectPackagesPrintUtility.PrintPackages(packages, projectName, listPackageArgs, ref hasAutoReference);
                                    autoReferenceFound = autoReferenceFound || hasAutoReference;
                                }
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine(string.Format(Strings.ListPkg_ErrorReadingAssetsFile, assetsPath));
                    }

                    // Unload project
                    ProjectCollection.GlobalProjectCollection.UnloadProject(project);
                }
            }

            // Print a legend message for auto-reference markers used
            if (autoReferenceFound)
            {
                Console.WriteLine(Strings.ListPkg_AutoReferenceDescription);
            }
        }