public void Load_WithPath_WhenJsonIsInvalid_Throws(string json) { using (var test = Test.Create(json)) { Assert.Throws <InvalidDataException>(() => DependencyGraphSpec.Load(test.FilePath)); } }
public void DependencyGraphSpec_ProjectsWithToolReferences_GetClosures() { // Arrange var json = JObject.Parse(ResourceTestUtility.GetResource("NuGet.ProjectModel.Test.compiler.resources.test2.dg", typeof(DependencyGraphSpecTests))); var childProject = @"f:\validation\test\dg\Project.Core\Project.Core\Project.Core.csproj"; var parentProject = @"f:\validation\test\dg\Project.Core\Project\Project.csproj"; var tool = @"atool-netcoreapp2.0-[1.0.0, )"; // Act var dg = DependencyGraphSpec.Load(json); var childClosure = dg.GetClosure(childProject).OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.Ordinal).ToList(); var parentClosure = dg.GetClosure(parentProject).OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.Ordinal).ToList(); var toolClosure = dg.GetClosure(tool).OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.Ordinal).ToList(); // Assert Assert.Equal(2, parentClosure.Count); Assert.Equal(childProject, parentClosure[0].RestoreMetadata.ProjectUniqueName); Assert.Equal(parentProject, parentClosure[1].RestoreMetadata.ProjectUniqueName); Assert.Equal(1, childClosure.Count); Assert.Equal(childProject, childClosure.Single().RestoreMetadata.ProjectUniqueName); Assert.Equal(1, toolClosure.Count); Assert.Equal(tool, toolClosure.Single().RestoreMetadata.ProjectUniqueName); }
public DependencyGraphSpec GenerateDependencyGraph(string projectPath) { var dgOutput = _fileSystem.Path.Combine(_fileSystem.Path.GetTempPath(), _fileSystem.Path.GetTempFileName()); string[] arguments = { "msbuild", $"\"{projectPath}\"", "/t:Restore,GenerateRestoreGraphFile", $"/p:RestoreGraphOutputPath=\"{dgOutput}\"" }; var runStatus = _dotNetRunner.Run(_fileSystem.Path.GetDirectoryName(projectPath), arguments); if (runStatus.IsSuccess) { /* * TempDirectory is a hacky workaround for DependencyGraphSpec(JObject) * being deprecated. Unfortunately it looks like the only alternative * is to load the file locally. Which is ok normally, but complicates * testing. */ using (var tempDirectory = new TempDirectory()) { var dependencyGraphFilename = System.IO.Path.Combine(tempDirectory.DirectoryPath, "DependencyGraph.json"); var dependencyGraphText = _fileSystem.File.ReadAllText(dgOutput); System.IO.File.WriteAllText(dependencyGraphFilename, dependencyGraphText); return(DependencyGraphSpec.Load(dependencyGraphFilename)); } } throw new CommandValidationException($"Unable to process the project `{projectPath}. Are you sure this is a valid .NET Core or .NET Standard project type?" + $"{Environment.NewLine}{Environment.NewLine}Here is the full error message returned from the Microsoft Build Engine:{Environment.NewLine}{Environment.NewLine}{runStatus.Output} - {runStatus.Errors} - exit code: {runStatus.ExitCode}"); }
public void GetClosure_WhenProjectHasToolReferences_ReturnsClosure() { // Arrange string jsonContent = GetResourceAsJson(Test2Dg); using var testDirectory = TestDirectory.Create(); var jsonPath = Path.Combine(testDirectory.Path, "dg.json"); File.WriteAllText(jsonPath, jsonContent); // Act var dg = DependencyGraphSpec.Load(jsonPath); var childProject = @"f:\validation\test\dg\Project.Core\Project.Core\Project.Core.csproj"; var parentProject = @"f:\validation\test\dg\Project.Core\Project\Project.csproj"; var tool = @"atool-netcoreapp2.0-[1.0.0, )"; var childClosure = dg.GetClosure(childProject).OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.Ordinal).ToList(); var parentClosure = dg.GetClosure(parentProject).OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.Ordinal).ToList(); var toolClosure = dg.GetClosure(tool).OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.Ordinal).ToList(); // Assert Assert.Equal(2, parentClosure.Count); Assert.Equal(childProject, parentClosure[0].RestoreMetadata.ProjectUniqueName); Assert.Equal(parentProject, parentClosure[1].RestoreMetadata.ProjectUniqueName); Assert.Equal(1, childClosure.Count); Assert.Equal(childProject, childClosure.Single().RestoreMetadata.ProjectUniqueName); Assert.Equal(1, toolClosure.Count); Assert.Equal(tool, toolClosure.Single().RestoreMetadata.ProjectUniqueName); }
public void GetParents_WhenCalledOnChild_ReturnsParents() { // Arrange string jsonContent = GetResourceAsJson(Test1Dg); using var testDirectory = TestDirectory.Create(); var jsonPath = Path.Combine(testDirectory.Path, "dg.json"); File.WriteAllText(jsonPath, jsonContent); // Act var dg = DependencyGraphSpec.Load(jsonPath); var xParents = dg.GetParents("A55205E7-4D08-4672-8011-0925467CC45F"); var yParents = dg.GetParents("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F"); var zParents = dg.GetParents("44B29B8D-8413-42D2-8DF4-72225659619B"); // Assert Assert.Equal(0, xParents.Count); Assert.Equal(1, yParents.Count); Assert.Equal("A55205E7-4D08-4672-8011-0925467CC45F", yParents.Single()); Assert.Equal(1, zParents.Count); Assert.Equal("A55205E7-4D08-4672-8011-0925467CC45F", zParents.Single()); }
public void GetClosure_WhenProjectHasToolReferences_ReturnsClosure() { // Arrange JObject json = GetResourceAsJObject(Test2Dg); var childProject = @"f:\validation\test\dg\Project.Core\Project.Core\Project.Core.csproj"; var parentProject = @"f:\validation\test\dg\Project.Core\Project\Project.csproj"; var tool = @"atool-netcoreapp2.0-[1.0.0, )"; // Act var dg = DependencyGraphSpec.Load(json); var childClosure = dg.GetClosure(childProject).OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.Ordinal).ToList(); var parentClosure = dg.GetClosure(parentProject).OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.Ordinal).ToList(); var toolClosure = dg.GetClosure(tool).OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.Ordinal).ToList(); // Assert Assert.Equal(2, parentClosure.Count); Assert.Equal(childProject, parentClosure[0].RestoreMetadata.ProjectUniqueName); Assert.Equal(parentProject, parentClosure[1].RestoreMetadata.ProjectUniqueName); Assert.Equal(1, childClosure.Count); Assert.Equal(childProject, childClosure.Single().RestoreMetadata.ProjectUniqueName); Assert.Equal(1, toolClosure.Count); Assert.Equal(tool, toolClosure.Single().RestoreMetadata.ProjectUniqueName); }
public void GetClosure_WhenClosureExistsCaseInsensitively_ReturnsClosure() { // Arrange string jsonContent = GetResourceAsJson(Test3Dg); using var testDirectory = TestDirectory.Create(); var jsonPath = Path.Combine(testDirectory.Path, "dg.json"); File.WriteAllText(jsonPath, jsonContent); // Act var dg = DependencyGraphSpec.Load(jsonPath); var xClosure = dg.GetClosure("A55205E7-4D08-4672-8011-0925467CC45F").OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.OrdinalIgnoreCase).ToList(); var yClosure = dg.GetClosure("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F").OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.OrdinalIgnoreCase).ToList(); // Assert Assert.Equal(3, xClosure.Count); Assert.Equal("44B29B8D-8413-42D2-8DF4-72225659619B", xClosure[0].RestoreMetadata.ProjectUniqueName); Assert.Equal("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F", xClosure[1].RestoreMetadata.ProjectUniqueName); Assert.Equal("A55205E7-4D08-4672-8011-0925467CC45F", xClosure[2].RestoreMetadata.ProjectUniqueName); Assert.Equal(1, yClosure.Count); Assert.Equal("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F", yClosure.Single().RestoreMetadata.ProjectUniqueName); }
public async Task RestoreUAP_VerifyProjectToProjectRestore() { // Arrange using (var pathContext = new SimpleTestPathContext()) { // Set up solution, project, and packages var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); var projectA = SimpleTestProjectContext.CreateLegacyPackageReference( "a", pathContext.SolutionRoot, NuGetFramework.AnyFramework); var projectB = SimpleTestProjectContext.CreateLegacyPackageReference( "b", pathContext.SolutionRoot, NuGetFramework.AnyFramework); projectA.Properties.Add("TargetPlatformIdentifier", "UAP"); projectA.Properties.Add("TargetPlatformVersion", "10.0.14393.0"); projectA.Properties.Add("TargetPlatformMinVersion", "10.0.10586.0"); // Set style for A since it has no references projectA.Properties.Add("RestoreProjectStyle", "PackageReference"); projectB.Properties.Add("TargetPlatformIdentifier", "UAP"); projectB.Properties.Add("TargetPlatformVersion", "10.0.14393.0"); projectB.Properties.Add("TargetPlatformMinVersion", "10.0.10586.0"); var packageX = new SimpleTestPackageContext() { Id = "x", Version = "1.0.0" }; projectB.AddPackageToAllFrameworks(packageX); projectA.AddProjectToAllFrameworks(projectB); solution.Projects.Add(projectA); solution.Create(pathContext.SolutionRoot); await SimpleTestPackageUtility.CreateFolderFeedV3Async( pathContext.PackageSource, PackageSaveMode.Defaultv3, packageX); // Act var r = RestoreSolution(pathContext); var dgPath = Path.Combine(pathContext.WorkingDirectory, "out.dg"); var dgSpec = DependencyGraphSpec.Load(dgPath); var assetsFile = projectA.AssetsFile; // Assert Assert.Equal("1.0.0", assetsFile.Libraries.Single(p => p.Name == "x").Version.ToNormalizedString()); } }
public void Json_WhenDgSpecWasCreatedWithLoadJObjectMethod_ReturnsSameJObject() { var expectedResult = new JObject(); DependencyGraphSpec dgSpec = DependencyGraphSpec.Load(expectedResult); Assert.Same(expectedResult, dgSpec.Json); }
public void Load_WithPath_WhenJsonContainsMultipleTopLevelEntities_IgnoresNonFirstEntities(string json) { using (Test test = Test.Create(json)) { DependencyGraphSpec dgSpec = DependencyGraphSpec.Load(test.FilePath); Assert.Equal("{}", dgSpec.Json.ToString()); } }
public static async Task <DependencyGraphSpec> GetSolutionRestoreSpec( ISolutionManager solutionManager, DependencyGraphCacheContext context) { var dgSpec = new DependencyGraphSpec(); var stringComparer = PathUtility.GetStringComparerBasedOnOS(); var uniqueProjectDependencies = new HashSet <string>(stringComparer); var projects = ((await solutionManager.GetNuGetProjectsAsync()).OfType <IDependencyGraphProject>()).ToList(); for (var i = 0; i < projects.Count; i++) { var packageSpecs = await projects[i].GetPackageSpecsAsync(context); 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)) { var persistedDGSpecPath = Path.Combine(outputPath, dgFileName); if (File.Exists(persistedDGSpecPath)) { var persistedDGSpec = DependencyGraphSpec.Load(persistedDGSpecPath); foreach (var dependentPackageSpec in persistedDGSpec.GetClosure(packageSpec.RestoreMetadata.ProjectUniqueName)) { if (!(uniqueProjectDependencies.Contains(dependentPackageSpec.RestoreMetadata.ProjectPath) || projects.Any(p => stringComparer.Equals(p.MSBuildProjectPath, dependentPackageSpec.RestoreMetadata.ProjectPath)))) { uniqueProjectDependencies.Add(dependentPackageSpec.RestoreMetadata.ProjectPath); dgSpec.AddProject(dependentPackageSpec); } } } } } } } // Return dg file return(dgSpec); }
public void Load_WithPath_WhenJsonIsInvalidDgSpec_Throws(string json) { using (Test test = Test.Create(json)) { InvalidDataException exception = Assert.Throws <InvalidDataException>( () => DependencyGraphSpec.Load(test.FilePath)); Assert.Null(exception.InnerException); } }
public async Task RestoreUAP_VerifyNoContentFiles() { // Arrange using (var pathContext = new SimpleTestPathContext()) { // Set up solution, project, and packages var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); var projectA = SimpleTestProjectContext.CreateLegacyPackageReference( "a", pathContext.SolutionRoot, NuGetFramework.AnyFramework); var packageX = new SimpleTestPackageContext() { Id = "x", Version = "1.0.0" }; packageX.AddFile("contentFiles/any/any/a.txt"); projectA.AddPackageToAllFrameworks(packageX); projectA.Properties.Add("TargetPlatformIdentifier", "UAP"); projectA.Properties.Add("TargetPlatformVersion", "10.0.14393.0"); projectA.Properties.Add("TargetPlatformMinVersion", "10.0.10586.0"); solution.Projects.Add(projectA); solution.Create(pathContext.SolutionRoot); await SimpleTestPackageUtility.CreateFolderFeedV3Async( pathContext.PackageSource, PackageSaveMode.Defaultv3, packageX); // Act var r = RestoreSolution(pathContext); var dgPath = Path.Combine(pathContext.WorkingDirectory, "out.dg"); var dgSpec = DependencyGraphSpec.Load(dgPath); var propsXML = XDocument.Load(projectA.PropsOutput); var styleNode = propsXML.Root.Elements().First().Elements(XName.Get("NuGetProjectStyle", "http://schemas.microsoft.com/developer/msbuild/2003")).FirstOrDefault(); var projectSpec = dgSpec.Projects.Single(); // Assert Assert.Equal(ProjectStyle.PackageReference, projectSpec.RestoreMetadata.ProjectStyle); Assert.Equal("PackageReference", styleNode.Value); Assert.Equal(NuGetFramework.Parse("UAP10.0.10586.0"), projectSpec.TargetFrameworks.Single().FrameworkName); Assert.DoesNotContain("a.txt", propsXML.ToString()); } }
public void Json_WhenDgSpecWasCreatedWithLoadFilePathMethod_ReturnsFileJObject() { string json = "{\"restore\":{}}"; using (Test test = Test.Create(json)) { DependencyGraphSpec dgSpec = DependencyGraphSpec.Load(test.FilePath); Assert.Equal(json, dgSpec.Json.ToString(Formatting.None)); } }
private static DependencyGraphSpec ReadProjectDependencyGraph(PackageReferenceArgs packageReferenceArgs) { DependencyGraphSpec spec = null; if (File.Exists(packageReferenceArgs.DgFilePath)) { spec = DependencyGraphSpec.Load(packageReferenceArgs.DgFilePath); } return(spec); }
public virtual Task <IReadOnlyList <RestoreSummaryRequest> > CreateRequests( string inputPath, RestoreArgs restoreContext) { var paths = new List <string>(); var requests = new List <RestoreSummaryRequest>(); var dgSpec = DependencyGraphSpec.Load(inputPath); var dgProvider = new DependencyGraphSpecRequestProvider(_providerCache, dgSpec); return(dgProvider.CreateRequests(restoreContext)); }
public static DependencyGraphSpec GetDependencyGraph(string resultsPath) { var fileInfo = new FileInfo(resultsPath); if (fileInfo.Exists && fileInfo.Length != 0) { return(DependencyGraphSpec.Load(resultsPath)); } else { return(new DependencyGraphSpec()); } }
public void Load_WithPath_WhenJsonStartsWithComment_SkipsComment() { var json = @"/* */ { }"; using (Test test = Test.Create(json)) { DependencyGraphSpec dgSpec = DependencyGraphSpec.Load(test.FilePath); Assert.NotNull(dgSpec); } }
public static async Task <DependencyGraphSpec> GenerateRestoreGraphFile(ILogger logger, string projectPath) { DependencyGraphSpec spec = null; using (var restoreGraphResult = new TemporaryFile()) { await Task.Run(() => { var pc = new Microsoft.Build.Evaluation.ProjectCollection(); try { var parameters = new BuildParameters(pc) { Loggers = new[] { new LoggerRedirect(logger, true) }, //Instance of ILogger instantiated earlier DisableInProcNode = true, }; // Run a MSBuild /t:Restore <projectfile> var request = new BuildRequestData(projectPath, new Dictionary <string, string> { { "RestoreGraphOutputPath", restoreGraphResult.Path }, { "RestoreRecursive", "false" } }, null, new[] { "GenerateRestoreGraphFile" }, null, BuildRequestDataFlags.None); mainBuildManager.Build(parameters, request); } finally { pc.UnloadAllProjects(); pc.Dispose(); } }); if (File.Exists(restoreGraphResult.Path) && new FileInfo(restoreGraphResult.Path).Length != 0) { spec = DependencyGraphSpec.Load(restoreGraphResult.Path); File.Delete(restoreGraphResult.Path); } else { spec = new DependencyGraphSpec(); } } return(spec); }
public void GetClosure_WhenClosureExistsCaseInsensitively_ReturnsClosure() { // Arrange JObject json = GetResourceAsJObject(Test3Dg); // Act var dg = DependencyGraphSpec.Load(json); var xClosure = dg.GetClosure("A55205E7-4D08-4672-8011-0925467CC45F").OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.OrdinalIgnoreCase).ToList(); var yClosure = dg.GetClosure("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F").OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.OrdinalIgnoreCase).ToList(); // Assert Assert.Equal(3, xClosure.Count); Assert.Equal("44B29B8D-8413-42D2-8DF4-72225659619B", xClosure[0].RestoreMetadata.ProjectUniqueName); Assert.Equal("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F", xClosure[1].RestoreMetadata.ProjectUniqueName); Assert.Equal("A55205E7-4D08-4672-8011-0925467CC45F", xClosure[2].RestoreMetadata.ProjectUniqueName); Assert.Equal(1, yClosure.Count); Assert.Equal("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F", yClosure.Single().RestoreMetadata.ProjectUniqueName); }
public void DependencyGraphSpec_GetParents() { // Arrange var json = JObject.Parse(ResourceTestUtility.GetResource("NuGet.ProjectModel.Test.compiler.resources.test1.dg", typeof(DependencyGraphSpecTests))); // Act var dg = DependencyGraphSpec.Load(json); var xParents = dg.GetParents("A55205E7-4D08-4672-8011-0925467CC45F"); var yParents = dg.GetParents("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F"); var zParents = dg.GetParents("44B29B8D-8413-42D2-8DF4-72225659619B"); // Assert Assert.Equal(0, xParents.Count); Assert.Equal(1, yParents.Count); Assert.Equal("A55205E7-4D08-4672-8011-0925467CC45F", yParents.Single()); Assert.Equal(1, zParents.Count); Assert.Equal("A55205E7-4D08-4672-8011-0925467CC45F", zParents.Single()); }
public void DependencyGraphSpec_ReadFileWithProjects_CaseInsensitive_GetClosures() { // Arrange var json = JObject.Parse(ResourceTestUtility.GetResource("NuGet.ProjectModel.Test.compiler.resources.test3.dg", typeof(DependencyGraphSpecTests))); // Act var dg = DependencyGraphSpec.Load(json); var xClosure = dg.GetClosure("A55205E7-4D08-4672-8011-0925467CC45F").OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.OrdinalIgnoreCase).ToList(); var yClosure = dg.GetClosure("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F").OrderBy(e => e.RestoreMetadata.ProjectUniqueName, StringComparer.OrdinalIgnoreCase).ToList(); // Assert Assert.Equal(3, xClosure.Count); Assert.Equal("44B29B8D-8413-42D2-8DF4-72225659619B", xClosure[0].RestoreMetadata.ProjectUniqueName); Assert.Equal("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F", xClosure[1].RestoreMetadata.ProjectUniqueName); Assert.Equal("A55205E7-4D08-4672-8011-0925467CC45F", xClosure[2].RestoreMetadata.ProjectUniqueName); Assert.Equal(1, yClosure.Count); Assert.Equal("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F", yClosure.Single().RestoreMetadata.ProjectUniqueName); }
public void GetParents_WhenCalledOnChild_ReturnsParents() { // Arrange JObject json = GetResourceAsJObject(Test1Dg); // Act var dg = DependencyGraphSpec.Load(json); var xParents = dg.GetParents("A55205E7-4D08-4672-8011-0925467CC45F"); var yParents = dg.GetParents("78A6AD3F-9FA5-47F6-A54E-84B46A48CB2F"); var zParents = dg.GetParents("44B29B8D-8413-42D2-8DF4-72225659619B"); // Assert Assert.Equal(0, xParents.Count); Assert.Equal(1, yParents.Count); Assert.Equal("A55205E7-4D08-4672-8011-0925467CC45F", yParents.Single()); Assert.Equal(1, zParents.Count); Assert.Equal("A55205E7-4D08-4672-8011-0925467CC45F", zParents.Single()); }
public void RestoreUAP_NoPackageReferences_VerifyRestoreStyleIsUsed() { // Arrange using (var pathContext = new SimpleTestPathContext()) { // Set up solution, project, and packages var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); var projectA = SimpleTestProjectContext.CreateLegacyPackageReference( "a", pathContext.SolutionRoot, NuGetFramework.AnyFramework); projectA.Properties.Add("TargetPlatformIdentifier", "UAP"); projectA.Properties.Add("TargetPlatformVersion", "10.0.14393.0"); projectA.Properties.Add("TargetPlatformMinVersion", "10.0.10586.0"); projectA.Properties.Add("RestoreProjectStyle", "PackageReference"); solution.Projects.Add(projectA); solution.Create(pathContext.SolutionRoot); // Act var r = RestoreSolution(pathContext); var dgPath = Path.Combine(pathContext.WorkingDirectory, "out.dg"); var dgSpec = DependencyGraphSpec.Load(dgPath); var propsXML = XDocument.Load(projectA.PropsOutput); var styleNode = propsXML.Root.Elements().First().Elements(XName.Get("NuGetProjectStyle", "http://schemas.microsoft.com/developer/msbuild/2003")).FirstOrDefault(); var projectSpec = dgSpec.Projects.Single(); // Assert Assert.Equal(ProjectStyle.PackageReference, projectSpec.RestoreMetadata.ProjectStyle); Assert.Equal("PackageReference", styleNode.Value); Assert.Equal(NuGetFramework.Parse("UAP10.0.10586.0"), projectSpec.TargetFrameworks.Single().FrameworkName); } }
public async Task <DependencyGraphSpec> GetOrCreateDependencyGraphSpecAsync(IProjectAdapter projectAdapter, BuildIntegratedNuGetProject project) { string projectFilePath = projectAdapter.ProjectFilePath; if (_projectDgCache.TryGetValue(projectFilePath, out var dg)) { return(dg); } var projectFileName = Path.GetFileName(projectFilePath); var outputPath = projectAdapter.Project.GetMSBuildProjectExtensionsPath(); var filePath = Path.Combine(outputPath, DependencyGraphSpec.GetDGSpecFileName(projectFileName)); // always restore await RestoreAsync(project); InitFileWatcher(projectAdapter); dg = DependencyGraphSpec.Load(filePath); _projectDgCache[projectFilePath] = dg; return(dg); }
public DependencyGraphSpec GenerateDependencyGraph(string projectPath, string pathToMsBuild) { var dotNetRunner = new ProcessRunner(); string outputFile = Path.GetTempFileName(); try { string[] arguments = new[] { $"\"{projectPath}\"", "/t:GenerateRestoreGraphFile", $"/p:RestoreGraphOutputPath={outputFile}" }; var runStatus = dotNetRunner.Run(pathToMsBuild, Path.GetDirectoryName(projectPath), arguments); if (runStatus.IsSuccess) { return(DependencyGraphSpec.Load(outputFile)); } else { throw new ArgumentException($"Unable to process the the project `{projectPath}. Are you sure this is a valid .NET Core or .NET Standard project type?" + $"\r\n\r\nHere is the full error message returned from the Microsoft Build Engine:\r\n\r\n" + runStatus.Output, nameof(projectPath)); } } finally { File.Delete(outputFile); } }
/// <summary> /// Returns the closure of project references for projects specified in <paramref name="projectPaths"/>. /// </summary> public static async Task <DependencyGraphSpec> GetProjectReferencesAsync( string msbuildDirectory, string[] projectPaths, int timeOut, IConsole console, bool recursive, string solutionDirectory, string restoreConfigFile, string[] sources, string packagesDirectory) { var msbuildPath = GetMsbuild(msbuildDirectory); if (!File.Exists(msbuildPath)) { throw new CommandLineException( string.Format( CultureInfo.CurrentCulture, LocalizedResourceManager.GetString(nameof(NuGetResources.MsBuildDoesNotExistAtPath)), msbuildPath)); } var nugetExePath = Assembly.GetEntryAssembly().Location; // Check for the non-ILMerged path var buildTasksPath = Path.Combine(Path.GetDirectoryName(nugetExePath), "NuGet.Build.Tasks.dll"); if (File.Exists(buildTasksPath)) { nugetExePath = buildTasksPath; } using (var entryPointTargetPath = new TempFile(".targets")) using (var resultsPath = new TempFile(".result")) { ExtractResource(NuGetTargets, entryPointTargetPath); // Use RestoreUseCustomAfterTargets=true to allow recursion // for scenarios where NuGet is not part of ImportsAfter. var argumentBuilder = new StringBuilder( "/t:GenerateRestoreGraphFile " + "/nologo /nr:false /p:RestoreUseCustomAfterTargets=true " + "/p:BuildProjectReferences=false"); // Set the msbuild verbosity level if specified var msbuildVerbosity = Environment.GetEnvironmentVariable("NUGET_RESTORE_MSBUILD_VERBOSITY"); if (string.IsNullOrEmpty(msbuildVerbosity)) { argumentBuilder.Append(" /v:q "); } else { argumentBuilder.Append($" /v:{msbuildVerbosity} "); } // Add additional args to msbuild if needed var msbuildAdditionalArgs = Environment.GetEnvironmentVariable("NUGET_RESTORE_MSBUILD_ARGS"); if (!string.IsNullOrEmpty(msbuildAdditionalArgs)) { argumentBuilder.Append($" {msbuildAdditionalArgs} "); } // Override the target under ImportsAfter with the current NuGet.targets version. argumentBuilder.Append(" /p:NuGetRestoreTargets="); AppendQuoted(argumentBuilder, entryPointTargetPath); // Set path to nuget.exe or the build task argumentBuilder.Append(" /p:RestoreTaskAssemblyFile="); AppendQuoted(argumentBuilder, nugetExePath); // dg file output path argumentBuilder.Append(" /p:RestoreGraphOutputPath="); AppendQuoted(argumentBuilder, resultsPath); // Disallow the import of targets/props from packages argumentBuilder.Append(" /p:ExcludeRestorePackageImports=true "); if (!string.IsNullOrEmpty(solutionDirectory)) { argumentBuilder.Append(" /p:RestoreSolutionDirectory="); argumentBuilder.Append(EscapeQuoted(solutionDirectory)); } if (!string.IsNullOrEmpty(restoreConfigFile)) { argumentBuilder.Append(" /p:RestoreConfigFile="); argumentBuilder.Append(EscapeQuoted(restoreConfigFile)); } var isMono = RuntimeEnvironmentHelper.IsMono && !RuntimeEnvironmentHelper.IsWindows; if (sources.Length != 0) { if (isMono) { argumentBuilder.Append(" /p:RestoreSources=\\\""); } else { argumentBuilder.Append(" /p:RestoreSources=\""); } for (var i = 0; i < sources.Length; i++) { if (isMono) { argumentBuilder.Append(sources[i]) .Append("\\;"); } else { argumentBuilder.Append(sources[i]) .Append(";"); } } if (isMono) { argumentBuilder.Append("\\\" "); } else { argumentBuilder.Append("\" "); } } if (!string.IsNullOrEmpty(packagesDirectory)) { argumentBuilder.Append(" /p:RestorePackagesPath="); AppendQuoted(argumentBuilder, packagesDirectory); } // Add all depenencies as top level restore projects if recursive is set argumentBuilder.Append($" /p:RestoreRecursive={recursive} "); // Filter out unknown project types and avoid errors from projects that do not support CustomAfterTargets argumentBuilder.Append($" /p:RestoreProjectFilterMode=exclusionlist /p:RestoreContinueOnError=WarnAndContinue "); // /p: foo = "bar;baz" doesn't work on bash. // /p: foo = /"bar/;baz/" works. // Need to escape quotes and semicolon on bash. if (isMono) { argumentBuilder.Append(" /p:RestoreGraphProjectInput=\\\""); } else { argumentBuilder.Append(" /p:RestoreGraphProjectInput=\""); } for (var i = 0; i < projectPaths.Length; i++) { if (isMono) { argumentBuilder.Append(projectPaths[i]) .Append("\\;"); } else { argumentBuilder.Append(projectPaths[i]) .Append(";"); } } if (isMono) { argumentBuilder.Append("\\\" "); } else { argumentBuilder.Append("\" "); } AppendQuoted(argumentBuilder, entryPointTargetPath); var processStartInfo = new ProcessStartInfo { UseShellExecute = false, FileName = msbuildPath, Arguments = argumentBuilder.ToString(), RedirectStandardError = true, RedirectStandardOutput = true }; console.LogDebug($"{processStartInfo.FileName} {processStartInfo.Arguments}"); using (var process = Process.Start(processStartInfo)) { var errors = new StringBuilder(); var output = new StringBuilder(); var excluded = new string[] { "msb4011", entryPointTargetPath }; // Read console output var errorTask = ConsumeStreamReaderAsync(process.StandardError, errors, filter: null); var outputTask = ConsumeStreamReaderAsync(process.StandardOutput, output, filter: (line) => IsIgnoredOutput(line, excluded)); // Run msbuild var finished = process.WaitForExit(timeOut); // Handle timeouts if (!finished) { try { process.Kill(); } catch (Exception ex) { throw new CommandLineException( LocalizedResourceManager.GetString(nameof(NuGetResources.Error_CannotKillMsBuild)) + " : " + ex.Message, ex); } } // Read all console output from msbuild. await Task.WhenAll(outputTask, errorTask); // By default log msbuild output so that it is only // displayed under -Verbosity detailed var logLevel = LogLevel.Verbose; if (process.ExitCode != 0 || !finished) { // If a problem occurred log all msbuild output as an error // so that the user can see it. // By default this runs with /v:q which means that only // errors and warnings will be in the output. logLevel = LogLevel.Error; } // MSBuild writes errors to the output stream, parsing the console output to find // the errors would be error prone so here we log all output combined with any // errors on the error stream (haven't seen the error stream used to date) // to give the user the complete info. await console.LogAsync(logLevel, output.ToString() + errors.ToString()); if (!finished) { // MSBuild timed out throw new CommandLineException( LocalizedResourceManager.GetString(nameof(NuGetResources.Error_MsBuildTimedOut))); } await outputTask; if (process.ExitCode != 0) { // Do not continue if msbuild failed. throw new ExitCodeException(1); } } DependencyGraphSpec spec = null; if (File.Exists(resultsPath) && new FileInfo(resultsPath).Length != 0) { spec = DependencyGraphSpec.Load(resultsPath); File.Delete(resultsPath); } else { spec = new DependencyGraphSpec(); } return(spec); } }
/// <summary> /// Returns the closure of project references for projects specified in <paramref name="projectPaths"/>. /// </summary> public static async Task <DependencyGraphSpec> GetProjectReferencesAsync( MsBuildToolset msbuildToolset, string[] projectPaths, int timeOut, IConsole console, bool recursive, string solutionDirectory, string solutionName, string restoreConfigFile, string[] sources, string packagesDirectory, RestoreLockProperties restoreLockProperties) { var msbuildPath = GetMsbuild(msbuildToolset.Path); if (!File.Exists(msbuildPath)) { throw new CommandException( string.Format( CultureInfo.CurrentCulture, LocalizedResourceManager.GetString(nameof(NuGetResources.MsBuildDoesNotExistAtPath)), msbuildPath)); } var nugetExePath = Assembly.GetEntryAssembly().Location; // Check for the non-ILMerged path var buildTasksPath = Path.Combine(Path.GetDirectoryName(nugetExePath), "NuGet.Build.Tasks.dll"); if (File.Exists(buildTasksPath)) { nugetExePath = buildTasksPath; } using (var inputTargetPath = new TempFile(".nugetinputs.targets")) using (var entryPointTargetPath = new TempFile(".nugetrestore.targets")) using (var resultsPath = new TempFile(".output.dg")) { // Read NuGet.targets from nuget.exe and write it to disk for msbuild.exe ExtractResource(NuGetTargets, entryPointTargetPath); // Build a .targets file of all restore inputs, this is needed to avoid going over the limit on command line arguments. var properties = new Dictionary <string, string>() { { "RestoreUseCustomAfterTargets", "true" }, { "RestoreGraphOutputPath", resultsPath }, { "RestoreRecursive", recursive.ToString().ToLowerInvariant() }, { "RestoreProjectFilterMode", "exclusionlist" } }; var inputTargetXML = GetRestoreInputFile(entryPointTargetPath, properties, projectPaths); inputTargetXML.Save(inputTargetPath); // Create msbuild parameters and include global properties that cannot be set in the input targets path var arguments = GetMSBuildArguments(entryPointTargetPath, inputTargetPath, nugetExePath, solutionDirectory, solutionName, restoreConfigFile, sources, packagesDirectory, msbuildToolset, restoreLockProperties, EnvironmentVariableWrapper.Instance); var processStartInfo = new ProcessStartInfo { UseShellExecute = false, FileName = msbuildPath, Arguments = arguments, RedirectStandardError = true, RedirectStandardOutput = true }; console.LogDebug($"{processStartInfo.FileName} {processStartInfo.Arguments}"); using (var process = Process.Start(processStartInfo)) { var errors = new StringBuilder(); var output = new StringBuilder(); var excluded = new string[] { "msb4011", entryPointTargetPath }; // Read console output var errorTask = ConsumeStreamReaderAsync(process.StandardError, errors, filter: null); var outputTask = ConsumeStreamReaderAsync(process.StandardOutput, output, filter: (line) => IsIgnoredOutput(line, excluded)); // Run msbuild var finished = process.WaitForExit(timeOut); // Handle timeouts if (!finished) { try { process.Kill(); } catch (Exception ex) { throw new CommandException( LocalizedResourceManager.GetString(nameof(NuGetResources.Error_CannotKillMsBuild)) + " : " + ex.Message, ex); } } // Read all console output from msbuild. await Task.WhenAll(outputTask, errorTask); // By default log msbuild output so that it is only // displayed under -Verbosity detailed var logLevel = LogLevel.Verbose; if (process.ExitCode != 0 || !finished) { // If a problem occurred log all msbuild output as an error // so that the user can see it. // By default this runs with /v:q which means that only // errors and warnings will be in the output. logLevel = LogLevel.Error; } // MSBuild writes errors to the output stream, parsing the console output to find // the errors would be error prone so here we log all output combined with any // errors on the error stream (haven't seen the error stream used to date) // to give the user the complete info. await console.LogAsync(logLevel, output.ToString() + errors.ToString()); if (!finished) { // MSBuild timed out throw new CommandException( LocalizedResourceManager.GetString(nameof(NuGetResources.Error_MsBuildTimedOut))); } await outputTask; if (process.ExitCode != 0) { // Do not continue if msbuild failed. throw new ExitCodeException(1); } } DependencyGraphSpec spec = null; if (File.Exists(resultsPath) && new FileInfo(resultsPath).Length != 0) { spec = DependencyGraphSpec.Load(resultsPath); File.Delete(resultsPath); } else { spec = new DependencyGraphSpec(); } return(spec); } }
private static void GenerateGraph(Options options) { var dependencyGraph = DependencyGraphSpec.Load(options.DependencyGrapthPath); var graph = new Graph <string>(); var projectVersions = new Dictionary <string, string>(); foreach (var project in dependencyGraph.Projects.Where(p => p.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference)) { //filtering test if (project.Name.Contains("test", StringComparison.OrdinalIgnoreCase)) { continue; } graph.AddVertex(project.Name); projectVersions.Add(project.Name, project.Version.ToNormalizedString()); } foreach (var project in dependencyGraph.Projects.Where(p => p.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference)) { //filtering test if (project.Name.Contains("test", StringComparison.OrdinalIgnoreCase)) { continue; } Console.WriteLine(project.Name); HashSet <string> dep = new HashSet <string>(); foreach (var targetFramework in project.TargetFrameworks) { foreach (var dependency in targetFramework.Dependencies) { //remove duplication if (dep.Contains(dependency.Name)) { continue; } dep.Add(dependency.Name); if (graph.Vertices.Any(v => v == dependency.Name)) { var notLastVersion = projectVersions[dependency.Name] != dependency.LibraryRange.VersionRange.ToShortString(); var attributes = new Dictionary <string, string>() { { "label", dependency.LibraryRange.VersionRange.ToShortString() } }; if (notLastVersion) { attributes.Add("color", "red"); } else { attributes.Add("color", "green"); } graph.AddEdge(new Edge <string>(project.Name, dependency.Name, attributes: attributes)); } } } } var writer = new StringWriter(); new GraphToDotConverter().Convert(writer, graph, new AttributesProvider(projectVersions)); var graphContent = writer.GetStringBuilder().ToString().Trim(); var dotFile = Path.ChangeExtension(options.OutputFilePath, "dot"); File.WriteAllText(dotFile, graphContent); var dotExec = Path.Combine(options.GraphvizBinPath, "dot.exe"); var arguments = $"-Tjpg {dotFile} -o {options.OutputFilePath}"; ProcessAsyncHelper.ExecuteShellCommand(dotExec, arguments, int.MaxValue).Wait(); }
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); }