Пример #1
0
        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);
                    }
                }
        }
Пример #2
0
        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());
                }
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
                }
        }
Пример #5
0
        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);
            }
        }