public void GetParents_WhenOnlyRootSpecsAreDirty_ReturnsOnlyTheSameDirtyProjects() { var projectA = GetPackageSpec("A"); var projectB = GetPackageSpec("B"); var projectC = GetPackageSpec("C"); var projectD = GetPackageSpec("D"); var projectE = GetPackageSpec("E"); var projectF = GetPackageSpec("F"); // A => B & C projectA = projectA.WithTestProjectReference(projectB).WithTestProjectReference(projectC); // B => D projectB = projectB.WithTestProjectReference(projectD); // C => E projectC = projectC.WithTestProjectReference(projectE); // F => D projectF = projectF.WithTestProjectReference(projectD); var dgSpec = new DependencyGraphSpec(); dgSpec.AddProject(projectA); dgSpec.AddRestore(projectA.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectB); dgSpec.AddRestore(projectB.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectC); dgSpec.AddRestore(projectC.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectD); dgSpec.AddRestore(projectD.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectE); dgSpec.AddRestore(projectE.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectF); dgSpec.AddRestore(projectF.RestoreMetadata.ProjectUniqueName); var expected = GetUniqueNames(projectA, projectF); var actual = SolutionUpToDateChecker.GetParents(GetUniqueNames(projectA, projectF), dgSpec); actual.Should().BeEquivalentTo(expected); }
public async Task RestoreRunner_BasicRestore() { // Arrange var sources = new List <PackageSource>(); var project1Json = @" { ""version"": ""1.0.0"", ""description"": """", ""authors"": [ ""author"" ], ""tags"": [ """" ], ""projectUrl"": """", ""licenseUrl"": """", ""frameworks"": { ""net45"": { } } }"; using (var workingDir = TestDirectory.Create()) { var projectName = "project1"; var packagesDir = new DirectoryInfo(Path.Combine(workingDir, "globalPackages")); var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource")); var project1 = new DirectoryInfo(Path.Combine(workingDir, "projects", projectName)); packagesDir.Create(); packageSource.Create(); project1.Create(); sources.Add(new PackageSource(packageSource.FullName)); var specPath1 = Path.Combine(project1.FullName, "project.json"); var dgPath = Path.Combine(project1.FullName, "project.dg"); File.WriteAllText(specPath1, project1Json); var spec1 = JsonPackageSpecReader.GetPackageSpec(project1Json, projectName, specPath1); spec1 = spec1.EnsureRestoreMetadata(); spec1.RestoreMetadata.Sources = new List <PackageSource> { new PackageSource(packageSource.FullName) }; spec1.RestoreMetadata.PackagesPath = packagesDir.FullName; var dgSpec = new DependencyGraphSpec(); dgSpec.AddProject(spec1); dgSpec.AddRestore(projectName); var logger = new TestLogger(); var lockPath = Path.Combine(project1.FullName, "project.assets.json"); var sourceRepos = sources.Select(source => Repository.Factory.GetCoreV3(source.Source)).ToList(); var providerCache = new RestoreCommandProvidersCache(); using (var cacheContext = new SourceCacheContext()) { var restoreContext = new RestoreArgs() { CacheContext = cacheContext, DisableParallel = true, GlobalPackagesFolder = packagesDir.FullName, Sources = new List <string>() { packageSource.FullName }, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(sources)), PreLoadedRequestProviders = new List <IPreLoadedRestoreRequestProvider>() { new DependencyGraphSpecRequestProvider(providerCache, dgSpec) } }; // Act var summaries = await RestoreRunner.RunAsync(restoreContext); var summary = summaries.Single(); // Assert Assert.True(summary.Success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); Assert.Equal(1, summary.FeedsUsed.Count); Assert.True(File.Exists(lockPath), lockPath); Assert.False(File.Exists(Path.Combine(project1.FullName, "project1.nuget.targets"))); // TODO NK - Why are we doing this? The name of the targets has changed! Assert.False(File.Exists(Path.Combine(project1.FullName, "project1.nuget.props"))); } } }
public void IsLockFileStillValid_TransitiveDependencyNotCentrallyManaged_DoesNotInvalidateLockFile() { // Arrange var framework = CommonFrameworks.NetStandard20; var projectName = "project"; var cpvm1 = new CentralPackageVersion("cpvm1", VersionRange.Parse("1.0.0")); var cpvm2 = new CentralPackageVersion("cpvm2", VersionRange.Parse("1.0.0")); var dependency1 = new LibraryDependency( new LibraryRange("cpvm1", versionRange: null, LibraryDependencyTarget.Package), LibraryDependencyType.Default, LibraryIncludeFlags.All, LibraryIncludeFlags.All, new List <Common.NuGetLogCode>(), autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, LibraryDependencyReferenceType.Direct, aliases: "stuff"); var tfm = new TargetFrameworkInformation(); tfm.FrameworkName = framework; tfm.CentralPackageVersions.Add("cpvm1", cpvm1); tfm.CentralPackageVersions.Add("cpvm2", cpvm2); tfm.Dependencies.Add(dependency1); LibraryDependency.ApplyCentralVersionInformation(tfm.Dependencies, tfm.CentralPackageVersions); var project = new PackageSpec(new List <TargetFrameworkInformation>() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = true }; DependencyGraphSpec dgSpec = new DependencyGraphSpec(); dgSpec.AddRestore(projectName); dgSpec.AddProject(project); var lockFile1 = new PackagesLockFileBuilder() .WithTarget(target => target .WithFramework(CommonFrameworks.NetStandard20) .WithDependency(dep => dep .WithId("cpvm1") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.Direct)) .WithDependency(dep => dep .WithId("otherDep") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.Transitive))) .Build(); var lockFile2 = new PackagesLockFileBuilder() .WithVersion(PackagesLockFileFormat.PackagesLockFileVersion) .WithTarget(target => target .WithFramework(CommonFrameworks.NetStandard20) .WithDependency(dep => dep .WithId("cpvm1") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.Direct)) .WithDependency(dep => dep .WithId("otherDep") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.Transitive))) .Build(); // Nothing changed // different versions of lock file versions are handled Assert.True(PackagesLockFileUtilities.IsLockFileStillValid(dgSpec, lockFile1)); Assert.True(PackagesLockFileUtilities.IsLockFileStillValid(dgSpec, lockFile2)); }
public static async Task <(DependencyGraphSpec dgSpec, IReadOnlyList <IAssetsLogMessage> additionalMessages)> GetSolutionRestoreSpecAndAdditionalMessages( ISolutionManager solutionManager, DependencyGraphCacheContext context) { var dgSpec = new DependencyGraphSpec(); List <IAssetsLogMessage> allAdditionalMessages = null; var projects = (await solutionManager.GetNuGetProjectsAsync()).OfType <IDependencyGraphProject>().ToList(); var knownProjects = projects.Select(e => e.MSBuildProjectPath).ToHashSet(PathUtility.GetStringComparerBasedOnOS()); for (var i = 0; i < projects.Count; i++) { var(packageSpecs, projectAdditionalMessages) = await projects[i].GetPackageSpecsAndAdditionalMessagesAsync(context); if (projectAdditionalMessages != null && projectAdditionalMessages.Count > 0) { if (allAdditionalMessages == null) { allAdditionalMessages = new List <IAssetsLogMessage>(); } allAdditionalMessages.AddRange(projectAdditionalMessages); } foreach (var packageSpec in packageSpecs) { dgSpec.AddProject(packageSpec); if (packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference || packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson || packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetCliTool || packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.Standalone) // Don't add global tools to restore specs for solutions { dgSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName); var projFileName = Path.GetFileName(packageSpec.RestoreMetadata.ProjectPath); var dgFileName = DependencyGraphSpec.GetDGSpecFileName(projFileName); var outputPath = packageSpec.RestoreMetadata.OutputPath; if (!string.IsNullOrEmpty(outputPath)) { for (int frameworkCount = 0; frameworkCount < packageSpec.RestoreMetadata.TargetFrameworks.Count; frameworkCount++) { for (var projectReferenceCount = 0; projectReferenceCount < packageSpec.RestoreMetadata.TargetFrameworks[frameworkCount].ProjectReferences.Count; projectReferenceCount++) { if (!knownProjects.Contains(packageSpec.RestoreMetadata.TargetFrameworks[frameworkCount].ProjectReferences[projectReferenceCount].ProjectPath)) { var persistedDGSpecPath = Path.Combine(outputPath, dgFileName); if (File.Exists(persistedDGSpecPath)) { var persistedDGSpec = DependencyGraphSpec.Load(persistedDGSpecPath); foreach (var dependentPackageSpec in persistedDGSpec.Projects.Where(e => !knownProjects.Contains(e.RestoreMetadata.ProjectPath))) { // Include all the missing projects from the closure. // Figuring out exactly what we need would be too and an overkill. That will happen later in the DependencyGraphSpecRequestProvider knownProjects.Add(dependentPackageSpec.RestoreMetadata.ProjectPath); dgSpec.AddProject(dependentPackageSpec); } } } } } } } } } // Return dg file return(dgSpec, allAdditionalMessages); }
public async Task GetInstallActionsAsync_WithProjectReferenceProject_WhenUpdatingPackage_ReturnsCorrectActions() { const string projectName = "a"; string projectId = Guid.NewGuid().ToString(); var projectSystemCache = new ProjectSystemCache(); using (TestDirectory testDirectory = TestDirectory.Create()) { var packageV1 = new SimpleTestPackageContext(packageId: "b", version: "1.0.0"); var packageV2 = new SimpleTestPackageContext(packageV1.Id, version: "2.0.0"); string packageSourceDirectoryPath = Path.Combine(testDirectory, "packageSource"); await SimpleTestPackageUtility.CreateFolderFeedV3Async( packageSourceDirectoryPath, PackageSaveMode.Defaultv3, packageV1, packageV2); var packageSource = new PackageSource(packageSourceDirectoryPath); var packageSources = new List <PackageSource>() { packageSource }; Initialize(packageSources); string projectFullPath = Path.Combine(testDirectory.Path, $"{projectName}.csproj"); var unconfiguredProject = new Mock <UnconfiguredProject>(); var configuredProject = new Mock <ConfiguredProject>(); var projectServices = new Mock <ConfiguredProjectServices>(); var packageReferencesService = new Mock <IPackageReferencesService>(); var result = new Mock <IUnresolvedPackageReference>(); unconfiguredProject.Setup(x => x.GetSuggestedConfiguredProjectAsync()) .ReturnsAsync(configuredProject.Object); configuredProject.SetupGet(x => x.Services) .Returns(projectServices.Object); projectServices.SetupGet(x => x.PackageReferences) .Returns(packageReferencesService.Object); packageReferencesService.Setup(x => x.AddAsync(It.IsNotNull <string>(), It.IsNotNull <string>())) .ReturnsAsync(new AddReferenceResult <IUnresolvedPackageReference>(result.Object, added: true)); var nuGetProjectServices = new Mock <INuGetProjectServices>(); nuGetProjectServices.SetupGet(x => x.ScriptService) .Returns(Mock.Of <IProjectScriptHostService>()); var project = new CpsPackageReferenceProject( projectName: projectName, projectUniqueName: projectFullPath, projectFullPath: projectFullPath, projectSystemCache, unconfiguredProject.Object, nuGetProjectServices.Object, projectId); PackageSpec packageSpec = CreatePackageSpec( project.ProjectName, Path.Combine(testDirectory, "package.spec")); DependencyGraphSpec projectRestoreInfo = ProjectJsonTestHelpers.GetDGSpecFromPackageSpecs(packageSpec); projectRestoreInfo.AddProject(packageSpec); var projectNames = new ProjectNames( fullName: projectFullPath, uniqueName: projectFullPath, shortName: projectName, customUniqueName: projectName, projectId: projectId); projectSystemCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, Array.Empty <IAssetsLogMessage>()); _solutionManager.NuGetProjects.Add(project); string[] projectIds = new[] { projectId }; string[] packageSourceNames = new[] { packageSource.Name }; await PerformOperationAsync(async (projectManager) => { IReadOnlyList <ProjectAction> actions = await projectManager.GetInstallActionsAsync( projectIds, packageV1.Identity, VersionConstraints.None, includePrelease: true, DependencyBehavior.Lowest, packageSourceNames, CancellationToken.None); Assert.NotEmpty(actions); Assert.Equal(1, actions.Count); ProjectAction action = actions[0]; Assert.Equal(packageV1.Identity, action.PackageIdentity); Assert.Equal(NuGetProjectActionType.Install, action.ProjectActionType); Assert.Equal(projectId, action.ProjectId); Assert.Equal(1, action.ImplicitActions.Count); ImplicitProjectAction implicitAction = action.ImplicitActions[0]; Assert.Equal(packageV1.Identity, implicitAction.PackageIdentity); Assert.Equal(NuGetProjectActionType.Install, implicitAction.ProjectActionType); await projectManager.ExecuteActionsAsync(actions, CancellationToken.None); }); await PerformOperationAsync(async (projectManager) => { IReadOnlyList <ProjectAction> actions = await projectManager.GetInstallActionsAsync( projectIds, packageV2.Identity, VersionConstraints.None, includePrelease: true, DependencyBehavior.Lowest, packageSourceNames, CancellationToken.None); Assert.NotEmpty(actions); Assert.Equal(1, actions.Count); ProjectAction action = actions[0]; Assert.Equal(packageV2.Identity, action.PackageIdentity); Assert.Equal(NuGetProjectActionType.Install, action.ProjectActionType); Assert.Equal(projectId, action.ProjectId); Assert.Equal(2, action.ImplicitActions.Count); ImplicitProjectAction implicitAction = action.ImplicitActions[0]; Assert.Equal(packageV1.Identity, implicitAction.PackageIdentity); Assert.Equal(NuGetProjectActionType.Uninstall, implicitAction.ProjectActionType); implicitAction = action.ImplicitActions[1]; Assert.Equal(packageV2.Identity, implicitAction.PackageIdentity); Assert.Equal(NuGetProjectActionType.Install, implicitAction.ProjectActionType); }); } }
public static async Task <(RestoreRequest, RestoreResult)> Restore(ILogger logger, string packageName, VersionRange versionRange) { var settings = NuGet.Configuration.Settings.LoadDefaultSettings(null); var packageSourceProvider = new PackageSourceProvider(settings); var installPath = SettingsUtility.GetGlobalPackagesFolder(settings); var assemblies = new List <string>(); var projectPath = Path.Combine("XenkoNugetResolver.json"); var spec = new PackageSpec() { Name = Path.GetFileNameWithoutExtension(projectPath), // make sure this package never collides with a dependency FilePath = projectPath, Dependencies = new List <LibraryDependency>() { new LibraryDependency { LibraryRange = new LibraryRange(packageName, versionRange, LibraryDependencyTarget.Package), } }, TargetFrameworks = { new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net48"), } }, RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectPath, ProjectName = Path.GetFileNameWithoutExtension(projectPath), ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = projectPath, OutputPath = Path.Combine(Path.GetTempPath(), $"XenkoNugetResolver-{packageName}-{versionRange.MinVersion.ToString()}"), OriginalTargetFrameworks = new[] { "net48" }, ConfigFilePaths = settings.GetConfigFilePaths(), PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings), Sources = SettingsUtility.GetEnabledSources(settings).ToList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList() }, }; // remove all remote sources, so we don't have to worry about connectivity issues // we are only restoring local dev packages anyway for (int i = 0; i < spec.RestoreMetadata.Sources.Count; i++) { var s = spec.RestoreMetadata.Sources[i]; if (s.IsLocal == false) { spec.RestoreMetadata.Sources.RemoveAt(i); i--; } } using (var context = new SourceCacheContext()) { context.IgnoreFailedSources = true; var dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(spec); dependencyGraphSpec.AddRestore(spec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); var restoreArgs = new RestoreArgs { AllowNoOp = true, CacheContext = context, CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)), Log = logger, }; // Create requests from the arguments var requests = requestProvider.CreateRequests(restoreArgs).Result; // Restore the packages for (int tryCount = 0; tryCount < 2; ++tryCount) { try { var results = await RestoreRunner.RunWithoutCommit(requests, restoreArgs); // Commit results so that noop cache works next time foreach (var result in results) { await result.Result.CommitAsync(logger, CancellationToken.None); } var mainResult = results.First(); return(mainResult.SummaryRequest.Request, mainResult.Result); } catch (Exception e) when(e is UnauthorizedAccessException || e is IOException) { // If we have an unauthorized access exception, it means assemblies are locked by running Xenko process // During first try, kill some known harmless processes, and try again if (tryCount == 1) { throw; } foreach (var process in new[] { "Xenko.ConnectionRouter" }.SelectMany(Process.GetProcessesByName)) { try { if (process.Id != Process.GetCurrentProcess().Id) { process.Kill(); process.WaitForExit(); } } catch (Exception) { } } } } throw new InvalidOperationException("Unreachable code"); } }
public async Task RestoreBuildTargetsAndProps_VerifyRestoreChange() { // Arrange using (var cacheContext = new SourceCacheContext()) using (var pathContext = new SimpleTestPathContext()) { var logger = new TestLogger(); var sources = new List <PackageSource>(); sources.Add(new PackageSource(pathContext.PackageSource)); var spec = GetProject("projectA", "net462", "netstandard1.6"); spec.RestoreMetadata.CrossTargeting = true; spec.Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); // Create fake projects, the real data is in the specs var projects = CreateProjectsFromSpecs(pathContext, spec); // Create dg file var dgFile = new DependencyGraphSpec(); dgFile.AddProject(spec); dgFile.AddRestore(spec.RestoreMetadata.ProjectUniqueName); dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg")); var packageX = new SimpleTestPackageContext() { Id = "x", Version = "1.0.0" }; var packageY = new SimpleTestPackageContext() { Id = "y", Version = "1.0.0" }; packageX.AddFile("build/x.targets"); packageX.AddFile("build/x.props"); packageX.AddFile("contentFiles/any/any/_._"); packageY.AddFile("build/y.targets"); packageY.AddFile("build/y.props"); packageY.AddFile("contentFiles/any/any/_._"); SimpleTestPackageUtility.CreatePackages(pathContext.PackageSource, packageX, packageY); var project = projects[0]; // First restore var summaries = await RunRestore(pathContext, logger, sources, dgFile, cacheContext); var success = summaries.All(s => s.Success); Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); // Modify spec spec.Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("y", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); // Act summaries = await RunRestore(pathContext, logger, sources, dgFile, cacheContext); success = summaries.All(s => s.Success); Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); // Verify the file was rewritten Assert.Contains("y.targets", File.ReadAllText(project.TargetsOutput)); Assert.Contains("y.props", File.ReadAllText(project.PropsOutput)); } }
/// <summary> /// Restores a package by querying, downloading, and unzipping it without generating any other files (like project.assets.json). /// </summary> /// <param name="projectPath">The full path to the project.</param> /// <param name="id">The ID of the package.</param> /// <param name="version">The version of the package.</param> /// <param name="settings">The NuGet settings to use.</param> /// <param name="logger">An <see cref="ILogger"/> to use for logging.</param> /// <returns></returns> public static Task <IReadOnlyList <RestoreResultPair> > RunWithoutCommit(string projectPath, string id, string version, ISettings settings, ILogger logger) { using (SourceCacheContext sourceCacheContext = new SourceCacheContext { IgnoreFailedSources = true, }) { // The package spec details what packages to restore PackageSpec packageSpec = new PackageSpec(TargetFrameworks.Select(i => new TargetFrameworkInformation { FrameworkName = i, }).ToList()) { Dependencies = new List <LibraryDependency> { new LibraryDependency { LibraryRange = new LibraryRange(id, new VersionRange(NuGetVersion.Parse(version)), LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All, AutoReferenced = true, IncludeType = LibraryIncludeFlags.None, Type = LibraryDependencyType.Build } }, RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectPath, ProjectName = Path.GetFileNameWithoutExtension(projectPath), ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = projectPath, OutputPath = Path.GetTempPath(), OriginalTargetFrameworks = TargetFrameworks.Select(i => i.ToString()).ToList(), ConfigFilePaths = SettingsUtility.GetConfigFilePaths(settings).ToList(), PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings), Sources = SettingsUtility.GetEnabledSources(settings).ToList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList() }, FilePath = projectPath, Name = Path.GetFileNameWithoutExtension(projectPath), }; DependencyGraphSpec dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(packageSpec); dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); RestoreArgs restoreArgs = new RestoreArgs { AllowNoOp = true, CacheContext = sourceCacheContext, CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)), Log = logger, }; // Create requests from the arguments IReadOnlyList <RestoreSummaryRequest> requests = requestProvider.CreateRequests(restoreArgs).Result; // Restore the package without generating extra files return(RestoreRunner.RunWithoutCommit(requests, restoreArgs)); } }
public async Task NETCoreProject2Project_ProjectReferenceOnlyUnderRestoreMetadata() { // Arrange using (var cacheContext = new SourceCacheContext()) using (var pathContext = new SimpleTestPathContext()) { var logger = new TestLogger(); var sources = new List <PackageSource>(); sources.Add(new PackageSource(pathContext.PackageSource)); var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6"); var spec2 = NETCoreRestoreTestUtility.GetProject(projectName: "projectB", framework: "netstandard1.3"); var specs = new[] { spec1, spec2 }; // Create fake projects, the real data is in the specs var projects = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, specs); // Link projects spec1.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference() { ProjectPath = projects[1].ProjectPath, ProjectUniqueName = spec2.RestoreMetadata.ProjectUniqueName, }); // Create dg file var dgFile = new DependencyGraphSpec(); foreach (var spec in specs) { dgFile.AddProject(spec); } // Restore only the first one dgFile.AddRestore(spec1.RestoreMetadata.ProjectUniqueName); dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg")); // Act var summaries = await NETCoreRestoreTestUtility.RunRestore(pathContext, logger, sources, dgFile, cacheContext); var success = summaries.All(s => s.Success); // Assert Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); var targetLib = projects[0].AssetsFile .Targets .Single(e => e.TargetFramework.Equals(NuGetFramework.Parse("netstandard1.6"))) .Libraries .Single(e => e.Name == "projectB"); var libraryLib = projects[0].AssetsFile .Libraries .Single(e => e.Name == "projectB"); Assert.Equal("projectB", targetLib.Name); Assert.Equal(NuGetFramework.Parse("netstandard1.3"), NuGetFramework.Parse(targetLib.Framework)); Assert.Equal("1.0.0", targetLib.Version.ToNormalizedString()); Assert.Equal("project", targetLib.Type); Assert.Equal("projectB", libraryLib.Name); Assert.Equal("project", libraryLib.Type); Assert.Equal("../projectB/projectB.csproj", libraryLib.MSBuildProject); Assert.Equal("../projectB/projectB.csproj", libraryLib.Path); Assert.Equal("1.0.0", libraryLib.Version.ToNormalizedString()); } }
public async Task NETCoreProject2Project_IgnoreXproj() { // Arrange using (var cacheContext = new SourceCacheContext()) using (var pathContext = new SimpleTestPathContext()) { var logger = new TestLogger(); var sources = new List <PackageSource>(); sources.Add(new PackageSource(pathContext.PackageSource)); var spec = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6"); var specs = new[] { spec }; spec.TargetFrameworks.Single().Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); // Create fake projects, the real data is in the specs var projects = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, spec); var packageX = new SimpleTestPackageContext() { Id = "x", Version = "1.0.0" }; var packageY = new SimpleTestPackageContext() { Id = "y", Version = "1.0.0" }; packageX.Dependencies.Add(packageY); await SimpleTestPackageUtility.CreateFolderFeedV3Async( pathContext.PackageSource, PackageSaveMode.Defaultv3, packageX, packageY); // Create dg file var dgFile = new DependencyGraphSpec(); // Only add projectA dgFile.AddProject(spec); dgFile.AddRestore(spec.RestoreMetadata.ProjectUniqueName); dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg")); var projectYRoot = Path.Combine(pathContext.SolutionRoot, "y"); Directory.CreateDirectory(projectYRoot); var projectYJson = Path.Combine(projectYRoot, "project.json"); var projectJsonContent = JObject.Parse(@"{ 'dependencies': { }, 'frameworks': { 'netstandard1.0': { } } }"); File.WriteAllText(projectYJson, projectJsonContent.ToString()); // Act var summaries = await NETCoreRestoreTestUtility.RunRestore(pathContext, logger, sources, dgFile, cacheContext); var success = summaries.All(s => s.Success); // Assert Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); // Verify only packages Assert.Empty(projects[0].AssetsFile.Libraries.Where(e => e.Type != "package")); } }
public async Task NETCoreProject2Project_VerifyCompileForTransitiveSettings(string expected, bool ab, bool bc, bool cd, bool ax, bool xy, bool yd) { // Arrange using (var cacheContext = new SourceCacheContext()) using (var pathContext = new SimpleTestPathContext()) { var logger = new TestLogger(); var sources = new List <PackageSource>(); sources.Add(new PackageSource(pathContext.PackageSource)); var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "A", framework: "netstandard1.6"); var spec2 = NETCoreRestoreTestUtility.GetProject(projectName: "B", framework: "netstandard1.6"); var spec3 = NETCoreRestoreTestUtility.GetProject(projectName: "C", framework: "netstandard1.6"); var spec4 = NETCoreRestoreTestUtility.GetProject(projectName: "D", framework: "netstandard1.6"); var spec5 = NETCoreRestoreTestUtility.GetProject(projectName: "X", framework: "netstandard1.6"); var spec6 = NETCoreRestoreTestUtility.GetProject(projectName: "Y", framework: "netstandard1.6"); var specs = new[] { spec1, spec2, spec3, spec4, spec5, spec6, }; // Create fake projects, the real data is in the specs var projects = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, specs); // Link projects // A -> B spec1.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference() { ProjectPath = projects[1].ProjectPath, ProjectUniqueName = spec2.RestoreMetadata.ProjectUniqueName, PrivateAssets = ab ? LibraryIncludeFlags.None : LibraryIncludeFlags.Compile }); // B -> C spec2.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference() { ProjectPath = projects[2].ProjectPath, ProjectUniqueName = spec3.RestoreMetadata.ProjectUniqueName, PrivateAssets = bc ? LibraryIncludeFlags.None : LibraryIncludeFlags.Compile }); // C -> D spec3.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference() { ProjectPath = projects[3].ProjectPath, ProjectUniqueName = spec4.RestoreMetadata.ProjectUniqueName, PrivateAssets = cd ? LibraryIncludeFlags.None : LibraryIncludeFlags.Compile }); // A -> X spec1.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference() { ProjectPath = projects[4].ProjectPath, ProjectUniqueName = spec5.RestoreMetadata.ProjectUniqueName, PrivateAssets = ax ? LibraryIncludeFlags.None : LibraryIncludeFlags.Compile }); // X -> Y spec5.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference() { ProjectPath = projects[5].ProjectPath, ProjectUniqueName = spec6.RestoreMetadata.ProjectUniqueName, PrivateAssets = xy ? LibraryIncludeFlags.None : LibraryIncludeFlags.Compile }); // Y -> D spec6.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference() { ProjectPath = projects[3].ProjectPath, ProjectUniqueName = spec4.RestoreMetadata.ProjectUniqueName, PrivateAssets = yd ? LibraryIncludeFlags.None : LibraryIncludeFlags.Compile }); // Create dg file var dgFile = new DependencyGraphSpec(); foreach (var spec in specs) { dgFile.AddProject(spec); var projectDir = Path.GetDirectoryName(spec.RestoreMetadata.ProjectPath); var absolutePath = Path.Combine(projectDir, "bin", "debug", "a.dll"); spec.RestoreMetadata.Files.Add(new ProjectRestoreMetadataFile("lib/netstandard1.6/a.dll", Path.Combine(projectDir, absolutePath))); } dgFile.AddRestore(spec1.RestoreMetadata.ProjectUniqueName); dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg")); var lockFormat = new LockFileFormat(); // Act var summaries = await NETCoreRestoreTestUtility.RunRestore(pathContext, logger, sources, dgFile, cacheContext); var success = summaries.All(s => s.Success); // Assert Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); var assetsFile = lockFormat.Read(Path.Combine(spec1.RestoreMetadata.OutputPath, LockFileFormat.AssetsFileName)); // Find all non _._ compile assets var flowingCompile = assetsFile.Targets.Single().Libraries .Where(e => e.Type == "project") .Where(e => e.CompileTimeAssemblies.Where(f => !f.Path.EndsWith("_._")).Any()) .Select(e => e.Name) .OrderBy(s => s, StringComparer.OrdinalIgnoreCase); Assert.Equal(expected, string.Join("", flowingCompile)); // Runtime should always flow var flowingRuntime = assetsFile.Targets.Single().Libraries .Where(e => e.Type == "project") .Where(e => e.RuntimeAssemblies.Where(f => !f.Path.EndsWith("_._")).Any()) .Select(e => e.Name) .OrderBy(s => s, StringComparer.OrdinalIgnoreCase); Assert.Equal("BCDXY", string.Join("", flowingRuntime)); } }
private RestoreTargetGraph GetRestoreTargetGraph(List <PackageReference> packages, string projectPath, List <NuGetFramework> targetFrameworks, SourceCacheContext sourceCacheContext) { // The package spec details what packages to restore PackageSpec packageSpec = new PackageSpec(targetFrameworks.Select(i => new TargetFrameworkInformation { FrameworkName = i }).ToList()) { //Dependencies = new List<LibraryDependency> //{ // new LibraryDependency // { // LibraryRange = new LibraryRange(id, new VersionRange(NuGetVersion.Parse(version)), LibraryDependencyTarget.Package), // SuppressParent = LibraryIncludeFlags.All, // AutoReferenced = true, // IncludeType = LibraryIncludeFlags.None, // Type = LibraryDependencyType.Build // } //}, Dependencies = packages.Select(i => new LibraryDependency { LibraryRange = new LibraryRange(i.PackageId, new VersionRange(i.PackageVersion), LibraryDependencyTarget.Package), //SuppressParent = LibraryIncludeFlags.All, //AutoReferenced = true, //IncludeType = LibraryIncludeFlags.None, //Type = LibraryDependencyType. }).ToList(), RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectPath, ProjectName = Path.GetFileNameWithoutExtension(projectPath), ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = projectPath, OutputPath = Path.GetTempPath(), OriginalTargetFrameworks = targetFrameworks.Select(i => i.ToString()).ToList(), ConfigFilePaths = SettingsUtility.GetConfigFilePaths(_nugetSettings).ToList(), PackagesPath = SettingsUtility.GetGlobalPackagesFolder(_nugetSettings), Sources = SettingsUtility.GetEnabledSources(_nugetSettings).ToList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(_nugetSettings).ToList() }, FilePath = projectPath, Name = Path.GetFileNameWithoutExtension(projectPath), }; DependencyGraphSpec dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(packageSpec); dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); RestoreArgs restoreArgs = new RestoreArgs { AllowNoOp = true, CacheContext = sourceCacheContext, CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(_nugetSettings)), Log = NullLogger.Instance, }; // Create requests from the arguments IReadOnlyList <RestoreSummaryRequest> requests = requestProvider.CreateRequests(restoreArgs).Result; // Restore the package without generating extra files RestoreResultPair restoreResult = RestoreRunner.RunWithoutCommit(requests, restoreArgs).Result.FirstOrDefault(); RestoreTargetGraph restoreTargetGraph = restoreResult?.Result.RestoreGraphs.FirstOrDefault(); return(restoreTargetGraph); }
public async Task RestoreRunner_RestoreWithRuntime() { // Arrange var sources = new List <PackageSource>(); var project1Json = @" { ""version"": ""1.0.0"", ""description"": """", ""authors"": [ ""author"" ], ""tags"": [ """" ], ""projectUrl"": """", ""licenseUrl"": """", ""frameworks"": { ""net45"": { } } }"; using (var workingDir = TestDirectory.Create()) { var packagesDir = new DirectoryInfo(Path.Combine(workingDir, "globalPackages")); var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource")); var project1 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1")); packagesDir.Create(); packageSource.Create(); project1.Create(); sources.Add(new PackageSource(packageSource.FullName)); File.WriteAllText(Path.Combine(project1.FullName, "project.json"), project1Json); var specPath1 = Path.Combine(project1.FullName, "project.json"); var spec1 = JsonPackageSpecReader.GetPackageSpec(project1Json, "project1", specPath1); spec1 = spec1.EnsureRestoreMetadata(); spec1.RestoreMetadata.Sources = new List <PackageSource> { new PackageSource(packageSource.FullName) }; spec1.RestoreMetadata.PackagesPath = packagesDir.FullName; var dgSpec = new DependencyGraphSpec(); dgSpec.AddProject(spec1); dgSpec.AddRestore("project1"); var logger = new TestLogger(); var lockPath1 = Path.Combine(project1.FullName, "project.assets.json"); var sourceRepos = sources.Select(source => Repository.Factory.GetCoreV3(source.Source)).ToList(); var providerCache = new RestoreCommandProvidersCache(); using (var cacheContext = new SourceCacheContext()) { var restoreContext = new RestoreArgs() { CacheContext = cacheContext, DisableParallel = true, GlobalPackagesFolder = spec1.RestoreMetadata.PackagesPath, Sources = new List <string>() { packageSource.FullName }, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(sources)), PreLoadedRequestProviders = new List <IPreLoadedRestoreRequestProvider>() { new DependencyGraphSpecRequestProvider(providerCache, dgSpec) } }; restoreContext.Runtimes.Add("linux-x86"); // Act var summaries = await RestoreRunner.RunAsync(restoreContext); var success = summaries.All(s => s.Success); var lockFormat = new LockFileFormat(); var lockFile = lockFormat.Read(lockPath1); // Assert Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); Assert.True(lockFile.Targets.Any(graph => graph.RuntimeIdentifier == "linux-x86")); } } }
public async Task RestoreRunner_BasicRestoreWithConfigFile() { // Arrange var sources = new List <PackageSource>(); var project1Json = @" { ""version"": ""1.0.0"", ""description"": """", ""authors"": [ ""author"" ], ""tags"": [ """" ], ""projectUrl"": """", ""licenseUrl"": """", ""frameworks"": { ""net45"": { } } }"; var configFile = @"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> <packageSources> <add key=""nuget.org"" value=""{0}"" /> </packageSources> </configuration> "; using (var workingDir = TestDirectory.Create()) { var packagesDir = new DirectoryInfo(Path.Combine(workingDir, "globalPackages")); var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource")); var project1 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1")); packagesDir.Create(); packageSource.Create(); project1.Create(); File.WriteAllText(Path.Combine(project1.FullName, "project.json"), project1Json); File.WriteAllText(Path.Combine(workingDir, "NuGet.Config"), String.Format(configFile, packageSource.FullName)); var specPath1 = Path.Combine(project1.FullName, "project.json"); var spec1 = JsonPackageSpecReader.GetPackageSpec(project1Json, "project1", specPath1); var configPath = Path.Combine(workingDir, "NuGet.Config"); var dgFile = new DependencyGraphSpec(); spec1 = spec1.EnsureRestoreMetadata(); spec1.RestoreMetadata.ConfigFilePaths = new List <string> { configPath }; spec1.RestoreMetadata.Sources = new List <PackageSource> { new PackageSource(packageSource.FullName) }; spec1.RestoreMetadata.PackagesPath = packagesDir.FullName; dgFile.AddProject(spec1); dgFile.AddRestore("project1"); var logger = new TestLogger(); var lockPath = Path.Combine(project1.FullName, "project.assets.json"); var providerCache = new RestoreCommandProvidersCache(); using (var cacheContext = new SourceCacheContext()) { var restoreContext = new RestoreArgs() { CacheContext = cacheContext, DisableParallel = true, GlobalPackagesFolder = spec1.RestoreMetadata.PackagesPath, ConfigFile = configPath, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(new List <PackageSource>())), PreLoadedRequestProviders = new List <IPreLoadedRestoreRequestProvider> { new DependencyGraphSpecRequestProvider(providerCache, dgFile) } }; // Act var summaries = await RestoreRunner.RunAsync(restoreContext); var summary = summaries.Single(); // Assert Assert.True(summary.Success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); Assert.Equal(1, summary.FeedsUsed.Count); Assert.True(File.Exists(lockPath), lockPath); } } }
public void GetParents_WithMultiLevelGraph_WhenALeafIsDirty_ReturnsProjectsFromEveryLevelAsDirty() { var projectA = GetPackageSpec("A"); var projectB = GetPackageSpec("B"); var projectC = GetPackageSpec("C"); var projectD = GetPackageSpec("D"); var projectE = GetPackageSpec("E"); var projectF = GetPackageSpec("F"); var projectG = GetPackageSpec("G"); var projectH = GetPackageSpec("H"); var projectI = GetPackageSpec("I"); var projectJ = GetPackageSpec("J"); var projectK = GetPackageSpec("K"); var projectL = GetPackageSpec("L"); var projectM = GetPackageSpec("M"); // A => B & C projectA = projectA.WithTestProjectReference(projectB).WithTestProjectReference(projectC); // B => D projectB = projectB.WithTestProjectReference(projectD); // D => F projectD = projectD.WithTestProjectReference(projectF); // C => E projectC = projectC.WithTestProjectReference(projectE); // G => D projectG = projectG.WithTestProjectReference(projectD); // H => C projectH = projectH.WithTestProjectReference(projectC); // I => F projectI = projectI.WithTestProjectReference(projectF); // H => I projectH = projectH.WithTestProjectReference(projectI); // K => L projectK = projectK.WithTestProjectReference(projectL); // J => K projectJ = projectJ.WithTestProjectReference(projectK); // H => J projectH = projectH.WithTestProjectReference(projectJ); // M => L projectM = projectM.WithTestProjectReference(projectL); var dgSpec = new DependencyGraphSpec(); dgSpec.AddProject(projectA); dgSpec.AddRestore(projectA.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectB); dgSpec.AddRestore(projectB.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectC); dgSpec.AddRestore(projectC.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectD); dgSpec.AddRestore(projectD.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectE); dgSpec.AddRestore(projectE.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectF); dgSpec.AddRestore(projectF.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectG); dgSpec.AddRestore(projectG.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectH); dgSpec.AddRestore(projectH.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectI); dgSpec.AddRestore(projectI.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectJ); dgSpec.AddRestore(projectJ.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectK); dgSpec.AddRestore(projectK.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectL); dgSpec.AddRestore(projectL.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(projectM); dgSpec.AddRestore(projectM.RestoreMetadata.ProjectUniqueName); var expected = GetUniqueNames(projectA, projectC, projectE, projectH, projectJ, projectK, projectL, projectM); var actual = SolutionUpToDateChecker.GetParents(GetUniqueNames(projectE, projectL), dgSpec); actual.Should().BeEquivalentTo(expected); }
public async Task NETCoreProject2Project_ProjectFileDependencyGroupsForNETCore() { // Arrange using (var cacheContext = new SourceCacheContext()) using (var pathContext = new SimpleTestPathContext()) { var logger = new TestLogger(); var sources = new List <PackageSource>(); sources.Add(new PackageSource(pathContext.PackageSource)); var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6"); var spec2 = NETCoreRestoreTestUtility.GetProject(projectName: "projectB", framework: "netstandard1.3"); var spec3 = NETCoreRestoreTestUtility.GetProject(projectName: "projectC", framework: "netstandard1.0"); var specs = new[] { spec1, spec2, spec3 }; // Create fake projects, the real data is in the specs var projects = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, specs); // Link projects spec1.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference() { ProjectPath = projects[1].ProjectPath, ProjectUniqueName = spec2.RestoreMetadata.ProjectUniqueName, }); spec2.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference() { ProjectPath = projects[2].ProjectPath, ProjectUniqueName = spec3.RestoreMetadata.ProjectUniqueName, }); // Create dg file var dgFile = new DependencyGraphSpec(); foreach (var spec in specs) { dgFile.AddProject(spec); } // Restore only the first one dgFile.AddRestore(spec1.RestoreMetadata.ProjectUniqueName); dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg")); // Act var summaries = await NETCoreRestoreTestUtility.RunRestore(pathContext, logger, sources, dgFile, cacheContext); var success = summaries.All(s => s.Success); // Assert Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); var dependencies = projects[0].AssetsFile.ProjectFileDependencyGroups.SelectMany(e => e.Dependencies).ToArray(); // Ensure ProjectC does not show up Assert.Equal(1, dependencies.Length); // Ensure ProjectC is in the libraries Assert.Equal(2, projects[0].AssetsFile.Libraries.Count); // Verify the project name is used not the path or unique name Assert.Equal("projectB >= 1.0.0", dependencies[0]); } }
/// <summary> /// Restores a package by querying, downloading, and unzipping it without generating any other files (like project.assets.json). /// </summary> /// <param name="libraryIdentity">The <see cref="LibraryIdentity"/> of the package.</param> /// <param name="settings">The NuGet settings to use.</param> /// <param name="logger">An <see cref="ILogger"/> to use for logging.</param> /// <returns></returns> public static Task <IReadOnlyList <RestoreResultPair> > RunWithoutCommit(LibraryIdentity libraryIdentity, ISettings settings, ILogger logger) { using (var sourceCacheContext = new SourceCacheContext { IgnoreFailedSources = true, }) { var projectDirectory = Path.Combine(NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), Guid.NewGuid().ToString("N")); var projectName = Guid.NewGuid().ToString("N"); var projectFullPath = Path.Combine(projectDirectory, $"{projectName}.proj"); // Iterate through TargetFrameworks to generate Lists required for packageSpec var frameworks = new List <TargetFrameworkInformation>(TargetFrameworks.Count); var originalTargetFrameworks = new List <string>(TargetFrameworks.Count); foreach (var tf in TargetFrameworks) { frameworks.Add(new TargetFrameworkInformation { FrameworkName = tf }); originalTargetFrameworks.Add(tf.ToString()); } // The package spec details what packages to restore var packageSpec = new PackageSpec(frameworks) { Dependencies = new List <LibraryDependency> { new LibraryDependency { LibraryRange = new LibraryRange( libraryIdentity.Name, new VersionRange( minVersion: libraryIdentity.Version, includeMinVersion: true, maxVersion: libraryIdentity.Version, includeMaxVersion: true), LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All, AutoReferenced = true, IncludeType = LibraryIncludeFlags.None, } }, RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectFullPath, ProjectName = projectName, ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = projectFullPath, OutputPath = projectDirectory, OriginalTargetFrameworks = originalTargetFrameworks, ConfigFilePaths = settings.GetConfigFilePaths(), PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings), Sources = SettingsUtility.GetEnabledSources(settings).AsList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList() }, FilePath = projectFullPath, Name = projectName, }; var dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(packageSpec); dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); var restoreArgs = new RestoreArgs { AllowNoOp = false, CacheContext = sourceCacheContext, #pragma warning disable CS0618 // Type or member is obsolete CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings, enablePackageSourcesChangedEvent: false)), #pragma warning restore CS0618 // Type or member is obsolete Log = logger, }; // Create requests from the arguments var requests = requestProvider.CreateRequests(restoreArgs).Result; // Restore the package without generating extra files return(RestoreRunner.RunWithoutCommit(requests, restoreArgs)); } }
public async Task DotnetCliTool_ToolRestoreNoOpsRegardlessOfProject() { // Arrange using (var pathContext = new SimpleTestPathContext()) { var logger1 = new TestLogger(); var logger2 = new TestLogger(); var spec1 = ToolRestoreUtility.GetSpec( Path.Combine(pathContext.SolutionRoot, "fake1.csproj"), "a", VersionRange.Parse("1.0.0"), NuGetFramework.Parse("netcoreapp1.0"), pathContext.UserPackagesFolder, new List <string>() { pathContext.FallbackFolder }, new List <PackageSource>() { new PackageSource(pathContext.PackageSource) }, projectWideWarningProperties: null); var spec2 = ToolRestoreUtility.GetSpec( Path.Combine(pathContext.SolutionRoot, "fake2.csproj"), "a", VersionRange.Parse("1.0.0"), NuGetFramework.Parse("netcoreapp1.0"), pathContext.UserPackagesFolder, new List <string>() { pathContext.FallbackFolder }, new List <PackageSource>() { new PackageSource(pathContext.PackageSource) }, projectWideWarningProperties: null); var dgFile1 = new DependencyGraphSpec(); dgFile1.AddProject(spec1); dgFile1.AddRestore(spec1.Name); var dgFile2 = new DependencyGraphSpec(); dgFile2.AddProject(spec2); dgFile2.AddRestore(spec2.Name); var pathResolver = new ToolPathResolver(pathContext.UserPackagesFolder); var path = pathResolver.GetLockFilePath( "a", NuGetVersion.Parse("1.0.0"), NuGetFramework.Parse("netcoreapp1.0")); await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, new PackageIdentity("a", NuGetVersion.Parse("1.0.0"))); // Act var results1 = await CommandsTestUtility.RunRestore(dgFile1, pathContext, logger1); // Assert Assert.Equal(1, results1.Count); var result1 = results1.Single(); Assert.True(result1.Success, "Failed: " + string.Join(Environment.NewLine, logger1.Messages)); Assert.False(result1.NoOpRestore, "Should not no-op: " + string.Join(Environment.NewLine, logger1.Messages)); Assert.True(File.Exists(path)); // Act var results2 = await CommandsTestUtility.RunRestore(dgFile2, pathContext, logger2); // Assert Assert.Equal(1, results2.Count); var result2 = results2.Single(); Assert.True(result2.Success, "Failed: " + string.Join(Environment.NewLine, logger2.Messages)); Assert.True(result2.NoOpRestore, "Should no-op: " + string.Join(Environment.NewLine, logger2.Messages)); Assert.True(File.Exists(path)); } }
public async Task RestoreBuildTargetsAndProps_VerifyPropsAndTargetsGenerated() { // Arrange using (var cacheContext = new SourceCacheContext()) using (var pathContext = new SimpleTestPathContext()) { var logger = new TestLogger(); var sources = new List <PackageSource>(); sources.Add(new PackageSource(pathContext.PackageSource)); var spec = GetProject("projectA", "net462", "netstandard1.6"); spec.RestoreMetadata.CrossTargeting = true; spec.Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); // Create fake projects, the real data is in the specs var projects = CreateProjectsFromSpecs(pathContext, spec); // Create dg file var dgFile = new DependencyGraphSpec(); dgFile.AddProject(spec); dgFile.AddRestore(spec.RestoreMetadata.ProjectUniqueName); dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg")); var packageX = new SimpleTestPackageContext() { Id = "x", Version = "1.0.0" }; packageX.AddFile("build/x.targets"); packageX.AddFile("build/x.props"); packageX.AddFile("contentFiles/any/any/_._"); SimpleTestPackageUtility.CreatePackages(pathContext.PackageSource, packageX); var project = projects[0]; // Act var summaries = await RunRestore(pathContext, logger, sources, dgFile, cacheContext); var success = summaries.All(s => s.Success); // Assert Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); var targetsXML = XDocument.Parse(File.ReadAllText(project.TargetsOutput)); var targetItemGroups = targetsXML.Root.Elements().Where(e => e.Name.LocalName == "ImportGroup").ToList(); var propsXML = XDocument.Parse(File.ReadAllText(project.PropsOutput)); var propsItemGroups = propsXML.Root.Elements().Where(e => e.Name.LocalName == "ImportGroup").ToList(); Assert.Equal("'$(TargetFramework)' == 'net462' AND '$(ExcludeRestorePackageImports)' != 'true'", targetItemGroups[0].Attribute(XName.Get("Condition")).Value.Trim()); Assert.Equal("'$(TargetFramework)' == 'netstandard1.6' AND '$(ExcludeRestorePackageImports)' != 'true'", targetItemGroups[1].Attribute(XName.Get("Condition")).Value.Trim()); Assert.Equal("'$(TargetFramework)' == 'net462' AND '$(ExcludeRestorePackageImports)' != 'true'", propsItemGroups[0].Attribute(XName.Get("Condition")).Value.Trim()); Assert.Equal("'$(TargetFramework)' == 'netstandard1.6' AND '$(ExcludeRestorePackageImports)' != 'true'", propsItemGroups[1].Attribute(XName.Get("Condition")).Value.Trim()); } }
public async Task DotnetCliTool_VerifyProjectsAreNotAllowed() { // Arrange using (var pathContext = new SimpleTestPathContext()) { var logger = new TestLogger(); var dgFile = new DependencyGraphSpec(); var spec = ToolRestoreUtility.GetSpec( Path.Combine(pathContext.SolutionRoot, "tool", "fake.csproj"), "a", VersionRange.Parse("1.0.0"), NuGetFramework.Parse("netcoreapp1.0"), pathContext.UserPackagesFolder, new List <string>() { pathContext.FallbackFolder }, new List <PackageSource>() { new PackageSource(pathContext.PackageSource) }, projectWideWarningProperties: null); dgFile.AddProject(spec); dgFile.AddRestore(spec.Name); var pathResolver = new ToolPathResolver(pathContext.UserPackagesFolder); var path = pathResolver.GetLockFilePath( "a", NuGetVersion.Parse("1.0.0"), NuGetFramework.Parse("netcoreapp1.0")); var packageA = new SimpleTestPackageContext() { Id = "a", Version = "1.0.0" }; var packageB = new SimpleTestPackageContext() { Id = "b", Version = "1.0.0" }; packageA.Dependencies.Add(packageB); await SimpleTestPackageUtility.CreateFolderFeedV3Async( pathContext.PackageSource, PackageSaveMode.Defaultv3, packageA, packageB); var projectYRoot = Path.Combine(pathContext.SolutionRoot, "b"); Directory.CreateDirectory(projectYRoot); var projectYJson = Path.Combine(projectYRoot, "project.json"); var projectJsonContent = JObject.Parse(@"{ 'dependencies': { }, 'frameworks': { 'netstandard1.0': { } } }"); File.WriteAllText(projectYJson, projectJsonContent.ToString()); // Act var result = await CommandsTestUtility.RunSingleRestore(dgFile, pathContext, logger); // Assert Assert.True(result.Success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); Assert.True(File.Exists(path)); var lockFormat = new LockFileFormat(); var lockFile = lockFormat.Read(path); // Verify only packages Assert.Empty(lockFile.Libraries.Where(e => e.Type != "package")); } }
/// <summary> /// Convert MSBuild items to a DependencyGraphSpec. /// </summary> public static DependencyGraphSpec GetDependencySpec(IEnumerable <IMSBuildItem> items) { if (items == null) { throw new ArgumentNullException(nameof(items)); } var graphSpec = new DependencyGraphSpec(); var itemsById = new Dictionary <string, List <IMSBuildItem> >(StringComparer.Ordinal); var restoreSpecs = new HashSet <string>(StringComparer.Ordinal); var validForRestore = new HashSet <string>(StringComparer.Ordinal); var toolItems = new List <IMSBuildItem>(); // Sort items and add restore specs foreach (var item in items) { var type = item.GetProperty("Type")?.ToLowerInvariant(); var projectUniqueName = item.GetProperty("ProjectUniqueName"); if ("restorespec".Equals(type, StringComparison.Ordinal)) { restoreSpecs.Add(projectUniqueName); } else if (!string.IsNullOrEmpty(projectUniqueName)) { List <IMSBuildItem> idItems; if (!itemsById.TryGetValue(projectUniqueName, out idItems)) { idItems = new List <IMSBuildItem>(1); itemsById.Add(projectUniqueName, idItems); } idItems.Add(item); } } // Add projects var validProjectSpecs = itemsById.Values.Select(GetPackageSpec).Where(e => e != null); foreach (var spec in validProjectSpecs) { if (spec.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference || spec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson || spec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetCliTool || spec.RestoreMetadata.ProjectStyle == ProjectStyle.Standalone) { validForRestore.Add(spec.RestoreMetadata.ProjectUniqueName); } graphSpec.AddProject(spec); } // Remove references to projects that could not be read by restore. RemoveMissingProjects(graphSpec); // Add valid projects to restore section foreach (var projectUniqueName in restoreSpecs.Intersect(validForRestore)) { graphSpec.AddRestore(projectUniqueName); } return(graphSpec); }
public async Task DotnetCliTool_BasicToolRestore_DifferentVersionRanges() { // Arrange using (var pathContext = new SimpleTestPathContext()) { var logger = new TestLogger(); var dgFile = new DependencyGraphSpec(); var versions = new List <VersionRange>(); var limit = 100; for (int i = 0; i < limit; i++) { var version = VersionRange.Parse($"{i + 1}.0.0"); versions.Add(version); var spec = ToolRestoreUtility.GetSpec( Path.Combine(pathContext.SolutionRoot, $"fake{i}.csproj"), "a", version, NuGetFramework.Parse("netcoreapp1.0"), pathContext.UserPackagesFolder, new List <string>() { pathContext.FallbackFolder }, new List <PackageSource>() { new PackageSource(pathContext.PackageSource) }, projectWideWarningProperties: null); dgFile.AddProject(spec); dgFile.AddRestore(spec.Name); } var pathResolver = new ToolPathResolver(pathContext.UserPackagesFolder); foreach (var version in versions) { await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, new PackageIdentity("a", version.MinVersion)); } // Act var results = await CommandsTestUtility.RunRestore(dgFile, pathContext, logger); // Assert Assert.Equal(limit, results.Count); foreach (var result in results) { Assert.True(result.Success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); } foreach (var version in versions) { var path = pathResolver.GetLockFilePath( "a", version.MinVersion, NuGetFramework.Parse("netcoreapp1.0")); Assert.True(File.Exists(path), $"{path} does not exist!"); } } }
/// <summary> /// Convert MSBuild items to a DependencyGraphSpec. /// </summary> public static DependencyGraphSpec GetDependencySpec(IEnumerable <IMSBuildItem> items) { if (items == null) { throw new ArgumentNullException(nameof(items)); } // Unique names created by the MSBuild restore target are project paths, these // can be different on case-insensitive file systems for the same project file. // To workaround this unique names should be compared based on the OS. var uniqueNameComparer = PathUtility.GetStringComparerBasedOnOS(); var graphSpec = new DependencyGraphSpec(); var itemsById = new Dictionary <string, List <IMSBuildItem> >(uniqueNameComparer); var restoreSpecs = new HashSet <string>(uniqueNameComparer); var validForRestore = new HashSet <string>(uniqueNameComparer); var projectPathLookup = new Dictionary <string, string>(uniqueNameComparer); var toolItems = new List <IMSBuildItem>(); // Sort items and add restore specs foreach (var item in items) { var projectUniqueName = item.GetProperty("ProjectUniqueName"); if (item.IsType("restorespec")) { restoreSpecs.Add(projectUniqueName); } else if (!string.IsNullOrEmpty(projectUniqueName)) { List <IMSBuildItem> idItems; if (!itemsById.TryGetValue(projectUniqueName, out idItems)) { idItems = new List <IMSBuildItem>(1); itemsById.Add(projectUniqueName, idItems); } idItems.Add(item); } } // Add projects var validProjectSpecs = itemsById.Values.Select(GetPackageSpec).Where(e => e != null); foreach (var spec in validProjectSpecs) { // Keep track of all project path casings var uniqueName = spec.RestoreMetadata.ProjectUniqueName; if (uniqueName != null && !projectPathLookup.ContainsKey(uniqueName)) { projectPathLookup.Add(uniqueName, uniqueName); } var projectPath = spec.RestoreMetadata.ProjectPath; if (projectPath != null && !projectPathLookup.ContainsKey(projectPath)) { projectPathLookup.Add(projectPath, projectPath); } if (spec.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference || spec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson || spec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetCliTool || spec.RestoreMetadata.ProjectStyle == ProjectStyle.Standalone || spec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetToolReference) { validForRestore.Add(spec.RestoreMetadata.ProjectUniqueName); } graphSpec.AddProject(spec); } // Fix project reference casings to match the original project on case insensitive file systems. NormalizePathCasings(projectPathLookup, graphSpec); // Remove references to projects that could not be read by restore. RemoveMissingProjects(graphSpec); // Add valid projects to restore section foreach (var projectUniqueName in restoreSpecs.Intersect(validForRestore)) { graphSpec.AddRestore(projectUniqueName); } return(graphSpec); }
public async Task RestoreRunner_BasicRestore_VerifyFailureWritesFiles_NETCore() { // Arrange var sources = new List <PackageSource>(); var project1Json = @" { ""version"": ""1.0.0"", ""description"": """", ""authors"": [ ""author"" ], ""tags"": [ """" ], ""projectUrl"": """", ""licenseUrl"": """", ""frameworks"": { ""net45"": { ""dependencies"": { ""x"": ""1.0.0"" } } } }"; using (var workingDir = TestDirectory.Create()) { var packagesDir = new DirectoryInfo(Path.Combine(workingDir, "globalPackages")); var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource")); var project1 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1")); packagesDir.Create(); packageSource.Create(); project1.Create(); sources.Add(new PackageSource(packageSource.FullName)); File.WriteAllText(Path.Combine(project1.FullName, "project.json"), project1Json); var specPath1 = Path.Combine(project1.FullName, "project.json"); var spec1 = JsonPackageSpecReader.GetPackageSpec(project1Json, "project1", specPath1); spec1.RestoreMetadata = new ProjectRestoreMetadata(); spec1.RestoreMetadata.OutputPath = Path.Combine(project1.FullName, "obj"); spec1.RestoreMetadata.ProjectStyle = ProjectStyle.PackageReference; spec1.RestoreMetadata.ProjectName = "project1"; spec1.RestoreMetadata.ProjectPath = Path.Combine(project1.FullName, "project1.csproj"); spec1.RestoreMetadata.ProjectUniqueName = spec1.RestoreMetadata.ProjectPath; spec1.RestoreMetadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.Parse("net45"))); spec1.RestoreMetadata.OriginalTargetFrameworks.Add("net45"); spec1.FilePath = spec1.RestoreMetadata.ProjectPath; var dgSpec = new DependencyGraphSpec(); dgSpec.AddProject(spec1); dgSpec.AddRestore(spec1.RestoreMetadata.ProjectUniqueName); var logger = new TestLogger(); var assetsPath = Path.Combine(project1.FullName, "obj", "project.assets.json"); var sourceRepos = sources.Select(source => Repository.Factory.GetCoreV3(source.Source)).ToList(); var providerCache = new RestoreCommandProvidersCache(); using (var cacheContext = new SourceCacheContext()) { var restoreContext = new RestoreArgs() { CacheContext = cacheContext, DisableParallel = true, GlobalPackagesFolder = packagesDir.FullName, Sources = new List <string>() { packageSource.FullName }, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(sources)), PreLoadedRequestProviders = new List <IPreLoadedRestoreRequestProvider>() { new DependencyGraphSpecRequestProvider(providerCache, dgSpec) } }; // Act var summaries = await RestoreRunner.Run(restoreContext); var summary = summaries.Single(); // Assert Assert.False(summary.Success); Assert.True(File.Exists(assetsPath), assetsPath); Assert.True(File.Exists(Path.Combine(project1.FullName, "obj", "project1.csproj.nuget.g.props"))); Assert.True(File.Exists(Path.Combine(project1.FullName, "obj", "project1.csproj.nuget.g.targets"))); } } }
/// <summary> /// Fetch, if not already downloaded, and install the package represented by /// (<paramref name="packageId"/>, <paramref name="version"/>). /// </summary> /// <remarks>It is safe to call it concurrently be cause we operations are done using the FileLock.</remarks> /// <param name="packageId">Name of package to install.</param> /// <param name="version">Version of package to install.</param> public async Task <NugetLocalPackage> InstallPackage(string packageId, PackageVersion version, IEnumerable <string> targetFrameworks, ProgressReport progress) { using (GetLocalRepositoryLock()) { currentProgressReport = progress; try { var identity = new PackageIdentity(packageId, version.ToNuGetVersion()); var resolutionContext = new ResolutionContext( DependencyBehavior.Lowest, true, true, VersionConstraints.None); var repositories = PackageSources.Select(sourceRepositoryProvider.CreateRepository).ToArray(); var projectContext = new EmptyNuGetProjectContext() { ActionType = NuGetActionType.Install, PackageExtractionContext = new PackageExtractionContext(PackageSaveMode.Defaultv3, XmlDocFileSaveMode.Skip, null, NativeLogger), }; ActivityCorrelationId.StartNew(); { var installPath = SettingsUtility.GetGlobalPackagesFolder(settings); // In case it's a package without any TFM (i.e. Visual Studio plugin), we still need to specify one if (!targetFrameworks.Any()) { targetFrameworks = new string[] { "net6.0" } } ; // Old version expects to be installed in GamePackages if (packageId == "Xenko" && version < new PackageVersion(3, 0, 0, 0) && oldRootDirectory != null) { installPath = oldRootDirectory; } var projectPath = Path.Combine("StrideLauncher.json"); var spec = new PackageSpec() { Name = Path.GetFileNameWithoutExtension(projectPath), // make sure this package never collides with a dependency FilePath = projectPath, Dependencies = new List <LibraryDependency>() { new LibraryDependency { LibraryRange = new LibraryRange(packageId, new VersionRange(version.ToNuGetVersion()), LibraryDependencyTarget.Package), } }, RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectPath, ProjectName = Path.GetFileNameWithoutExtension(projectPath), ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = projectPath, OutputPath = Path.Combine(Path.GetTempPath(), $"StrideLauncher-{packageId}-{version.ToString()}"), OriginalTargetFrameworks = targetFrameworks.ToList(), ConfigFilePaths = settings.GetConfigFilePaths(), PackagesPath = installPath, Sources = SettingsUtility.GetEnabledSources(settings).ToList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList() }, }; foreach (var targetFramework in targetFrameworks) { spec.TargetFrameworks.Add(new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse(targetFramework) }); } using (var context = new SourceCacheContext { MaxAge = DateTimeOffset.UtcNow }) { context.IgnoreFailedSources = true; var dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(spec); dependencyGraphSpec.AddRestore(spec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); var restoreArgs = new RestoreArgs { AllowNoOp = true, CacheContext = context, CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)), Log = NativeLogger, }; // Create requests from the arguments var requests = requestProvider.CreateRequests(restoreArgs).Result; foreach (var request in requests) { // Limit concurrency to avoid timeout request.Request.MaxDegreeOfConcurrency = 4; var command = new RestoreCommand(request.Request); // Act var result = await command.ExecuteAsync(); if (!result.Success) { throw new InvalidOperationException($"Could not restore package {packageId}"); } foreach (var install in result.RestoreGraphs.Last().Install) { var package = result.LockFile.Libraries.FirstOrDefault(x => x.Name == install.Library.Name && x.Version == install.Library.Version); if (package != null) { var packagePath = Path.Combine(installPath, package.Path); OnPackageInstalled(this, new PackageOperationEventArgs(new PackageName(install.Library.Name, install.Library.Version.ToPackageVersion()), packagePath)); } } } } if (packageId == "Xenko" && version < new PackageVersion(3, 0, 0, 0)) { UpdateTargetsHelper(); } } // Load the recently installed package var installedPackages = GetPackagesInstalled(new[] { packageId }); return(installedPackages.FirstOrDefault(p => p.Version == version)); } finally { currentProgressReport = null; } } }
public async Task RestoreRunner_RestoreWithExternalFile_NetCoreOutput() { // Arrange var sources = new List <PackageSource>(); var targetFrameworkInfo1 = new TargetFrameworkInformation(); targetFrameworkInfo1.FrameworkName = NuGetFramework.Parse("net45"); var frameworks1 = new[] { targetFrameworkInfo1 }; var targetFrameworkInfo2 = new TargetFrameworkInformation(); targetFrameworkInfo2.FrameworkName = NuGetFramework.Parse("net45"); var frameworks2 = new[] { targetFrameworkInfo2 }; // Create two net45 projects var spec1 = new PackageSpec(frameworks1); spec1.RestoreMetadata = new ProjectRestoreMetadata(); spec1.RestoreMetadata.ProjectUniqueName = "project1"; spec1.RestoreMetadata.ProjectName = "project1"; spec1.RestoreMetadata.ProjectStyle = ProjectStyle.PackageReference; spec1.RestoreMetadata.OriginalTargetFrameworks.Add("net45"); var spec2 = new PackageSpec(frameworks2); spec2.RestoreMetadata = new ProjectRestoreMetadata(); spec2.RestoreMetadata.ProjectUniqueName = "project2"; spec2.RestoreMetadata.ProjectName = "project2"; spec2.RestoreMetadata.ProjectStyle = ProjectStyle.PackageReference; spec2.RestoreMetadata.OriginalTargetFrameworks.Add("net45"); var specs = new[] { spec1, spec2 }; using (var workingDir = TestDirectory.Create()) { var packagesDir = new DirectoryInfo(Path.Combine(workingDir, "globalPackages")); var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource")); var project1 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1")); var project2 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project2")); packagesDir.Create(); packageSource.Create(); project1.Create(); project2.Create(); sources.Add(new PackageSource(packageSource.FullName)); var projPath1 = Path.Combine(project1.FullName, "project1.csproj"); var projPath2 = Path.Combine(project2.FullName, "project2.csproj"); File.WriteAllText(projPath1, string.Empty); File.WriteAllText(projPath2, string.Empty); spec1.RestoreMetadata.ProjectPath = projPath1; spec1.FilePath = projPath1; spec1.Name = "project1"; spec2.RestoreMetadata.ProjectPath = projPath2; spec2.FilePath = projPath1; spec2.Name = "project2"; var logger = new TestLogger(); var objPath1 = Path.Combine(project1.FullName, "obj"); var objPath2 = Path.Combine(project2.FullName, "obj"); spec1.RestoreMetadata.OutputPath = objPath1; spec2.RestoreMetadata.OutputPath = objPath2; spec1.RestoreMetadata.OriginalTargetFrameworks.Add("net45"); spec2.RestoreMetadata.OriginalTargetFrameworks.Add("net45"); var lockPath1 = Path.Combine(objPath1, "project.assets.json"); var lockPath2 = Path.Combine(objPath2, "project.assets.json"); // Link projects spec1.TargetFrameworks.Single().Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange() { Name = "project2", TypeConstraint = LibraryDependencyTarget.ExternalProject } }); spec1.RestoreMetadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.Parse("net45"))); spec1.RestoreMetadata.TargetFrameworks .Single() .ProjectReferences .Add(new ProjectRestoreReference() { ProjectPath = projPath2, ProjectUniqueName = "project2" }); // Create dg file var dgFile = new DependencyGraphSpec(); foreach (var spec in specs) { dgFile.AddRestore(spec.RestoreMetadata.ProjectName); dgFile.AddProject(spec); } var dgPath = Path.Combine(workingDir, "input.dg"); dgFile.Save(dgPath); var sourceRepos = sources.Select(source => Repository.Factory.GetCoreV3(source.Source)).ToList(); var providerCache = new RestoreCommandProvidersCache(); using (var cacheContext = new SourceCacheContext()) { var restoreContext = new RestoreArgs() { CacheContext = cacheContext, DisableParallel = true, GlobalPackagesFolder = packagesDir.FullName, Sources = new List <string>() { packageSource.FullName }, Inputs = new List <string>() { dgPath }, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(sources)), RequestProviders = new List <IRestoreRequestProvider>() { new DependencyGraphFileRequestProvider(providerCache) } }; // Act var summaries = await RestoreRunner.Run(restoreContext); var success = summaries.All(s => s.Success); var lockFormat = new LockFileFormat(); var lockFile1 = lockFormat.Read(lockPath1); var project2Lib = lockFile1.Libraries.First(); // Assert Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); Assert.True(File.Exists(lockPath1), lockPath1); Assert.True(File.Exists(lockPath2), lockPath2); Assert.Equal("project2", project2Lib.Name); } } }
/// <summary> /// Gets a <see cref="DependencyGraphSpec" /> for the specified project. /// </summary> /// <param name="entryProjectPath">The full path to a project or Visual Studio Solution File.</param> /// <param name="globalProperties">An <see cref="IDictionary{String,String}" /> containing the global properties to use when evaluation MSBuild projects.</param> /// <returns>A <see cref="DependencyGraphSpec" /> for the specified project if they could be loaded, otherwise <code>null</code>.</returns> private DependencyGraphSpec GetDependencyGraphSpec(string entryProjectPath, IDictionary <string, string> globalProperties) { try { // TODO: Use a localized resource from https://github.com/NuGet/NuGet.Client/pull/3111 MSBuildLogger.LogMinimal("Determining projects to restore..."); var entryProjects = GetProjectGraphEntryPoints(entryProjectPath, globalProperties); // Load the projects via MSBuild and create an array of them since Parallel.ForEach is optimized for arrays var projects = LoadProjects(entryProjects)?.ToArray(); // If no projects were loaded, return null indicating that the projects could not be loaded. if (projects == null || projects.Length == 0) { return(null); } var sw = Stopwatch.StartNew(); var dependencyGraphSpec = new DependencyGraphSpec(isReadOnly: true); // Unique names created by the MSBuild restore target are project paths, these // can be different on case-insensitive file systems for the same project file. // To workaround this unique names should be compared based on the OS. var uniqueNameComparer = PathUtility.GetStringComparerBasedOnOS(); var projectPathLookup = new ConcurrentDictionary <string, string>(uniqueNameComparer); try { // Get the PackageSpecs in parallel because creating each one is relatively expensive so parallelism speeds things up Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, project => { var packageSpec = GetPackageSpec(project.OuterProject, project); if (packageSpec != null) { // Keep track of all project path casings var uniqueName = packageSpec.RestoreMetadata.ProjectUniqueName; if (uniqueName != null && !projectPathLookup.ContainsKey(uniqueName)) { projectPathLookup.TryAdd(uniqueName, uniqueName); } var projectPath = packageSpec.RestoreMetadata.ProjectPath; if (projectPath != null && !projectPathLookup.ContainsKey(projectPath)) { projectPathLookup.TryAdd(projectPath, projectPath); } // TODO: Remove this lock once https://github.com/NuGet/Home/issues/9002 is fixed lock (dependencyGraphSpec) { dependencyGraphSpec.AddProject(packageSpec); } } }); } catch (AggregateException e) { // Log exceptions thrown while creating PackageSpec objects foreach (var exception in e.Flatten().InnerExceptions) { LoggingQueue.TaskLoggingHelper.LogErrorFromException(exception); } return(null); } // Fix project reference casings to match the original project on case insensitive file systems. MSBuildRestoreUtility.NormalizePathCasings(projectPathLookup, dependencyGraphSpec); // Add all entry projects if they support restore. In most cases this is just a single project but if the entry // project is a solution, then all projects in the solution are added (if they support restore) foreach (var entryPoint in entryProjects) { PackageSpec project = dependencyGraphSpec.GetProjectSpec(entryPoint.ProjectFile); if (project != null && BuildTasksUtility.DoesProjectSupportRestore(project)) { dependencyGraphSpec.AddRestore(entryPoint.ProjectFile); } } sw.Stop(); MSBuildLogger.LogDebug(string.Format(CultureInfo.CurrentCulture, Strings.CreatedDependencyGraphSpec, sw.ElapsedMilliseconds)); return(dependencyGraphSpec); } catch (Exception e) { LoggingQueue.TaskLoggingHelper.LogErrorFromException(e, showStackTrace: true); } return(null); }
public async Task ContentFilesMSBuild_VerifyConditionForFallbackContentItemGroup(string files, string expected) { // Arrange var logger = new TestLogger(); using (var cacheContext = new SourceCacheContext()) using (var pathContext = new SimpleTestPathContext()) { var tfi = new List <TargetFrameworkInformation> { new TargetFrameworkInformation() { FrameworkName = NuGetFramework.Parse("net462") } }; var spec = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "net46"); spec.Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("a", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); var project = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, spec).Single(); var packageA = new SimpleTestPackageContext("a"); packageA.AddFile("contentFiles/any/any/anyMarker.txt"); foreach (var file in files.Split('|')) { packageA.AddFile(file); } SimpleTestPackageUtility.CreatePackages(pathContext.PackageSource, packageA); // Create dg file var dgFile = new DependencyGraphSpec(); dgFile.AddProject(spec); dgFile.AddRestore(spec.RestoreMetadata.ProjectUniqueName); dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg")); // Act var result = (await NETCoreRestoreTestUtility.RunRestore( pathContext, logger, new List <PackageSource>() { new PackageSource(pathContext.PackageSource) }, dgFile, cacheContext)).Single(); var props = XDocument.Load(project.PropsOutput); var itemGroups = props.Root.Elements(XName.Get("ItemGroup", "http://schemas.microsoft.com/developer/msbuild/2003")).ToArray(); var group = itemGroups.Single(e => e.ToString().Contains("anyMarker.txt")); // Assert Assert.True(result.Success, logger.ShowErrors()); Assert.Equal(expected.Trim(), group.Attribute(XName.Get("Condition")).Value.Trim()); } }
public async Task InstallPackageFromAnotherProcessVerifyCacheIsClearedAsync() { // Arrange var logger = new TestLogger(); using (var cacheContext = new SourceCacheContext()) using (var pathContext = new SimpleTestPathContext()) { var tfi = new List <TargetFrameworkInformation> { new TargetFrameworkInformation() { FrameworkName = NuGetFramework.Parse("net462") } }; var spec = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "net46"); spec.Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("a", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); var project = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, spec).Single(); var packageA = new SimpleTestPackageContext("a"); await SimpleTestPackageUtility.CreatePackagesAsync(pathContext.PackageSource, packageA); // Create dg file var dgFile = new DependencyGraphSpec(); dgFile.AddProject(spec); dgFile.AddRestore(spec.RestoreMetadata.ProjectUniqueName); dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg")); var providerCache = new RestoreCommandProvidersCache(); var sources = new List <string>() { pathContext.PackageSource }; var restoreContext = new RestoreArgs() { CacheContext = cacheContext, DisableParallel = true, GlobalPackagesFolder = pathContext.UserPackagesFolder, Sources = sources, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(new List <PackageSource>() { new PackageSource(pathContext.PackageSource) })), PreLoadedRequestProviders = new List <IPreLoadedRestoreRequestProvider>() { new DependencyGraphSpecRequestProvider(providerCache, dgFile) } }; var request = (await RestoreRunner.GetRequests(restoreContext)).Single(); var providers = providerCache.GetOrCreate(pathContext.UserPackagesFolder, sources, new List <SourceRepository>(), cacheContext, logger, false); var command = new RestoreCommand(request.Request); // Add to cache before install on all providers var globalPackages = providers.GlobalPackages; var packages = globalPackages.FindPackagesById("a"); packages.Should().BeEmpty("has not been installed yet"); foreach (var local in providers.LocalProviders) { await local.GetDependenciesAsync(new LibraryIdentity("a", NuGetVersion.Parse("1.0.0"), LibraryType.Package), NuGetFramework.Parse("net46"), cacheContext, logger, CancellationToken.None); } // Install the package without updating the cache await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.UserPackagesFolder, PackageSaveMode.Defaultv3, packageA); // Run restore using an incorrect cache var result = await command.ExecuteAsync(); // Verify a is in the output assets file result.Success.Should().BeTrue(); result.LockFile.GetLibrary("a", new NuGetVersion(1, 0, 0)).Should().NotBeNull(); } }
public async Task RestoreRunner_BasicRestore_VerifyFailureWritesFiles() { // Arrange var sources = new List <PackageSource>(); var project1Json = @" { ""version"": ""1.0.0"", ""description"": """", ""authors"": [ ""author"" ], ""tags"": [ """" ], ""projectUrl"": """", ""licenseUrl"": """", ""frameworks"": { ""net45"": { ""dependencies"": { ""x"": ""1.0.0"" } } } }"; using (var workingDir = TestDirectory.Create()) { var packagesDir = new DirectoryInfo(Path.Combine(workingDir, "globalPackages")); var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource")); var project1 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1")); packagesDir.Create(); packageSource.Create(); project1.Create(); sources.Add(new PackageSource(packageSource.FullName)); File.WriteAllText(Path.Combine(project1.FullName, "project.json"), project1Json); var specPath1 = Path.Combine(project1.FullName, "project.json"); var spec1 = JsonPackageSpecReader.GetPackageSpec(project1Json, "project1", specPath1); spec1 = spec1.EnsureRestoreMetadata(); spec1.RestoreMetadata.Sources = new List <PackageSource> { new PackageSource(packageSource.FullName) }; spec1.RestoreMetadata.PackagesPath = packagesDir.FullName; var dgFile = new DependencyGraphSpec(); dgFile.AddProject(spec1); dgFile.AddRestore("project1"); var logger = new TestLogger(); var lockPath = Path.Combine(project1.FullName, "project.assets.json"); var sourceRepos = sources.Select(source => Repository.Factory.GetCoreV3(source.Source)).ToList(); var packageX = new SimpleTestPackageContext() { Id = "x", Version = "1.0.0" }; packageX.AddFile("build/net45/x.targets"); var packageY = new SimpleTestPackageContext("y"); packageX.Dependencies.Add(packageY); var yPath = SimpleTestPackageUtility.CreateFullPackage(packageSource.FullName, packageY); SimpleTestPackageUtility.CreateFullPackage(packageSource.FullName, packageX); // y does not exist yPath.Delete(); var providerCache = new RestoreCommandProvidersCache(); using (var cacheContext = new SourceCacheContext()) { var restoreContext = new RestoreArgs() { CacheContext = cacheContext, DisableParallel = true, GlobalPackagesFolder = packagesDir.FullName, Sources = new List <string>() { packageSource.FullName }, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(sources)), PreLoadedRequestProviders = new List <IPreLoadedRestoreRequestProvider>() { new DependencyGraphSpecRequestProvider(providerCache, dgFile) } }; var targetsPath = Path.Combine(project1.FullName, "project1.csproj.nuget.g.targets"); var propsPath = Path.Combine(project1.FullName, "project1.nuget.props"); // Act var summaries = await RestoreRunner.RunAsync(restoreContext); var summary = summaries.Single(); var targets = TargetsUtility.GetMSBuildPackageImports(targetsPath); // Assert Assert.False(summary.Success); Assert.True(File.Exists(lockPath), lockPath); Assert.True(File.Exists(targetsPath)); Assert.False(File.Exists(propsPath)); Assert.Equal(1, targets.Count); } } }