public Task <int> ExecuteCommand(PackageReferenceArgs packageReferenceArgs, MSBuildAPIUtility msBuild)
        {
            packageReferenceArgs.Logger.LogInformation(string.Format(CultureInfo.CurrentCulture,
                                                                     Strings.Info_RemovePkgRemovingReference,
                                                                     packageReferenceArgs.PackageDependency.Id,
                                                                     packageReferenceArgs.ProjectPath));

            // Remove reference from the project
            var result = msBuild.RemovePackageReference(packageReferenceArgs.ProjectPath,
                                                        packageReferenceArgs.PackageDependency);

            return(Task.FromResult(result));
        }
        public static void Register(CommandLineApplication app, Func <ILogger> getLogger,
                                    Func <IPackageReferenceCommandRunner> getCommandRunner)
        {
            app.Command("remove", removePkg =>
            {
                removePkg.Description = Strings.RemovePkg_Description;
                removePkg.HelpOption(XPlatUtility.HelpOption);

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

                var id = removePkg.Option(
                    "--package",
                    Strings.RemovePkg_PackageIdDescription,
                    CommandOptionType.SingleValue);

                var projectPath = removePkg.Option(
                    "-p|--project",
                    Strings.RemovePkg_ProjectPathDescription,
                    CommandOptionType.SingleValue);

                var interactive = removePkg.Option(
                    "--interactive",
                    Strings.AddPkg_InteractiveDescription,
                    CommandOptionType.NoValue);

                removePkg.OnExecute(() =>
                {
                    ValidateArgument(id, removePkg.Name);
                    ValidateArgument(projectPath, removePkg.Name);
                    ValidateProjectPath(projectPath, removePkg.Name);
                    var logger         = getLogger();
                    var packageRefArgs = new PackageReferenceArgs(projectPath.Value(), logger)
                    {
                        Interactive = interactive.HasValue(),
                        PackageId   = id.Value()
                    };
                    var msBuild = new MSBuildAPIUtility(logger);
                    var removePackageRefCommandRunner = getCommandRunner();
                    return(removePackageRefCommandRunner.ExecuteCommand(packageRefArgs, msBuild));
                });
            });
        }
Example #3
0
        public Task <int> ExecuteCommand(PackageReferenceArgs packageReferenceArgs, MSBuildAPIUtility msBuild)
        {
            packageReferenceArgs.Logger.LogInformation(string.Format(CultureInfo.CurrentCulture,
                                                                     Strings.Info_RemovePkgRemovingReference,
                                                                     packageReferenceArgs.PackageDependency.Id,
                                                                     packageReferenceArgs.ProjectPath));

            var libraryDependency = new LibraryDependency
            {
                LibraryRange = new LibraryRange(
                    name: packageReferenceArgs.PackageDependency.Id,
                    versionRange: packageReferenceArgs.PackageDependency.VersionRange,
                    typeConstraint: LibraryDependencyTarget.Package)
            };

            // Remove reference from the project
            var result = msBuild.RemovePackageReference(packageReferenceArgs.ProjectPath, libraryDependency);

            return(Task.FromResult(result));
        }
        public Task <int> ExecuteCommand(PackageReferenceArgs packageReferenceArgs, MSBuildAPIUtility msBuild)
        {
            packageReferenceArgs.Logger.LogInformation(string.Format(CultureInfo.CurrentCulture,
                                                                     Strings.Info_RemovePkgRemovingReference,
                                                                     packageReferenceArgs.PackageId,
                                                                     packageReferenceArgs.ProjectPath));

            //Setup the Credential Service - This allows the msbuild sdk resolver to auth if needed.
            DefaultCredentialServiceUtility.SetupDefaultCredentialService(packageReferenceArgs.Logger, !packageReferenceArgs.Interactive);

            var libraryDependency = new LibraryDependency
            {
                LibraryRange = new LibraryRange(
                    name: packageReferenceArgs.PackageId,
                    versionRange: VersionRange.All,
                    typeConstraint: LibraryDependencyTarget.Package)
            };

            // Remove reference from the project
            var result = msBuild.RemovePackageReference(packageReferenceArgs.ProjectPath, libraryDependency);

            return(Task.FromResult(result));
        }
Example #5
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);
            }
        }
        public static void Register(CommandLineApplication app, Func <ILogger> getLogger,
                                    Func <IPackageReferenceCommandRunner> getCommandRunner)
        {
            app.Command("add", addpkg =>
            {
                addpkg.Description = Strings.AddPkg_Description;
                addpkg.HelpOption(XPlatUtility.HelpOption);

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

                var id = addpkg.Option(
                    "--package",
                    Strings.AddPkg_PackageIdDescription,
                    CommandOptionType.SingleValue);

                var version = addpkg.Option(
                    "--version",
                    Strings.AddPkg_PackageVersionDescription,
                    CommandOptionType.SingleValue);

                var dgFilePath = addpkg.Option(
                    "-d|--dg-file",
                    Strings.AddPkg_DgFileDescription,
                    CommandOptionType.SingleValue);

                var projectPath = addpkg.Option(
                    "-p|--project",
                    Strings.AddPkg_ProjectPathDescription,
                    CommandOptionType.SingleValue);

                var frameworks = addpkg.Option(
                    "-f|--framework",
                    Strings.AddPkg_FrameworksDescription,
                    CommandOptionType.MultipleValue);

                var noRestore = addpkg.Option(
                    "-n|--no-restore",
                    Strings.AddPkg_NoRestoreDescription,
                    CommandOptionType.NoValue);

                var sources = addpkg.Option(
                    "-s|--source",
                    Strings.AddPkg_SourcesDescription,
                    CommandOptionType.MultipleValue);

                var packageDirectory = addpkg.Option(
                    "--package-directory",
                    Strings.AddPkg_PackageDirectoryDescription,
                    CommandOptionType.SingleValue);

                var interactive = addpkg.Option(
                    "--interactive",
                    Strings.AddPkg_InteractiveDescription,
                    CommandOptionType.NoValue);

                var prerelease = addpkg.Option(
                    "--prerelease",
                    Strings.AddPkg_PackagePrerelease,
                    CommandOptionType.NoValue);

                addpkg.OnExecute(() =>
                {
                    ValidateArgument(id, addpkg.Name);
                    ValidateArgument(projectPath, addpkg.Name);
                    ValidateProjectPath(projectPath, addpkg.Name);
                    if (!noRestore.HasValue())
                    {
                        ValidateArgument(dgFilePath, addpkg.Name);
                    }
                    var logger         = getLogger();
                    var noVersion      = !version.HasValue();
                    var packageVersion = version.HasValue() ? version.Value() : null;
                    ValidatePrerelease(prerelease.HasValue(), noVersion, addpkg.Name);
                    var packageRefArgs = new PackageReferenceArgs(projectPath.Value(), logger)
                    {
                        Frameworks       = CommandLineUtility.SplitAndJoinAcrossMultipleValues(frameworks.Values),
                        Sources          = CommandLineUtility.SplitAndJoinAcrossMultipleValues(sources.Values),
                        PackageDirectory = packageDirectory.Value(),
                        NoRestore        = noRestore.HasValue(),
                        NoVersion        = noVersion,
                        DgFilePath       = dgFilePath.Value(),
                        Interactive      = interactive.HasValue(),
                        Prerelease       = prerelease.HasValue(),
                        PackageVersion   = packageVersion,
                        PackageId        = id.Values[0]
                    };
                    var msBuild = new MSBuildAPIUtility(logger);
                    var addPackageRefCommandRunner = getCommandRunner();
                    return(addPackageRefCommandRunner.ExecuteCommand(packageRefArgs, msBuild));
                });
            });
        }
Example #7
0
        public async Task <int> ExecuteCommand(PackageReferenceArgs packageReferenceArgs, MSBuildAPIUtility msBuild)
        {
            packageReferenceArgs.Logger.LogInformation(string.Format(CultureInfo.CurrentCulture,
                                                                     Strings.Info_AddPkgAddingReference,
                                                                     packageReferenceArgs.PackageDependency.Id,
                                                                     packageReferenceArgs.ProjectPath));

            if (packageReferenceArgs.NoRestore)
            {
                packageReferenceArgs.Logger.LogWarning(string.Format(CultureInfo.CurrentCulture,
                                                                     Strings.Warn_AddPkgWithoutRestore));

                var libraryDependency = new LibraryDependency
                {
                    LibraryRange = new LibraryRange(
                        name: packageReferenceArgs.PackageDependency.Id,
                        versionRange: packageReferenceArgs.PackageDependency.VersionRange,
                        typeConstraint: LibraryDependencyTarget.Package)
                };

                msBuild.AddPackageReference(packageReferenceArgs.ProjectPath, libraryDependency);
                return(0);
            }

            // 1. Get project dg file
            packageReferenceArgs.Logger.LogDebug("Reading project Dependency Graph");
            var dgSpec = ReadProjectDependencyGraph(packageReferenceArgs);

            if (dgSpec == null)
            {
                // Logging non localized error on debug stream.
                packageReferenceArgs.Logger.LogDebug(Strings.Error_NoDgSpec);

                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings.Error_NoDgSpec));
            }
            packageReferenceArgs.Logger.LogDebug("Project Dependency Graph Read");

            var projectFullPath = Path.GetFullPath(packageReferenceArgs.ProjectPath);

            var matchingPackageSpecs = dgSpec
                                       .Projects
                                       .Where(p => p.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference &&
                                              PathUtility.GetStringComparerBasedOnOS().Equals(Path.GetFullPath(p.RestoreMetadata.ProjectPath), projectFullPath))
                                       .ToArray();

            // This ensures that the DG specs generated in previous steps contain exactly 1 project with the same path as the project requesting add package.
            // Throw otherwise since we cannot proceed further.
            if (matchingPackageSpecs.Length != 1)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
                                                                  Strings.Error_UnsupportedProject,
                                                                  packageReferenceArgs.PackageDependency.Id,
                                                                  packageReferenceArgs.ProjectPath));
            }

            // Parse the user specified frameworks once to avoid re-do's
            var userSpecifiedFrameworks = Enumerable.Empty <NuGetFramework>();

            if (packageReferenceArgs.Frameworks?.Any() == true)
            {
                userSpecifiedFrameworks = packageReferenceArgs
                                          .Frameworks
                                          .Select(f => NuGetFramework.Parse(f));
            }


            var originalPackageSpec = matchingPackageSpecs.FirstOrDefault();

            // Create a copy to avoid modifying the original spec which may be shared.
            var updatedPackageSpec = originalPackageSpec.Clone();

            if (packageReferenceArgs.Frameworks?.Any() == true)
            {
                // If user specified frameworks then just use them to add the dependency
                PackageSpecOperations.AddOrUpdateDependency(updatedPackageSpec,
                                                            packageReferenceArgs.PackageDependency,
                                                            userSpecifiedFrameworks);
            }
            else
            {
                // If the user has not specified a framework, then just add it to all frameworks
                PackageSpecOperations.AddOrUpdateDependency(updatedPackageSpec, packageReferenceArgs.PackageDependency, updatedPackageSpec.TargetFrameworks.Select(e => e.FrameworkName));
            }


            var updatedDgSpec = dgSpec.WithReplacedSpec(updatedPackageSpec).WithoutRestores();

            updatedDgSpec.AddRestore(updatedPackageSpec.RestoreMetadata.ProjectUniqueName);

            // 2. Run Restore Preview
            packageReferenceArgs.Logger.LogDebug("Running Restore preview");

            var restorePreviewResult = await PreviewAddPackageReferenceAsync(packageReferenceArgs,
                                                                             updatedDgSpec);

            packageReferenceArgs.Logger.LogDebug("Restore Review completed");

            // 3. Process Restore Result
            var compatibleFrameworks = new HashSet <NuGetFramework>(
                restorePreviewResult
                .Result
                .CompatibilityCheckResults
                .Where(t => t.Success)
                .Select(t => t.Graph.Framework), new NuGetFrameworkFullComparer());

            if (packageReferenceArgs.Frameworks?.Any() == true)
            {
                // If the user has specified frameworks then we intersect that with the compatible frameworks.
                var userSpecifiedFrameworkSet = new HashSet <NuGetFramework>(
                    userSpecifiedFrameworks,
                    new NuGetFrameworkFullComparer());

                compatibleFrameworks.IntersectWith(userSpecifiedFrameworkSet);
            }

            // 4. Write to Project
            if (compatibleFrameworks.Count == 0)
            {
                // Package is compatible with none of the project TFMs
                // Do not add a package reference, throw appropriate error
                packageReferenceArgs.Logger.LogError(string.Format(CultureInfo.CurrentCulture,
                                                                   Strings.Error_AddPkgIncompatibleWithAllFrameworks,
                                                                   packageReferenceArgs.PackageDependency.Id,
                                                                   packageReferenceArgs.Frameworks?.Any() == true ? Strings.AddPkg_UserSpecified : Strings.AddPkg_All,
                                                                   packageReferenceArgs.ProjectPath));

                return(1);
            }
            // Ignore the graphs with RID
            else if (compatibleFrameworks.Count ==
                     restorePreviewResult.Result.CompatibilityCheckResults.Where(r => string.IsNullOrEmpty(r.Graph.RuntimeIdentifier)).Count())
            {
                // Package is compatible with all the project TFMs
                // Add an unconditional package reference to the project
                packageReferenceArgs.Logger.LogInformation(string.Format(CultureInfo.CurrentCulture,
                                                                         Strings.Info_AddPkgCompatibleWithAllFrameworks,
                                                                         packageReferenceArgs.PackageDependency.Id,
                                                                         packageReferenceArgs.ProjectPath));

                // generate a library dependency with all the metadata like Include, Exlude and SuppressParent
                var libraryDependency = GenerateLibraryDependency(updatedPackageSpec, packageReferenceArgs, restorePreviewResult, userSpecifiedFrameworks);

                msBuild.AddPackageReference(packageReferenceArgs.ProjectPath, libraryDependency);
            }
            else
            {
                // Package is compatible with some of the project TFMs
                // Add conditional package references to the project for the compatible TFMs
                packageReferenceArgs.Logger.LogInformation(string.Format(CultureInfo.CurrentCulture,
                                                                         Strings.Info_AddPkgCompatibleWithSubsetFrameworks,
                                                                         packageReferenceArgs.PackageDependency.Id,
                                                                         packageReferenceArgs.ProjectPath));

                var compatibleOriginalFrameworks = originalPackageSpec.RestoreMetadata
                                                   .OriginalTargetFrameworks
                                                   .Where(s => compatibleFrameworks.Contains(NuGetFramework.Parse(s)));

                // generate a library dependency with all the metadata like Include, Exlude and SuppressParent
                var libraryDependency = GenerateLibraryDependency(updatedPackageSpec, packageReferenceArgs, restorePreviewResult, userSpecifiedFrameworks);

                msBuild.AddPackageReferencePerTFM(packageReferenceArgs.ProjectPath,
                                                  libraryDependency,
                                                  compatibleOriginalFrameworks);
            }

            // 5. Commit restore result
            await RestoreRunner.CommitAsync(restorePreviewResult, CancellationToken.None);

            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 <int> ExecuteCommand(PackageReferenceArgs packageReferenceArgs, MSBuildAPIUtility msBuild)
        {
            packageReferenceArgs.Logger.LogInformation(string.Format(CultureInfo.CurrentCulture,
                                                                     Strings.Info_AddPkgAddingReference,
                                                                     packageReferenceArgs.PackageDependency.Id,
                                                                     packageReferenceArgs.ProjectPath));

            if (packageReferenceArgs.NoRestore)
            {
                packageReferenceArgs.Logger.LogWarning(string.Format(CultureInfo.CurrentCulture,
                                                                     Strings.Warn_AddPkgWithoutRestore));

                msBuild.AddPackageReference(packageReferenceArgs.ProjectPath, packageReferenceArgs.PackageDependency);
                return(0);
            }

            // 1. Get project dg file
            packageReferenceArgs.Logger.LogDebug("Reading project Dependency Graph");
            var dgSpec = ReadProjectDependencyGraph(packageReferenceArgs);

            if (dgSpec == null)
            {
                throw new Exception(Strings.Error_NoDgSpec);
            }
            packageReferenceArgs.Logger.LogDebug("Project Dependency Graph Read");

            var projectName         = dgSpec.Restore.FirstOrDefault();
            var originalPackageSpec = dgSpec.GetProjectSpec(projectName);

            // Create a copy to avoid modifying the original spec which may be shared.
            var updatedPackageSpec = originalPackageSpec.Clone();

            PackageSpecOperations.AddOrUpdateDependency(updatedPackageSpec, packageReferenceArgs.PackageDependency);

            var updatedDgSpec = dgSpec.WithReplacedSpec(updatedPackageSpec).WithoutRestores();

            updatedDgSpec.AddRestore(updatedPackageSpec.RestoreMetadata.ProjectUniqueName);

            // 2. Run Restore Preview
            packageReferenceArgs.Logger.LogDebug("Running Restore preview");
            var restorePreviewResult = await PreviewAddPackageReference(packageReferenceArgs,
                                                                        updatedDgSpec,
                                                                        updatedPackageSpec);

            packageReferenceArgs.Logger.LogDebug("Restore Review completed");

            // 3. Process Restore Result
            var compatibleFrameworks = new HashSet <NuGetFramework>(
                restorePreviewResult
                .Result
                .CompatibilityCheckResults
                .Where(t => t.Success)
                .Select(t => t.Graph.Framework));

            if (packageReferenceArgs.Frameworks?.Any() == true)
            {
                // If the user has specified frameworks then we intersect that with the compatible frameworks.
                var userSpecifiedFrameworks = new HashSet <NuGetFramework>(
                    packageReferenceArgs
                    .Frameworks
                    .Select(f => NuGetFramework.Parse(f)));

                compatibleFrameworks.IntersectWith(userSpecifiedFrameworks);
            }

            // 4. Write to Project
            if (compatibleFrameworks.Count == 0)
            {
                // Package is compatible with none of the project TFMs
                // Do not add a package reference, throw appropriate error
                packageReferenceArgs.Logger.LogError(string.Format(CultureInfo.CurrentCulture,
                                                                   Strings.Error_AddPkgIncompatibleWithAllFrameworks,
                                                                   packageReferenceArgs.PackageDependency.Id,
                                                                   packageReferenceArgs.Frameworks?.Any() == true ? Strings.AddPkg_UserSpecified : Strings.AddPkg_All,
                                                                   packageReferenceArgs.ProjectPath));

                return(1);
            }
            else if (compatibleFrameworks.Count == restorePreviewResult.Result.CompatibilityCheckResults.Count())
            {
                // Package is compatible with all the project TFMs
                // Add an unconditional package reference to the project
                packageReferenceArgs.Logger.LogInformation(string.Format(CultureInfo.CurrentCulture,
                                                                         Strings.Info_AddPkgCompatibleWithAllFrameworks,
                                                                         packageReferenceArgs.PackageDependency.Id,
                                                                         packageReferenceArgs.ProjectPath));

                // If the user did not specify a version then update the version to resolved version
                UpdatePackageVersionIfNeeded(restorePreviewResult, packageReferenceArgs);

                msBuild.AddPackageReference(packageReferenceArgs.ProjectPath,
                                            packageReferenceArgs.PackageDependency);
            }
            else
            {
                // Package is compatible with some of the project TFMs
                // Add conditional package references to the project for the compatible TFMs
                packageReferenceArgs.Logger.LogInformation(string.Format(CultureInfo.CurrentCulture,
                                                                         Strings.Info_AddPkgCompatibleWithSubsetFrameworks,
                                                                         packageReferenceArgs.PackageDependency.Id,
                                                                         packageReferenceArgs.ProjectPath));

                var compatibleOriginalFrameworks = originalPackageSpec.RestoreMetadata
                                                   .OriginalTargetFrameworks
                                                   .Where(s => compatibleFrameworks.Contains(NuGetFramework.Parse(s)));

                // If the user did not specify a version then update the version to resolved version
                UpdatePackageVersionIfNeeded(restorePreviewResult, packageReferenceArgs);

                msBuild.AddPackageReferencePerTFM(packageReferenceArgs.ProjectPath,
                                                  packageReferenceArgs.PackageDependency,
                                                  compatibleOriginalFrameworks);
            }

            return(0);
        }