/// <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; } } } }
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())); }
/// <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); } }
/// <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); } }
/// <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; } }
/// <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); } } }
/// <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); }
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)))); } } }
/// <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); }); }); }
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); } }
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); } }