public void AddDependency_ToSpecificFrameworks_RejectsExistingDependencies()
        {
            // Arrange
            var frameworkA = new TargetFrameworkInformation
            {
                FrameworkName = FrameworkConstants.CommonFrameworks.Net45
            };
            var frameworkB = new TargetFrameworkInformation
            {
                FrameworkName = FrameworkConstants.CommonFrameworks.NetStandard16
            };
            var spec     = new PackageSpec(new[] { frameworkA, frameworkB });
            var identity = new PackageIdentity("NuGet.Versioning", new NuGetVersion("1.0.0"));

            // Act
            PackageSpecOperations.AddOrUpdateDependency(
                spec,
                identity,
                new[] { frameworkB.FrameworkName });

            // Assert
            Assert.Empty(spec.Dependencies);

            Assert.Empty(spec.TargetFrameworks[0].Dependencies);

            Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Count);
            Assert.Equal(identity.Id, spec.TargetFrameworks[1].Dependencies[0].LibraryRange.Name);
            Assert.Equal(
                identity.Version,
                spec.TargetFrameworks[1].Dependencies[0].LibraryRange.VersionRange.MinVersion);
        }
Esempio n. 2
0
        public void AddOrUpdateDependency_WithCentralPackageManagementEnabled_AddsDependency()
        {
            // Arrange
            var packageIdentity = new PackageIdentity("NuGet.Versioning", new NuGetVersion("1.0.0"));

            var targetFrameworkInformation = new TargetFrameworkInformation
            {
                FrameworkName = FrameworkConstants.CommonFrameworks.Net45
            };

            var spec = new PackageSpec(new[] { targetFrameworkInformation })
            {
                RestoreMetadata = new ProjectRestoreMetadata
                {
                    CentralPackageVersionsEnabled = true
                }
            };

            // Act
            PackageSpecOperations.AddOrUpdateDependency(
                spec,
                packageIdentity,
                new[] { targetFrameworkInformation.FrameworkName });

            // Assert
            Assert.Equal(1, spec.TargetFrameworks[0].Dependencies.Count);
            Assert.Equal(packageIdentity.Id, spec.TargetFrameworks[0].Dependencies[0].LibraryRange.Name);
            Assert.Equal(packageIdentity.Version, spec.TargetFrameworks[0].Dependencies[0].LibraryRange.VersionRange.MinVersion);
            Assert.True(spec.TargetFrameworks[0].Dependencies[0].VersionCentrallyManaged);

            Assert.True(spec.TargetFrameworks[0].CentralPackageVersions.ContainsKey(packageIdentity.Id));
            Assert.Equal(packageIdentity.Version, spec.TargetFrameworks[0].CentralPackageVersions[packageIdentity.Id].VersionRange.MinVersion);
        }
Esempio n. 3
0
        public void AddOrUpdateDependency_UpdatesPackageDependency()
        {
            // Arrange
            var frameworkA = new TargetFrameworkInformation
            {
                FrameworkName = FrameworkConstants.CommonFrameworks.Net45
            };

            frameworkA.Dependencies.Add(new LibraryDependency
            {
                LibraryRange = new LibraryRange
                {
                    Name         = "nuget.versioning",
                    VersionRange = new VersionRange(new NuGetVersion("0.9.0"))
                }
            });
            var frameworkB = new TargetFrameworkInformation
            {
                FrameworkName = FrameworkConstants.CommonFrameworks.NetStandard16
            };

            frameworkB.Dependencies.Add(new LibraryDependency
            {
                LibraryRange = new LibraryRange
                {
                    Name         = "NUGET.VERSIONING",
                    VersionRange = new VersionRange(new NuGetVersion("0.8.0"))
                }
            });
            var spec              = new PackageSpec(new[] { frameworkA, frameworkB });
            var identity          = new PackageIdentity("NuGet.Versioning", new NuGetVersion("1.0.0"));
            var packageDependency = new PackageDependency(identity.Id, new VersionRange(identity.Version));

            // Act
            PackageSpecOperations.AddOrUpdateDependency(spec, packageDependency);

            // Assert
            Assert.Empty(spec.Dependencies);

            Assert.Equal(1, spec.TargetFrameworks[0].Dependencies.Count);
            Assert.Equal("nuget.versioning", spec.TargetFrameworks[0].Dependencies[0].LibraryRange.Name);
            Assert.Equal(
                identity.Version,
                spec.TargetFrameworks[0].Dependencies[0].LibraryRange.VersionRange.MinVersion);

            Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Count);
            Assert.Equal("NUGET.VERSIONING", spec.TargetFrameworks[1].Dependencies[0].LibraryRange.Name);
            Assert.Equal(
                identity.Version,
                spec.TargetFrameworks[1].Dependencies[0].LibraryRange.VersionRange.MinVersion);
        }
Esempio n. 4
0
        public void AddOrUpdateDependency_ToSpecificFrameworks_AddsNewDependency()
        {
            // Arrange
            var packageId  = "NuGet.Versioning";
            var oldVersion = new NuGetVersion("1.0.0");
            var newVersion = new NuGetVersion("2.0.0");

            var frameworkA = new TargetFrameworkInformation
            {
                FrameworkName = FrameworkConstants.CommonFrameworks.Net45
            };
            var ld = new LibraryDependency();

            ld.LibraryRange = new LibraryRange(packageId, new VersionRange(oldVersion), LibraryDependencyTarget.Package);
            var frameworkB = new TargetFrameworkInformation
            {
                FrameworkName = FrameworkConstants.CommonFrameworks.NetStandard16,
                Dependencies  = new List <LibraryDependency>()
                {
                    ld
                }
            };
            var spec     = new PackageSpec(new[] { frameworkA, frameworkB });
            var identity = new PackageIdentity(packageId, newVersion);

            //Preconditions
            Assert.Equal(
                oldVersion,
                spec.TargetFrameworks[1].Dependencies[0].LibraryRange.VersionRange.MinVersion);

            // Act
            PackageSpecOperations.AddOrUpdateDependency(
                spec,
                identity,
                new[] { frameworkB.FrameworkName });

            // Assert
            Assert.Empty(spec.Dependencies);

            Assert.Empty(spec.TargetFrameworks[0].Dependencies);

            Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Count);
            Assert.Equal(identity.Id, spec.TargetFrameworks[1].Dependencies[0].LibraryRange.Name);
            Assert.Equal(
                identity.Version,
                spec.TargetFrameworks[1].Dependencies[0].LibraryRange.VersionRange.MinVersion);
        }
        private static async Task <RestoreResultPair> PreviewAddPackageReference(PackageReferenceArgs packageReferenceArgs,
                                                                                 DependencyGraphSpec dgSpec,
                                                                                 PackageSpec originalPackageSpec)
        {
            // Set user agent and connection settings.
            XPlatUtility.ConfigureProtocol();

            var providerCache = new RestoreCommandProvidersCache();

            using (var cacheContext = new SourceCacheContext())
            {
                cacheContext.NoCache             = false;
                cacheContext.IgnoreFailedSources = false;

                // Pre-loaded request provider containing the graph file
                var providers = new List <IPreLoadedRestoreRequestProvider>();

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

                PackageSpecOperations.AddOrUpdateDependency(updatedPackageSpec, packageReferenceArgs.PackageDependency);

                providers.Add(new DependencyGraphSpecRequestProvider(providerCache, dgSpec));

                var restoreContext = new RestoreArgs()
                {
                    CacheContext              = cacheContext,
                    LockFileVersion           = LockFileFormat.Version,
                    Log                       = packageReferenceArgs.Logger,
                    MachineWideSettings       = new XPlatMachineWideSetting(),
                    GlobalPackagesFolder      = packageReferenceArgs.PackageDirectory,
                    PreLoadedRequestProviders = providers,
                    Sources                   = packageReferenceArgs.Sources?.ToList()
                };

                // Generate Restore Requests. There will always be 1 request here since we are restoring for 1 project.
                var restoreRequests = await RestoreRunner.GetRequests(restoreContext);

                // Run restore without commit. This will always return 1 Result pair since we are restoring for 1 request.
                var restoreResult = await RestoreRunner.RunWithoutCommit(restoreRequests, restoreContext);

                return(restoreResult.Single());
            }
        }
Esempio n. 6
0
        public void AddOrUpdateDependency_AddsNewDependencyToAllFrameworks()
        {
            // Arrange
            var spec = new PackageSpec(new[]
            {
                new TargetFrameworkInformation
                {
                    FrameworkName = FrameworkConstants.CommonFrameworks.Net45
                }
            });
            var identity = new PackageIdentity("NuGet.Versioning", new NuGetVersion("1.0.0"));

            // Act
            PackageSpecOperations.AddOrUpdateDependency(spec, identity);

            // Assert
            Assert.Equal(1, spec.Dependencies.Count);
            Assert.Empty(spec.TargetFrameworks[0].Dependencies);
            Assert.Equal(identity.Id, spec.Dependencies[0].LibraryRange.Name);
            Assert.Equal(identity.Version, spec.Dependencies[0].LibraryRange.VersionRange.MinVersion);
        }
Esempio n. 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 <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);
        }
Esempio n. 9
0
        public void AddOrUpdateDependency_WithCentralPackageManagementEnabled_UpdatesDependency()
        {
            // Arrange
            var packageId  = "NuGet.Versioning";
            var oldVersion = new NuGetVersion("1.0.0");
            var newVersion = new NuGetVersion("2.0.0");

            var frameworkA = new TargetFrameworkInformation
            {
                FrameworkName = FrameworkConstants.CommonFrameworks.Net45
            };

            var ld = new LibraryDependency
            {
                LibraryRange            = new LibraryRange(packageId, new VersionRange(oldVersion), LibraryDependencyTarget.Package),
                VersionCentrallyManaged = true
            };

            var frameworkB = new TargetFrameworkInformation
            {
                FrameworkName = FrameworkConstants.CommonFrameworks.NetStandard16,
                Dependencies  = new List <LibraryDependency>()
                {
                    ld
                },
            };

            frameworkB.CentralPackageVersions[ld.Name] = new CentralPackageVersion(ld.Name, ld.LibraryRange.VersionRange);

            var spec = new PackageSpec(new[] { frameworkA, frameworkB })
            {
                RestoreMetadata = new ProjectRestoreMetadata
                {
                    CentralPackageVersionsEnabled = true
                }
            };
            var identity = new PackageIdentity(packageId, newVersion);

            //Preconditions
            Assert.Equal(
                oldVersion,
                spec.TargetFrameworks[1].Dependencies[0].LibraryRange.VersionRange.MinVersion);

            // Act
            PackageSpecOperations.AddOrUpdateDependency(
                spec,
                identity,
                new[] { frameworkB.FrameworkName });

            // Assert
            Assert.Empty(spec.Dependencies);

            Assert.Empty(spec.TargetFrameworks[0].Dependencies);

            Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Count);
            Assert.Equal(identity.Id, spec.TargetFrameworks[1].Dependencies[0].LibraryRange.Name);
            Assert.Equal(identity.Version, spec.TargetFrameworks[1].Dependencies[0].LibraryRange.VersionRange.MinVersion);
            Assert.True(spec.TargetFrameworks[1].Dependencies[0].VersionCentrallyManaged);

            Assert.True(spec.TargetFrameworks[1].CentralPackageVersions.ContainsKey(identity.Id));
            Assert.Equal(identity.Version, spec.TargetFrameworks[1].CentralPackageVersions[identity.Id].VersionRange.MinVersion);
        }