From 51c12525077117b8a4cbfc83857bdc082762851e Mon Sep 17 00:00:00 2001 From: Alberto Monteiro Date: Tue, 18 Jul 2023 09:02:29 -0300 Subject: [PATCH 1/4] WIP: Full support IsTestProject Signed-off-by: Alberto Monteiro Signed-off-by: Alberto Monteiro Signed-off-by: Michael Tsfoni --- CycloneDX.Tests/ProjectFileServiceTests.cs | 62 +++++++------------ CycloneDX.Tests/ValidationTests.cs | 2 +- CycloneDX/CycloneDX.csproj | 1 + CycloneDX/Interfaces/IProjectFileService.cs | 2 +- CycloneDX/Runner.cs | 2 +- CycloneDX/Services/ProjectFileService.cs | 38 +++++++----- CycloneDX/Services/SolutionFileService.cs | 23 +++++-- Directory.Packages.props | 1 + TestProjects/SolutionPath/Project/Class1.cs | 6 ++ .../SolutionPath/Project/Project.csproj | 16 +++++ TestProjects/SolutionPath/Project1/Class1.cs | 6 ++ .../SolutionPath/Project1/Project1.csproj | 14 +++++ TestProjects/SolutionPath/Project2/Class1.cs | 6 ++ .../SolutionPath/Project2/Project2.csproj | 14 +++++ TestProjects/SolutionPath/Project3/Class1.cs | 6 ++ .../SolutionPath/Project3/Project3.csproj | 12 ++++ 16 files changed, 145 insertions(+), 66 deletions(-) mode change 100755 => 100644 CycloneDX.Tests/ProjectFileServiceTests.cs mode change 100755 => 100644 CycloneDX/Interfaces/IProjectFileService.cs mode change 100755 => 100644 CycloneDX/Services/ProjectFileService.cs mode change 100755 => 100644 CycloneDX/Services/SolutionFileService.cs create mode 100644 TestProjects/SolutionPath/Project/Class1.cs create mode 100644 TestProjects/SolutionPath/Project/Project.csproj create mode 100644 TestProjects/SolutionPath/Project1/Class1.cs create mode 100644 TestProjects/SolutionPath/Project1/Project1.csproj create mode 100644 TestProjects/SolutionPath/Project2/Class1.cs create mode 100644 TestProjects/SolutionPath/Project2/Project2.csproj create mode 100644 TestProjects/SolutionPath/Project3/Class1.cs create mode 100644 TestProjects/SolutionPath/Project3/Project3.csproj diff --git a/CycloneDX.Tests/ProjectFileServiceTests.cs b/CycloneDX.Tests/ProjectFileServiceTests.cs old mode 100755 new mode 100644 index 255c2dd5..f9baf012 --- a/CycloneDX.Tests/ProjectFileServiceTests.cs +++ b/CycloneDX.Tests/ProjectFileServiceTests.cs @@ -16,6 +16,7 @@ // Copyright (c) OWASP Foundation. All Rights Reserved. using System; +using System.IO; using System.Collections.Generic; using System.Threading.Tasks; using Xunit; @@ -32,6 +33,9 @@ namespace CycloneDX.Tests { public class ProjectFileServiceTests { + + private readonly string _testProjectsBaseDir = XFS.Path(Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "..", "..", "..", "..", "TestProjects", "SolutionPath"))); + private ProjectFileService GetInstanceOfProjectFileService() { var fileSystem = new FileSystem(); @@ -56,14 +60,14 @@ public void GetPropertyUseProjectFileName(string projectFilePath, string baseInt [Fact] public void IsTestProjectTrue() { - string szProjectPath = System.Environment.CurrentDirectory + XFS.Path(@"\..\..\..\..\CycloneDX.Tests\CycloneDX.Tests.csproj"); + string szProjectPath = XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project3\Project3.csproj")); Assert.True(GetInstanceOfProjectFileService().IsTestProject(szProjectPath)); } [Fact] public void IsTestProjectFalse() { - string szProjectPath = System.Environment.CurrentDirectory + XFS.Path(@"\..\..\..\..\CycloneDX\CycloneDX.csproj"); + string szProjectPath = XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project\Project.csproj")); Assert.False(GetInstanceOfProjectFileService().IsTestProject(szProjectPath)); } @@ -93,7 +97,7 @@ public async Task GetProjectDotnetDependencys_WithProjectAssetsFile_ReturnsDotne mockPackageFileService.Object, mockProjectAssetsFileService.Object); - var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "").ConfigureAwait(true); + var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "", null).ConfigureAwait(true); Assert.Collection(packages, item => { @@ -129,7 +133,7 @@ public async Task GetProjectDotnetDependencys_WithProjectAssetsFileWithoutRestor mockProjectAssetsFileService.Object); projectFileService.DisablePackageRestore = true; - var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "").ConfigureAwait(true); + var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "", null).ConfigureAwait(true); Assert.Collection(packages, item => { @@ -166,7 +170,7 @@ public async Task GetProjectDotnetDependencys_WithProjectAssetsFile_ReturnsMulti mockPackageFileService.Object, mockProjectAssetsFileService.Object); - var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "").ConfigureAwait(true); + var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "", null).ConfigureAwait(true); var sortedPackages = new List(packages); sortedPackages.Sort(); @@ -207,7 +211,7 @@ public async Task GetProjectDotnetDependencys_WithPackagesConfig_ReturnsDotnetDe mockPackageFileService.Object, mockProjectAssetsFileService.Object); - var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "").ConfigureAwait(true); + var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "", null).ConfigureAwait(true); Assert.Collection(packages, item => { @@ -249,7 +253,7 @@ public async Task GetProjectDotnetDependencys_WithPackagesConfig_ReturnsMultiple mockPackageFileService.Object, mockProjectAssetsFileService.Object); - var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "").ConfigureAwait(true); + var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "", null).ConfigureAwait(true); var sortedPackages = new List(packages); sortedPackages.Sort(); @@ -262,69 +266,45 @@ public async Task GetProjectDotnetDependencys_WithPackagesConfig_ReturnsMultiple [Fact] public async Task GetProjectReferences_ReturnsProjectReferences() { - var mockFileSystem = new MockFileSystem(new Dictionary - { - { XFS.Path(@"c:\SolutionPath\Project\Project.csproj"), Helpers.GetProjectFileWithProjectReferences( - new[] { - @"..\Project1\Project1.csproj", - @"..\Project2\Project2.csproj", - @"..\Project3\Project3.csproj", - }) - }, - }); var mockDotnetUtilsService = new Mock(); var mockPackageFileService = new Mock(); var mockProjectAssetsFileService = new Mock(); var projectFileService = new ProjectFileService( - mockFileSystem, + new System.IO.Abstractions.FileSystem(), mockDotnetUtilsService.Object, mockPackageFileService.Object, mockProjectAssetsFileService.Object); - var projects = await projectFileService.GetProjectReferencesAsync(XFS.Path(@"c:\SolutionPath\Project\Project.csproj")).ConfigureAwait(true); + var projects = await projectFileService.GetProjectReferencesAsync(XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project\Project.csproj"))).ConfigureAwait(true); var sortedProjects = new List(projects); sortedProjects.Sort(); Assert.Collection(sortedProjects, - item => Assert.Equal(XFS.Path(@"c:\SolutionPath\Project1\Project1.csproj"), item), - item => Assert.Equal(XFS.Path(@"c:\SolutionPath\Project2\Project2.csproj"), item), - item => Assert.Equal(XFS.Path(@"c:\SolutionPath\Project3\Project3.csproj"), item)); + item => Assert.Equal(XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project1\Project1.csproj")), item), + item => Assert.Equal(XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project2\Project2.csproj")), item), + item => Assert.Equal(XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project3\Project3.csproj")), item)); } [Fact] public async Task RecursivelyGetProjectReferences_ReturnsProjectReferences() { - var mockFileSystem = new MockFileSystem(new Dictionary - { - { XFS.Path(@"c:\SolutionPath\Project1\Project1.csproj"), Helpers.GetProjectFileWithProjectReferences( - new[] { - @"..\Project2\Project2.csproj", - }) - }, - { XFS.Path(@"c:\SolutionPath\Project2\Project2.csproj"), Helpers.GetProjectFileWithProjectReferences( - new[] { - @"..\Project3\Project3.csproj", - }) - }, - { XFS.Path(@"c:\SolutionPath\Project3\Project3.csproj"), new MockFileData(@"") }, - }); var mockDotnetUtilsService = new Mock(); var mockPackageFileService = new Mock(); var mockProjectAssetsFileService = new Mock(); var projectFileService = new ProjectFileService( - mockFileSystem, + new System.IO.Abstractions.FileSystem(), mockDotnetUtilsService.Object, mockPackageFileService.Object, mockProjectAssetsFileService.Object); - var projects = await projectFileService.RecursivelyGetProjectReferencesAsync(XFS.Path(@"c:\SolutionPath\Project1\Project1.csproj")).ConfigureAwait(true); + var projects = await projectFileService.RecursivelyGetProjectReferencesAsync(XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project1\Project1.csproj"))).ConfigureAwait(true); var sortedProjects = new List(projects.Select(d => d.Path)); sortedProjects.Sort(); Assert.Collection(sortedProjects, - item => Assert.Equal(XFS.Path(@"c:\SolutionPath\Project1\Project1.csproj"), item), - item => Assert.Equal(XFS.Path(@"c:\SolutionPath\Project2\Project2.csproj"), item), - item => Assert.Equal(XFS.Path(@"c:\SolutionPath\Project3\Project3.csproj"), item)); + item => Assert.Equal(XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project1\Project1.csproj")), item), + item => Assert.Equal(XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project2\Project2.csproj")), item), + item => Assert.Equal(XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project3\Project3.csproj")), item)); } } } diff --git a/CycloneDX.Tests/ValidationTests.cs b/CycloneDX.Tests/ValidationTests.cs index 6c73693e..0c21a445 100644 --- a/CycloneDX.Tests/ValidationTests.cs +++ b/CycloneDX.Tests/ValidationTests.cs @@ -38,7 +38,7 @@ public async Task Validation(string fileFormat, bool disableGitHubLicenses) var mockProjectFileService = new Mock(); mockProjectFileService.Setup(mock => - mock.GetProjectDotnetDependencysAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()) + mock.GetProjectDotnetDependencysAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()) ).ReturnsAsync(packages); Runner runner = new Runner(fileSystem: mockFileSystem, null, null, null, null, projectFileService: mockProjectFileService.Object, solutionFileService: null, null); diff --git a/CycloneDX/CycloneDX.csproj b/CycloneDX/CycloneDX.csproj index 1ae39c5b..4f6797d3 100644 --- a/CycloneDX/CycloneDX.csproj +++ b/CycloneDX/CycloneDX.csproj @@ -35,6 +35,7 @@ + diff --git a/CycloneDX/Interfaces/IProjectFileService.cs b/CycloneDX/Interfaces/IProjectFileService.cs old mode 100755 new mode 100644 index 7a6728c2..4b757579 --- a/CycloneDX/Interfaces/IProjectFileService.cs +++ b/CycloneDX/Interfaces/IProjectFileService.cs @@ -24,7 +24,7 @@ namespace CycloneDX.Interfaces public interface IProjectFileService { bool DisablePackageRestore { get; set; } - Task> GetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime); + Task> GetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime, bool? isTestProject); Task> GetProjectReferencesAsync(string projectFilePath); Task> RecursivelyGetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime); Task> RecursivelyGetProjectReferencesAsync(string projectFilePath); diff --git a/CycloneDX/Runner.cs b/CycloneDX/Runner.cs index eaef36be..b0d197e5 100644 --- a/CycloneDX/Runner.cs +++ b/CycloneDX/Runner.cs @@ -174,7 +174,7 @@ public async Task HandleCommandAsync(RunOptions options) } else if (Utils.IsSupportedProjectType(SolutionOrProjectFile)) { - packages = await projectFileService.GetProjectDotnetDependencysAsync(fullSolutionOrProjectFilePath, baseIntermediateOutputPath, excludetestprojects, framework, runtime).ConfigureAwait(false); + packages = await projectFileService.GetProjectDotnetDependencysAsync(fullSolutionOrProjectFilePath, baseIntermediateOutputPath, excludetestprojects, framework, runtime, null).ConfigureAwait(false); topLevelComponent.Name = fileSystem.Path.GetFileNameWithoutExtension(SolutionOrProjectFile); } else if (this.fileSystem.Path.GetFileName(SolutionOrProjectFile).ToLowerInvariant().Equals("packages.config", StringComparison.OrdinalIgnoreCase)) diff --git a/CycloneDX/Services/ProjectFileService.cs b/CycloneDX/Services/ProjectFileService.cs old mode 100755 new mode 100644 index 27570877..767e8f86 --- a/CycloneDX/Services/ProjectFileService.cs +++ b/CycloneDX/Services/ProjectFileService.cs @@ -25,6 +25,7 @@ using CycloneDX.Interfaces; using CycloneDX.Models; using System.Text.RegularExpressions; +using Buildalyzer; namespace CycloneDX.Services { @@ -65,19 +66,21 @@ public bool IsTestProject(string projectFilePath) { return false; } + var manager = new AnalyzerManager(); + try + { + var project = manager.GetProject(projectFilePath); + var buildResults = project.Build(); + var isTestProject = buildResults.SelectMany(x => x.Properties) + .Any(x => x.Key.Equals("IsTestProject", StringComparison.OrdinalIgnoreCase) && x.Value.Equals("true", StringComparison.OrdinalIgnoreCase)); - XmlDocument xmldoc = new XmlDocument(); - using var fileStream = _fileSystem.FileStream.New(projectFilePath, FileMode.Open); - xmldoc.Load(fileStream); - - XmlElement testSdkReference = xmldoc.SelectSingleNode("/Project/ItemGroup/PackageReference[@Include='Microsoft.NET.Test.Sdk']") as XmlElement; - if (testSdkReference != null) + return isTestProject; + } + catch (ArgumentException) { - return true; + // can only happen while testing (because it will be checked before this method is called) + return false; } - // if this is meant for old csproj file format, then it's probably not working because there is no namespace given - XmlElement testProjectPropertyGroup = xmldoc.SelectSingleNode("/Project/PropertyGroup[IsTestProject='true']") as XmlElement; - return testProjectPropertyGroup != null; } private (string name, string version) GetProjectNameAndVersion(string projectFilePath) @@ -148,7 +151,7 @@ static internal string GetProjectProperty(string projectFilePath, string baseInt /// /// /// - public async Task> GetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime) + public async Task> GetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime, bool? isTestProject) { if (!_fileSystem.File.Exists(projectFilePath)) { @@ -156,12 +159,15 @@ public async Task> GetProjectDotnetDependencysAsync(st return new HashSet(); } - var isTestProject = IsTestProject(projectFilePath); + if (!isTestProject.HasValue) + { + isTestProject = IsTestProject(projectFilePath); + } Console.WriteLine(); Console.WriteLine($"» Analyzing: {projectFilePath}"); - if (excludeTestProjects && isTestProject) + if (excludeTestProjects && isTestProject.Value) { Console.WriteLine($"Skipping: {projectFilePath}"); return new HashSet(); @@ -189,7 +195,7 @@ public async Task> GetProjectDotnetDependencysAsync(st { Console.WriteLine($"File not found: \"{assetsFilename}\", \"{projectFilePath}\" "); } - var packages = _projectAssetsFileService.GetDotnetDependencys(projectFilePath, assetsFilename, isTestProject); + var packages = _projectAssetsFileService.GetDotnetDependencys(projectFilePath, assetsFilename, isTestProject.Value); // if there are no project file package references look for a packages.config @@ -214,7 +220,7 @@ public async Task> GetProjectDotnetDependencysAsync(st /// public async Task> RecursivelyGetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime) { - var dotnetDependencys = await GetProjectDotnetDependencysAsync(projectFilePath, baseIntermediateOutputPath, excludeTestProjects, framework, runtime).ConfigureAwait(false); + var dotnetDependencys = await GetProjectDotnetDependencysAsync(projectFilePath, baseIntermediateOutputPath, excludeTestProjects, framework, runtime, null).ConfigureAwait(false); foreach (var item in dotnetDependencys) { item.IsDirectReference = true; @@ -230,7 +236,7 @@ public async Task> RecursivelyGetProjectDotnetDependen foreach (var project in projectReferences) { - var projectDotnetDependencys = await GetProjectDotnetDependencysAsync(project.Path, baseIntermediateOutputPath, excludeTestProjects, framework, runtime).ConfigureAwait(false); + var projectDotnetDependencys = await GetProjectDotnetDependencysAsync(project.Path, baseIntermediateOutputPath, excludeTestProjects, framework, runtime, null).ConfigureAwait(false); //Add dependencies for dependency graph foreach (var dependency in projectDotnetDependencys) diff --git a/CycloneDX/Services/SolutionFileService.cs b/CycloneDX/Services/SolutionFileService.cs old mode 100755 new mode 100644 index bddb211e..d7073c68 --- a/CycloneDX/Services/SolutionFileService.cs +++ b/CycloneDX/Services/SolutionFileService.cs @@ -17,10 +17,11 @@ using System; using System.Collections.Generic; -using System.Text.RegularExpressions; -using System.Threading.Tasks; using System.IO.Abstractions; using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Buildalyzer; using CycloneDX.Interfaces; using CycloneDX.Models; @@ -96,7 +97,17 @@ public async Task> GetSolutionDotnetDependencys(string var packages = new HashSet(); - var projectPaths = await GetSolutionProjectReferencesAsync(solutionFilePath).ConfigureAwait(false); + HashSet<(string path,bool isTestProject)> projectPaths = new(); + + AnalyzerManager manager = new AnalyzerManager(solutionFilePath); + foreach (var (key, project) in manager.Projects) + { + var buildResults = project.Build(); + var isTestProject = buildResults.SelectMany(x => x.Properties) + .Any(x => x.Key.Equals("IsTestProject", StringComparison.OrdinalIgnoreCase) && x.Value.Equals("true", StringComparison.OrdinalIgnoreCase)); + + projectPaths.Add((project.ProjectFile.Path, isTestProject)); + } if (projectPaths.Count == 0) { @@ -108,12 +119,12 @@ public async Task> GetSolutionDotnetDependencys(string } // Process first all productive projects, then test projects (scope order) - var projectQuery = from p in projectPaths orderby _projectFileService.IsTestProject(p) select p; + var projectQuery = from p in projectPaths orderby p.isTestProject select p; var directReferencePackages = new HashSet(); - foreach (var projectFilePath in projectQuery) + foreach (var (projectFilePath, isTest) in projectQuery) { Console.WriteLine(); - var projectPackages = await _projectFileService.GetProjectDotnetDependencysAsync(projectFilePath, baseIntermediateOutputPath, excludeTestProjects, framework, runtime).ConfigureAwait(false); + var projectPackages = await _projectFileService.GetProjectDotnetDependencysAsync(projectFilePath, baseIntermediateOutputPath, excludeTestProjects, framework, runtime, isTest).ConfigureAwait(false); directReferencePackages.UnionWith(projectPackages.Where(p => p.IsDirectReference)); packages.UnionWith(projectPackages); } diff --git a/Directory.Packages.props b/Directory.Packages.props index 2345d615..3fc18047 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -17,5 +17,6 @@ + \ No newline at end of file diff --git a/TestProjects/SolutionPath/Project/Class1.cs b/TestProjects/SolutionPath/Project/Class1.cs new file mode 100644 index 00000000..8c367fea --- /dev/null +++ b/TestProjects/SolutionPath/Project/Class1.cs @@ -0,0 +1,6 @@ +namespace Project; + +public class Class1 +{ + +} diff --git a/TestProjects/SolutionPath/Project/Project.csproj b/TestProjects/SolutionPath/Project/Project.csproj new file mode 100644 index 00000000..e4f4c467 --- /dev/null +++ b/TestProjects/SolutionPath/Project/Project.csproj @@ -0,0 +1,16 @@ + + + + + + + + + + net7.0 + enable + enable + false + + + diff --git a/TestProjects/SolutionPath/Project1/Class1.cs b/TestProjects/SolutionPath/Project1/Class1.cs new file mode 100644 index 00000000..172f7ce7 --- /dev/null +++ b/TestProjects/SolutionPath/Project1/Class1.cs @@ -0,0 +1,6 @@ +namespace Project1; + +public class Class1 +{ + +} diff --git a/TestProjects/SolutionPath/Project1/Project1.csproj b/TestProjects/SolutionPath/Project1/Project1.csproj new file mode 100644 index 00000000..1fe96ec2 --- /dev/null +++ b/TestProjects/SolutionPath/Project1/Project1.csproj @@ -0,0 +1,14 @@ + + + + + + + + net7.0 + enable + enable + false + + + diff --git a/TestProjects/SolutionPath/Project2/Class1.cs b/TestProjects/SolutionPath/Project2/Class1.cs new file mode 100644 index 00000000..407e7161 --- /dev/null +++ b/TestProjects/SolutionPath/Project2/Class1.cs @@ -0,0 +1,6 @@ +namespace Project2; + +public class Class1 +{ + +} diff --git a/TestProjects/SolutionPath/Project2/Project2.csproj b/TestProjects/SolutionPath/Project2/Project2.csproj new file mode 100644 index 00000000..d4c58021 --- /dev/null +++ b/TestProjects/SolutionPath/Project2/Project2.csproj @@ -0,0 +1,14 @@ + + + + + + + + net7.0 + enable + enable + false + + + diff --git a/TestProjects/SolutionPath/Project3/Class1.cs b/TestProjects/SolutionPath/Project3/Class1.cs new file mode 100644 index 00000000..72265c3f --- /dev/null +++ b/TestProjects/SolutionPath/Project3/Class1.cs @@ -0,0 +1,6 @@ +namespace Project3; + +public class Class1 +{ + +} diff --git a/TestProjects/SolutionPath/Project3/Project3.csproj b/TestProjects/SolutionPath/Project3/Project3.csproj new file mode 100644 index 00000000..d549f130 --- /dev/null +++ b/TestProjects/SolutionPath/Project3/Project3.csproj @@ -0,0 +1,12 @@ + + + + net7.0 + enable + enable + + true + false + + + From 0ccc998c0061b615a2b7414d98680abca1a4d613 Mon Sep 17 00:00:00 2001 From: Alberto Monteiro Date: Mon, 8 Jan 2024 08:54:08 -0300 Subject: [PATCH 2/4] New version of Buildalyzer Signed-off-by: Alberto Monteiro --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 3fc18047..d20f86e6 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -17,6 +17,6 @@ - + \ No newline at end of file From 815c83f6941e028c7d3ddfe9d8b3475341d88c10 Mon Sep 17 00:00:00 2001 From: MTsfoni Date: Sat, 20 Jan 2024 23:04:21 +0100 Subject: [PATCH 3/4] Move Buildalyzer into new BuildalyzerService. Extend IsTestproject for .net Framework Projects. Add Caching for AnalyzerResults. Add Testcases and Testsupport for Buildalyzer Signed-off-by: MTsfoni --- .../BuildalyzerServiceTestWrapper.cs | 105 ++++ CycloneDX.Tests/CycloneDX.Tests.csproj | 15 + .../ExcludeTestDependencies.cs | 85 +++ .../assetsProject1.json | 200 +++++++ .../assetsTestProject1.json | 554 ++++++++++++++++++ .../ExcludeTestDependencies/project1.xml | 117 ++++ .../ExcludeTestDependencies/sln.txt | 31 + .../ExcludeTestDependencies/testproject1.xml | 58 ++ .../FunctionalTests/FunctionalTestHelper.cs | 2 +- .../project1assets.json | 6 +- .../project2assets.json | 6 +- CycloneDX.Tests/ProgramTests.cs | 8 +- CycloneDX.Tests/ProjectFileServiceTests.cs | 41 +- CycloneDX.Tests/SolutionFileServiceTests.cs | 9 +- CycloneDX.Tests/ValidationTests.cs | 4 +- CycloneDX/Interfaces/IProjectFileService.cs | 2 +- CycloneDX/Runner.cs | 16 +- CycloneDX/Services/BuildalyzerService.cs | 104 ++++ CycloneDX/Services/IBuildalyzerService.cs | 28 + CycloneDX/Services/ProjectFileService.cs | 44 +- CycloneDX/Services/SolutionFileService.cs | 29 +- 21 files changed, 1383 insertions(+), 81 deletions(-) create mode 100644 CycloneDX.Tests/BuildalyzerServiceTestWrapper.cs create mode 100644 CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/ExcludeTestDependencies.cs create mode 100644 CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/assetsProject1.json create mode 100644 CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/assetsTestProject1.json create mode 100644 CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/project1.xml create mode 100644 CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/sln.txt create mode 100644 CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/testproject1.xml create mode 100644 CycloneDX/Services/BuildalyzerService.cs create mode 100644 CycloneDX/Services/IBuildalyzerService.cs diff --git a/CycloneDX.Tests/BuildalyzerServiceTestWrapper.cs b/CycloneDX.Tests/BuildalyzerServiceTestWrapper.cs new file mode 100644 index 00000000..d89358f1 --- /dev/null +++ b/CycloneDX.Tests/BuildalyzerServiceTestWrapper.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.IO.Abstractions; +using System.IO.Abstractions.TestingHelpers; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CycloneDX.Services; + +namespace CycloneDX.Tests +{ + /// + /// Buildalyzer doesn't work with System.IO.Abstraction. So we dump it all on the regular FS for it and translate all incoming paths. + /// + public class BuildalyzerServiceTestWrapper : IBuildalyzerService + { + readonly BuildalyzerService coreBuildAnalyzerService = new(); + private string _tempFolderPath; + readonly MockFileSystem fileSystem; + + public BuildalyzerServiceTestWrapper(MockFileSystem fileSystem) + { + this.fileSystem = fileSystem; + DumpFilesystemOnDisk(); + } + + Dictionary reversePathMap = []; + + + void DumpFilesystemOnDisk() + { + // Create a temporary folder to hold the mock file system + _tempFolderPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + Directory.CreateDirectory(_tempFolderPath); + + // Copy all files and directories from the mock file system to the temp folder + foreach (var file in fileSystem.AllFiles) + { + string tempFilePath = TranslatePath(file); + string directoryPath = Path.GetDirectoryName(tempFilePath); + + if (!Directory.Exists(directoryPath)) + { + Directory.CreateDirectory(directoryPath); + } + + File.WriteAllText(tempFilePath, fileSystem.File.ReadAllText(file)); + reversePathMap.Add(tempFilePath, file); + } + } + + private string TranslatePath(string originalPath) + { + // Translate the original path from the mock file system to the corresponding path in the temp folder + return Path.Combine(_tempFolderPath, fileSystem.Path.GetRelativePath(fileSystem.Path.GetPathRoot(originalPath), originalPath)); + + + } + + public string TranslatePathBackwards(string tempPath) + { + return reversePathMap[tempPath]; + } + + public HashSet GetProjectPathsOfSolution() + { + return coreBuildAnalyzerService + .GetProjectPathsOfSolution() + .Select(TranslatePathBackwards) + .ToHashSet(); + } + + public void InitializeAnalyzer(string solutionFilePath) + { + coreBuildAnalyzerService.InitializeAnalyzer(TranslatePath(solutionFilePath)); + } + + public bool IsTestProject(string projectFilePath) + { + return coreBuildAnalyzerService.IsTestProject(TranslatePath(projectFilePath)); + } + + ~BuildalyzerServiceTestWrapper() + { + CleanUpTempFolder(); + } + + private void CleanUpTempFolder() + { + try + { + if (Directory.Exists(_tempFolderPath)) + { + Directory.Delete(_tempFolderPath, true); + } + } + catch (Exception) + { + } + } + } +} diff --git a/CycloneDX.Tests/CycloneDX.Tests.csproj b/CycloneDX.Tests/CycloneDX.Tests.csproj index ff51c778..43d001fb 100644 --- a/CycloneDX.Tests/CycloneDX.Tests.csproj +++ b/CycloneDX.Tests/CycloneDX.Tests.csproj @@ -33,6 +33,21 @@ + + Always + + + Always + + + Always + + + Always + + + Always + Always diff --git a/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/ExcludeTestDependencies.cs b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/ExcludeTestDependencies.cs new file mode 100644 index 00000000..1ece7448 --- /dev/null +++ b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/ExcludeTestDependencies.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.CommandLine; +using System.IO; +using System.IO.Abstractions; +using System.IO.Abstractions.TestingHelpers; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CycloneDX.Models; +using Xunit; + +namespace CycloneDX.Tests.FunctionalTests +{ + public class ExcludeTestDependencies + { + + readonly string testFileFolder = "ExcludeTestDependencies"; + + private MockFileSystem getMockFS() + { + return new MockFileSystem(new Dictionary + { + + { + MockUnixSupport.Path("c:/solution.sln"), + new MockFileData( + File.ReadAllText(Path.Combine("FunctionalTests", testFileFolder, "sln.txt"))) + },{ + MockUnixSupport.Path("c:/project1/project1.vbproj"), + new MockFileData( + File.ReadAllText(Path.Combine("FunctionalTests", testFileFolder, "project1.xml"))) + },{ + MockUnixSupport.Path("c:/testProject1/testProject1.csproj"), + new MockFileData( + File.ReadAllText(Path.Combine("FunctionalTests", testFileFolder, "testproject1.xml"))) + },{ + MockUnixSupport.Path("c:/project1/obj/project.assets.json"), + new MockFileData( + File.ReadAllText(Path.Combine("FunctionalTests", testFileFolder, "assetsProject1.json"))) + },{ + MockUnixSupport.Path("c:/testProject1/obj/project.assets.json"), + new MockFileData( + File.ReadAllText(Path.Combine("FunctionalTests", testFileFolder, "assetsTestProject1.json"))) + } + }); + } + + [Fact] + public async Task IncludesTestDependenciesByDefault() + { + var options = new RunOptions + { + SolutionOrProjectFile = "c:/solution.sln" + }; + + //Just test that there is no exception + var bom = await FunctionalTestHelper.Test(options, getMockFS()); + + Assert.Contains(bom.Components, c => string.Compare(c.Name, "log4net", true) == 0 && c.Version == "2.0.15"); + Assert.Contains(bom.Components, c => string.Compare(c.Name, "MSTest.TestFramework", true) == 0 && c.Version == "2.2.10"); + + Assert.True(bom.Components.First(c => string.Compare(c.Name, "MSTest.TestFramework", true) == 0 && c.Version == "2.2.10").Scope == Component.ComponentScope.Excluded); + } + + + [Fact] + public async Task ExcludesTestDependenciesWhenOptionIsSet() + { + var options = new RunOptions + { + SolutionOrProjectFile = "c:/solution.sln", + excludeTestProjects = true + + }; + + //Just test that there is no exception + var bom = await FunctionalTestHelper.Test(options, getMockFS()); + + Assert.Contains(bom.Components, c => string.Compare(c.Name, "log4net", true) == 0 && c.Version == "2.0.15"); + Assert.DoesNotContain(bom.Components, c => string.Compare(c.Name, "MSTest.TestFramework", true) == 0 && c.Version == "2.2.10"); + + } + } +} diff --git a/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/assetsProject1.json b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/assetsProject1.json new file mode 100644 index 00000000..3703dae6 --- /dev/null +++ b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/assetsProject1.json @@ -0,0 +1,200 @@ +{ + "version": 3, + "targets": { + ".NETFramework,Version=v4.8": { + "log4net/2.0.15": { + "type": "package", + "frameworkAssemblies": [ + "System.Configuration", + "System.Web" + ], + "compile": { + "lib/net45/log4net.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net45/log4net.dll": { + "related": ".xml" + } + } + } + }, + ".NETFramework,Version=v4.8/win": { + "log4net/2.0.15": { + "type": "package", + "frameworkAssemblies": [ + "System.Configuration", + "System.Web" + ], + "compile": { + "lib/net45/log4net.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net45/log4net.dll": { + "related": ".xml" + } + } + } + }, + ".NETFramework,Version=v4.8/win-arm64": { + "log4net/2.0.15": { + "type": "package", + "frameworkAssemblies": [ + "System.Configuration", + "System.Web" + ], + "compile": { + "lib/net45/log4net.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net45/log4net.dll": { + "related": ".xml" + } + } + } + }, + ".NETFramework,Version=v4.8/win-x64": { + "log4net/2.0.15": { + "type": "package", + "frameworkAssemblies": [ + "System.Configuration", + "System.Web" + ], + "compile": { + "lib/net45/log4net.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net45/log4net.dll": { + "related": ".xml" + } + } + } + }, + ".NETFramework,Version=v4.8/win-x86": { + "log4net/2.0.15": { + "type": "package", + "frameworkAssemblies": [ + "System.Configuration", + "System.Web" + ], + "compile": { + "lib/net45/log4net.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net45/log4net.dll": { + "related": ".xml" + } + } + } + } + }, + "libraries": { + "log4net/2.0.15": { + "sha512": "GahnO9ZgFka+xYcFwAfIFjW+k86P2nxFoaEpH6t3v4hiGj7tv2ksVZphxCVIHmJxoySS0HeU3dgCW+bSCcfD0A==", + "type": "package", + "path": "log4net/2.0.15", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net20/log4net.dll", + "lib/net20/log4net.xml", + "lib/net35/log4net.dll", + "lib/net35/log4net.xml", + "lib/net40-client/log4net.dll", + "lib/net40-client/log4net.xml", + "lib/net40/log4net.dll", + "lib/net40/log4net.xml", + "lib/net45/log4net.dll", + "lib/net45/log4net.xml", + "lib/netstandard1.3/log4net.dll", + "lib/netstandard1.3/log4net.xml", + "lib/netstandard2.0/log4net.dll", + "lib/netstandard2.0/log4net.xml", + "log4net.2.0.15.nupkg.sha512", + "log4net.nuspec", + "package-icon.png" + ] + } + }, + "projectFileDependencyGroups": { + ".NETFramework,Version=v4.8": [ + "log4net >= 2.0.15" + ] + }, + "packageFolders": { + "C:\\Users\\user\\.nuget\\packages\\": {}, + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "E:\\src\\CycloneDX-303\\FrameworkSolutionWithTestProject736\\FrameworkSolutionWithTestProject736\\FrameworkSolutionWithTestProject736.vbproj", + "projectName": "FrameworkSolutionWithTestProject736", + "projectPath": "E:\\src\\CycloneDX-303\\FrameworkSolutionWithTestProject736\\FrameworkSolutionWithTestProject736\\FrameworkSolutionWithTestProject736.vbproj", + "packagesPath": "C:\\Users\\user\\.nuget\\packages\\", + "outputPath": "E:\\src\\CycloneDX-303\\FrameworkSolutionWithTestProject736\\FrameworkSolutionWithTestProject736\\obj\\", + "projectStyle": "PackageReference", + "skipContentFileWrite": true, + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\user\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net48" + ], + "sources": { + "http://localhost:8081/repository/nuget-group/index.json": {} + }, + "frameworks": { + "net48": { + "projectReferences": {} + } + } + }, + "frameworks": { + "net48": { + "dependencies": { + "log4net": { + "target": "Package", + "version": "[2.0.15, )" + } + } + } + }, + "runtimes": { + "win": { + "#import": [] + }, + "win-arm64": { + "#import": [] + }, + "win-x64": { + "#import": [] + }, + "win-x86": { + "#import": [] + } + } + }, + "logs": [ + { + "code": "NU1803", + "level": "Warning", + "warningLevel": 1, + "message": "You are running the 'restore' operation with an 'HTTP' source, 'http://localhost:8081/repository/nuget-group/index.json'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source." + } + ] +} diff --git a/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/assetsTestProject1.json b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/assetsTestProject1.json new file mode 100644 index 00000000..6b504c05 --- /dev/null +++ b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/assetsTestProject1.json @@ -0,0 +1,554 @@ +{ + "version": 3, + "targets": { + ".NETFramework,Version=v4.8": { + "MSTest.TestAdapter/2.2.10": { + "type": "package", + "build": { + "build/net46/MSTest.TestAdapter.props": {}, + "build/net46/MSTest.TestAdapter.targets": {} + } + }, + "MSTest.TestFramework/2.2.10": { + "type": "package", + "compile": { + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll": { + "related": ".XML" + }, + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll": { + "related": ".Extensions.XML;.XML" + } + }, + "runtime": { + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll": { + "related": ".XML" + }, + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll": { + "related": ".Extensions.XML;.XML" + } + } + } + }, + ".NETFramework,Version=v4.8/win": { + "MSTest.TestAdapter/2.2.10": { + "type": "package", + "build": { + "build/net46/MSTest.TestAdapter.props": {}, + "build/net46/MSTest.TestAdapter.targets": {} + } + }, + "MSTest.TestFramework/2.2.10": { + "type": "package", + "compile": { + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll": { + "related": ".XML" + }, + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll": { + "related": ".Extensions.XML;.XML" + } + }, + "runtime": { + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll": { + "related": ".XML" + }, + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll": { + "related": ".Extensions.XML;.XML" + } + } + } + }, + ".NETFramework,Version=v4.8/win-arm64": { + "MSTest.TestAdapter/2.2.10": { + "type": "package", + "build": { + "build/net46/MSTest.TestAdapter.props": {}, + "build/net46/MSTest.TestAdapter.targets": {} + } + }, + "MSTest.TestFramework/2.2.10": { + "type": "package", + "compile": { + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll": { + "related": ".XML" + }, + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll": { + "related": ".Extensions.XML;.XML" + } + }, + "runtime": { + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll": { + "related": ".XML" + }, + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll": { + "related": ".Extensions.XML;.XML" + } + } + } + }, + ".NETFramework,Version=v4.8/win-x64": { + "MSTest.TestAdapter/2.2.10": { + "type": "package", + "build": { + "build/net46/MSTest.TestAdapter.props": {}, + "build/net46/MSTest.TestAdapter.targets": {} + } + }, + "MSTest.TestFramework/2.2.10": { + "type": "package", + "compile": { + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll": { + "related": ".XML" + }, + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll": { + "related": ".Extensions.XML;.XML" + } + }, + "runtime": { + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll": { + "related": ".XML" + }, + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll": { + "related": ".Extensions.XML;.XML" + } + } + } + }, + ".NETFramework,Version=v4.8/win-x86": { + "MSTest.TestAdapter/2.2.10": { + "type": "package", + "build": { + "build/net46/MSTest.TestAdapter.props": {}, + "build/net46/MSTest.TestAdapter.targets": {} + } + }, + "MSTest.TestFramework/2.2.10": { + "type": "package", + "compile": { + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll": { + "related": ".XML" + }, + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll": { + "related": ".Extensions.XML;.XML" + } + }, + "runtime": { + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll": { + "related": ".XML" + }, + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll": { + "related": ".Extensions.XML;.XML" + } + } + } + } + }, + "libraries": { + "MSTest.TestAdapter/2.2.10": { + "sha512": "KOc7XVNM0Q5GrTAx4RhxTgwdt9O5gOqSzmLpUMyl9ywa6vvUNFVQ9nCjtEE7qDQW54MZdc82e287PzZDc7yQtA==", + "type": "package", + "path": "mstest.testadapter/2.2.10", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "build/_common/Microsoft.TestPlatform.AdapterUtilities.dll", + "build/_common/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.dll", + "build/_common/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.dll", + "build/_common/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll", + "build/_common/Microsoft.VisualStudio.TestPlatform.TestFramework.dll", + "build/_common/cs/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/cs/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/cs/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/cs/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/cs/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/cs/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/de/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/de/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/de/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/de/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/de/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/de/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/es/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/es/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/es/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/es/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/es/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/es/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/fr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/fr/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/fr/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/fr/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/fr/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/fr/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/it/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/it/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/it/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/it/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/it/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/it/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/ja/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/ja/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/ja/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/ja/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/ja/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/ja/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/ko/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/ko/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/ko/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/ko/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/ko/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/ko/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/pl/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/pl/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/pl/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/pl/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/pl/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/pl/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/pt-BR/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/pt-BR/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/pt-BR/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/pt-BR/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/pt-BR/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/pt-BR/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/ru/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/ru/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/ru/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/ru/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/ru/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/ru/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/tr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/tr/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/tr/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/tr/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/tr/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/tr/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/zh-Hans/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/zh-Hans/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/zh-Hans/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/zh-Hans/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/zh-Hans/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/zh-Hans/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/_common/zh-Hant/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/_common/zh-Hant/Microsoft.TestPlatform.CoreUtilities.resources.dll", + "build/_common/zh-Hant/Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources.dll", + "build/_common/zh-Hant/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.resources.dll", + "build/_common/zh-Hant/Microsoft.VisualStudio.TestPlatform.ObjectModel.resources.dll", + "build/_common/zh-Hant/Microsoft.VisualStudio.TestPlatform.TestFramework.resources.dll", + "build/net45/MSTest.TestAdapter.props", + "build/net45/MSTest.TestAdapter.targets", + "build/net45/Microsoft.TestPlatform.AdapterUtilities.dll", + "build/net45/cs/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/de/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/es/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/fr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/it/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/ja/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/ko/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/pl/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/pt-BR/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/ru/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/tr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/zh-Hans/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net45/zh-Hant/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/MSTest.TestAdapter.props", + "build/net46/MSTest.TestAdapter.targets", + "build/net46/Microsoft.TestPlatform.AdapterUtilities.dll", + "build/net46/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll", + "build/net46/cs/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/de/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/es/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/fr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/it/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/ja/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/ko/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/pl/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/pt-BR/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/ru/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/tr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/zh-Hans/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net46/zh-Hant/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/MSTest.TestAdapter.props", + "build/net5.0/MSTest.TestAdapter.targets", + "build/net5.0/Microsoft.TestPlatform.AdapterUtilities.dll", + "build/net5.0/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll", + "build/net5.0/cs/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/de/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/es/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/fr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/it/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/ja/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/ko/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/pl/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/pt-BR/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/ru/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/tr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/winui/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll", + "build/net5.0/zh-Hans/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/net5.0/zh-Hant/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/MSTest.TestAdapter.props", + "build/netcoreapp1.0/Microsoft.TestPlatform.AdapterUtilities.dll", + "build/netcoreapp1.0/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll", + "build/netcoreapp1.0/cs/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/de/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/es/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/fr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/it/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/ja/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/ko/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/pl/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/pt-BR/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/ru/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/tr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/zh-Hans/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netcoreapp1.0/zh-Hant/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/MSTest.TestAdapter.props", + "build/netstandard1.5/Microsoft.TestPlatform.AdapterUtilities.dll", + "build/netstandard1.5/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll", + "build/netstandard1.5/cs/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/de/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/es/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/fr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/it/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/ja/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/ko/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/pl/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/pt-BR/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/ru/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/tr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/zh-Hans/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/netstandard1.5/zh-Hant/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/MSTest.TestAdapter.props", + "build/uap10.0/MSTest.TestAdapter.targets", + "build/uap10.0/Microsoft.TestPlatform.AdapterUtilities.dll", + "build/uap10.0/Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll", + "build/uap10.0/cs/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/de/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/es/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/fr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/it/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/ja/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/ko/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/pl/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/pt-BR/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/ru/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/tr/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/zh-Hans/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "build/uap10.0/zh-Hant/Microsoft.TestPlatform.AdapterUtilities.resources.dll", + "mstest.testadapter.2.2.10.nupkg.sha512", + "mstest.testadapter.nuspec" + ] + }, + "MSTest.TestFramework/2.2.10": { + "sha512": "JZRVXKq19uRhkj8MuzsU8zJhPV2JV3ZToFPAIg+BU53L1L9mNDfm9jXerdRfbrE4HBcf2M54Ij80zPOdlha3+Q==", + "type": "package", + "path": "mstest.testframework/2.2.10", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "build/net5.0/MSTest.TestFramework.targets", + "build/net5.0/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.XML", + "build/net5.0/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll", + "build/net5.0/cs/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/de/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/es/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/fr/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/it/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/ja/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/ko/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/pl/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/pt-BR/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/ru/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/tr/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/winui/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.XML", + "build/net5.0/winui/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll", + "build/net5.0/zh-Hans/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "build/net5.0/zh-Hant/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.XML", + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll", + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.XML", + "lib/net45/Microsoft.VisualStudio.TestPlatform.TestFramework.dll", + "lib/net45/cs/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/cs/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/de/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/de/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/es/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/es/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/fr/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/fr/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/it/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/it/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/ja/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/ja/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/ko/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/ko/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/pl/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/pl/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/pt-BR/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/pt-BR/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/ru/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/ru/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/tr/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/tr/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/zh-Hans/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/zh-Hans/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net45/zh-Hant/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/net45/zh-Hant/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/Microsoft.VisualStudio.TestPlatform.TestFramework.XML", + "lib/net5.0/Microsoft.VisualStudio.TestPlatform.TestFramework.dll", + "lib/net5.0/cs/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/de/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/es/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/fr/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/it/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/ja/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/ko/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/pl/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/pt-BR/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/ru/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/tr/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/zh-Hans/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/net5.0/zh-Hant/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.XML", + "lib/netstandard1.0/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll", + "lib/netstandard1.0/Microsoft.VisualStudio.TestPlatform.TestFramework.XML", + "lib/netstandard1.0/Microsoft.VisualStudio.TestPlatform.TestFramework.dll", + "lib/netstandard1.0/cs/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/cs/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/de/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/de/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/es/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/es/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/fr/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/fr/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/it/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/it/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/ja/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/ja/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/ko/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/ko/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/pl/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/pl/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/pt-BR/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/pt-BR/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/ru/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/ru/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/tr/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/tr/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/zh-Hans/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/zh-Hans/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/netstandard1.0/zh-Hant/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/netstandard1.0/zh-Hant/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.XML", + "lib/uap10.0/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll", + "lib/uap10.0/Microsoft.VisualStudio.TestPlatform.TestFramework.XML", + "lib/uap10.0/Microsoft.VisualStudio.TestPlatform.TestFramework.dll", + "lib/uap10.0/cs/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/cs/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/de/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/de/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/es/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/es/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/fr/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/fr/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/it/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/it/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/ja/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/ja/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/ko/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/ko/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/pl/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/pl/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/pt-BR/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/pt-BR/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/ru/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/ru/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/tr/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/tr/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/zh-Hans/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/zh-Hans/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "lib/uap10.0/zh-Hant/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.xml", + "lib/uap10.0/zh-Hant/Microsoft.VisualStudio.TestPlatform.TestFramework.xml", + "mstest.testframework.2.2.10.nupkg.sha512", + "mstest.testframework.nuspec" + ] + } + }, + "projectFileDependencyGroups": { + ".NETFramework,Version=v4.8": [ + "MSTest.TestAdapter >= 2.2.10", + "MSTest.TestFramework >= 2.2.10" + ] + }, + "packageFolders": { + "C:\\Users\\user\\.nuget\\packages\\": {}, + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "E:\\src\\CycloneDX-303\\FrameworkSolutionWithTestProject736\\UnitTestProject1\\UnitTestProject1.csproj", + "projectName": "UnitTestProject1", + "projectPath": "E:\\src\\CycloneDX-303\\FrameworkSolutionWithTestProject736\\UnitTestProject1\\UnitTestProject1.csproj", + "packagesPath": "C:\\Users\\user\\.nuget\\packages\\", + "outputPath": "E:\\src\\CycloneDX-303\\FrameworkSolutionWithTestProject736\\UnitTestProject1\\obj\\", + "projectStyle": "PackageReference", + "skipContentFileWrite": true, + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], + "configFilePaths": [ + "C:\\Users\\user\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net48" + ], + "sources": { + "http://localhost:8081/repository/nuget-group/index.json": {} + }, + "frameworks": { + "net48": { + "projectReferences": {} + } + } + }, + "frameworks": { + "net48": { + "dependencies": { + "MSTest.TestAdapter": { + "target": "Package", + "version": "[2.2.10, )" + }, + "MSTest.TestFramework": { + "target": "Package", + "version": "[2.2.10, )" + } + } + } + }, + "runtimes": { + "win": { + "#import": [] + }, + "win-arm64": { + "#import": [] + }, + "win-x64": { + "#import": [] + }, + "win-x86": { + "#import": [] + } + } + }, + "logs": [ + { + "code": "NU1803", + "level": "Warning", + "warningLevel": 1, + "message": "You are running the 'restore' operation with an 'HTTP' source, 'http://localhost:8081/repository/nuget-group/index.json'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source." + } + ] +} diff --git a/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/project1.xml b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/project1.xml new file mode 100644 index 00000000..92fc5aeb --- /dev/null +++ b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/project1.xml @@ -0,0 +1,117 @@ + + + + + Debug + AnyCPU + {FCEDA75C-DF35-44C8-A2B9-BFD294F2D575} + Exe + FrameworkSolutionWithTestProject736.Module1 + FrameworkSolutionWithTestProject736 + FrameworkSolutionWithTestProject736 + 512 + Console + v4.8 + true + true + + + AnyCPU + true + full + true + true + bin\Debug\ + FrameworkSolutionWithTestProject736.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + AnyCPU + pdbonly + false + true + true + bin\Release\ + FrameworkSolutionWithTestProject736.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + On + + + Binary + + + Off + + + On + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + Application.myapp + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + Designer + + + + + MyApplicationCodeGenerator + Application.Designer.vb + + + SettingsSingleFileGenerator + My + Settings.Designer.vb + + + + + + 2.0.15 + + + + diff --git a/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/sln.txt b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/sln.txt new file mode 100644 index 00000000..94045690 --- /dev/null +++ b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/sln.txt @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Project1", "project1\project1.vbproj", "{FCEDA75C-DF35-44C8-A2B9-BFD294F2D575}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTestProject1", "testProject1\testProject1.csproj", "{0B611E61-DE2E-47EE-A400-BC5F0CE20038}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FCEDA75C-DF35-44C8-A2B9-BFD294F2D575}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FCEDA75C-DF35-44C8-A2B9-BFD294F2D575}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FCEDA75C-DF35-44C8-A2B9-BFD294F2D575}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FCEDA75C-DF35-44C8-A2B9-BFD294F2D575}.Release|Any CPU.Build.0 = Release|Any CPU + {0B611E61-DE2E-47EE-A400-BC5F0CE20038}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0B611E61-DE2E-47EE-A400-BC5F0CE20038}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0B611E61-DE2E-47EE-A400-BC5F0CE20038}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0B611E61-DE2E-47EE-A400-BC5F0CE20038}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {70BD4EB6-DB1C-4A89-8D55-599FE83E33B2} + EndGlobalSection +EndGlobal diff --git a/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/testproject1.xml b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/testproject1.xml new file mode 100644 index 00000000..967f5232 --- /dev/null +++ b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/testproject1.xml @@ -0,0 +1,58 @@ + + + + + Debug + AnyCPU + {0B611E61-DE2E-47EE-A400-BC5F0CE20038} + Library + Properties + UnitTestProject1 + UnitTestProject1 + v4.8 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + 2.2.10 + + + 2.2.10 + + + + + diff --git a/CycloneDX.Tests/FunctionalTests/FunctionalTestHelper.cs b/CycloneDX.Tests/FunctionalTests/FunctionalTestHelper.cs index 81b401c6..dbedea21 100644 --- a/CycloneDX.Tests/FunctionalTests/FunctionalTestHelper.cs +++ b/CycloneDX.Tests/FunctionalTests/FunctionalTestHelper.cs @@ -79,7 +79,7 @@ public static async Task Test(RunOptions options, INugetServiceFactory nuge options.SolutionOrProjectFile ??= MockUnixSupport.Path("c:/ProjectPath/Project.csproj"); options.disablePackageRestore = true; - Runner runner = new Runner(mockFileSystem, null, null, null, null, null, null, nugetService); + Runner runner = new Runner(fileSystem: mockFileSystem, null, null, null, null, new BuildalyzerServiceTestWrapper(mockFileSystem) , null, null, nugetServiceFactory: nugetService); int exitCode = await runner.HandleCommandAsync(options); Assert.Equal((int)ExitCode.OK, exitCode); diff --git a/CycloneDX.Tests/FunctionalTests/Issue830-rsMultipleFrameworks/project1assets.json b/CycloneDX.Tests/FunctionalTests/Issue830-rsMultipleFrameworks/project1assets.json index c1a30fb5..bda1a1bd 100644 --- a/CycloneDX.Tests/FunctionalTests/Issue830-rsMultipleFrameworks/project1assets.json +++ b/CycloneDX.Tests/FunctionalTests/Issue830-rsMultipleFrameworks/project1assets.json @@ -886,7 +886,7 @@ ] }, "packageFolders": { - "C:\\Users\\mibau\\.nuget\\packages\\": {}, + "C:\\Users\\user\\.nuget\\packages\\": {}, "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} }, "project": { @@ -895,14 +895,14 @@ "projectUniqueName": "E:\\src\\CycloneDX-830\\CrashReproduction\\ConsoleApp1\\ConsoleApp1.csproj", "projectName": "ConsoleApp1", "projectPath": "E:\\src\\CycloneDX-830\\CrashReproduction\\ConsoleApp1\\ConsoleApp1.csproj", - "packagesPath": "C:\\Users\\mibau\\.nuget\\packages\\", + "packagesPath": "C:\\Users\\user\\.nuget\\packages\\", "outputPath": "E:\\src\\CycloneDX-830\\CrashReproduction\\ConsoleApp1\\obj\\", "projectStyle": "PackageReference", "fallbackFolders": [ "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" ], "configFilePaths": [ - "C:\\Users\\mibau\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Users\\user\\AppData\\Roaming\\NuGet\\NuGet.Config", "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" ], diff --git a/CycloneDX.Tests/FunctionalTests/Issue830-rsMultipleFrameworks/project2assets.json b/CycloneDX.Tests/FunctionalTests/Issue830-rsMultipleFrameworks/project2assets.json index f395e6ba..266cdf62 100644 --- a/CycloneDX.Tests/FunctionalTests/Issue830-rsMultipleFrameworks/project2assets.json +++ b/CycloneDX.Tests/FunctionalTests/Issue830-rsMultipleFrameworks/project2assets.json @@ -1317,7 +1317,7 @@ ] }, "packageFolders": { - "C:\\Users\\mibau\\.nuget\\packages\\": {}, + "C:\\Users\\user\\.nuget\\packages\\": {}, "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} }, "project": { @@ -1326,7 +1326,7 @@ "projectUniqueName": "E:\\src\\CycloneDX-830\\CrashReproduction\\ConsoleApp2\\ConsoleApp2.csproj", "projectName": "ConsoleApp2", "projectPath": "E:\\src\\CycloneDX-830\\CrashReproduction\\ConsoleApp2\\ConsoleApp2.csproj", - "packagesPath": "C:\\Users\\mibau\\.nuget\\packages\\", + "packagesPath": "C:\\Users\\user\\.nuget\\packages\\", "outputPath": "E:\\src\\CycloneDX-830\\CrashReproduction\\ConsoleApp2\\obj\\", "projectStyle": "PackageReference", "crossTargeting": true, @@ -1334,7 +1334,7 @@ "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" ], "configFilePaths": [ - "C:\\Users\\mibau\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Users\\user\\AppData\\Roaming\\NuGet\\NuGet.Config", "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" ], diff --git a/CycloneDX.Tests/ProgramTests.cs b/CycloneDX.Tests/ProgramTests.cs index 7817fffd..0f51a8ba 100755 --- a/CycloneDX.Tests/ProgramTests.cs +++ b/CycloneDX.Tests/ProgramTests.cs @@ -43,14 +43,14 @@ public async Task CallingCycloneDX_CreatesOutputDirectory() { var mockFileSystem = new MockFileSystem(new Dictionary { - { XFS.Path(@"c:\SolutionPath\SolutionFile.sln"), "" } + { XFS.Path(@"c:\SolutionPath\SolutionFile.sln"), "Microsoft Visual Studio Solution File, Format Version 12.00" } }); var mockSolutionFileService = new Mock(); mockSolutionFileService .Setup(s => s.GetSolutionDotnetDependencys(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(new HashSet()); - Runner runner = new Runner(fileSystem: mockFileSystem, null, null, null, null, null, solutionFileService: mockSolutionFileService.Object, null); + Runner runner = new Runner(fileSystem: mockFileSystem, null, null, null, null, buildalyzerService: new BuildalyzerServiceTestWrapper(mockFileSystem), null, solutionFileService: mockSolutionFileService.Object, null); RunOptions runOptions = new RunOptions { @@ -68,14 +68,14 @@ public async Task CallingCycloneDX_WithOutputFilename_CreatesOutputFilename() { var mockFileSystem = new MockFileSystem(new Dictionary { - { XFS.Path(@"c:\SolutionPath\SolutionFile.sln"), "" } + { XFS.Path(@"c:\SolutionPath\SolutionFile.sln"), "Microsoft Visual Studio Solution File, Format Version 12.00" } }); var mockSolutionFileService = new Mock(); mockSolutionFileService .Setup(s => s.GetSolutionDotnetDependencys(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(new HashSet()); - Runner runner = new Runner(fileSystem: mockFileSystem, null, null, null, null, null, solutionFileService: mockSolutionFileService.Object, null); + Runner runner = new Runner(fileSystem: mockFileSystem, null, null, null, null, buildalyzerService: new BuildalyzerServiceTestWrapper(mockFileSystem), null, solutionFileService: mockSolutionFileService.Object, null); RunOptions runOptions = new RunOptions { diff --git a/CycloneDX.Tests/ProjectFileServiceTests.cs b/CycloneDX.Tests/ProjectFileServiceTests.cs index f9baf012..8749ed1d 100644 --- a/CycloneDX.Tests/ProjectFileServiceTests.cs +++ b/CycloneDX.Tests/ProjectFileServiceTests.cs @@ -36,6 +36,12 @@ public class ProjectFileServiceTests private readonly string _testProjectsBaseDir = XFS.Path(Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "..", "..", "..", "..", "TestProjects", "SolutionPath"))); + private IBuildalyzerService GetBuildalyzerServiceMock() + { + return new Mock().Object; + } + + private ProjectFileService GetInstanceOfProjectFileService() { var fileSystem = new FileSystem(); @@ -44,7 +50,9 @@ private ProjectFileService GetInstanceOfProjectFileService() fileSystem, new DotnetUtilsService(fileSystem, dotnetCommandService), new PackagesFileService(fileSystem), - new ProjectAssetsFileService(fileSystem, () => new AssetFileReader())); + new ProjectAssetsFileService(fileSystem, () => new AssetFileReader()), + new BuildalyzerService() + ); } @@ -95,9 +103,10 @@ public async Task GetProjectDotnetDependencys_WithProjectAssetsFile_ReturnsDotne mockFileSystem, mockDotnetUtilsService.Object, mockPackageFileService.Object, - mockProjectAssetsFileService.Object); + mockProjectAssetsFileService.Object, + GetBuildalyzerServiceMock()); - var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "", null).ConfigureAwait(true); + var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "").ConfigureAwait(true); Assert.Collection(packages, item => { @@ -130,10 +139,12 @@ public async Task GetProjectDotnetDependencys_WithProjectAssetsFileWithoutRestor mockFileSystem, mockDotnetUtilsService.Object, mockPackageFileService.Object, - mockProjectAssetsFileService.Object); + mockProjectAssetsFileService.Object, + GetBuildalyzerServiceMock() + ); projectFileService.DisablePackageRestore = true; - var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "", null).ConfigureAwait(true); + var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "").ConfigureAwait(true); Assert.Collection(packages, item => { @@ -168,9 +179,10 @@ public async Task GetProjectDotnetDependencys_WithProjectAssetsFile_ReturnsMulti mockFileSystem, mockDotnetUtilsService.Object, mockPackageFileService.Object, - mockProjectAssetsFileService.Object); + mockProjectAssetsFileService.Object, + GetBuildalyzerServiceMock()); - var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "", null).ConfigureAwait(true); + var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "").ConfigureAwait(true); var sortedPackages = new List(packages); sortedPackages.Sort(); @@ -209,9 +221,9 @@ public async Task GetProjectDotnetDependencys_WithPackagesConfig_ReturnsDotnetDe mockFileSystem, mockDotnetUtilsService.Object, mockPackageFileService.Object, - mockProjectAssetsFileService.Object); + mockProjectAssetsFileService.Object, GetBuildalyzerServiceMock()); - var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "", null).ConfigureAwait(true); + var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "").ConfigureAwait(true); Assert.Collection(packages, item => { @@ -251,9 +263,10 @@ public async Task GetProjectDotnetDependencys_WithPackagesConfig_ReturnsMultiple mockFileSystem, mockDotnetUtilsService.Object, mockPackageFileService.Object, - mockProjectAssetsFileService.Object); + mockProjectAssetsFileService.Object, + GetBuildalyzerServiceMock()); - var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "", null).ConfigureAwait(true); + var packages = await projectFileService.GetProjectDotnetDependencysAsync(XFS.Path(@"c:\Project\Project.csproj"), "", false, "", "").ConfigureAwait(true); var sortedPackages = new List(packages); sortedPackages.Sort(); @@ -273,7 +286,8 @@ public async Task GetProjectReferences_ReturnsProjectReferences() new System.IO.Abstractions.FileSystem(), mockDotnetUtilsService.Object, mockPackageFileService.Object, - mockProjectAssetsFileService.Object); + mockProjectAssetsFileService.Object, + GetBuildalyzerServiceMock()); var projects = await projectFileService.GetProjectReferencesAsync(XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project\Project.csproj"))).ConfigureAwait(true); var sortedProjects = new List(projects); @@ -295,7 +309,8 @@ public async Task RecursivelyGetProjectReferences_ReturnsProjectReferences() new System.IO.Abstractions.FileSystem(), mockDotnetUtilsService.Object, mockPackageFileService.Object, - mockProjectAssetsFileService.Object); + mockProjectAssetsFileService.Object, + GetBuildalyzerServiceMock()); var projects = await projectFileService.RecursivelyGetProjectReferencesAsync(XFS.Path(Path.Combine(_testProjectsBaseDir, @"Project1\Project1.csproj"))).ConfigureAwait(true); var sortedProjects = new List(projects.Select(d => d.Path)); diff --git a/CycloneDX.Tests/SolutionFileServiceTests.cs b/CycloneDX.Tests/SolutionFileServiceTests.cs index a15a708a..21b86e37 100644 --- a/CycloneDX.Tests/SolutionFileServiceTests.cs +++ b/CycloneDX.Tests/SolutionFileServiceTests.cs @@ -30,6 +30,7 @@ namespace CycloneDX.Tests { public class SolutionFileServiceTests { + [Fact] public async Task GetSolutionProjectReferences_ReturnsProjectThatExists() { @@ -44,7 +45,7 @@ public async Task GetSolutionProjectReferences_ReturnsProjectThatExists() mockProjectFileService .Setup(s => s.RecursivelyGetProjectReferencesAsync(It.IsAny())) .ReturnsAsync(new HashSet()); - var solutionFileService = new SolutionFileService(mockFileSystem, mockProjectFileService.Object); + var solutionFileService = new SolutionFileService(mockFileSystem, mockProjectFileService.Object, new BuildalyzerServiceTestWrapper(mockFileSystem)); var projects = await solutionFileService.GetSolutionProjectReferencesAsync(XFS.Path(@"c:\SolutionPath\SolutionFile.sln")).ConfigureAwait(true); @@ -72,7 +73,7 @@ public async Task GetSolutionProjectReferences_ReturnsListOfProjects() .ReturnsAsync(new HashSet()) .ReturnsAsync(new HashSet()) .ReturnsAsync(new HashSet()); - var solutionFileService = new SolutionFileService(mockFileSystem, mockProjectFileService.Object); + var solutionFileService = new SolutionFileService(mockFileSystem, mockProjectFileService.Object, new BuildalyzerServiceTestWrapper(mockFileSystem)); var projects = await solutionFileService.GetSolutionProjectReferencesAsync(XFS.Path(@"c:\SolutionPath\SolutionFile.sln")).ConfigureAwait(true); var sortedProjects = new List(projects); @@ -104,7 +105,7 @@ public async Task GetSolutionProjectReferences_ReturnsListOfProjectsIncludingFSh .ReturnsAsync(new HashSet()) .ReturnsAsync(new HashSet()) .ReturnsAsync(new HashSet()); - var solutionFileService = new SolutionFileService(mockFileSystem, mockProjectFileService.Object); + var solutionFileService = new SolutionFileService(mockFileSystem, mockProjectFileService.Object, new BuildalyzerServiceTestWrapper(mockFileSystem)); var projects = await solutionFileService.GetSolutionProjectReferencesAsync(XFS.Path(@"c:\SolutionPath\SolutionFile.sln")).ConfigureAwait(true); var sortedProjects = new List(projects); @@ -138,7 +139,7 @@ public async Task GetSolutionProjectReferences_ReturnsListOfProjects_IncludingSe } }) .ReturnsAsync(new HashSet()); - var solutionFileService = new SolutionFileService(mockFileSystem, mockProjectFileService.Object); + var solutionFileService = new SolutionFileService(mockFileSystem, mockProjectFileService.Object, new BuildalyzerServiceTestWrapper(mockFileSystem)); var projects = await solutionFileService.GetSolutionProjectReferencesAsync(XFS.Path(@"c:\SolutionPath\SolutionFile.sln")).ConfigureAwait(true); var sortedProjects = new List(projects); diff --git a/CycloneDX.Tests/ValidationTests.cs b/CycloneDX.Tests/ValidationTests.cs index 0c21a445..1c634bfd 100644 --- a/CycloneDX.Tests/ValidationTests.cs +++ b/CycloneDX.Tests/ValidationTests.cs @@ -38,10 +38,10 @@ public async Task Validation(string fileFormat, bool disableGitHubLicenses) var mockProjectFileService = new Mock(); mockProjectFileService.Setup(mock => - mock.GetProjectDotnetDependencysAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()) + mock.GetProjectDotnetDependencysAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()) ).ReturnsAsync(packages); - Runner runner = new Runner(fileSystem: mockFileSystem, null, null, null, null, projectFileService: mockProjectFileService.Object, solutionFileService: null, null); + Runner runner = new Runner(fileSystem: mockFileSystem, null, null, null, null, null, projectFileService: mockProjectFileService.Object, solutionFileService: null, null); RunOptions runOptions = new RunOptions diff --git a/CycloneDX/Interfaces/IProjectFileService.cs b/CycloneDX/Interfaces/IProjectFileService.cs index 4b757579..7a6728c2 100644 --- a/CycloneDX/Interfaces/IProjectFileService.cs +++ b/CycloneDX/Interfaces/IProjectFileService.cs @@ -24,7 +24,7 @@ namespace CycloneDX.Interfaces public interface IProjectFileService { bool DisablePackageRestore { get; set; } - Task> GetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime, bool? isTestProject); + Task> GetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime); Task> GetProjectReferencesAsync(string projectFilePath); Task> RecursivelyGetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime); Task> RecursivelyGetProjectReferencesAsync(string projectFilePath); diff --git a/CycloneDX/Runner.cs b/CycloneDX/Runner.cs index b0d197e5..c85316ff 100644 --- a/CycloneDX/Runner.cs +++ b/CycloneDX/Runner.cs @@ -37,6 +37,7 @@ public class Runner readonly IDotnetCommandService dotnetCommandService; readonly IDotnetUtilsService dotnetUtilsService; readonly IPackagesFileService packagesFileService; + readonly IBuildalyzerService buildalyzerService; readonly IProjectFileService projectFileService; readonly ISolutionFileService solutionFileService; readonly INugetServiceFactory nugetServiceFactory; @@ -46,6 +47,7 @@ public Runner(IFileSystem fileSystem, IProjectAssetsFileService projectAssetsFileService, IDotnetUtilsService dotnetUtilsService, IPackagesFileService packagesFileService, + IBuildalyzerService buildalyzerService, IProjectFileService projectFileService, ISolutionFileService solutionFileService, INugetServiceFactory nugetServiceFactory) @@ -55,11 +57,12 @@ public Runner(IFileSystem fileSystem, projectAssetsFileService ??= new ProjectAssetsFileService(this.fileSystem, () => new AssetFileReader()); this.dotnetUtilsService = dotnetUtilsService ?? new DotnetUtilsService(this.fileSystem, this.dotnetCommandService); this.packagesFileService = packagesFileService ?? new PackagesFileService(this.fileSystem); - this.projectFileService = projectFileService ?? new ProjectFileService(this.fileSystem, this.dotnetUtilsService, this.packagesFileService, projectAssetsFileService); - this.solutionFileService = solutionFileService ?? new SolutionFileService(this.fileSystem, this.projectFileService); + this.buildalyzerService = buildalyzerService ?? new BuildalyzerService(); + this.projectFileService = projectFileService ?? new ProjectFileService(this.fileSystem, this.dotnetUtilsService, this.packagesFileService, projectAssetsFileService, this.buildalyzerService); + this.solutionFileService = solutionFileService ?? new SolutionFileService(this.fileSystem, this.projectFileService, this.buildalyzerService); this.nugetServiceFactory = nugetServiceFactory ?? new NugetV3ServiceFactory(); } - public Runner() : this(null, null, null, null, null, null, null, null) { } + public Runner() : this(null, null, null, null, null, null, null, null, null) { } public async Task HandleCommandAsync(RunOptions options) { @@ -129,8 +132,11 @@ public async Task HandleCommandAsync(RunOptions options) githubService = new GithubService(new HttpClient()); } } - var nugetService = nugetServiceFactory.Create(options, fileSystem, githubService, packageCachePathsResult.Result); + if (SolutionOrProjectFile.ToLowerInvariant().EndsWith(".sln", StringComparison.OrdinalIgnoreCase)) + { + buildalyzerService.InitializeAnalyzer(SolutionOrProjectFile); + } var packages = new HashSet(); @@ -174,7 +180,7 @@ public async Task HandleCommandAsync(RunOptions options) } else if (Utils.IsSupportedProjectType(SolutionOrProjectFile)) { - packages = await projectFileService.GetProjectDotnetDependencysAsync(fullSolutionOrProjectFilePath, baseIntermediateOutputPath, excludetestprojects, framework, runtime, null).ConfigureAwait(false); + packages = await projectFileService.GetProjectDotnetDependencysAsync(fullSolutionOrProjectFilePath, baseIntermediateOutputPath, excludetestprojects, framework, runtime).ConfigureAwait(false); topLevelComponent.Name = fileSystem.Path.GetFileNameWithoutExtension(SolutionOrProjectFile); } else if (this.fileSystem.Path.GetFileName(SolutionOrProjectFile).ToLowerInvariant().Equals("packages.config", StringComparison.OrdinalIgnoreCase)) diff --git a/CycloneDX/Services/BuildalyzerService.cs b/CycloneDX/Services/BuildalyzerService.cs new file mode 100644 index 00000000..bca669d8 --- /dev/null +++ b/CycloneDX/Services/BuildalyzerService.cs @@ -0,0 +1,104 @@ +// This file is part of CycloneDX Tool for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Abstractions; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Buildalyzer; +using CycloneDX.Models; + +namespace CycloneDX.Services +{ + public class BuildalyzerService : IBuildalyzerService + { + AnalyzerManager _manager; + AnalyzerManager manager + { + get + { + if (_manager == null) + InitializeAnalyzer(null); + return _manager; + } + } + Dictionary cachedResults { get; } = new Dictionary(); + string tempPath { get; } + + public BuildalyzerService() + { + tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + Directory.CreateDirectory(tempPath); + + } + + ~ BuildalyzerService() + { + Directory.Delete(tempPath, true); + } + + public void InitializeAnalyzer(string solutionFilePath) + { + if (_manager != null) + { + throw new InvalidOperationException("Analyzer has already been initialized. It cannot be initialized twice."); + } + + _manager = string.IsNullOrEmpty(solutionFilePath) + ? new AnalyzerManager() + : new AnalyzerManager(solutionFilePath); + + _manager.SetGlobalProperty("UseArtifactsOutput", "true"); + _manager.SetGlobalProperty("ArtifactsPath", tempPath); + } + + + + + + private IAnalyzerResults getAnalyzerResults(string projectFilePath) + { + if (!cachedResults.TryGetValue(projectFilePath, out var results)) + { + var project = manager.GetProject(projectFilePath); + results = project.Build(); + cachedResults.Add(projectFilePath, results); + } + return results; + } + + public bool IsTestProject(string projectFilePath) + { + var buildResults = getAnalyzerResults(projectFilePath); + var isTestProjectSDK = buildResults.SelectMany(x => x.Properties) + .Any(x => x.Key.Equals("IsTestProject", StringComparison.OrdinalIgnoreCase) && x.Value.Equals("true", StringComparison.OrdinalIgnoreCase)); + + var isTestProjectLegacy = buildResults.SelectMany(x => x.Properties) + .Any(x => x.Key.Equals("TestProjectType", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(x.Value)); + + return isTestProjectSDK || isTestProjectLegacy; + } + + public HashSet GetProjectPathsOfSolution() + { + return manager.Projects.Select(p => p.Key).ToHashSet(); + } + } +} diff --git a/CycloneDX/Services/IBuildalyzerService.cs b/CycloneDX/Services/IBuildalyzerService.cs new file mode 100644 index 00000000..ef3e836e --- /dev/null +++ b/CycloneDX/Services/IBuildalyzerService.cs @@ -0,0 +1,28 @@ +// This file is part of CycloneDX Tool for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System.Collections.Generic; + +namespace CycloneDX.Services +{ + public interface IBuildalyzerService + { + HashSet GetProjectPathsOfSolution(); + void InitializeAnalyzer(string solutionFilePath); + bool IsTestProject(string projectFilePath); + } +} diff --git a/CycloneDX/Services/ProjectFileService.cs b/CycloneDX/Services/ProjectFileService.cs index 767e8f86..b831ef35 100644 --- a/CycloneDX/Services/ProjectFileService.cs +++ b/CycloneDX/Services/ProjectFileService.cs @@ -25,7 +25,6 @@ using CycloneDX.Interfaces; using CycloneDX.Models; using System.Text.RegularExpressions; -using Buildalyzer; namespace CycloneDX.Services { @@ -47,17 +46,20 @@ public class ProjectFileService : IProjectFileService private IDotnetUtilsService _dotnetUtilsService; private IPackagesFileService _packagesFileService; private IProjectAssetsFileService _projectAssetsFileService; + private IBuildalyzerService _buildalyzerService; public ProjectFileService( IFileSystem fileSystem, IDotnetUtilsService dotnetUtilsService, IPackagesFileService packagesFileService, - IProjectAssetsFileService projectAssetsFileService) + IProjectAssetsFileService projectAssetsFileService, + IBuildalyzerService buildalyzerService) { _fileSystem = fileSystem; _dotnetUtilsService = dotnetUtilsService; _packagesFileService = packagesFileService; _projectAssetsFileService = projectAssetsFileService; + this._buildalyzerService = buildalyzerService ?? throw new ArgumentNullException(nameof(buildalyzerService)); } public bool IsTestProject(string projectFilePath) @@ -66,21 +68,7 @@ public bool IsTestProject(string projectFilePath) { return false; } - var manager = new AnalyzerManager(); - try - { - var project = manager.GetProject(projectFilePath); - var buildResults = project.Build(); - var isTestProject = buildResults.SelectMany(x => x.Properties) - .Any(x => x.Key.Equals("IsTestProject", StringComparison.OrdinalIgnoreCase) && x.Value.Equals("true", StringComparison.OrdinalIgnoreCase)); - - return isTestProject; - } - catch (ArgumentException) - { - // can only happen while testing (because it will be checked before this method is called) - return false; - } + return _buildalyzerService.IsTestProject(projectFilePath); } private (string name, string version) GetProjectNameAndVersion(string projectFilePath) @@ -151,7 +139,7 @@ static internal string GetProjectProperty(string projectFilePath, string baseInt /// /// /// - public async Task> GetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime, bool? isTestProject) + public async Task> GetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime) { if (!_fileSystem.File.Exists(projectFilePath)) { @@ -159,15 +147,17 @@ public async Task> GetProjectDotnetDependencysAsync(st return new HashSet(); } - if (!isTestProject.HasValue) - { - isTestProject = IsTestProject(projectFilePath); - } - Console.WriteLine(); Console.WriteLine($"» Analyzing: {projectFilePath}"); - if (excludeTestProjects && isTestProject.Value) + var isTestProject = IsTestProject(projectFilePath); + + if(isTestProject) + { + Console.WriteLine($" Identified {projectFilePath} as a test project"); + } + + if (excludeTestProjects && isTestProject) { Console.WriteLine($"Skipping: {projectFilePath}"); return new HashSet(); @@ -195,7 +185,7 @@ public async Task> GetProjectDotnetDependencysAsync(st { Console.WriteLine($"File not found: \"{assetsFilename}\", \"{projectFilePath}\" "); } - var packages = _projectAssetsFileService.GetDotnetDependencys(projectFilePath, assetsFilename, isTestProject.Value); + var packages = _projectAssetsFileService.GetDotnetDependencys(projectFilePath, assetsFilename, isTestProject); // if there are no project file package references look for a packages.config @@ -220,7 +210,7 @@ public async Task> GetProjectDotnetDependencysAsync(st /// public async Task> RecursivelyGetProjectDotnetDependencysAsync(string projectFilePath, string baseIntermediateOutputPath, bool excludeTestProjects, string framework, string runtime) { - var dotnetDependencys = await GetProjectDotnetDependencysAsync(projectFilePath, baseIntermediateOutputPath, excludeTestProjects, framework, runtime, null).ConfigureAwait(false); + var dotnetDependencys = await GetProjectDotnetDependencysAsync(projectFilePath, baseIntermediateOutputPath, excludeTestProjects, framework, runtime).ConfigureAwait(false); foreach (var item in dotnetDependencys) { item.IsDirectReference = true; @@ -236,7 +226,7 @@ public async Task> RecursivelyGetProjectDotnetDependen foreach (var project in projectReferences) { - var projectDotnetDependencys = await GetProjectDotnetDependencysAsync(project.Path, baseIntermediateOutputPath, excludeTestProjects, framework, runtime, null).ConfigureAwait(false); + var projectDotnetDependencys = await GetProjectDotnetDependencysAsync(project.Path, baseIntermediateOutputPath, excludeTestProjects, framework, runtime).ConfigureAwait(false); //Add dependencies for dependency graph foreach (var dependency in projectDotnetDependencys) diff --git a/CycloneDX/Services/SolutionFileService.cs b/CycloneDX/Services/SolutionFileService.cs index d7073c68..4d7bd65b 100644 --- a/CycloneDX/Services/SolutionFileService.cs +++ b/CycloneDX/Services/SolutionFileService.cs @@ -21,9 +21,9 @@ using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; -using Buildalyzer; using CycloneDX.Interfaces; using CycloneDX.Models; +using Microsoft.Build.Logging.StructuredLogger; namespace CycloneDX.Services { @@ -31,11 +31,13 @@ public class SolutionFileService : ISolutionFileService { private IFileSystem _fileSystem; private IProjectFileService _projectFileService; + private IBuildalyzerService _buildalyzerService; - public SolutionFileService(IFileSystem fileSystem, IProjectFileService projectFileService) + public SolutionFileService(IFileSystem fileSystem, IProjectFileService projectFileService, IBuildalyzerService buildalyzerService) { _fileSystem = fileSystem; _projectFileService = projectFileService; + _buildalyzerService = buildalyzerService ?? throw new ArgumentNullException(nameof(buildalyzerService)); } /// @@ -97,17 +99,7 @@ public async Task> GetSolutionDotnetDependencys(string var packages = new HashSet(); - HashSet<(string path,bool isTestProject)> projectPaths = new(); - - AnalyzerManager manager = new AnalyzerManager(solutionFilePath); - foreach (var (key, project) in manager.Projects) - { - var buildResults = project.Build(); - var isTestProject = buildResults.SelectMany(x => x.Properties) - .Any(x => x.Key.Equals("IsTestProject", StringComparison.OrdinalIgnoreCase) && x.Value.Equals("true", StringComparison.OrdinalIgnoreCase)); - - projectPaths.Add((project.ProjectFile.Path, isTestProject)); - } + HashSet projectPaths = _buildalyzerService.GetProjectPathsOfSolution(); if (projectPaths.Count == 0) { @@ -119,12 +111,13 @@ public async Task> GetSolutionDotnetDependencys(string } // Process first all productive projects, then test projects (scope order) - var projectQuery = from p in projectPaths orderby p.isTestProject select p; var directReferencePackages = new HashSet(); - foreach (var (projectFilePath, isTest) in projectQuery) - { - Console.WriteLine(); - var projectPackages = await _projectFileService.GetProjectDotnetDependencysAsync(projectFilePath, baseIntermediateOutputPath, excludeTestProjects, framework, runtime, isTest).ConfigureAwait(false); + foreach (string projectFilePath in projectPaths) + { + if (excludeTestProjects && _buildalyzerService.IsTestProject(projectFilePath)) + continue; + + var projectPackages = await _projectFileService.GetProjectDotnetDependencysAsync(projectFilePath, baseIntermediateOutputPath, excludeTestProjects, framework, runtime).ConfigureAwait(false); directReferencePackages.UnionWith(projectPackages.Where(p => p.IsDirectReference)); packages.UnionWith(projectPackages); } From eedcebdf7210f70d96fc3bad623f307446fb1545 Mon Sep 17 00:00:00 2001 From: MTsfoni Date: Sun, 21 Jan 2024 12:03:56 +0100 Subject: [PATCH 4/4] Fix Codacy-Remarks and hopefully test on Linux Signed-off-by: MTsfoni --- CycloneDX.Tests/BuildalyzerServiceTestWrapper.cs | 8 +++++--- .../ExcludeTestDependencies/ExcludeTestDependencies.cs | 4 ++-- .../{Services => Interfaces}/IBuildalyzerService.cs | 2 +- CycloneDX/Services/BuildalyzerService.cs | 3 +++ CycloneDX/Services/ProjectFileService.cs | 10 +++++----- CycloneDX/Services/SolutionFileService.cs | 10 +++++----- 6 files changed, 21 insertions(+), 16 deletions(-) rename CycloneDX/{Services => Interfaces}/IBuildalyzerService.cs (96%) diff --git a/CycloneDX.Tests/BuildalyzerServiceTestWrapper.cs b/CycloneDX.Tests/BuildalyzerServiceTestWrapper.cs index d89358f1..6981d62f 100644 --- a/CycloneDX.Tests/BuildalyzerServiceTestWrapper.cs +++ b/CycloneDX.Tests/BuildalyzerServiceTestWrapper.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using CycloneDX.Interfaces; using CycloneDX.Services; namespace CycloneDX.Tests @@ -27,7 +28,7 @@ public BuildalyzerServiceTestWrapper(MockFileSystem fileSystem) DumpFilesystemOnDisk(); } - Dictionary reversePathMap = []; + readonly Dictionary reversePathMap = []; void DumpFilesystemOnDisk() @@ -97,8 +98,9 @@ private void CleanUpTempFolder() Directory.Delete(_tempFolderPath, true); } } - catch (Exception) - { + catch (Exception ex) + { + Console.WriteLine($"{ex.GetType()} when deleting {_tempFolderPath}\r\n{ex.Message}"); } } } diff --git a/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/ExcludeTestDependencies.cs b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/ExcludeTestDependencies.cs index 1ece7448..67c1c120 100644 --- a/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/ExcludeTestDependencies.cs +++ b/CycloneDX.Tests/FunctionalTests/ExcludeTestDependencies/ExcludeTestDependencies.cs @@ -51,7 +51,7 @@ public async Task IncludesTestDependenciesByDefault() { var options = new RunOptions { - SolutionOrProjectFile = "c:/solution.sln" + SolutionOrProjectFile = MockUnixSupport.Path("c:/solution.sln") }; //Just test that there is no exception @@ -69,7 +69,7 @@ public async Task ExcludesTestDependenciesWhenOptionIsSet() { var options = new RunOptions { - SolutionOrProjectFile = "c:/solution.sln", + SolutionOrProjectFile = MockUnixSupport.Path("c:/solution.sln"), excludeTestProjects = true }; diff --git a/CycloneDX/Services/IBuildalyzerService.cs b/CycloneDX/Interfaces/IBuildalyzerService.cs similarity index 96% rename from CycloneDX/Services/IBuildalyzerService.cs rename to CycloneDX/Interfaces/IBuildalyzerService.cs index ef3e836e..6dd62751 100644 --- a/CycloneDX/Services/IBuildalyzerService.cs +++ b/CycloneDX/Interfaces/IBuildalyzerService.cs @@ -17,7 +17,7 @@ using System.Collections.Generic; -namespace CycloneDX.Services +namespace CycloneDX.Interfaces { public interface IBuildalyzerService { diff --git a/CycloneDX/Services/BuildalyzerService.cs b/CycloneDX/Services/BuildalyzerService.cs index bca669d8..fc75dda8 100644 --- a/CycloneDX/Services/BuildalyzerService.cs +++ b/CycloneDX/Services/BuildalyzerService.cs @@ -23,6 +23,7 @@ using System.Text; using System.Threading.Tasks; using Buildalyzer; +using CycloneDX.Interfaces; using CycloneDX.Models; namespace CycloneDX.Services @@ -35,7 +36,9 @@ AnalyzerManager manager get { if (_manager == null) + { InitializeAnalyzer(null); + } return _manager; } } diff --git a/CycloneDX/Services/ProjectFileService.cs b/CycloneDX/Services/ProjectFileService.cs index b831ef35..d1e4bf3f 100644 --- a/CycloneDX/Services/ProjectFileService.cs +++ b/CycloneDX/Services/ProjectFileService.cs @@ -42,11 +42,11 @@ public class ProjectFileService : IProjectFileService Async = true }; - private IFileSystem _fileSystem; - private IDotnetUtilsService _dotnetUtilsService; - private IPackagesFileService _packagesFileService; - private IProjectAssetsFileService _projectAssetsFileService; - private IBuildalyzerService _buildalyzerService; + private readonly IFileSystem _fileSystem; + private readonly IDotnetUtilsService _dotnetUtilsService; + private readonly IPackagesFileService _packagesFileService; + private readonly IProjectAssetsFileService _projectAssetsFileService; + private readonly IBuildalyzerService _buildalyzerService; public ProjectFileService( IFileSystem fileSystem, diff --git a/CycloneDX/Services/SolutionFileService.cs b/CycloneDX/Services/SolutionFileService.cs index 4d7bd65b..637e609d 100644 --- a/CycloneDX/Services/SolutionFileService.cs +++ b/CycloneDX/Services/SolutionFileService.cs @@ -29,9 +29,9 @@ namespace CycloneDX.Services { public class SolutionFileService : ISolutionFileService { - private IFileSystem _fileSystem; - private IProjectFileService _projectFileService; - private IBuildalyzerService _buildalyzerService; + private readonly IFileSystem _fileSystem; + private readonly IProjectFileService _projectFileService; + private readonly IBuildalyzerService _buildalyzerService; public SolutionFileService(IFileSystem fileSystem, IProjectFileService projectFileService, IBuildalyzerService buildalyzerService) { @@ -113,9 +113,9 @@ public async Task> GetSolutionDotnetDependencys(string // Process first all productive projects, then test projects (scope order) var directReferencePackages = new HashSet(); foreach (string projectFilePath in projectPaths) - { + { if (excludeTestProjects && _buildalyzerService.IsTestProject(projectFilePath)) - continue; + { continue; } var projectPackages = await _projectFileService.GetProjectDotnetDependencysAsync(projectFilePath, baseIntermediateOutputPath, excludeTestProjects, framework, runtime).ConfigureAwait(false); directReferencePackages.UnionWith(projectPackages.Where(p => p.IsDirectReference));