public void HasPackage_ReturnsTrueWhenIdIsForAllFrameworks() { // Arrange var framework = new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.Net45 }; var spec = new PackageSpec(new[] { framework }); spec.Dependencies.Add(new LibraryDependency { LibraryRange = new LibraryRange { Name = "nuget.versioning", VersionRange = new VersionRange(new NuGetVersion("0.9.0")) } }); var id = "NuGet.Versioning"; // Act var actual = PackageSpecOperations.HasPackage(spec, id); // Assert Assert.True(actual); }
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); }
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); }
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); }
public void RemoveDependency_RemovesFromAllFrameworkLists() { // 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 }); spec.Dependencies.Add(new LibraryDependency { LibraryRange = new LibraryRange { Name = "NuGet.VERSIONING", VersionRange = new VersionRange(new NuGetVersion("0.7.0")) } }); var id = "NuGet.Versioning"; // Act PackageSpecOperations.RemoveDependency(spec, id); // Assert Assert.Empty(spec.Dependencies); Assert.Empty(spec.TargetFrameworks[0].Dependencies); Assert.Empty(spec.TargetFrameworks[1].Dependencies); }
public void HasPackage_ReturnsFalseWhenIdIsNotInSpec() { // Arrange var framework = new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.Net45 }; var spec = new PackageSpec(new[] { framework }); var id = "NuGet.Versioning"; // Act var actual = PackageSpecOperations.HasPackage(spec, id); // Assert Assert.False(actual); }
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()); } }
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); }
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); }
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); }