public async Task BuildAssetsUtils_GeneratePathPropertyForTools(bool hasTools) { using (var pathContext = new SimpleTestPathContext()) using (var randomProjectDirectory = TestDirectory.Create()) { // Arrange var identity = new PackageIdentity("packagea", NuGetVersion.Parse("1.0.0")); var packageDirectory = Directory.CreateDirectory(Path.Combine(pathContext.UserPackagesFolder, identity.Id, identity.Version.ToNormalizedString())); File.WriteAllText(Path.Combine(packageDirectory.FullName, $"{identity.Id}.{identity.Version.ToNormalizedString()}.nupkg.sha512"), string.Empty); var packagePath = await SimpleTestPackageUtility.CreateFullPackageAsync( packageDirectory.FullName, identity.Id, identity.Version.ToString()); var logger = new TestLogger(); 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); spec.RestoreMetadata.ProjectStyle = ProjectStyle.PackageReference; spec.Dependencies.Add(new LibraryDependency { IncludeType = LibraryIncludeFlags.All, LibraryRange = new LibraryRange(identity.Id, new VersionRange(identity.Version), LibraryDependencyTarget.Package) }); var targetGraphs = new List <RestoreTargetGraph> { OriginalCaseGlobalPackageFolderTests.GetRestoreTargetGraph(pathContext.PackageSource, identity, packagePath, logger) }; targetGraphs[0].Graphs.FirstOrDefault().Item.Data.Dependencies = spec.Dependencies; var lockFile = new LockFile { Libraries = { new LockFileLibrary { Name = identity.Id, Version = identity.Version, Path = $"{identity.Id.ToLowerInvariant()}/{identity.Version.ToNormalizedString()}", Type = LibraryType.Package, HasTools = hasTools, } }, Targets = { new LockFileTarget { RuntimeIdentifier = targetGraphs[0].RuntimeIdentifier, TargetFramework = targetGraphs[0].Framework, Libraries = { new LockFileTargetLibrary { Name = identity.Id, Version = identity.Version } } } } }; var repositories = new List <NuGetv3LocalRepository> { new NuGetv3LocalRepository(pathContext.UserPackagesFolder) }; var restoreRequest = new TestRestoreRequest(spec, new[] { new PackageSource(pathContext.PackageSource) }, pathContext.PackagesV2, logger) { ProjectStyle = spec.RestoreMetadata.ProjectStyle }; var assetsFilePath = Path.Combine(randomProjectDirectory, "obj", "project.assets.json"); // Act var outputFiles = BuildAssetsUtils.GetMSBuildOutputFiles(spec, lockFile, targetGraphs, repositories, restoreRequest, assetsFilePath, true, logger); var expectedPropertyName = $"Pkg{identity.Id.Replace(".", "_")}"; var actualPropertyElement = outputFiles.FirstOrDefault().Content.Root.Descendants().Where(i => i.Name.LocalName.Equals(expectedPropertyName)).FirstOrDefault(); if (hasTools) { // Assert Assert.NotNull(actualPropertyElement); Assert.Equal($" '$({actualPropertyElement.Name.LocalName})' == '' ", actualPropertyElement.Attribute("Condition")?.Value); Assert.Equal(packageDirectory.FullName, actualPropertyElement?.Value, ignoreCase: true); Assert.Equal(" '$(ExcludeRestorePackageImports)' != 'true' ", actualPropertyElement.Parent.Attribute("Condition")?.Value); } else { Assert.Null(actualPropertyElement); } } }
public void BuildAssetsUtils_VerifyPositionAndSortOrder() { // Arrange using (var globalPackagesFolder = TestDirectory.Create()) using (var randomProjectDirectory = TestDirectory.Create()) { var props = new List <MSBuildRestoreItemGroup>(); var targets = new List <MSBuildRestoreItemGroup>(); targets.Add(new MSBuildRestoreItemGroup() { Conditions = new List <string>() { "b" }, Items = new List <XElement>() { BuildAssetsUtils.GenerateImport("a.targets") }, Position = 0 }); targets.Add(new MSBuildRestoreItemGroup() { Conditions = new List <string>() { "a" }, Items = new List <XElement>() { BuildAssetsUtils.GenerateImport("a.targets") }, Position = 0 }); targets.Add(new MSBuildRestoreItemGroup() { Conditions = new List <string>() { "z" }, Items = new List <XElement>() { BuildAssetsUtils.GenerateImport("a.targets") }, Position = -1 }); targets.Add(new MSBuildRestoreItemGroup() { Conditions = new List <string>() { "x" }, Items = new List <XElement>() { BuildAssetsUtils.GenerateImport("a.targets") }, Position = 100 }); // Act var xml = BuildAssetsUtils.GenerateMSBuildFile( targets, ProjectStyle.ProjectJson); // Assert var targetItemGroups = xml.Root.Elements().Where(e => e.Name.LocalName == "ImportGroup").ToList(); Assert.Equal(4, targetItemGroups.Count); Assert.Equal("z", targetItemGroups[0].Attribute(XName.Get("Condition")).Value.Trim()); Assert.Equal("a", targetItemGroups[1].Attribute(XName.Get("Condition")).Value.Trim()); Assert.Equal("b", targetItemGroups[2].Attribute(XName.Get("Condition")).Value.Trim()); Assert.Equal("x", targetItemGroups[3].Attribute(XName.Get("Condition")).Value.Trim()); } }
public async Task BuildAssetsUtils_GeneratePathProperty() { using (var pathContext = new SimpleTestPathContext()) { // Arrange var identity = new PackageIdentity("packagea", NuGetVersion.Parse("1.0.0")); var packageDirectory = Directory.CreateDirectory(Path.Combine(pathContext.UserPackagesFolder, identity.Id, identity.Version.ToNormalizedString())); File.WriteAllText(Path.Combine(packageDirectory.FullName, $"{identity.Id}.{identity.Version.ToNormalizedString()}.nupkg.sha512"), string.Empty); var packagePath = await SimpleTestPackageUtility.CreateFullPackageAsync( packageDirectory.FullName, identity.Id, identity.Version.ToString()); var logger = new TestLogger(); const string referenceSpec = @" { ""frameworks"": { ""netcoreapp1.0"": { ""dependencies"": { } } } }"; var projectName = "a"; var rootProjectsPath = pathContext.WorkingDirectory; var projectDirectory = Path.Combine(rootProjectsPath, projectName); var spec = JsonPackageSpecReader.GetPackageSpec(referenceSpec, projectName, Path.Combine(projectDirectory, projectName)).WithTestRestoreMetadata(); spec.Dependencies.Add(new LibraryDependency { GeneratePathProperty = true, IncludeType = LibraryIncludeFlags.All, LibraryRange = new LibraryRange(identity.Id.ToUpperInvariant(), new VersionRange(identity.Version), LibraryDependencyTarget.Package) }); var targetGraphs = new List <RestoreTargetGraph> { OriginalCaseGlobalPackageFolderTests.GetRestoreTargetGraph(pathContext.PackageSource, identity, packagePath, logger) }; targetGraphs[0].Graphs.FirstOrDefault().Item.Data.Dependencies = spec.Dependencies.ToList(); var lockFile = new LockFile { Libraries = { new LockFileLibrary { Name = identity.Id, Version = identity.Version, Path = $"{identity.Id.ToLowerInvariant()}/{identity.Version.ToNormalizedString()}", Type = LibraryType.Package } }, Targets = { new LockFileTarget { RuntimeIdentifier = targetGraphs[0].RuntimeIdentifier, TargetFramework = targetGraphs[0].Framework, Libraries = { new LockFileTargetLibrary { Name = identity.Id, Version = identity.Version } } } } }; var repositories = new List <NuGetv3LocalRepository> { new NuGetv3LocalRepository(pathContext.UserPackagesFolder) }; var restoreRequest = new TestRestoreRequest(spec, new[] { new PackageSource(pathContext.PackageSource) }, pathContext.PackagesV2, logger) { ProjectStyle = spec.RestoreMetadata.ProjectStyle }; var assetsFilePath = Path.Combine(projectDirectory, "obj", "project.assets.json"); // Act var outputFiles = BuildAssetsUtils.GetMSBuildOutputFiles(spec, lockFile, targetGraphs, repositories, restoreRequest, assetsFilePath, true, logger); // Assert var expectedPropertyGroup = outputFiles.FirstOrDefault().Content.Root.Elements().LastOrDefault(); Assert.NotNull(expectedPropertyGroup); Assert.Equal(" '$(ExcludeRestorePackageImports)' != 'true' ", expectedPropertyGroup.Attribute("Condition")?.Value); var expectedProperty = expectedPropertyGroup.Elements().FirstOrDefault(); Assert.Equal($"Pkg{identity.Id.Replace(".", "_")}", expectedProperty.Name.LocalName); Assert.Equal($" '$({expectedProperty.Name.LocalName})' == '' ", expectedProperty.Attribute("Condition")?.Value); Assert.Equal(packageDirectory.FullName, expectedProperty?.Value, ignoreCase: true); } }
public void BuildAssetsUtils_MultipleTFMs() { // Arrange using (var globalPackagesFolder = TestDirectory.Create()) using (var randomProjectDirectory = TestDirectory.Create()) { var props = new List <MSBuildRestoreItemGroup>(); var targets = new List <MSBuildRestoreItemGroup>(); targets.Add(new MSBuildRestoreItemGroup() { Conditions = new List <string>() { "'$(TargetFramework)' == 'net45'" }, Items = new List <XElement>() { BuildAssetsUtils.GenerateImport("a.targets"), BuildAssetsUtils.GenerateImport("b.targets") }, }); targets.Add(new MSBuildRestoreItemGroup() { Conditions = new List <string>() { "'$(TargetFramework)' == 'netstandard16'" }, Items = new List <XElement>() { BuildAssetsUtils.GenerateImport("c.targets") }, }); targets.Add(new MSBuildRestoreItemGroup() { Conditions = new List <string>() { "'$(TargetFramework)' == 'netStandard1.7'" } }); // Act var targetsXML = BuildAssetsUtils.GenerateMSBuildFile( targets, ProjectStyle.PackageReference); // Assert var targetItemGroups = targetsXML.Root.Elements().Where(e => e.Name.LocalName == "ImportGroup").ToList(); Assert.Equal(2, targetItemGroups.Count); Assert.Equal("'$(TargetFramework)' == 'net45'", targetItemGroups[0].Attribute(XName.Get("Condition")).Value.Trim()); Assert.Equal("'$(TargetFramework)' == 'netstandard16'", targetItemGroups[1].Attribute(XName.Get("Condition")).Value.Trim()); Assert.Equal(2, targetItemGroups[0].Elements().Count()); Assert.Equal("a.targets", targetItemGroups[0].Elements().ToList()[0].Attribute(XName.Get("Project")).Value); Assert.Equal("b.targets", targetItemGroups[0].Elements().ToList()[1].Attribute(XName.Get("Project")).Value); Assert.Equal(1, targetItemGroups[1].Elements().Count()); Assert.Equal("c.targets", targetItemGroups[1].Elements().ToList()[0].Attribute(XName.Get("Project")).Value); } }
public static async Task <bool> RestoreAsync( DependencyGraphSpec dependencyGraphSpec, bool interactive, bool recursive, bool noCache, bool ignoreFailedSources, bool disableParallel, bool force, bool forceEvaluate, bool hideWarningsAndErrors, bool restorePC, bool cleanupAssetsForUnsupportedProjects, Common.ILogger log, CancellationToken cancellationToken) { if (dependencyGraphSpec == null) { throw new ArgumentNullException(nameof(dependencyGraphSpec)); } if (log == null) { throw new ArgumentNullException(nameof(log)); } try { DefaultCredentialServiceUtility.SetupDefaultCredentialService(log, !interactive); // Set connection limit NetworkProtocolUtility.SetConnectionLimit(); // Set user agent string used for network calls #if IS_CORECLR UserAgent.SetUserAgentString(new UserAgentStringBuilder("NuGet .NET Core MSBuild Task") .WithOSDescription(RuntimeInformation.OSDescription)); #else // OS description is set by default on Desktop UserAgent.SetUserAgentString(new UserAgentStringBuilder("NuGet Desktop MSBuild Task")); #endif var restoreSummaries = new List <RestoreSummary>(); var providerCache = new RestoreCommandProvidersCache(); #if IS_DESKTOP if (restorePC && dependencyGraphSpec.Projects.Any(i => i.RestoreMetadata.ProjectStyle == ProjectStyle.PackagesConfig)) { var v2RestoreResult = await PerformNuGetV2RestoreAsync(log, dependencyGraphSpec, noCache, disableParallel, interactive); restoreSummaries.Add(v2RestoreResult); if (restoreSummaries.Count < 1) { var message = string.Format( Strings.InstallCommandNothingToInstall, "packages.config" ); log.LogMinimal(message); } if (!v2RestoreResult.Success) { v2RestoreResult .Errors .Where(l => l.Level == LogLevel.Warning) .ForEach(message => { log.LogWarning(message.Message); }); } } #endif using (var cacheContext = new SourceCacheContext()) { cacheContext.NoCache = noCache; cacheContext.IgnoreFailedSources = ignoreFailedSources; // Pre-loaded request provider containing the graph file var providers = new List <IPreLoadedRestoreRequestProvider>(); if (dependencyGraphSpec.Restore.Count > 0) { // Add all child projects if (recursive) { AddAllProjectsForRestore(dependencyGraphSpec); } providers.Add(new DependencyGraphSpecRequestProvider(providerCache, dependencyGraphSpec)); var restoreContext = new RestoreArgs() { CacheContext = cacheContext, LockFileVersion = LockFileFormat.Version, // 'dotnet restore' fails on slow machines (https://github.com/NuGet/Home/issues/6742) // The workaround is to pass the '--disable-parallel' option. // We apply the workaround by default when the system has 1 cpu. // This will fix restore failures on VMs with 1 CPU and containers with less or equal to 1 CPU assigned. DisableParallel = Environment.ProcessorCount == 1 ? true : disableParallel, Log = log, MachineWideSettings = new XPlatMachineWideSetting(), PreLoadedRequestProviders = providers, AllowNoOp = !force, HideWarningsAndErrors = hideWarningsAndErrors, RestoreForceEvaluate = forceEvaluate }; if (restoreContext.DisableParallel) { HttpSourceResourceProvider.Throttle = SemaphoreSlimThrottle.CreateBinarySemaphore(); } cancellationToken.ThrowIfCancellationRequested(); restoreSummaries.AddRange(await RestoreRunner.RunAsync(restoreContext, cancellationToken)); } if (cleanupAssetsForUnsupportedProjects) { // Restore assets are normally left on disk between restores for all projects. This can cause a condition where a project that supports PackageReference was restored // but then a user changes a branch or some other condition and now the project does not use PackageReference. Since the restore assets are left on disk, the build // consumes them which can cause build errors. The code below cleans up all of the files that we write so that they are not used during build Parallel.ForEach(dependencyGraphSpec.Projects.Where(i => !DoesProjectSupportRestore(i)), project => { if (project.RestoreMetadata == null || string.IsNullOrWhiteSpace(project.RestoreMetadata.OutputPath) || string.IsNullOrWhiteSpace(project.RestoreMetadata.ProjectPath)) { return; } // project.assets.json FileUtility.Delete(Path.Combine(project.RestoreMetadata.OutputPath, LockFileFormat.AssetsFileName)); // project.csproj.nuget.cache FileUtility.Delete(project.RestoreMetadata.CacheFilePath); // project.csproj.nuget.g.props FileUtility.Delete(BuildAssetsUtils.GetMSBuildFilePathForPackageReferenceStyleProject(project, BuildAssetsUtils.PropsExtension)); // project..csproj.nuget.g.targets FileUtility.Delete(BuildAssetsUtils.GetMSBuildFilePathForPackageReferenceStyleProject(project, BuildAssetsUtils.TargetsExtension)); // project.csproj.nuget.dgspec.json FileUtility.Delete(Path.Combine(project.RestoreMetadata.OutputPath, DependencyGraphSpec.GetDGSpecFileName(Path.GetFileName(project.RestoreMetadata.ProjectPath)))); }); } } if (restoreSummaries.Count < 1) { log.LogMinimal(Strings.NoProjectsToRestore); } else { RestoreSummary.Log(log, restoreSummaries); } return(restoreSummaries.All(x => x.Success)); } finally { // The CredentialService lifetime is for the duration of the process. We should not leave a potentially unavailable logger. // We need to update the delegating logger with a null instance // because the tear downs of the plugins and similar rely on idleness and process exit. DefaultCredentialServiceUtility.UpdateCredentialServiceDelegatingLogger(NullLogger.Instance); } }