Beispiel #1
0
        async Task <int> OnExecute()
        {
            Console.WriteLine();

            // check parameter values
            if (string.IsNullOrEmpty(SolutionOrProjectFile))
            {
                Console.Error.WriteLine($"A path is required");
                return((int)ExitCode.SolutionOrProjectFileParameterMissing);
            }

            if (string.IsNullOrEmpty(outputDirectory))
            {
                Console.Error.WriteLine($"The output directory is required");
                return((int)ExitCode.OutputDirectoryParameterMissing);
            }

            if (string.IsNullOrEmpty(githubUsername) ^ string.IsNullOrEmpty(githubToken))
            {
                Console.Error.WriteLine($"Both GitHub username and token are required");
                return((int)ExitCode.GitHubParameterMissing);
            }

            // instantiate services
            var fileDiscoveryService = new FileDiscoveryService(Program.fileSystem);
            // GitHubService requires its own HttpClient as it adds a default authorization header
            GithubService githubService;

            if (string.IsNullOrEmpty(githubUsername) || string.IsNullOrEmpty(githubToken))
            {
                githubService = new GithubService(new HttpClient());
            }
            else
            {
                githubService = new GithubService(new HttpClient(), githubUsername, githubToken);
            }
            var nugetService        = new NugetService(Program.httpClient, githubService, baseUrl);
            var packagesFileService = new PackagesFileService(Program.fileSystem);
            var projectFileService  = new ProjectFileService(Program.fileSystem);
            var solutionFileService = new SolutionFileService(Program.fileSystem);
            var packages            = new HashSet <NugetPackage>();

            // determine what we are analyzing and do the analysis
            var fullSolutionOrProjectFilePath = Program.fileSystem.Path.GetFullPath(SolutionOrProjectFile);
            var attr = Program.fileSystem.File.GetAttributes(fullSolutionOrProjectFilePath);

            if (SolutionOrProjectFile.ToLowerInvariant().EndsWith(".sln", StringComparison.OrdinalIgnoreCase))
            {
                packages = await solutionFileService.GetSolutionNugetPackages(fullSolutionOrProjectFilePath);
            }
            else if (Utils.IsSupportedProjectType(SolutionOrProjectFile) && scanProjectReferences)
            {
                packages = await projectFileService.RecursivelyGetProjectNugetPackagesAsync(fullSolutionOrProjectFilePath);
            }
            else if (Utils.IsSupportedProjectType(SolutionOrProjectFile))
            {
                packages = await projectFileService.GetProjectNugetPackagesAsync(fullSolutionOrProjectFilePath);
            }
            else if (Program.fileSystem.Path.GetFileName(SolutionOrProjectFile).ToLowerInvariant().Equals("packages.config", StringComparison.OrdinalIgnoreCase))
            {
                packages = await packagesFileService.GetNugetPackagesAsync(fullSolutionOrProjectFilePath);
            }
            else if (attr.HasFlag(FileAttributes.Directory))
            {
                packages = await packagesFileService.RecursivelyGetNugetPackagesAsync(fullSolutionOrProjectFilePath);
            }
            else
            {
                Console.Error.WriteLine($"Only .sln, .csproj, .vbproj, and packages.config files are supported");
                return((int)ExitCode.InvalidOptions);
            }

            // get all the components from the NuGet packages
            var components = new HashSet <Component>();

            try
            {
                foreach (var package in packages)
                {
                    var component = await nugetService.GetComponentAsync(package);

                    if (component != null)
                    {
                        components.Add(component);
                    }
                }
            }
            catch (InvalidGitHubApiCredentialsException)
            {
                return((int)ExitCode.InvalidGitHubApiCredentials);
            }
            catch (GitHubApiRateLimitExceededException)
            {
                return((int)ExitCode.GitHubApiRateLimitExceeded);
            }

            // create the BOM
            Console.WriteLine();
            Console.WriteLine("Creating CycloneDX BoM");
            var bomXml = BomService.CreateXmlDocument(components, noSerialNumber);

            // check if the output directory exists and create it if needed
            var bomPath = Program.fileSystem.Path.GetFullPath(outputDirectory);

            if (!Program.fileSystem.Directory.Exists(bomPath))
            {
                Program.fileSystem.Directory.CreateDirectory(bomPath);
            }

            // write the BOM to disk
            var bomFile = Program.fileSystem.Path.Combine(bomPath, "bom.xml");

            Console.WriteLine("Writing to: " + bomFile);
            using (var fileStream = Program.fileSystem.FileStream.Create(bomFile, FileMode.Create))
                using (var writer = new StreamWriter(fileStream, new UTF8Encoding(false))) {
                    bomXml.Save(writer);
                }

            return(0);
        }
        public async Task RecursivelyGetProjectNugetPackages_ReturnsNugetPackages()
        {
            var mockFileSystem = new MockFileSystem(new Dictionary <string, MockFileData>
            {
                { XFS.Path(@"c:\SolutionPath\Project1\Project1.csproj"), Helpers.GetProjectFileWithReferences(
                      new string[] {
                        @"..\Project2\Project2.csproj",
                        @"..\Project3\Project3.csproj",
                    },
                      new NugetPackage[] {
                        new NugetPackage {
                            Name = "Package1", Version = "1.2.3"
                        },
                        new NugetPackage {
                            Name = "Package2", Version = "1.2.3"
                        },
                        new NugetPackage {
                            Name = "Package3", Version = "1.2.3"
                        },
                    }) },
                { XFS.Path(@"c:\SolutionPath\Project2\Project2.csproj"), Helpers.GetProjectFileWithReferences(
                      new string[] {
                        @"..\Project3\Project3.csproj",
                    },
                      new NugetPackage[] {
                        new NugetPackage {
                            Name = "Package1", Version = "1.2.4"
                        },
                    }) },
                { XFS.Path(@"c:\SolutionPath\Project3\Project3.csproj"), Helpers.GetProjectFileWithReferences(
                      null,
                      new NugetPackage[] {
                        new NugetPackage {
                            Name = "Package1", Version = "1.2.3"
                        },
                    }) },
            });
            var projectFileService = new ProjectFileService(mockFileSystem);

            var packages = await projectFileService.RecursivelyGetProjectNugetPackagesAsync(XFS.Path(@"c:\SolutionPath\Project1\Project1.csproj"));

            var sortedPackages = new List <NugetPackage>(packages);

            sortedPackages.Sort();

            Assert.Collection(sortedPackages,
                              item => {
                Assert.Equal("Package1", item.Name);
                Assert.Equal("1.2.3", item.Version);
            },
                              item => {
                Assert.Equal("Package1", item.Name);
                Assert.Equal("1.2.4", item.Version);
            },
                              item => {
                Assert.Equal("Package2", item.Name);
                Assert.Equal("1.2.3", item.Version);
            },
                              item => {
                Assert.Equal("Package3", item.Name);
                Assert.Equal("1.2.3", item.Version);
            }
                              );
        }