├── .azdo
└── release.yaml
├── .devcontainer
└── devcontainer.json
├── .dockerignore
├── .editorconfig
├── .git-blame-ignore-revs
├── .gitattributes
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ └── feature_request.yml
├── PULL_REQUEST_TEMPLATE
│ └── new_detector_template.md
├── codecov.yml
├── dependabot.yml
├── release-drafter.yml
└── workflows
│ ├── build.yml
│ ├── codeql-analysis.yml
│ ├── detector-version-bump-reminder.yml
│ ├── gen-docs.yml
│ ├── ossf-scorecard.yml
│ ├── release-drafter.yml
│ ├── release.yml
│ ├── smoke-test.yml
│ ├── snapshot-publish.yml
│ └── snapshot-verify.yml
├── .gitignore
├── .vscode
├── launch.json
└── tasks.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ComponentDetection.sln
├── Directory.Build.props
├── Directory.Build.targets
├── Directory.Packages.props
├── Dockerfile
├── LICENSE.txt
├── README.md
├── SECURITY.md
├── docs
├── community-meetings.md
├── creating-a-new-detector.md
├── creating-a-new-service.md
├── detector-arguments.md
├── detectors
│ ├── README.md
│ ├── conan.md
│ ├── conda.md
│ ├── dotnet.md
│ ├── go.md
│ ├── gradle.md
│ ├── linux.md
│ ├── maven.md
│ ├── npm.md
│ ├── nuget.md
│ ├── pip.md
│ ├── pnpm.md
│ ├── poetry.md
│ ├── swift.md
│ └── vcpkg.md
├── enable-default-off.md
├── environment-variables.md
├── feature-overview.md
├── images
│ ├── creating-a-new-detector
│ │ ├── component-type.png
│ │ ├── component-utilities.png
│ │ ├── detector-class.png
│ │ ├── go-detector-test-utility.png
│ │ ├── multi-root-dependency.png
│ │ ├── npm-component.png
│ │ ├── ruby-component-detector.png
│ │ ├── single-root-dependency.png
│ │ ├── test-projects.png
│ │ └── vs-projects.png
│ └── readme
│ │ ├── component-detection-screenshot.png
│ │ └── component-detection.png
├── issue-labeling.md
├── renewing-secrets.md
├── running-verification-tests.md
├── schema
│ └── manifest.schema.json
└── update-syft.md
├── global.json
├── renovate.json
├── src
├── Directory.Build.props
├── Microsoft.ComponentDetection.Common
│ ├── AsyncExecution.cs
│ ├── Column.cs
│ ├── CommandLineInvocationService.cs
│ ├── ComponentComparer.cs
│ ├── ComponentStream.cs
│ ├── ComponentStreamEnumerable.cs
│ ├── ComponentStreamEnumerableFactory.cs
│ ├── ConsoleWritingService.cs
│ ├── DependencyGraph
│ │ ├── ComponentRecorder.cs
│ │ └── DependencyGraph.cs
│ ├── DependencyScopeComparer.cs
│ ├── DirectoryItemFacade.cs
│ ├── DirectoryItemFacadeOptimized.cs
│ ├── DirectoryUtilityService.cs
│ ├── DockerReference
│ │ ├── DigestUtility.cs
│ │ ├── DockerReferenceException.cs
│ │ ├── DockerReferenceUtility.cs
│ │ └── DockerRegex.cs
│ ├── DockerService.cs
│ ├── EnvironmentVariableService.cs
│ ├── Exceptions
│ │ └── InvalidUserInputException.cs
│ ├── FastDirectoryWalkerFactory.cs
│ ├── FileUtilityService.cs
│ ├── FileWritingService.cs
│ ├── IConsoleWritingService.cs
│ ├── IFileWritingService.cs
│ ├── ISafeFileEnumerableFactory.cs
│ ├── LazyComponentStream.cs
│ ├── MatchedFile.cs
│ ├── Microsoft.ComponentDetection.Common.csproj
│ ├── PathUtilityService.cs
│ ├── PatternMatchingUtility.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── SafeFileEnumerable.cs
│ ├── SafeFileEnumerableFactory.cs
│ ├── ScanType.cs
│ ├── TabularStringFormat.cs
│ ├── Telemetry
│ │ ├── Attributes
│ │ │ └── MetricAttribute.cs
│ │ ├── CommandLineTelemetryService.cs
│ │ ├── ITelemetryService.cs
│ │ ├── Records
│ │ │ ├── BaseDetectionTelemetryRecord.cs
│ │ │ ├── BcdeExecutionTelemetryRecord.cs
│ │ │ ├── CommandLineInvocationTelemetryRecord.cs
│ │ │ ├── DependencyGraphTranslationRecord.cs
│ │ │ ├── DetectedComponentScopeRecord.cs
│ │ │ ├── DetectorExecutionTelemetryRecord.cs
│ │ │ ├── DockerServiceImageExistsLocallyTelemetryRecord.cs
│ │ │ ├── DockerServiceInspectImageTelemetryRecord.cs
│ │ │ ├── DockerServiceSystemInfoTelemetryRecord.cs
│ │ │ ├── DockerServiceTelemetryRecord.cs
│ │ │ ├── DockerServiceTryPullImageTelemetryRecord.cs
│ │ │ ├── FailedParsingFileRecord.cs
│ │ │ ├── GoGraphTelemetryRecord.cs
│ │ │ ├── GoReplaceTelemetryRecord.cs
│ │ │ ├── IDetectionTelemetryRecord.cs
│ │ │ ├── InvalidParseVersionTelemetryRecord.cs
│ │ │ ├── LinuxContainerDetectorImageDetectionFailed.cs
│ │ │ ├── LinuxContainerDetectorLayerAwareness.cs
│ │ │ ├── LinuxContainerDetectorMissingRepoNameAndTagRecord.cs
│ │ │ ├── LinuxContainerDetectorMissingVersion.cs
│ │ │ ├── LinuxContainerDetectorTimeout.cs
│ │ │ ├── LinuxContainerDetectorUnsupportedOs.cs
│ │ │ ├── LinuxScannerSyftTelemetryRecord.cs
│ │ │ ├── LinuxScannerTelemetryRecord.cs
│ │ │ ├── LoadComponentDetectorsTelemetryRecord.cs
│ │ │ ├── NuGetProjectAssetsTelemetryRecord.cs
│ │ │ ├── PipReportFailureTelemetryRecord.cs
│ │ │ ├── PipReportSkipTelemetryRecord.cs
│ │ │ ├── PipReportTypeTelemetryRecord.cs
│ │ │ ├── PyPiCacheTelemetryRecord.cs
│ │ │ ├── PypiFailureTelemetryRecord.cs
│ │ │ ├── PypiMaxRetriesReachedTelemetryRecord.cs
│ │ │ ├── PypiRetryTelemetryRecord.cs
│ │ │ ├── RustCrateDetectorTelemetryRecord.cs
│ │ │ ├── RustGraphTelemetryRecord.cs
│ │ │ └── SimplePypiCacheTelemetryRecord.cs
│ │ ├── TelemetryConstants.cs
│ │ ├── TelemetryMode.cs
│ │ └── TelemetryRelay.cs
│ ├── Utilities
│ │ └── StringUtilities.cs
│ └── WarnOnAlertSeverity.cs
├── Microsoft.ComponentDetection.Contracts
│ ├── BcdeModels
│ │ ├── ContainerDetails.cs
│ │ ├── DefaultGraphScanResult.cs
│ │ ├── DependencyGraph.cs
│ │ ├── DependencyGraphCollection.cs
│ │ ├── DependencyGraphWithMetadata.cs
│ │ ├── DependencyScope.cs
│ │ ├── Detector.cs
│ │ ├── DockerLayer.cs
│ │ ├── LayerMappedLinuxComponents.cs
│ │ ├── ScanResult.cs
│ │ ├── ScannedComponent.cs
│ │ └── TypedComponentConverter.cs
│ ├── ConcurrentHashSet.cs
│ ├── DetectedComponent.cs
│ ├── DetectorClass.cs
│ ├── DockerReference.cs
│ ├── FileComponentDetector.cs
│ ├── FileComponentDetectorWithCleanup.cs
│ ├── ICommandLineInvocationService.cs
│ ├── IComponentDetector.cs
│ ├── IComponentRecorder.cs
│ ├── IComponentStream.cs
│ ├── IComponentStreamEnumerableFactory.cs
│ ├── IDirectoryUtilityService.cs
│ ├── IDockerService.cs
│ ├── IEnvironmentVariableService.cs
│ ├── IFileUtilityService.cs
│ ├── IObservableDirectoryWalkerFactory.cs
│ ├── IPathUtilityService.cs
│ ├── IndividualDetectorScanResult.cs
│ ├── Internal
│ │ ├── NpmAuthor.cs
│ │ └── ProcessRequest.cs
│ ├── KillSwitchConfiguration.cs
│ ├── Microsoft.ComponentDetection.Contracts.csproj
│ ├── ProcessingResultCode.cs
│ ├── ScanRequest.cs
│ └── TypedComponent
│ │ ├── CargoComponent.cs
│ │ ├── ComponentType.cs
│ │ ├── ConanComponent.cs
│ │ ├── CondaComponent.cs
│ │ ├── DockerImageComponent.cs
│ │ ├── DockerReferenceComponent.cs
│ │ ├── DotNetComponent.cs
│ │ ├── GitComponent.cs
│ │ ├── GoComponent.cs
│ │ ├── LinuxComponent.cs
│ │ ├── MavenComponent.cs
│ │ ├── NpmComponent.cs
│ │ ├── NugetComponent.cs
│ │ ├── OtherComponent.cs
│ │ ├── PipComponent.cs
│ │ ├── PodComponent.cs
│ │ ├── RubyGemsComponent.cs
│ │ ├── SpdxComponent.cs
│ │ ├── SwiftComponent.cs
│ │ ├── TypedComponent.cs
│ │ └── VcpkgComponent.cs
├── Microsoft.ComponentDetection.Detectors
│ ├── Microsoft.ComponentDetection.Detectors.csproj
│ ├── cocoapods
│ │ └── PodComponentDetector.cs
│ ├── conan
│ │ ├── ConanLockComponentDetector.cs
│ │ └── Contracts
│ │ │ ├── ConanLock.cs
│ │ │ ├── ConanLockGraph.cs
│ │ │ └── ConanLockNode.cs
│ ├── conda
│ │ ├── CondaDependencyResolver.cs
│ │ ├── CondaLockComponentDetector.cs
│ │ └── Contracts
│ │ │ ├── CondaLock.cs
│ │ │ ├── CondaMetadata.cs
│ │ │ └── CondaPackage.cs
│ ├── dockerfile
│ │ └── DockerfileComponentDetector.cs
│ ├── dotnet
│ │ └── DotNetComponentDetector.cs
│ ├── go
│ │ ├── Go117ComponentDetector.cs
│ │ ├── GoComponentDetector.cs
│ │ ├── Parsers
│ │ │ ├── GoCLIParser.cs
│ │ │ ├── GoModParser.cs
│ │ │ ├── GoParserFactory.cs
│ │ │ ├── GoParserType.cs
│ │ │ ├── GoSumParser.cs
│ │ │ ├── IGoParser.cs
│ │ │ └── IGoParserFactory.cs
│ │ └── Utils
│ │ │ ├── GoDependencyGraphUtility.cs
│ │ │ └── GoDetectorUtils.cs
│ ├── gradle
│ │ └── GradleComponentDetector.cs
│ ├── ivy
│ │ ├── IvyDetector.cs
│ │ └── Resources
│ │ │ ├── build.xml
│ │ │ └── java-src
│ │ │ └── IvyComponentDetectionAntTask.java
│ ├── linux
│ │ ├── Contracts
│ │ │ ├── ImageScanningResult.cs
│ │ │ └── SyftOutput.cs
│ │ ├── Exceptions
│ │ │ └── MissingContainerDetailException.cs
│ │ ├── ILinuxScanner.cs
│ │ ├── LinuxContainerDetector.cs
│ │ └── LinuxScanner.cs
│ ├── maven
│ │ ├── GraphNode.cs
│ │ ├── IMavenCommandService.cs
│ │ ├── IMavenStyleDependencyGraphParserService.cs
│ │ ├── MavenCommandService.cs
│ │ ├── MavenParsingUtilities.cs
│ │ ├── MavenStyleDependencyGraphParser.cs
│ │ ├── MavenStyleDependencyGraphParserService.cs
│ │ └── MvnCliComponentDetector.cs
│ ├── npm
│ │ ├── Contracts
│ │ │ ├── PackageLockV1.cs
│ │ │ ├── PackageLockV1Dependency.cs
│ │ │ ├── PackageLockV2.cs
│ │ │ ├── PackageLockV2Dependency.cs
│ │ │ ├── PackageLockV2Package.cs
│ │ │ ├── PackageLockV3.cs
│ │ │ └── PackageLockV3Package.cs
│ │ ├── NpmComponentDetector.cs
│ │ ├── NpmComponentDetectorWithRoots.cs
│ │ ├── NpmComponentUtilities.cs
│ │ ├── NpmLockfile3Detector.cs
│ │ └── NpmLockfileDetectorBase.cs
│ ├── nuget
│ │ ├── FrameworkPackages
│ │ │ ├── FrameworkPackages.cs
│ │ │ ├── FrameworkPackages.net461.cs
│ │ │ ├── FrameworkPackages.net5.0.cs
│ │ │ ├── FrameworkPackages.net6.0.cs
│ │ │ ├── FrameworkPackages.net7.0.cs
│ │ │ ├── FrameworkPackages.net8.0.cs
│ │ │ ├── FrameworkPackages.net9.0.cs
│ │ │ ├── FrameworkPackages.netcoreapp2.0.cs
│ │ │ ├── FrameworkPackages.netcoreapp2.1.cs
│ │ │ ├── FrameworkPackages.netcoreapp2.2.cs
│ │ │ ├── FrameworkPackages.netcoreapp3.0.cs
│ │ │ ├── FrameworkPackages.netcoreapp3.1.cs
│ │ │ ├── FrameworkPackages.netstandard2.0.cs
│ │ │ ├── FrameworkPackages.netstandard2.1.cs
│ │ │ └── Readme.md
│ │ ├── NuGetComponentDetector.cs
│ │ ├── NuGetNuspecUtilities.cs
│ │ ├── NuGetPackagesConfigDetector.cs
│ │ └── NuGetProjectModelProjectCentricComponentDetector.cs
│ ├── pip
│ │ ├── Contracts
│ │ │ ├── IPipCommandService.cs
│ │ │ ├── IPythonCommandService.cs
│ │ │ ├── IPythonResolver.cs
│ │ │ ├── ISimplePyPiClient.cs
│ │ │ ├── ISimplePythonResolver.cs
│ │ │ ├── PipDependencySpecification.cs
│ │ │ ├── PipGraphNode.cs
│ │ │ ├── PipInstallationMetadata.cs
│ │ │ ├── PipInstallationReport.cs
│ │ │ ├── PipInstallationReportItem.cs
│ │ │ ├── PipReportGraphNode.cs
│ │ │ ├── PythonProject.cs
│ │ │ ├── PythonProjectInfo.cs
│ │ │ ├── PythonProjectRelease.cs
│ │ │ ├── PythonResolverState.cs
│ │ │ └── PythonVersion.cs
│ │ ├── IPyPiClient.cs
│ │ ├── PipCommandService.cs
│ │ ├── PipComponentDetector.cs
│ │ ├── PipReportComponentDetector.cs
│ │ ├── PipReportUtilities.cs
│ │ ├── PythonCommandService.cs
│ │ ├── PythonNotFoundException.cs
│ │ ├── PythonResolver.cs
│ │ ├── PythonResolverBase.cs
│ │ ├── PythonVersionComparer.cs
│ │ ├── PythonVersionUtilities.cs
│ │ ├── SharedPipUtilities.cs
│ │ ├── SimplePipComponentDetector.cs
│ │ ├── SimplePypiClient.cs
│ │ ├── SimplePypiProject.cs
│ │ ├── SimplePypiProjectRelease.cs
│ │ └── SimplePythonResolver.cs
│ ├── pnpm
│ │ ├── Contracts
│ │ │ ├── Package.cs
│ │ │ ├── PnpmVersionSpecification.md
│ │ │ ├── PnpmYaml.cs
│ │ │ ├── PnpmYamlV5.cs
│ │ │ ├── V6
│ │ │ │ ├── PnpmHasDependenciesV6.cs
│ │ │ │ ├── PnpmYamlV6.cs
│ │ │ │ └── PnpmYamlV6Dependency.cs
│ │ │ └── V9
│ │ │ │ ├── PnpmHasDependenciesV9.cs
│ │ │ │ ├── PnpmYamlV9.cs
│ │ │ │ └── PnpmYamlV9Dependency.cs
│ │ ├── IPnpmDetector.cs
│ │ ├── ParsingUtilities
│ │ │ ├── PnpmParsingUtilitiesBase.cs
│ │ │ ├── PnpmParsingUtilitiesFactory.cs
│ │ │ ├── PnpmV5ParsingUtilities.cs
│ │ │ ├── PnpmV6ParsingUtilities.cs
│ │ │ └── PnpmV9ParsingUtilities.cs
│ │ ├── Pnpm5Detector.cs
│ │ ├── Pnpm6Detector.cs
│ │ ├── Pnpm9Detector.cs
│ │ └── PnpmComponentDetectorFactory.cs
│ ├── poetry
│ │ ├── Contracts
│ │ │ ├── PoetryLock.cs
│ │ │ ├── PoetryPackage.cs
│ │ │ └── PoetrySource.cs
│ │ └── PoetryComponentDetector.cs
│ ├── ruby
│ │ └── RubyComponentDetector.cs
│ ├── rust
│ │ ├── CargoDependencyData.cs
│ │ ├── Contracts
│ │ │ ├── CargoLock.cs
│ │ │ ├── CargoMetadata.cs
│ │ │ ├── CargoPackage.cs
│ │ │ ├── CargoSbom.cs
│ │ │ └── CargoToml.cs
│ │ ├── DependencySpecification.cs
│ │ ├── InvalidRustTomlFileException.cs
│ │ ├── RustCliDetector.cs
│ │ ├── RustCrateDetector.cs
│ │ └── RustSbomDetector.cs
│ ├── spdx
│ │ └── Spdx22ComponentDetector.cs
│ ├── swiftpm
│ │ ├── Contracts
│ │ │ └── SwiftResolvedFile.cs
│ │ └── SwiftResolvedComponentDetector.cs
│ ├── vcpkg
│ │ ├── Contracts
│ │ │ ├── Annotation.cs
│ │ │ ├── Package.cs
│ │ │ └── VcpkgSBOM.cs
│ │ └── VcpkgComponentDetector.cs
│ └── yarn
│ │ ├── Contracts
│ │ ├── YarnBerryDependencyMeta.cs
│ │ ├── YarnBerryLockfile.cs
│ │ ├── YarnBerryLockfileEntry.cs
│ │ ├── YarnBerryLockfileMetadata.cs
│ │ ├── YarnBerryPeerDependencyMeta.cs
│ │ └── YarnBerryTypeConverter.cs
│ │ ├── IYarnLockFileFactory.cs
│ │ ├── IYarnLockParser.cs
│ │ ├── InvalidYarnLockFileException.cs
│ │ ├── Parsers
│ │ ├── IYarnBlockFile.cs
│ │ ├── YarnBlock.cs
│ │ ├── YarnBlockFile.cs
│ │ └── YarnLockParser.cs
│ │ ├── YarnDependency.cs
│ │ ├── YarnEntry.cs
│ │ ├── YarnLockComponentDetector.cs
│ │ ├── YarnLockFile.cs
│ │ ├── YarnLockFileFactory.cs
│ │ └── YarnLockVersion.cs
├── Microsoft.ComponentDetection.Orchestrator
│ ├── ArgumentHelper.cs
│ ├── Commands
│ │ ├── BaseSettings.cs
│ │ ├── Interceptor.cs
│ │ ├── ListDetectorsCommand.cs
│ │ ├── ListDetectorsSettings.cs
│ │ ├── ScanCommand.cs
│ │ └── ScanSettings.cs
│ ├── DetectorRestrictions.cs
│ ├── DetectorRunResult.cs
│ ├── Exceptions
│ │ ├── InvalidDetectorCategoriesException.cs
│ │ └── InvalidDetectorFilterException.cs
│ ├── Experiments
│ │ ├── Configs
│ │ │ ├── Go117DetectorExperiment.cs
│ │ │ ├── IExperimentConfiguration.cs
│ │ │ ├── RustCliDetectorExperiment.cs
│ │ │ ├── RustSbomVsCliExperiment.cs
│ │ │ ├── RustSbomVsCrateExperiment.cs
│ │ │ └── SimplePipExperiment.cs
│ │ ├── DefaultExperimentProcessor.cs
│ │ ├── DetectorExperiments.cs
│ │ ├── ExperimentComponentComparer.cs
│ │ ├── ExperimentService.cs
│ │ ├── IExperimentProcessor.cs
│ │ ├── IExperimentService.cs
│ │ └── Models
│ │ │ ├── ExperimentComponent.cs
│ │ │ ├── ExperimentDiff.cs
│ │ │ └── ExperimentResults.cs
│ ├── Extensions
│ │ ├── CommaDelimitedConverter.cs
│ │ ├── KeyValueDelimitedConverter.cs
│ │ ├── SemicolonDelimitedConverter.cs
│ │ ├── ServiceCollectionExtensions.cs
│ │ ├── TypeRegistrar.cs
│ │ └── TypeResolver.cs
│ ├── IArgumentHelper.cs
│ ├── LoggingEnricher.cs
│ ├── Microsoft.ComponentDetection.Orchestrator.csproj
│ └── Services
│ │ ├── DetectorProcessingResult.cs
│ │ ├── DetectorProcessingService.cs
│ │ ├── DetectorRestrictionService.cs
│ │ ├── GraphTranslation
│ │ ├── DefaultGraphTranslationService.cs
│ │ ├── GraphTranslationUtility.cs
│ │ └── IGraphTranslationService.cs
│ │ ├── IDetectorProcessingService.cs
│ │ ├── IDetectorRestrictionService.cs
│ │ ├── IScanExecutionService.cs
│ │ └── ScanExecutionService.cs
└── Microsoft.ComponentDetection
│ ├── Microsoft.ComponentDetection.csproj
│ └── Program.cs
└── test
├── .editorconfig
├── Directory.Build.props
├── Microsoft.ComponentDetection.Common.Tests
├── AsyncExceptionTests.cs
├── BaseDetectionTelemetryRecordTests.cs
├── CommandLineInvocationServiceTests.cs
├── ComponentRecorderTests.cs
├── ComponentStreamEnumerableTests.cs
├── ConsoleWritingServiceTests.cs
├── CreateDirectoryTraversalStructure.ps1
├── DependencyGraphTests.cs
├── DependencyScopeComparerTests.cs
├── DirectoryUtilityServiceTests.cs
├── DockerReferenceUtilityTests.cs
├── DockerServiceTests.cs
├── EnvironmentVariableServiceTests.cs
├── FileEnumerationTests.cs
├── FileUtilityServiceTests.cs
├── FileWritingServiceTests.cs
├── LazyComponentStreamTests.cs
├── Microsoft.ComponentDetection.Common.Tests.csproj
├── PathUtilityServiceTests.cs
├── PatternMatchingUtilityTests.cs
├── Resources
│ ├── __pycache__
│ │ └── testing.pyc
│ └── test-file-duplicate.txt
├── SafeFileEnumerableTests.cs
├── StringUtilitiesTests.cs
└── TabularStringFormatTests.cs
├── Microsoft.ComponentDetection.Contracts.Tests
├── DetectedComponentTests.cs
├── FileComponentDetectorWithCleanupTests.cs
├── Microsoft.ComponentDetection.Contracts.Tests.csproj
├── PurlGenerationTests.cs
├── ScanResultSerializationTests.cs
└── TypedComponentSerializationTests.cs
├── Microsoft.ComponentDetection.Detectors.Tests
├── ComponentDetectorTests.cs
├── ConanLockComponentDetectorTests.cs
├── CondaLockComponentDetectorTests.cs
├── DotNetComponentDetectorTests.cs
├── Go117ComponentDetectorTests.cs
├── GoComponentDetectorTests.cs
├── GoComponentTests.cs
├── GradleComponentDetectorTests.cs
├── GradleTestUtilities.cs
├── IvyDetectorTests.cs
├── LinuxContainerDetectorTests.cs
├── LinuxScannerTests.cs
├── MavenCommandServiceTests.cs
├── MavenParsingUtilitiesTests.cs
├── MavenStyleDependencyGraphParserTests.cs
├── MavenTestUtilities.cs
├── Microsoft.ComponentDetection.Detectors.Tests.csproj
├── Mocks
│ ├── GradlewDependencyOutput.txt
│ ├── Invalid
│ │ └── invalid.component-detection-pip-report.json
│ ├── MvnCliDependencyOutput.txt
│ ├── TestResources.Designer.cs
│ ├── TestResources.resx
│ ├── pip_report_jupyterlab.json
│ ├── pip_report_multi_pkg.json
│ ├── pip_report_simple_extras.json
│ ├── pip_report_single_pkg.json
│ ├── pip_report_single_pkg_bad_version.json
│ ├── pip_report_single_pkg_invalid_pkg_version.json
│ └── test.component-detection-pip-report.json
├── MvnCliDetectorTests.cs
├── NpmDetectorTests.cs
├── NpmDetectorWithRootsTests.cs
├── NpmLockfile3DetectorTests.cs
├── NpmTestUtilities.cs
├── NpmUtilitiesTests.cs
├── NuGetComponentDetectorTests.cs
├── NuGetNuspecUtilitiesTests.cs
├── NuGetProjectModelProjectCentricComponentDetectorTests.cs
├── NugetTestUtilities.cs
├── PipCommandServiceTests.cs
├── PipComponentDetectorTests.cs
├── PipDependencySpecifierTests.cs
├── PipReportComponentDetectorTests.cs
├── PipReportUtilitiesTests.cs
├── PipResolverTests.cs
├── PnpmDetectorTests.cs
├── PnpmParsingUtilitiesTest.cs
├── PodDetectorTest.cs
├── PoetryComponentDetectorTests.cs
├── PyPiClientTests.cs
├── PythonCommandServiceTests.cs
├── PythonVersionTests.cs
├── Resources
│ ├── project.assets_1_1_console.json
│ ├── project.assets_1_1_web.json
│ ├── project.assets_2_1_web.json
│ ├── project_assets_2_2.json
│ ├── project_assets_2_2_additional.json
│ ├── project_assets_3_1.json
│ ├── project_assets_42_15_web.json
│ ├── project_assets_6_0_8_0_multi_framework.json
│ ├── project_assets_8_0_multi_framework.json
│ ├── project_assets_8_0_web.json
│ └── project_assets_packageDownload.json
├── RubyDetectorTest.cs
├── RustCliDetectorTests.cs
├── RustCrateDetectorTests.cs
├── RustDependencySpecifierTest.cs
├── RustSbomDetectorTests.cs
├── SPDX22ComponentDetectorTests.cs
├── SimplePipComponentDetectorTests.cs
├── SimplePypiClientTests.cs
├── SimplePythonResolverTests.cs
├── SwiftComponentTests.cs
├── SwiftResolvedDetectorTests.cs
├── TestFiles
│ └── go_WithLocalReferences.mod
├── Utilities
│ ├── ComponentRecorderTestUtilities.cs
│ ├── EnumerableStringComparer.cs
│ └── TestUtilityExtensions.cs
├── VcpkgComponentDetectorTests.cs
├── Yarn
│ └── YarnBerryTypeConverterTests.cs
├── YarnBlockFileTests.cs
├── YarnLockDetectorTests.cs
├── YarnParserTests.cs
├── YarnTestUtilities.cs
└── nuget
│ └── NuGetPackagesConfigDetectorTests.cs
├── Microsoft.ComponentDetection.Orchestrator.Tests
├── Commands
│ ├── BaseSettingsTests.cs
│ ├── InterceptorTests.cs
│ ├── ListDetectorCommandTests.cs
│ ├── ScanCommandTests.cs
│ └── ScanSettingsTests.cs
├── Experiments
│ ├── DefaultExperimentProcessorTests.cs
│ ├── ExperimentConfigTests.cs
│ ├── ExperimentDiffTests.cs
│ ├── ExperimentResultsTests.cs
│ ├── ExperimentServiceTests.cs
│ └── ExperimentTestUtils.cs
├── Extensions
│ ├── CommaDelimitedConverterTests.cs
│ ├── KeyValueDelimitedConverterTests.cs
│ ├── SemicolonDelimitedConverterTests.cs
│ └── TypeRegistrarTests.cs
├── GraphTranslationUtilityTests.cs
├── LoggingEnricherTests.cs
├── Microsoft.ComponentDetection.Orchestrator.Tests.csproj
├── Services
│ ├── BcdeScanExecutionServiceTests.cs
│ ├── DefaultGraphTranslationServiceTests.cs
│ ├── DetectorProcessingServiceTests.cs
│ └── DetectorRestrictionServiceTests.cs
└── TelemetryHelper.cs
├── Microsoft.ComponentDetection.TestsUtilities
├── Attributes
│ ├── SkipTestIfNotWindowsAttribute.cs
│ └── SkipTestOnWindowsAttribute.cs
├── BaseDetectorTest.cs
├── DetectorTestUtilityBuilder.cs
├── EnumerableStringComparer.cs
├── ExtensionMethods.cs
└── Microsoft.ComponentDetection.TestsUtilities.csproj
└── Microsoft.ComponentDetection.VerificationTests
├── ComponentDetectionIntegrationTests.cs
├── JsonSchemaTests.cs
├── Microsoft.ComponentDetection.VerificationTests.csproj
└── resources
├── VerificationTest.ps1
├── cocoapods
├── simple
│ ├── Podfile
│ └── Podfile.lock
└── tree
│ └── Podfile
├── conan
├── conanPythonFile
│ ├── conan.lock
│ └── conanfile.py
└── conanTextFile
│ ├── conan.lock
│ └── conanfile.txt
├── conda
└── conda-lock.yml
├── dockerFiles
├── Dockerfile
├── alpine.dockerfile
├── atlassian.dockerfile
├── python.dockerfile
└── ubuntu.dockerfile
├── go
├── go.mod
├── go.sum
└── main.go
├── gradle
├── .gitignore
├── build.gradle
└── buildscript-gradle.lockfile
├── ivy
└── ivy.xml
├── maven
├── .gitignore
├── lib
│ └── pom.xml
└── pom.xml
├── npm
├── .gitignore
├── lockfile
│ ├── package-lock.json
│ └── package.json
├── lockfile3
│ ├── package-lock.json
│ └── package.json
├── no-lockfile
│ ├── .gitignore
│ └── package.json
└── shrinkwrap
│ ├── .gitignore
│ ├── npm-shrinkwrap.json
│ └── package.json
├── nuget
├── nuspec
│ ├── NuGet.config
│ └── TestProject.nuspec
├── packages-config
│ └── packages.config
└── project-assets
│ └── project.assets.json
├── pip
├── fallback
│ └── requirements.txt
├── index-removal
│ └── requirements.txt
├── parallel
│ ├── parallel-test-1
│ │ └── requirements.txt
│ ├── parallel-test-2
│ │ └── requirements.txt
│ ├── parallel-test-3
│ │ └── requirements.txt
│ ├── parallel-test-4
│ │ └── requirements.txt
│ └── parallel-test-5
│ │ └── requirements.txt
├── pre-generated
│ ├── invalid
│ │ ├── component-detection-pip-report.json
│ │ └── requirements.txt
│ ├── multiple
│ │ ├── 1.component-detection-pip-report.json
│ │ ├── a.component-detection-pip-report.json
│ │ └── requirements.txt
│ └── simple
│ │ ├── component-detection-pip-report.json
│ │ └── requirements.txt
├── pytestresultpkg
│ └── python
│ │ ├── setup.py
│ │ └── src
│ │ └── pytest_pyresultreport
│ │ ├── __init__.py
│ │ └── plugin.py
├── requirements.txt
├── roots
│ └── requirements.txt
└── simple-extras
│ └── requirements.txt
├── pnpm
├── README.md
├── v5
│ ├── package.json
│ └── pnpm-lock.yaml
└── v6
│ ├── package.json
│ └── pnpm-lock.yaml
├── poetry
├── poetry.lock
└── pyproject.toml
├── ruby
├── Gemfile
├── Gemfile.lock
└── component-detection.gemspec
├── rust
├── standard
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── main.rs
│ └── target
│ │ ├── .rustc_info.json
│ │ └── CACHEDIR.TAG
└── workspaces
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── lib
│ ├── Cargo.toml
│ └── main.rs
├── spdx
└── manifest.spdx.json
├── swift
└── Package.resolved
├── vcpkg
├── nlohmann-json
│ └── vcpkg.spdx.json
└── tinyxml2
│ └── vcpkg.spdx.json
└── yarn
├── .gitignore
├── v1
├── package.json
└── yarn.lock
└── v2
├── .gitignore
├── .yarn
└── releases
│ └── yarn-3.1.1.cjs
├── .yarnrc.yml
├── package.json
└── yarn.lock
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3 | "name": "Component Detection",
4 | "image": "mcr.microsoft.com/vscode/devcontainers/dotnet:8.0",
5 | "runArgs": ["--init"],
6 | "extensions": [
7 | "eamodio.gitlens",
8 | "github.vscode-pull-request-github",
9 | "ms-dotnettools.csharp"
10 | ],
11 | "postCreateCommand": "dotnet restore",
12 | "features": {
13 | "docker-from-docker": "latest"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | [Bb]in/
2 | [Oo]bj/
3 |
--------------------------------------------------------------------------------
/.git-blame-ignore-revs:
--------------------------------------------------------------------------------
1 | # refactor: use file scoped namespaces
2 | 0f3fa8a84488f6f8878532d1e5812580998a045e
3 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Relevant documentation for CODEOWNERS file: https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
2 |
3 | # All files in this repo are owned by ose-component-detection-maintainers team.
4 |
5 | # Reviewers are then assigned round-robin style: https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/managing-code-review-assignment-for-your-team
6 |
7 | * @microsoft/ose-component-detection-maintainers
8 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | name: Feature request
2 | about: Suggest an idea for this project
3 | title: '[Feature]: '
4 | labels: ['triage', 'enhancement']
5 |
6 | body:
7 | - type: markdown
8 | attributes:
9 | value: |
10 | Thanks for taking the time to fill out this feature request!
11 | - type: input
12 | id: problem
13 | attributes:
14 | label: Is your feature request related to a problem? Please describe.
15 | description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
16 | - type: input
17 | id: summary
18 | attributes:
19 | label: Describe the feature
20 | description: A clear and concise description of what you want to happen.
21 | validations:
22 | required: true
23 | - type: textarea
24 | id: context
25 | attributes:
26 | label: Additional context, alternatives considered, etc.
27 | description: Add any other context or screenshots about the feature request here.
28 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/new_detector_template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #### New Detector Checklist
6 |
7 | - [ ] I have gone through the docs for creating a new detector [here](https://github.com/microsoft/component-detection/blob/main/docs/creating-a-new-detector.md)
8 | - [ ] My new detector implements `IDefaultOffComponentDetector`
9 | - [ ] I have created a PR to the [verification repo](https://github.com/microsoft/componentdetection-verification) with components that my new detector can find
10 | - [ ] (If necessary) I have updated the [Feature Overview](https://github.com/microsoft/component-detection/blob/main/README.md#feature-overview) table in the README
11 |
--------------------------------------------------------------------------------
/.github/codecov.yml:
--------------------------------------------------------------------------------
1 | # ref: https://docs.codecov.com/docs/codecovyml-reference
2 | coverage:
3 | range: 60..80
4 | round: down
5 | precision: 1
6 | status:
7 | # ref: https://docs.codecov.com/docs/commit-status
8 | project:
9 | default:
10 | # Avoid false negatives
11 | threshold: 1%
12 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: 'github-actions'
4 | directory: '/'
5 | schedule:
6 | interval: 'daily'
7 | reviewers:
8 | - "JamieMagee"
9 | labels:
10 | - "type:ci"
11 |
12 | - package-ecosystem: 'nuget'
13 | directory: '/'
14 | schedule:
15 | interval: 'daily'
16 | # Disable version updates for nuget (doesn't impact security updates)
17 | # https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#open-pull-requests-limit
18 | open-pull-requests-limit: 0
19 |
--------------------------------------------------------------------------------
/.github/release-drafter.yml:
--------------------------------------------------------------------------------
1 | # release-drafter automatically creates a draft release for you each time you complete a PR in the main branch.
2 | # It uses GitHub labels to categorize changes (See categories) and draft the release.
3 | # release-drafter also generates a version for your release based on GitHub labels. You can add a label of 'major',
4 | # 'minor' or 'patch' to determine which number in the version to increment.
5 | # You may need to add these labels yourself.
6 | # See https://github.com/release-drafter/release-drafter
7 | name-template: 'v$RESOLVED_VERSION'
8 | tag-template: 'v$RESOLVED_VERSION'
9 | change-template: '- $TITLE by @$AUTHOR (#$NUMBER)'
10 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
11 | no-changes-template: '- No changes'
12 | categories:
13 | - title: '📝 Documentation'
14 | labels:
15 | - 'type:docs'
16 | - title: '🚀 New Features'
17 | labels:
18 | - 'type:feature'
19 | - title: '🐛 Bug Fixes'
20 | labels:
21 | - 'type:bug'
22 | - title: '🧰 Maintenance'
23 | labels:
24 | - 'type:ci'
25 | - 'type:refactor'
26 | version-resolver:
27 | major:
28 | labels:
29 | - 'version:major'
30 | minor:
31 | labels:
32 | - 'version:minor'
33 | patch:
34 | labels:
35 | - 'version:patch'
36 | default: patch
37 | template: |
38 | ## ⚙️ Changes
39 | $CHANGES
40 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | pull_request:
6 |
7 | permissions:
8 | contents: read
9 |
10 | jobs:
11 | build:
12 | strategy:
13 | matrix:
14 | os: [ubuntu-latest, windows-latest]
15 |
16 | runs-on: ${{ matrix.os }}
17 |
18 | env:
19 | # Set the build number in MinVer.
20 | MINVERBUILDMETADATA: build.${{github.run_number}}
21 |
22 | steps:
23 | - name: Checkout repository
24 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
25 | with:
26 | fetch-depth: 0
27 |
28 | - name: Setup .NET
29 | uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0
30 |
31 | - name: Restore packages
32 | run: dotnet restore
33 |
34 | - name: Build
35 | run: dotnet build --no-restore --configuration Debug
36 |
37 | - name: Run tests
38 | run: dotnet test --no-build --configuration Debug --collect:"Code Coverage;Format=cobertura;CoverageFileName=coverage.cobertura.xml"
39 |
40 | - name: Upload coverage reports to Codecov
41 | uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
42 | env:
43 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
44 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL"
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 | schedule:
9 | - cron: '27 10 * * 1'
10 |
11 | permissions:
12 | contents: read
13 |
14 | jobs:
15 | analyze:
16 | name: Analyze
17 | runs-on: ubuntu-latest
18 | permissions:
19 | actions: read
20 | contents: read
21 | security-events: write
22 |
23 | steps:
24 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
25 | with:
26 | fetch-depth: 0
27 |
28 | - name: Initialize CodeQL
29 | uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
30 | with:
31 | languages: 'csharp'
32 | debug: true
33 |
34 | - name: Autobuild
35 | uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
36 |
37 | - name: Perform CodeQL Analysis
38 | uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
39 |
--------------------------------------------------------------------------------
/.github/workflows/detector-version-bump-reminder.yml:
--------------------------------------------------------------------------------
1 | name: "Detector version bump reminder"
2 | on:
3 | push:
4 | paths:
5 | - 'src/Microsoft.ComponentDetection.Detectors/**'
6 |
7 | permissions:
8 | pull-requests: write
9 |
10 | jobs:
11 | comment:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2
15 | with:
16 | repo-token: ${{ secrets.GITHUB_TOKEN }}
17 | message: |
18 | 👋 Hi! It looks like you modified some files in the `Detectors` folder.
19 | You may need to bump the detector versions if any of the following scenarios apply:
20 | * The detector detects more or fewer components than before
21 | * The detector generates different parent/child graph relationships than before
22 | * The detector generates different `devDependencies` values than before
23 |
24 | If none of the above scenarios apply, feel free to ignore this comment 🙂
25 |
--------------------------------------------------------------------------------
/.github/workflows/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name: Release Drafter
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | workflow_dispatch:
8 |
9 | permissions:
10 | contents: read
11 |
12 | jobs:
13 | update_release_draft:
14 | permissions:
15 | contents: write
16 | pull-requests: read
17 | runs-on: ubuntu-latest
18 | steps:
19 | - uses: release-drafter/release-drafter@3f0f87098bd6b5c5b9a36d49c41d998ea58f9348 # v6
20 | with:
21 | disable-autolabeler: true
22 | env:
23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | *.*~
3 | project.lock.json
4 | .DS_Store
5 | *.pyc
6 |
7 | # FAKE Build
8 | .paket
9 | .fake
10 | .patcache
11 | LegacyPackage.nuspec
12 |
13 | # Visual Studio Code
14 | **/.vscode/*
15 | !launch.json
16 | !tasks.json
17 | **/.ionide/*
18 |
19 | # User-specific files
20 | *.suo
21 | *.user
22 | *.userosscache
23 | *.sln.docstates
24 | ComponentDetection/src/Microsoft.ComponentDetection.Loader/Properties/launchSettings.json
25 |
26 | # Diff work files
27 | *.orig
28 |
29 | # Node excludes
30 | node_modules/
31 | dist/
32 | dist-nuget/
33 |
34 | # Build results
35 | [Dd]ebug/
36 | [Dd]ebugPublic/
37 | [Rr]elease/
38 | [Rr]eleases/
39 | x64/
40 | x86/
41 | bld/
42 | [Bb]in/
43 | [Oo]bj/
44 | msbuild.log
45 | msbuild.err
46 | msbuild.wrn
47 | *.vsix
48 | TestResults/
49 | coverage.cobertura.xml
50 |
51 | # Visual Studio
52 | .vs/
53 | launchSettings.json
54 |
55 | # Dev nupkgs
56 | dev-source
57 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to find out which attributes exist for C# debugging
3 | // Use hover for the description of the existing attributes
4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": ".NET Core Launch (console)",
9 | "type": "coreclr",
10 | "request": "launch",
11 | "preLaunchTask": "build",
12 | // If you have changed target frameworks, make sure to update the program path.
13 | "program": "${workspaceFolder}/src/Microsoft.ComponentDetection/bin/Debug/netcoreapp3.1/Microsoft.ComponentDetection.dll",
14 | "args": ["scan", "--Debug", "--Verbosity", "Verbose", "--Output", "${workspaceFolder}/scan-output", "--SourceDirectory", "${workspaceFolder}"],
15 | "cwd": "${workspaceFolder}/src/Microsoft.ComponentDetection",
16 | // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
17 | "console": "internalConsole",
18 | "stopAtEntry": false
19 | },
20 | {
21 | "name": ".NET Core Attach",
22 | "type": "coreclr",
23 | "request": "attach",
24 | "processId": "${command:pickProcess}"
25 | }
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | preview.0
6 | v
7 | normal
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/sdk:6.0-cbl-mariner2.0@sha256:a153d63a5f0eb33d217e0740d57a97b001f762b14b340f647a0819c82a9552ff AS build
2 | WORKDIR /app
3 | COPY . .
4 | RUN dotnet publish -c Release -o out \
5 | -r linux-x64 \
6 | -p:MinVerSkip=true \
7 | --self-contained true \
8 | -p:PublishReadyToRun=false \
9 | -p:IncludeNativeLibrariesForSelfExtract=true \
10 | -p:PublishSingleFile=true \
11 | ./src/Microsoft.ComponentDetection
12 |
13 | FROM mcr.microsoft.com/dotnet/runtime-deps:6.0-cbl-mariner2.0@sha256:c3e48fb02e9b6956d0795a3bebd583198978447a8dece82fce1f652759f78b39 AS runtime
14 | WORKDIR /app
15 | COPY --from=build /app/out ./
16 |
17 | RUN tdnf install -y \
18 | golang \
19 | moby-engine \
20 | maven \
21 | pnpm \
22 | poetry \
23 | python
24 |
25 | ENTRYPOINT ["/app/Microsoft.ComponentDetection"]
26 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) Microsoft Corporation.
2 |
3 | MIT License
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/detectors/conan.md:
--------------------------------------------------------------------------------
1 | # Conan Detection
2 | ## Requirements
3 | Conan detection relies on a conan.lock file being present.
4 |
5 | ## Detection strategy
6 | Conan detection is performed by parsing every **conan.lock** found under the scan directory.
7 |
8 | ## Known limitations
9 | Conan detection will not work if lock files are not being used or not yet generated. So ensure to run the conan build to generate the lock file(s) before running the scan.
10 |
11 | Full dependency graph generation is not supported. However, dependency relationships identified/present in the **conan.lock** file is captured.
12 |
--------------------------------------------------------------------------------
/docs/detectors/conda.md:
--------------------------------------------------------------------------------
1 | # Conda Detection
2 |
3 | ## Requirements
4 |
5 | The lock file produced by `conda-lock` will be used. Accordingly the only requirement is that this file is present.
6 |
7 | ## Default Detection strategy
8 |
9 | The detector will parse `conda-lock.json` and `*.conda-lock.json` files. The full dependency graph is generated based on the information in these files.
10 |
--------------------------------------------------------------------------------
/docs/detectors/gradle.md:
--------------------------------------------------------------------------------
1 | # Gradle Detection
2 |
3 | ## Requirements
4 |
5 | Gradle detection depends on the following to successfully run:
6 |
7 | - Gradle 7 or prior using [Single File lock](https://docs.gradle.org/6.8.1/userguide/dependency_locking.html#single_lock_file_per_project)
8 | - One or more `.lockfile` files
9 |
10 | ## Detection strategy
11 |
12 | Gradle detection is performed by parsing any `*.lockfile` found under the scan directory.
13 |
14 | ## Known limitations
15 |
16 | Gradle detection will not work if lock files are not being used.
17 |
18 | Dev dependency tagging is not supported.
19 |
20 | Full dependency graph generation is not supported.
21 |
--------------------------------------------------------------------------------
/docs/detectors/linux.md:
--------------------------------------------------------------------------------
1 | # Linux Detection
2 |
3 | ## Requirements
4 |
5 | Linux detection depends on the following:
6 |
7 | - [Docker](https://www.docker.com/)
8 |
9 | ## Detection strategy
10 |
11 | Linux package detection is performed by running [Syft](https://github.com/anchore/syft) and parsing the output.
12 | The output contains the package name, version, and the layer of the container in which it was found.
13 |
14 | ## Known limitations
15 |
16 | - Windows container scanning is not supported
17 |
--------------------------------------------------------------------------------
/docs/detectors/maven.md:
--------------------------------------------------------------------------------
1 | # Maven Detection
2 |
3 | ## Requirements
4 |
5 | Maven detection depends on the following to successfully run:
6 |
7 | - Maven CLI as part of your PATH. mvn should be runnable from a given command line.
8 | - Maven Dependency Plugin (installed with Maven).
9 | - One or more `pom.xml` files.
10 |
11 | ## Detection strategy
12 |
13 | Maven detection is performed by running `mvn dependency:tree -f {pom.xml}` for each pom file and parsing down the results.
14 |
15 | Components tagged as a test dependency are marked as development dependencies.
16 |
17 | Full dependency graph generation is supported.
18 |
19 | ## Known limitations
20 |
21 | Maven detection will not run if `mvn` is unavailable.
22 |
23 | ## Environment Variables
24 |
25 | The environment variable `MvnCLIFileLevelTimeoutSeconds` is used to control the max execution time Mvn CLI is allowed to take per each `pom.xml` file. Default value, unbounded. This will restrict any spikes in scanning time caused by Mvn CLI during package restore. We suggest to restore the Maven packages beforehand, so that no network calls happen when executing "mvn dependency:tree" and the graph is captured quickly.
26 |
--------------------------------------------------------------------------------
/docs/detectors/pnpm.md:
--------------------------------------------------------------------------------
1 | # Pnpm detection
2 |
3 | ## Known limitations
4 |
5 | The Pnpm detector doesn't support the resolution of local dependencies
6 | like:
7 |
8 | - Link dependencies
9 | ```
10 | dependencies:
11 | '@learningclient/common': link:../common
12 | ```
13 |
14 | - File dependencies
15 | ```
16 | dependencies:
17 | file:./projects/gmc-bootstrapper.tgz
18 | ```
19 | These kind of components are ignored by the Pnpm detector.
20 |
21 | In the case of `link` dependencies that refer to a folder with a `package.json` file
22 | the component is then going to be detected by the `NpmComponentDetector`. This is going to happen
23 | only if the folder is inside the path that is been use for scanning.
24 |
--------------------------------------------------------------------------------
/docs/detectors/poetry.md:
--------------------------------------------------------------------------------
1 | # Poetry Detection
2 | ## Requirements
3 | Poetry detection relies on a poetry.lock file being present.
4 |
5 | ## Detection strategy
6 | Poetry detection is performed by parsing a poetry.lock found under the scan directory.
7 |
8 | ## Known limitations
9 | 1. Poetry detection will not work if lock files are not being used.
10 | 2. Dev dependencies are flagged as normal dependencies since it is not possible to determine whether or not
11 | a dependency is a development dependency via the lockfile alone.
12 |
13 | Full dependency graph generation is not supported.
14 |
--------------------------------------------------------------------------------
/docs/detectors/swift.md:
--------------------------------------------------------------------------------
1 | # Swift Package Manager Detection
2 |
3 | ## Requirements
4 |
5 | Swift Package Manager detection requires the following file to be present in the scan directory:
6 |
7 | - `Package.resolved` file
8 |
9 | ## Detection strategy
10 |
11 | The detector `SwiftResolvedComponentDetector` only parses the `Package.resolved` file to get the dependencies.
12 | This file contains a json representation of the resolved dependencies of the project with the transitive dependencies.
13 | The version, the url and commit hash of the dependencies are stored in this file.
14 |
15 | [This is the only reference in the Apple documentation to the `Package.resolved` file.][1]
16 |
17 | ## Known limitations
18 |
19 | Right now the detector does not support parsing `Package.swift` file to get the dependencies.
20 | It only supports parsing `Package.resolved` file.
21 | Some projects only commit the `Package.swift`, which is why it is planned to support parsing `Package.swift` in the future.
22 |
23 | [1]: https://docs.swift.org/package-manager/PackageDescription/PackageDescription.html#package-dependency
24 |
--------------------------------------------------------------------------------
/docs/detectors/vcpkg.md:
--------------------------------------------------------------------------------
1 | # vcpkg Detection
2 |
3 | ## Requirements
4 |
5 | vcpkg detection triggers off of `vcpkg.spdx.json` files found under the scan directory. You must use a version of vcpkg in your build that generates SBOM files (newer than 2022-05-05).
6 |
7 | ## Detection strategy
8 |
9 | The vcpkg detector searches for `vcpkg.spdx.json` files produced by vcpkg during the install process. These files are typically found under the installed packages directory in a path like `installed//share//vcpkg.spdx.json`. Each vcpkg port installes a separate `vcpkg.spdx.json` file[1].
10 |
11 | Because this detection strategy looks for the concrete files in the installed tree, it will accurately detect the precise packages used
12 | during this build and exclude packages optionally used on other platforms.
13 |
14 | ## Known limitations
15 |
16 | The vcpkg detector does not distinguish between direct dependencies and transitive dependencies. It also does not distinguish
17 | "development-only" dependencies that are not intended to impact the final shipping product.
18 |
19 | [1]: https://learn.microsoft.com/vcpkg/reference/software-bill-of-materials
20 |
--------------------------------------------------------------------------------
/docs/enable-default-off.md:
--------------------------------------------------------------------------------
1 | Whenever a detector implemenets the IDefaultOffDetector interface, it must be explicitly enabled using one of the following methods. This is intended to allow customers who want to test out the detectors in Beta and they should be warned that these detectors are not guaranteed to be completely accurate/functional
2 |
3 | # From CLI Run
4 | add the arg `--DetectorArgs =EnableIfDefaultOff` Additional Detectors can be added with a comma separator.
5 |
6 | eg:`--DetectorArgs Pip=EnableIfDefaultOff,GradlewCli=EnableIfDefaultOff`
7 |
8 |
--------------------------------------------------------------------------------
/docs/images/creating-a-new-detector/component-type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/creating-a-new-detector/component-type.png
--------------------------------------------------------------------------------
/docs/images/creating-a-new-detector/component-utilities.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/creating-a-new-detector/component-utilities.png
--------------------------------------------------------------------------------
/docs/images/creating-a-new-detector/detector-class.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/creating-a-new-detector/detector-class.png
--------------------------------------------------------------------------------
/docs/images/creating-a-new-detector/go-detector-test-utility.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/creating-a-new-detector/go-detector-test-utility.png
--------------------------------------------------------------------------------
/docs/images/creating-a-new-detector/multi-root-dependency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/creating-a-new-detector/multi-root-dependency.png
--------------------------------------------------------------------------------
/docs/images/creating-a-new-detector/npm-component.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/creating-a-new-detector/npm-component.png
--------------------------------------------------------------------------------
/docs/images/creating-a-new-detector/ruby-component-detector.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/creating-a-new-detector/ruby-component-detector.png
--------------------------------------------------------------------------------
/docs/images/creating-a-new-detector/single-root-dependency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/creating-a-new-detector/single-root-dependency.png
--------------------------------------------------------------------------------
/docs/images/creating-a-new-detector/test-projects.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/creating-a-new-detector/test-projects.png
--------------------------------------------------------------------------------
/docs/images/creating-a-new-detector/vs-projects.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/creating-a-new-detector/vs-projects.png
--------------------------------------------------------------------------------
/docs/images/readme/component-detection-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/readme/component-detection-screenshot.png
--------------------------------------------------------------------------------
/docs/images/readme/component-detection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/component-detection/2a41d42b4cbe93ae3047e067508e69fd2b901271/docs/images/readme/component-detection.png
--------------------------------------------------------------------------------
/docs/renewing-secrets.md:
--------------------------------------------------------------------------------
1 | # Renewing secrets
2 |
3 | Almost all of our [workflows](../.github/workflows) require secrets and those secrets can be invalidated, deleted or expired so we need to know how to renew them.
4 |
5 | The secrets in use today in the Component Detection repo can be found [here](https://github.com/microsoft/component-detection/settings/secrets):
6 |
7 | * GH_PRIVATE_REPO_PAT
8 |
9 | ## Renewing GH_PRIVATE_REPO_PAT
10 |
11 | 1. Click this link: https://github.com/settings/tokens/new
12 | 1. (Optional) Name the token COMPONENT_DETECTION_GH_PRIVATE_REPO_PAT. This will make things easier to track in the future
13 | 1. Check the following permissions:
14 | * Full `repo` scope
15 | * `read:packages` scope
16 | 1. Click **Generate token**
17 | 1. Copy and paste that token into notepad once you see it because it will disappear as soon as you leave the page
18 | 1. Enable SSO for Microsoft organizations for the token
19 | 1. In the [Component Detection secrets page](https://github.com/microsoft/component-detection/settings/secrets) click update on **GH_PRIVATE_REPO_PAT**
20 | 1. Paste in your new token
21 | 1. Click **Update Secret**
22 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "8.0.408",
4 | "rollForward": "latestMinor"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:base",
5 | "helpers:pinGitHubActionDigests",
6 | ":maintainLockFilesWeekly"
7 | ],
8 | "branchConcurrentLimit": 3
9 | }
10 |
--------------------------------------------------------------------------------
/src/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | true
7 | snupkg
8 |
9 |
10 |
11 | true
12 | true
13 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Column.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | public class Column
4 | {
5 | public int Width { get; set; }
6 |
7 | public string Header { get; set; }
8 |
9 | public string Format { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/ComponentComparer.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | using System.Collections.Generic;
4 | using Microsoft.ComponentDetection.Contracts.TypedComponent;
5 |
6 | ///
7 | /// Compares two s by their .
8 | ///
9 | public class ComponentComparer : EqualityComparer
10 | {
11 | ///
12 | /// Determines whether the specified objects are equal.
13 | ///
14 | /// The first object of type to compare.
15 | /// The second object of type to compare.
16 | /// true if the specified objects are equal; otherwise, false.
17 | public override bool Equals(TypedComponent x, TypedComponent y)
18 | {
19 | return x.Id.Equals(y.Id);
20 | }
21 |
22 | ///
23 | /// Returns a hash code for the specified object.
24 | ///
25 | /// The for which a hash code is to be returned.
26 | /// A hash code for the specified object.
27 | public override int GetHashCode(TypedComponent obj)
28 | {
29 | return obj.Id.GetHashCode();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/ComponentStream.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | using System.IO;
4 | using Microsoft.ComponentDetection.Contracts;
5 |
6 | ///
7 | public class ComponentStream : IComponentStream
8 | {
9 | ///
10 | public Stream Stream { get; set; }
11 |
12 | ///
13 | public string Pattern { get; set; }
14 |
15 | ///
16 | public string Location { get; set; }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/ConsoleWritingService.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | using System;
4 |
5 | public class ConsoleWritingService : IConsoleWritingService
6 | {
7 | public void Write(string content)
8 | {
9 | Console.Write(content);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/DependencyScopeComparer.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | using Microsoft.ComponentDetection.Contracts.BcdeModels;
4 |
5 | ///
6 | /// Merges dependnecy Scope in their order of Priority.
7 | /// Higher priority scope, as indicated by its lower enum value is given precendence.
8 | ///
9 | public static class DependencyScopeComparer
10 | {
11 | public static DependencyScope? GetMergedDependencyScope(DependencyScope? scope1, DependencyScope? scope2)
12 | {
13 | if (!scope1.HasValue)
14 | {
15 | return scope2;
16 | }
17 | else if (!scope2.HasValue)
18 | {
19 | return scope1;
20 | }
21 |
22 | return (int)scope1 < (int)scope2 ? scope1 : scope2;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/DirectoryItemFacade.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using Microsoft.ComponentDetection.Contracts;
6 |
7 | [DebuggerDisplay("{Name}")]
8 | public class DirectoryItemFacade
9 | {
10 | public string Name { get; set; }
11 |
12 | public List Directories { get; set; }
13 |
14 | public List Files { get; set; }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/DirectoryItemFacadeOptimized.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 |
6 | [DebuggerDisplay("{Name}")]
7 | public class DirectoryItemFacadeOptimized
8 | {
9 | public string Name { get; set; }
10 |
11 | public HashSet FileNames { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Exceptions/InvalidUserInputException.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Exceptions;
2 |
3 | using System;
4 |
5 | ///
6 | /// Exception thrown when the user input is invalid.
7 | ///
8 | public class InvalidUserInputException : Exception
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The message that describes the error.
14 | /// The exception that is the cause of the current exception.
15 | public InvalidUserInputException(string message, Exception innerException)
16 | : base(message, innerException)
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public InvalidUserInputException()
24 | {
25 | }
26 |
27 | ///
28 | /// Initializes a new instance of the class.
29 | ///
30 | /// The message that describes the error.
31 | public InvalidUserInputException(string message)
32 | : base(message)
33 | {
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/IConsoleWritingService.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | public interface IConsoleWritingService
4 | {
5 | void Write(string content);
6 | }
7 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/ISafeFileEnumerableFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using Microsoft.ComponentDetection.Contracts;
6 |
7 | /// Factory for generating safe file enumerables.
8 | public interface ISafeFileEnumerableFactory
9 | {
10 | /// Creates a "safe" file enumerable, which provides logging while evaluating search patterns on a known directory structure.
11 | /// The directory to search "from", e.g. the top level directory being searched.
12 | /// The patterns to use in the search.
13 | /// Predicate which indicates which directories should be excluded.
14 | /// A FileInfo enumerable that should be iterated over, containing all valid files given the input patterns and directory exclusions.
15 | IEnumerable CreateSafeFileEnumerable(DirectoryInfo directory, IEnumerable searchPatterns, ExcludeDirectoryPredicate directoryExclusionPredicate);
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/MatchedFile.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | using System.IO;
4 |
5 | public class MatchedFile
6 | {
7 | public FileInfo File { get; set; }
8 |
9 | public string Pattern { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Microsoft.ComponentDetection.Common.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Resources.resx
17 | True
18 | True
19 |
20 |
21 | Resources.Designer.cs
22 | ResXFileCodeGenerator
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/SafeFileEnumerableFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using Microsoft.ComponentDetection.Contracts;
6 | using Microsoft.Extensions.Logging;
7 |
8 | public class SafeFileEnumerableFactory : ISafeFileEnumerableFactory
9 | {
10 | private readonly IPathUtilityService pathUtilityService;
11 | private readonly ILogger logger;
12 |
13 | public SafeFileEnumerableFactory()
14 | {
15 | }
16 |
17 | public SafeFileEnumerableFactory(IPathUtilityService pathUtilityService, ILogger logger)
18 | {
19 | this.pathUtilityService = pathUtilityService;
20 | this.logger = logger;
21 | }
22 |
23 | public IEnumerable CreateSafeFileEnumerable(DirectoryInfo directory, IEnumerable searchPatterns, ExcludeDirectoryPredicate directoryExclusionPredicate)
24 | {
25 | return new SafeFileEnumerable(directory, searchPatterns, this.logger, this.pathUtilityService, directoryExclusionPredicate);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/ScanType.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | public enum ScanType
4 | {
5 | Invalid = 0,
6 | Register = 1,
7 | LogOnly = 2,
8 | }
9 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Attributes/MetricAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Attributes;
2 |
3 | using System;
4 |
5 | ///
6 | /// Denotes that a telemetry property should be treated as a Metric (numeric) value
7 | ///
8 | /// It is up to the implementing Telemetry Service to interpret this value.
9 | ///
10 | [AttributeUsage(AttributeTargets.Property)]
11 | public sealed class MetricAttribute : Attribute
12 | {
13 | }
14 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/ITelemetryService.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry;
2 |
3 | using Microsoft.ComponentDetection.Common.Telemetry.Records;
4 |
5 | public interface ITelemetryService
6 | {
7 | ///
8 | /// Post a record to the telemetry service.
9 | ///
10 | /// The telemetry record to post.
11 | void PostRecord(IDetectionTelemetryRecord record);
12 |
13 | ///
14 | /// Flush all telemetry events from the queue (usually called on shutdown to clear the queue).
15 | ///
16 | void Flush();
17 |
18 | ///
19 | /// Sets the telemetry mode for the service.
20 | ///
21 | void SetMode(TelemetryMode mode);
22 | }
23 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/CommandLineInvocationTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | using System;
4 | using Microsoft.ComponentDetection.Contracts;
5 |
6 | public class CommandLineInvocationTelemetryRecord : BaseDetectionTelemetryRecord
7 | {
8 | public override string RecordName => "CommandLineInvocation";
9 |
10 | public string PathThatWasRan { get; set; }
11 |
12 | public string Parameters { get; set; }
13 |
14 | public int? ExitCode { get; set; }
15 |
16 | public string StandardError { get; set; }
17 |
18 | public string UnhandledException { get; set; }
19 |
20 | internal void Track(CommandLineExecutionResult result, string path, string parameters)
21 | {
22 | this.ExitCode = result.ExitCode;
23 | this.StandardError = result.StdErr;
24 | this.TrackCommon(path, parameters);
25 | }
26 |
27 | internal void Track(Exception ex, string path, string parameters)
28 | {
29 | this.ExitCode = -1;
30 | this.UnhandledException = ex.ToString();
31 | this.TrackCommon(path, parameters);
32 | }
33 |
34 | private void TrackCommon(string path, string parameters)
35 | {
36 | this.PathThatWasRan = path;
37 | this.Parameters = parameters;
38 | this.StopExecutionTimer();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/DependencyGraphTranslationRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | using System;
4 |
5 | public class DependencyGraphTranslationRecord : BaseDetectionTelemetryRecord
6 | {
7 | public override string RecordName => "DependencyGraphTranslationRecord";
8 |
9 | public string DetectorId { get; set; }
10 |
11 | public TimeSpan? TimeToAddRoots { get; set; }
12 |
13 | public TimeSpan? TimeToAddAncestors { get; set; }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/DetectedComponentScopeRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | using System.Runtime.CompilerServices;
4 |
5 | public class DetectedComponentScopeRecord : BaseDetectionTelemetryRecord
6 | {
7 | public override string RecordName => "ComponentScopeRecord";
8 |
9 | public int? MavenProvidedScopeCount { get; set; } = 0;
10 |
11 | [MethodImpl(MethodImplOptions.Synchronized)]
12 | public void IncrementProvidedScopeCount()
13 | {
14 | this.MavenProvidedScopeCount++;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/DetectorExecutionTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class DetectorExecutionTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "DetectorExecution";
6 |
7 | public string DetectorId { get; set; }
8 |
9 | public int? DetectedComponentCount { get; set; }
10 |
11 | public int? ExplicitlyReferencedComponentCount { get; set; }
12 |
13 | public int? ReturnCode { get; set; }
14 |
15 | public bool IsExperimental { get; set; }
16 |
17 | public string ExperimentalInformation { get; set; }
18 |
19 | public string AdditionalTelemetryDetails { get; set; }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/DockerServiceImageExistsLocallyTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class DockerServiceImageExistsLocallyTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "DockerServiceImageExistsLocally";
6 |
7 | public string Image { get; set; }
8 |
9 | public string ImageInspectResponse { get; set; }
10 |
11 | public string ExceptionMessage { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/DockerServiceInspectImageTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class DockerServiceInspectImageTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "DockerServiceInspectImage";
6 |
7 | public string Image { get; set; }
8 |
9 | public string BaseImageDigest { get; set; }
10 |
11 | public string BaseImageRef { get; set; }
12 |
13 | public string ImageInspectResponse { get; set; }
14 |
15 | public string ExceptionMessage { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/DockerServiceSystemInfoTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class DockerServiceSystemInfoTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "DockerServiceSystemInfo";
6 |
7 | public string SystemInfo { get; set; }
8 |
9 | public string ExceptionMessage { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/DockerServiceTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class DockerServiceTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "DockerService";
6 |
7 | public string Image { get; set; }
8 |
9 | public string Command { get; set; }
10 |
11 | public string Container { get; set; }
12 |
13 | public string Stdout { get; set; }
14 |
15 | public string Stderr { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/DockerServiceTryPullImageTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class DockerServiceTryPullImageTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "DockerServiceTryPullImage";
6 |
7 | public string Image { get; set; }
8 |
9 | public string CreateImageProgress { get; set; }
10 |
11 | public string ExceptionMessage { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/FailedParsingFileRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class FailedParsingFileRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "FailedParsingFile";
6 |
7 | public string DetectorId { get; set; }
8 |
9 | public string FilePath { get; set; }
10 |
11 | public string ExceptionMessage { get; set; }
12 |
13 | public string StackTrace { get; set; }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/GoGraphTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class GoGraphTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "GoGraph";
6 |
7 | public string ProjectRoot { get; set; }
8 |
9 | public bool IsGoAvailable { get; set; }
10 |
11 | public bool WasGraphSuccessful { get; set; }
12 |
13 | public bool WasGoCliDisabled { get; set; }
14 |
15 | public bool WasGoFallbackStrategyUsed { get; set; }
16 |
17 | public bool DidGoCliCommandFail { get; set; }
18 |
19 | public string GoCliCommandError { get; set; }
20 |
21 | public string GoModVersion { get; set; }
22 |
23 | public string ExceptionMessage { get; set; }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/GoReplaceTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class GoReplaceTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "GoReplace";
6 |
7 | public string GoModPathAndVersion { get; set; }
8 |
9 | public string GoModReplacement { get; set; }
10 |
11 | public string ExceptionMessage { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/IDetectionTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | using System;
4 |
5 | public interface IDetectionTelemetryRecord : IDisposable
6 | {
7 | ///
8 | /// Gets the name of the record to be logged.
9 | ///
10 | string RecordName { get; }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/InvalidParseVersionTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class InvalidParseVersionTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "InvalidParseVersion";
6 |
7 | public string DetectorId { get; set; }
8 |
9 | public string FilePath { get; set; }
10 |
11 | public string Version { get; set; }
12 |
13 | public string MaxVersion { get; set; }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/LinuxContainerDetectorImageDetectionFailed.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class LinuxContainerDetectorImageDetectionFailed : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "LinuxContainerDetectorImageDetectionFailed";
6 |
7 | public string ImageId { get; set; }
8 |
9 | public string Message { get; set; }
10 |
11 | public string ExceptionType { get; set; }
12 |
13 | public string StackTrace { get; set; }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/LinuxContainerDetectorLayerAwareness.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class LinuxContainerDetectorLayerAwareness : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "LinuxContainerDetectorLayerAwareness";
6 |
7 | public string BaseImageRef { get; set; }
8 |
9 | public string BaseImageDigest { get; set; }
10 |
11 | public int? BaseImageLayerCount { get; set; }
12 |
13 | public int? LayerCount { get; set; }
14 |
15 | public string BaseImageLayerMessage { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/LinuxContainerDetectorMissingRepoNameAndTagRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class LinuxContainerDetectorMissingRepoNameAndTagRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "MissingRepoNameAndTag";
6 | }
7 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/LinuxContainerDetectorMissingVersion.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class LinuxContainerDetectorMissingVersion : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName { get; } = "MissingVersion";
6 |
7 | public string Distribution { get; set; }
8 |
9 | public string Release { get; set; }
10 |
11 | public string[] PackageNames { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/LinuxContainerDetectorTimeout.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class LinuxContainerDetectorTimeout : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "LinuxContainerDetectorTimeout";
6 | }
7 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/LinuxContainerDetectorUnsupportedOs.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class LinuxContainerDetectorUnsupportedOs : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "LinuxContainerDetectorUnsupportedOs";
6 |
7 | public string Os { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/LinuxScannerSyftTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class LinuxScannerSyftTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "LinuxScannerSyftTelemetry";
6 |
7 | public string LinuxComponents { get; set; }
8 |
9 | public string Exception { get; set; }
10 |
11 | public string Mariner2ComponentsRemoved { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/LinuxScannerTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class LinuxScannerTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "LinuxScannerTelemetry";
6 |
7 | public string ImageToScan { get; set; }
8 |
9 | public string ScanStdOut { get; set; }
10 |
11 | public string ScanStdErr { get; set; }
12 |
13 | public string FailedDeserializingScannerOutput { get; set; }
14 |
15 | public bool SemaphoreFailure { get; set; }
16 |
17 | public string ScannerVersion { get; set; }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/LoadComponentDetectorsTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class LoadComponentDetectorsTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "LoadComponentDetectors";
6 |
7 | public string DetectorIds { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/NuGetProjectAssetsTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | using System;
4 |
5 | public class NuGetProjectAssetsTelemetryRecord : IDetectionTelemetryRecord, IDisposable
6 | {
7 | private bool disposedValue;
8 |
9 | public string RecordName => "NuGetProjectAssets";
10 |
11 | public string FoundTargets { get; set; }
12 |
13 | public string UnhandledException { get; set; }
14 |
15 | public string Frameworks { get; set; }
16 |
17 | public void Dispose()
18 | {
19 | this.Dispose(true);
20 | GC.SuppressFinalize(this);
21 | }
22 |
23 | protected virtual void Dispose(bool disposing)
24 | {
25 | if (!this.disposedValue)
26 | {
27 | if (disposing)
28 | {
29 | TelemetryRelay.Instance.PostTelemetryRecord(this);
30 | }
31 |
32 | this.disposedValue = true;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/PipReportFailureTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class PipReportFailureTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "PipReportFailure";
6 |
7 | public int ExitCode { get; set; }
8 |
9 | public string StdErr { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/PipReportSkipTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class PipReportSkipTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "PipReportSkip";
6 |
7 | public string SkipReason { get; set; }
8 |
9 | public string DetectorId { get; set; }
10 |
11 | public int DetectorVersion { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/PipReportTypeTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class PipReportTypeTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "PipReportType";
6 |
7 | public bool PreGenerated { get; set; }
8 |
9 | public string FilePath { get; set; }
10 |
11 | public int PackageCount { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/PyPiCacheTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class PypiCacheTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "PyPiCache";
6 |
7 | ///
8 | /// Gets or sets total number of PyPi requests that hit the cache instead of PyPi APIs.
9 | ///
10 | public int NumCacheHits { get; set; }
11 |
12 | ///
13 | /// Gets or sets the size of the PyPi cache at class destruction.
14 | ///
15 | public int FinalCacheSize { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/PypiFailureTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | using System.Net;
4 |
5 | public class PypiFailureTelemetryRecord : BaseDetectionTelemetryRecord
6 | {
7 | public override string RecordName => "PypiFailure";
8 |
9 | ///
10 | /// Gets or sets the package Name (ex: pyyaml).
11 | ///
12 | public string Name { get; set; }
13 |
14 | ///
15 | /// Gets or sets the set of dependency specifications that constrain the overall dependency request (ex: ==1.0, >=2.0).
16 | ///
17 | public string[] DependencySpecifiers { get; set; }
18 |
19 | ///
20 | /// Gets or sets the status code of the last failed call.
21 | ///
22 | public HttpStatusCode StatusCode { get; set; }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/PypiMaxRetriesReachedTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class PypiMaxRetriesReachedTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "PypiMaxRetriesReached";
6 |
7 | ///
8 | /// Gets or sets the package Name (ex: pyyaml).
9 | ///
10 | public string Name { get; set; }
11 |
12 | ///
13 | /// Gets or sets the set of dependency specifications that constrain the overall dependency request (ex: ==1.0, >=2.0).
14 | ///
15 | public string[] DependencySpecifiers { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/PypiRetryTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | using System.Net;
4 |
5 | public class PypiRetryTelemetryRecord : BaseDetectionTelemetryRecord
6 | {
7 | public override string RecordName => "PypiRetry";
8 |
9 | ///
10 | /// Gets or sets the package Name (ex: pyyaml).
11 | ///
12 | public string Name { get; set; }
13 |
14 | ///
15 | /// Gets or sets the set of dependency specifications that constrain the overall dependency request (ex: ==1.0, >=2.0).
16 | ///
17 | public string[] DependencySpecifiers { get; set; }
18 |
19 | ///
20 | /// Gets or sets the status code of the last failed call that caused the retry.
21 | ///
22 | public HttpStatusCode StatusCode { get; set; }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/RustCrateDetectorTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class RustCrateDetectorTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "RustCrateMalformedDependencies";
6 |
7 | public string PackageInfo { get; set; }
8 |
9 | public string Dependencies { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/RustGraphTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class RustGraphTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "RustGraph";
6 |
7 | public string CargoTomlLocation { get; set; }
8 |
9 | public bool WasRustFallbackStrategyUsed { get; set; }
10 |
11 | public string FallbackReason { get; set; }
12 |
13 | public bool FallbackCargoLockFound { get; set; }
14 |
15 | public string FallbackCargoLockLocation { get; set; }
16 |
17 | public bool DidRustCliCommandFail { get; set; }
18 |
19 | public string RustCliCommandError { get; set; }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/Records/SimplePypiCacheTelemetryRecord.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2 |
3 | public class SimplePypiCacheTelemetryRecord : BaseDetectionTelemetryRecord
4 | {
5 | public override string RecordName => "SimplePyPiCache";
6 |
7 | ///
8 | /// Gets or sets total number of PyPi project requests that hit the cache instead of SimplePyPi API.
9 | ///
10 | public int NumSimpleProjectCacheHits { get; set; }
11 |
12 | ///
13 | /// Gets or sets total number of project wheel file requests that hit the cache instead of API.
14 | ///
15 | public int NumProjectFileCacheHits { get; set; }
16 |
17 | ///
18 | /// Gets or sets the size of the Simple Project cache at class destruction.
19 | ///
20 | public int FinalSimpleProjectCacheSize { get; set; }
21 |
22 | ///
23 | /// Gets or sets the size of the Project Wheel File cache at class destruction.
24 | ///
25 | public int FinalProjectFileCacheSize { get; set; }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/TelemetryConstants.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.CompilerServices;
3 |
4 | [assembly: InternalsVisibleTo("Microsoft.ComponentDetection.Orchestrator")]
5 |
6 | namespace Microsoft.ComponentDetection.Common.Telemetry;
7 |
8 | public static class TelemetryConstants
9 | {
10 | private static Guid correlationId;
11 |
12 | public static Guid CorrelationId
13 | {
14 | get
15 | {
16 | if (correlationId == Guid.Empty)
17 | {
18 | correlationId = Guid.NewGuid();
19 | }
20 |
21 | return correlationId;
22 | }
23 |
24 | set // This is temporarily public, but once a process boundary exists it will be internal and initialized by Orchestrator in BCDE
25 | {
26 | correlationId = value;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/Telemetry/TelemetryMode.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common.Telemetry;
2 |
3 | public enum TelemetryMode
4 | {
5 | Disabled = 0,
6 |
7 | Debug = 1,
8 |
9 | Production = 2,
10 | }
11 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Common/WarnOnAlertSeverity.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Common;
2 |
3 | public enum WarnOnAlertSeverity
4 | {
5 | Never = 0,
6 | Critical = 1,
7 | High = 2,
8 | Medium = 3,
9 | Low = 4,
10 | }
11 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DefaultGraphScanResult.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.BcdeModels;
2 |
3 | using Newtonsoft.Json;
4 | using Newtonsoft.Json.Serialization;
5 |
6 | [JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))]
7 | public class DefaultGraphScanResult : ScanResult
8 | {
9 | public DependencyGraphCollection DependencyGraphs { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyGraph.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.BcdeModels;
2 |
3 | using System.Collections.Generic;
4 |
5 | public class DependencyGraph : Dictionary>
6 | {
7 | }
8 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyGraphCollection.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.BcdeModels;
2 |
3 | using System.Collections.Generic;
4 |
5 | public class DependencyGraphCollection : Dictionary
6 | {
7 | }
8 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyGraphWithMetadata.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.BcdeModels;
2 |
3 | using System.Collections.Generic;
4 | using Newtonsoft.Json;
5 | using Newtonsoft.Json.Serialization;
6 |
7 | [JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))]
8 | public class DependencyGraphWithMetadata
9 | {
10 | public DependencyGraph Graph { get; set; }
11 |
12 | public HashSet ExplicitlyReferencedComponentIds { get; set; }
13 |
14 | public HashSet DevelopmentDependencies { get; set; }
15 |
16 | public HashSet Dependencies { get; set; }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DependencyScope.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.BcdeModels;
2 |
3 | /// Used to communicate Dependency Scope of Component.
4 | /// Currently only populated for Maven component.
5 | /// The values are ordered in terms of priority, which is used to resolve the scope for duplicate component while merging them.
6 | ///
7 | public enum DependencyScope
8 | {
9 | /// default scope. dependencies are available in the project during all build tasks. propogated to dependent projects.
10 | MavenCompile = 0,
11 |
12 | /// Required at Runtime, but not at compile time.
13 | MavenRuntime = 1,
14 |
15 | /// Dependencies are available only at compile time and in the test classpath of the project. These dependencies are also not transitive.
16 | MavenProvided = 2,
17 |
18 | /// Similar to provided scope. Requires explicit reference to Jar.
19 | MavenSystem = 3,
20 |
21 | /// Used only at runtime.
22 | MavenTest = 4,
23 | }
24 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/BcdeModels/Detector.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.BcdeModels;
2 |
3 | using System.Collections.Generic;
4 | using Microsoft.ComponentDetection.Contracts.TypedComponent;
5 | using Newtonsoft.Json;
6 | using Newtonsoft.Json.Converters;
7 | using Newtonsoft.Json.Serialization;
8 |
9 | [JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))]
10 | public class Detector
11 | {
12 | public string DetectorId { get; set; }
13 |
14 | public bool IsExperimental { get; set; }
15 |
16 | public int Version { get; set; }
17 |
18 | [JsonProperty(ItemConverterType = typeof(StringEnumConverter))]
19 | public IEnumerable SupportedComponentTypes { get; set; }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/BcdeModels/DockerLayer.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.BcdeModels;
2 |
3 | public class DockerLayer
4 | {
5 | // Summary:
6 | // the command/script that was executed in order to create the layer.
7 | public string CreatedBy { get; set; }
8 |
9 | // Summary:
10 | // The Layer hash (docker inspect) that represents the changes between this layer and the previous layer
11 | public string DiffId { get; set; }
12 |
13 | // Summary:
14 | // Whether or not this layer was found in the base image of the container
15 | public bool IsBaseImage { get; set; }
16 |
17 | // Summary:
18 | // 0-indexed monotonically increasing ID for the order of the layer in the container.
19 | // Note: only includes non-empty layers
20 | public int LayerIndex { get; set; }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/BcdeModels/LayerMappedLinuxComponents.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.BcdeModels;
2 |
3 | using System.Collections.Generic;
4 | using Microsoft.ComponentDetection.Contracts.TypedComponent;
5 |
6 | public class LayerMappedLinuxComponents
7 | {
8 | public IEnumerable LinuxComponents { get; set; }
9 |
10 | public DockerLayer DockerLayer { get; set; }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScanResult.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.BcdeModels;
2 |
3 | using System.Collections.Generic;
4 | using Newtonsoft.Json;
5 | using Newtonsoft.Json.Converters;
6 | using Newtonsoft.Json.Serialization;
7 |
8 | [JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))]
9 | public class ScanResult
10 | {
11 | public IEnumerable ComponentsFound { get; set; }
12 |
13 | public IEnumerable DetectorsInScan { get; set; }
14 |
15 | public IEnumerable DetectorsNotInScan { get; set; }
16 |
17 | public Dictionary ContainerDetailsMap { get; set; }
18 |
19 | [JsonConverter(typeof(StringEnumConverter))]
20 | public ProcessingResultCode ResultCode { get; set; }
21 |
22 | public string SourceDirectory { get; set; }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScannedComponent.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.BcdeModels;
2 |
3 | using System.Collections.Generic;
4 | using Newtonsoft.Json;
5 | using Newtonsoft.Json.Converters;
6 | using Newtonsoft.Json.Serialization;
7 |
8 | [JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))]
9 | public class ScannedComponent
10 | {
11 | public IEnumerable LocationsFoundAt { get; set; }
12 |
13 | public TypedComponent.TypedComponent Component { get; set; }
14 |
15 | public string DetectorId { get; set; }
16 |
17 | public bool? IsDevelopmentDependency { get; set; }
18 |
19 | [JsonConverter(typeof(StringEnumConverter))]
20 | public DependencyScope? DependencyScope { get; set; }
21 |
22 | public IEnumerable TopLevelReferrers { get; set; }
23 |
24 | public IEnumerable AncestralReferrers { get; set; }
25 |
26 | public IEnumerable ContainerDetailIds { get; set; }
27 |
28 | public IDictionary> ContainerLayerIds { get; set; }
29 |
30 | public ISet TargetFrameworks { get; set; }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/IComponentStream.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts;
2 |
3 | using System.IO;
4 |
5 | ///
6 | /// Represents a stream that was discovered by the provided pattern to />.
7 | ///
8 | public interface IComponentStream
9 | {
10 | ///
11 | /// Gets the stream object that was discovered by the provided pattern to />.
12 | ///
13 | Stream Stream { get; }
14 |
15 | ///
16 | /// Gets the pattern that this stream matched. Ex: If *.bar was used to match Foo.bar, this field would contain *.bar.
17 | ///
18 | string Pattern { get; }
19 |
20 | ///
21 | /// Gets the location for this stream. Often a file path if not in test circumstances.
22 | ///
23 | string Location { get; }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/IObservableDirectoryWalkerFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 | using Microsoft.ComponentDetection.Contracts.Internal;
7 |
8 | public delegate bool ExcludeDirectoryPredicate(ReadOnlySpan nameOfDirectoryToConsider, ReadOnlySpan pathOfParentOfDirectoryToConsider);
9 |
10 | public interface IObservableDirectoryWalkerFactory
11 | {
12 | void Initialize(DirectoryInfo root, ExcludeDirectoryPredicate directoryExclusionPredicate, int count, IEnumerable filePatterns = null);
13 |
14 | IObservable GetFilteredComponentStreamObservable(DirectoryInfo root, IEnumerable patterns, IComponentRecorder componentRecorder);
15 | }
16 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/IndividualDetectorScanResult.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts;
2 |
3 | using System.Collections.Generic;
4 | using Microsoft.ComponentDetection.Contracts.BcdeModels;
5 |
6 | ///
7 | /// Results object for a component scan.
8 | ///
9 | public class IndividualDetectorScanResult
10 | {
11 | ///
12 | /// Gets or sets the result code for the scan, indicating Success or Failure.
13 | ///
14 | public ProcessingResultCode ResultCode { get; set; }
15 |
16 | ///
17 | /// Gets or sets the list of containers found during the scan.
18 | ///
19 | public IEnumerable ContainerDetails { get; set; } = [];
20 |
21 | ///
22 | /// Gets or sets any additional telemetry details for the scan.
23 | ///
24 | public Dictionary AdditionalTelemetryDetails { get; set; }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/Internal/NpmAuthor.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.Internal;
2 |
3 | using System;
4 |
5 | public class NpmAuthor
6 | {
7 | public NpmAuthor(string name, string email = null)
8 | {
9 | this.Name = name ?? throw new ArgumentNullException(nameof(name));
10 | this.Email = string.IsNullOrEmpty(email) ? null : email;
11 | }
12 |
13 | public string Name { get; set; }
14 |
15 | public string Email { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/Internal/ProcessRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.Internal;
2 |
3 | public class ProcessRequest
4 | {
5 | public IComponentStream ComponentStream { get; set; }
6 |
7 | public ISingleFileComponentRecorder SingleFileComponentRecorder { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/KillSwitchConfiguration.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts;
2 |
3 | ///
4 | /// Represents the configuration for the kill switch.
5 | ///
6 | public class KillSwitchConfiguration
7 | {
8 | ///
9 | /// Gets or sets a value indicating whether the detection should be stopped.
10 | ///
11 | public bool IsDetectionStopped { get; set; }
12 |
13 | ///
14 | /// Gets or sets the reason for stopping the detection.
15 | ///
16 | public string ReasonForStoppingDetection { get; set; }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/Microsoft.ComponentDetection.Contracts.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/ProcessingResultCode.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts;
2 |
3 | /// Code used to communicate the state of a scan after completion.
4 | public enum ProcessingResultCode
5 | {
6 | /// The scan was completely successful.
7 | Success = 0,
8 |
9 | /// The scan had some detections complete while others encountered errors. The log file should indicate any issues that happened during the scan.
10 | PartialSuccess = 1,
11 |
12 | /// A critical error occurred during the scan.
13 | Error = 2,
14 |
15 | /// A critical error occurred during the scan, related to user input specifically.
16 | InputError = 3,
17 |
18 | /// The execution exceeded the expected amount of time to run.
19 | TimeoutError = 4,
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/TypedComponent/ComponentType.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.TypedComponent;
2 |
3 | using System.Runtime.Serialization;
4 |
5 | // This is used in BcdeModels as well
6 | [DataContract]
7 | public enum ComponentType : byte
8 | {
9 | [EnumMember]
10 | Other = 0,
11 |
12 | [EnumMember]
13 | NuGet = 1,
14 |
15 | [EnumMember]
16 | Npm = 2,
17 |
18 | [EnumMember]
19 | Maven = 3,
20 |
21 | [EnumMember]
22 | Git = 4,
23 |
24 | [EnumMember]
25 | RubyGems = 6,
26 |
27 | [EnumMember]
28 | Cargo = 7,
29 |
30 | [EnumMember]
31 | Pip = 8,
32 |
33 | [EnumMember]
34 | Go = 9,
35 |
36 | [EnumMember]
37 | DockerImage = 10,
38 |
39 | [EnumMember]
40 | Pod = 11,
41 |
42 | [EnumMember]
43 | Linux = 12,
44 |
45 | [EnumMember]
46 | Conda = 13,
47 |
48 | [EnumMember]
49 | Spdx = 14,
50 |
51 | [EnumMember]
52 | Vcpkg = 15,
53 |
54 | [EnumMember]
55 | DockerReference = 16,
56 |
57 | [EnumMember]
58 | Conan = 17,
59 |
60 | [EnumMember]
61 | Swift = 18,
62 |
63 | [EnumMember]
64 | DotNet = 19,
65 | }
66 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DockerImageComponent.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.TypedComponent;
2 |
3 | public class DockerImageComponent : TypedComponent
4 | {
5 | private DockerImageComponent()
6 | {
7 | /* Reserved for deserialization */
8 | }
9 |
10 | public DockerImageComponent(string hash, string name = null, string tag = null)
11 | {
12 | this.Digest = this.ValidateRequiredInput(hash, nameof(this.Digest), nameof(ComponentType.DockerImage));
13 | this.Name = name;
14 | this.Tag = tag;
15 | }
16 |
17 | public string Name { get; set; }
18 |
19 | public string Digest { get; set; }
20 |
21 | public string Tag { get; set; }
22 |
23 | public override ComponentType Type => ComponentType.DockerImage;
24 |
25 | protected override string ComputeId() => $"{this.Name} {this.Tag} {this.Digest}";
26 | }
27 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/TypedComponent/DockerReferenceComponent.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.TypedComponent;
2 |
3 | public class DockerReferenceComponent : TypedComponent
4 | {
5 | public DockerReferenceComponent(string hash, string repository = null, string tag = null)
6 | {
7 | this.Digest = this.ValidateRequiredInput(hash, nameof(this.Digest), nameof(ComponentType.DockerReference));
8 | this.Repository = repository;
9 | this.Tag = tag;
10 | }
11 |
12 | public DockerReferenceComponent(DockerReference reference)
13 | {
14 | }
15 |
16 | private DockerReferenceComponent()
17 | {
18 | /* Reserved for deserialization */
19 | }
20 |
21 | public string Repository { get; set; }
22 |
23 | public string Digest { get; set; }
24 |
25 | public string Tag { get; set; }
26 |
27 | public string Domain { get; set; }
28 |
29 | public override ComponentType Type => ComponentType.DockerReference;
30 |
31 | public DockerReference FullReference
32 | {
33 | get
34 | {
35 | return DockerReference.CreateDockerReference(this.Repository, this.Domain, this.Digest, this.Tag);
36 | }
37 | }
38 |
39 | protected override string ComputeId() => $"{this.Repository} {this.Tag} {this.Digest}";
40 | }
41 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/TypedComponent/GitComponent.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.TypedComponent;
2 |
3 | using System;
4 |
5 | public class GitComponent : TypedComponent
6 | {
7 | public GitComponent(Uri repositoryUrl, string commitHash)
8 | {
9 | this.RepositoryUrl = this.ValidateRequiredInput(repositoryUrl, nameof(this.RepositoryUrl), nameof(ComponentType.Git));
10 | this.CommitHash = this.ValidateRequiredInput(commitHash, nameof(this.CommitHash), nameof(ComponentType.Git));
11 | }
12 |
13 | public GitComponent(Uri repositoryUrl, string commitHash, string tag)
14 | : this(repositoryUrl, commitHash) => this.Tag = tag;
15 |
16 | private GitComponent()
17 | {
18 | /* Reserved for deserialization */
19 | }
20 |
21 | public Uri RepositoryUrl { get; set; }
22 |
23 | public string CommitHash { get; set; }
24 |
25 | public string Tag { get; set; }
26 |
27 | public override ComponentType Type => ComponentType.Git;
28 |
29 | protected override string ComputeId() => $"{this.RepositoryUrl} : {this.CommitHash} - {this.Type}";
30 | }
31 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/TypedComponent/MavenComponent.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.TypedComponent;
2 |
3 | using PackageUrl;
4 |
5 | public class MavenComponent : TypedComponent
6 | {
7 | public MavenComponent(string groupId, string artifactId, string version)
8 | {
9 | this.GroupId = this.ValidateRequiredInput(groupId, nameof(this.GroupId), nameof(ComponentType.Maven));
10 | this.ArtifactId = this.ValidateRequiredInput(artifactId, nameof(this.ArtifactId), nameof(ComponentType.Maven));
11 | this.Version = this.ValidateRequiredInput(version, nameof(this.Version), nameof(ComponentType.Maven));
12 | }
13 |
14 | private MavenComponent()
15 | {
16 | /* Reserved for deserialization */
17 | }
18 |
19 | public string GroupId { get; set; }
20 |
21 | public string ArtifactId { get; set; }
22 |
23 | public string Version { get; set; }
24 |
25 | public override ComponentType Type => ComponentType.Maven;
26 |
27 | public override PackageURL PackageUrl => new PackageURL("maven", this.GroupId, this.ArtifactId, this.Version, null, null);
28 |
29 | protected override string ComputeId() => $"{this.GroupId} {this.ArtifactId} {this.Version} - {this.Type}";
30 | }
31 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/TypedComponent/NpmComponent.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.TypedComponent;
2 |
3 | using Microsoft.ComponentDetection.Contracts.Internal;
4 | using PackageUrl;
5 |
6 | public class NpmComponent : TypedComponent
7 | {
8 | private NpmComponent()
9 | {
10 | /* Reserved for deserialization */
11 | }
12 |
13 | public NpmComponent(string name, string version, string hash = null, NpmAuthor author = null)
14 | {
15 | this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.Npm));
16 | this.Version = this.ValidateRequiredInput(version, nameof(this.Version), nameof(ComponentType.Npm));
17 | this.Hash = hash; // Not required; only found in package-lock.json, not package.json
18 | this.Author = author;
19 | }
20 |
21 | public string Name { get; set; }
22 |
23 | public string Version { get; set; }
24 |
25 | public string Hash { get; set; }
26 |
27 | public NpmAuthor Author { get; set; }
28 |
29 | public override ComponentType Type => ComponentType.Npm;
30 |
31 | public override PackageURL PackageUrl => new PackageURL("npm", null, this.Name, this.Version, null, null);
32 |
33 | protected override string ComputeId() => $"{this.Name} {this.Version} - {this.Type}";
34 | }
35 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/TypedComponent/NugetComponent.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.TypedComponent;
2 |
3 | using PackageUrl;
4 |
5 | public class NuGetComponent : TypedComponent
6 | {
7 | private NuGetComponent()
8 | {
9 | /* Reserved for deserialization */
10 | }
11 |
12 | public NuGetComponent(string name, string version, string[] authors = null)
13 | {
14 | this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.NuGet));
15 | this.Version = this.ValidateRequiredInput(version, nameof(this.Version), nameof(ComponentType.NuGet));
16 | this.Authors = authors;
17 | }
18 |
19 | public string Name { get; set; }
20 |
21 | public string Version { get; set; }
22 |
23 | public string[] Authors { get; set; }
24 |
25 | public override ComponentType Type => ComponentType.NuGet;
26 |
27 | public override PackageURL PackageUrl => new PackageURL("nuget", null, this.Name, this.Version, null, null);
28 |
29 | protected override string ComputeId() => $"{this.Name} {this.Version} - {this.Type}";
30 | }
31 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/TypedComponent/OtherComponent.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.TypedComponent;
2 |
3 | using System;
4 |
5 | public class OtherComponent : TypedComponent
6 | {
7 | private OtherComponent()
8 | {
9 | /* Reserved for deserialization */
10 | }
11 |
12 | public OtherComponent(string name, string version, Uri downloadUrl, string hash)
13 | {
14 | this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.Other));
15 | this.Version = this.ValidateRequiredInput(version, nameof(this.Version), nameof(ComponentType.Other));
16 | this.DownloadUrl = this.ValidateRequiredInput(downloadUrl, nameof(this.DownloadUrl), nameof(ComponentType.Other));
17 | this.Hash = hash;
18 | }
19 |
20 | public string Name { get; set; }
21 |
22 | public string Version { get; set; }
23 |
24 | public Uri DownloadUrl { get; set; }
25 |
26 | public string Hash { get; set; }
27 |
28 | public override ComponentType Type => ComponentType.Other;
29 |
30 | protected override string ComputeId() => $"{this.Name} {this.Version} {this.DownloadUrl} - {this.Type}";
31 | }
32 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Contracts/TypedComponent/RubyGemsComponent.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Contracts.TypedComponent;
2 |
3 | using PackageUrl;
4 |
5 | public class RubyGemsComponent : TypedComponent
6 | {
7 | private RubyGemsComponent()
8 | {
9 | /* Reserved for deserialization */
10 | }
11 |
12 | public RubyGemsComponent(string name, string version, string source = "")
13 | {
14 | this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.RubyGems));
15 | this.Version = this.ValidateRequiredInput(version, nameof(this.Version), nameof(ComponentType.RubyGems));
16 | this.Source = source;
17 | }
18 |
19 | public string Name { get; set; }
20 |
21 | public string Version { get; set; }
22 |
23 | public string Source { get; set; }
24 |
25 | public override ComponentType Type => ComponentType.RubyGems;
26 |
27 | public override PackageURL PackageUrl => new PackageURL("gem", null, this.Name, this.Version, null, null);
28 |
29 | protected override string ComputeId() => $"{this.Name} {this.Version} - {this.Type}";
30 | }
31 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/conan/Contracts/ConanLock.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Conan.Contracts;
2 |
3 | using System.Text.Json.Serialization;
4 |
5 | public class ConanLock
6 | {
7 | [JsonPropertyName("version")]
8 | public string Version { get; set; }
9 |
10 | [JsonPropertyName("profile_host")]
11 | public string ProfileHost { get; set; }
12 |
13 | [JsonPropertyName("profile_build")]
14 | public string ProfileBuild { get; set; }
15 |
16 | [JsonPropertyName("graph_lock")]
17 | public ConanLockGraph GraphLock { get; set; }
18 |
19 | internal bool HasNodes() => this.GraphLock?.Nodes?.Count > 0;
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/conan/Contracts/ConanLockGraph.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Conan.Contracts;
2 |
3 | using System.Collections.Generic;
4 | using System.Text.Json.Serialization;
5 |
6 | public class ConanLockGraph
7 | {
8 | [JsonPropertyName("revisions_enabled")]
9 | public bool RevisionsEnabled { get; set; }
10 |
11 | [JsonPropertyName("nodes")]
12 | public Dictionary Nodes { get; set; }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/conda/Contracts/CondaLock.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.CondaLock.Contracts;
2 |
3 | using System.Collections.Generic;
4 | using System.Runtime.Serialization;
5 | using YamlDotNet.Serialization;
6 |
7 | ///
8 | /// Model of the conda-lock file.
9 | ///
10 | [DataContract]
11 | public class CondaLock
12 | {
13 | [YamlMember(Alias = "metadata")]
14 | public CondaMetadata Metadata { get; set; }
15 |
16 | [YamlMember(Alias = "package")]
17 | public List Package { get; set; }
18 |
19 | [YamlMember(Alias = "version")]
20 | public int Version { get; set; }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/conda/Contracts/CondaMetadata.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.CondaLock.Contracts;
2 |
3 | using System.Collections.Generic;
4 | using YamlDotNet.Serialization;
5 |
6 | ///
7 | /// Model of the metadata section in the conda-lock file.
8 | ///
9 | public class CondaMetadata
10 | {
11 | [YamlMember(Alias = "platforms")]
12 | public List Platforms { get; set; }
13 |
14 | [YamlMember(Alias = "sources")]
15 | public List Sources { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/conda/Contracts/CondaPackage.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.CondaLock.Contracts;
2 |
3 | using System.Collections.Generic;
4 | using System.Runtime.Serialization;
5 | using YamlDotNet.Serialization;
6 |
7 | ///
8 | /// Model of the package section in the conda-lock file.
9 | ///
10 | [DataContract]
11 | public class CondaPackage
12 | {
13 | [YamlMember(Alias = "category")]
14 | public string Category { get; set; }
15 |
16 | [YamlMember(Alias = "dependencies")]
17 | public Dictionary Dependencies { get; set; }
18 |
19 | [YamlMember(Alias = "hash")]
20 | public Dictionary Hash { get; set; }
21 |
22 | [YamlMember(Alias = "manager")]
23 | public string Manager { get; set; }
24 |
25 | [YamlMember(Alias = "name")]
26 | public string Name { get; set; }
27 |
28 | [YamlMember(Alias = "optional")]
29 | public bool Optional { get; set; }
30 |
31 | [YamlMember(Alias = "platform")]
32 | public string Platform { get; set; }
33 |
34 | [YamlMember(Alias = "url")]
35 | public string Url { get; set; }
36 |
37 | [YamlMember(Alias = "version")]
38 | public string Version { get; set; }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/go/Parsers/GoParserFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Go;
2 |
3 | using System;
4 | using Microsoft.ComponentDetection.Contracts;
5 | using Microsoft.Extensions.Logging;
6 |
7 | public class GoParserFactory : IGoParserFactory
8 | {
9 | private readonly IFileUtilityService fileUtilityService;
10 | private readonly ICommandLineInvocationService commandLineInvocationService;
11 |
12 | public GoParserFactory(IFileUtilityService fileUtilityService, ICommandLineInvocationService commandLineInvocationService)
13 | {
14 | this.fileUtilityService = fileUtilityService;
15 | this.commandLineInvocationService = commandLineInvocationService;
16 | }
17 |
18 | public IGoParser CreateParser(GoParserType type, ILogger logger)
19 | {
20 | return type switch
21 | {
22 | GoParserType.GoMod => new GoModParser(logger),
23 | GoParserType.GoSum => new GoSumParser(logger),
24 | GoParserType.GoCLI => new GoCLIParser(logger, this.fileUtilityService, this.commandLineInvocationService),
25 | _ => throw new ArgumentException($"Unknown parser type: {type}"),
26 | };
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/go/Parsers/GoParserType.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Go;
2 |
3 | public enum GoParserType
4 | {
5 | GoMod,
6 | GoSum,
7 | GoCLI,
8 | }
9 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/go/Parsers/IGoParser.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Go;
2 |
3 | using System.Threading.Tasks;
4 | using Microsoft.ComponentDetection.Common.Telemetry.Records;
5 | using Microsoft.ComponentDetection.Contracts;
6 |
7 | public interface IGoParser
8 | {
9 | Task ParseAsync(ISingleFileComponentRecorder singleFileComponentRecorder, IComponentStream file, GoGraphTelemetryRecord record);
10 | }
11 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/go/Parsers/IGoParserFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Go;
2 |
3 | using Microsoft.Extensions.Logging;
4 |
5 | public interface IGoParserFactory
6 | {
7 | IGoParser CreateParser(GoParserType type, ILogger logger);
8 | }
9 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/ivy/Resources/build.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/linux/Contracts/ImageScanningResult.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Linux.Contracts;
2 |
3 | using System.Collections.Generic;
4 | using Microsoft.ComponentDetection.Contracts;
5 | using Microsoft.ComponentDetection.Contracts.BcdeModels;
6 |
7 | internal class ImageScanningResult
8 | {
9 | public ContainerDetails ContainerDetails { get; set; }
10 |
11 | public IEnumerable Components { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/linux/Exceptions/MissingContainerDetailException.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Linux.Exceptions;
2 |
3 | using System;
4 |
5 | public class MissingContainerDetailException : Exception
6 | {
7 | public MissingContainerDetailException(string imageId)
8 | : base($"No container details information could be found for image ${imageId}")
9 | {
10 | }
11 |
12 | public MissingContainerDetailException()
13 | {
14 | }
15 |
16 | public MissingContainerDetailException(string message, Exception innerException)
17 | : base(message, innerException)
18 | {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/linux/ILinuxScanner.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Linux;
2 |
3 | using System.Collections.Generic;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Microsoft.ComponentDetection.Contracts.BcdeModels;
7 |
8 | public interface ILinuxScanner
9 | {
10 | Task> ScanLinuxAsync(string imageHash, IEnumerable dockerLayers, int baseImageLayerCount, CancellationToken cancellationToken = default);
11 | }
12 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/maven/GraphNode.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Maven;
2 |
3 | using System.Collections.Generic;
4 |
5 | ///
6 | /// Internal state holder used by Maven detector.
7 | ///
8 | /// Node type.
9 | public class GraphNode
10 | {
11 | public GraphNode(T value) => this.Value = value;
12 |
13 | public T Value { get; set; }
14 |
15 | public List> Children { get; } = [];
16 |
17 | public List> Parents { get; } = [];
18 | }
19 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/maven/IMavenCommandService.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Maven;
2 |
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using Microsoft.ComponentDetection.Contracts.Internal;
6 |
7 | public interface IMavenCommandService
8 | {
9 | string BcdeMvnDependencyFileName { get; }
10 |
11 | Task MavenCLIExistsAsync();
12 |
13 | Task GenerateDependenciesFileAsync(ProcessRequest processRequest, CancellationToken cancellationToken = default);
14 |
15 | void ParseDependenciesFile(ProcessRequest processRequest);
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/maven/IMavenStyleDependencyGraphParserService.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Maven;
2 |
3 | using Microsoft.ComponentDetection.Contracts;
4 |
5 | public interface IMavenStyleDependencyGraphParserService
6 | {
7 | void Parse(string[] lines, ISingleFileComponentRecorder singleFileComponentRecorder);
8 | }
9 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/maven/MavenStyleDependencyGraphParserService.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Maven;
2 |
3 | using Microsoft.ComponentDetection.Contracts;
4 | using Microsoft.Extensions.Logging;
5 |
6 | public class MavenStyleDependencyGraphParserService : IMavenStyleDependencyGraphParserService
7 | {
8 | private readonly ILogger logger;
9 |
10 | public MavenStyleDependencyGraphParserService(ILogger logger) => this.logger = logger;
11 |
12 | public void Parse(string[] lines, ISingleFileComponentRecorder singleFileComponentRecorder)
13 | {
14 | var parser = new MavenStyleDependencyGraphParser();
15 | parser.Parse(lines, singleFileComponentRecorder, this.logger);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/nuget/FrameworkPackages/FrameworkPackages.net461.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.NuGet;
2 |
3 | using static global::NuGet.Frameworks.FrameworkConstants.CommonFrameworks;
4 |
5 | ///
6 | /// Framework packages for .NETFramework,Version=v4.6.1.
7 | ///
8 | internal partial class FrameworkPackages
9 | {
10 | internal static class NET461
11 | {
12 | internal static FrameworkPackages Instance { get; } = new(Net461, DefaultFrameworkKey, NETStandard20.Instance);
13 |
14 | internal static void Register() => FrameworkPackages.Register(Instance);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/nuget/FrameworkPackages/FrameworkPackages.netcoreapp2.2.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.NuGet;
2 |
3 | using static global::NuGet.Frameworks.FrameworkConstants.CommonFrameworks;
4 |
5 | ///
6 | /// Framework packages for .NETCoreApp,Version=v2.2.
7 | ///
8 | internal partial class FrameworkPackages
9 | {
10 | internal static class NETCoreApp22
11 | {
12 | // .NETCore 2.2 was the same as .NETCore 2.1
13 | internal static FrameworkPackages Instance { get; } = new(NetCoreApp22, FrameworkNames.NetCoreApp, NETCoreApp21.Instance);
14 |
15 | internal static void Register() => FrameworkPackages.Register(Instance);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/IPythonCommandService.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System.Collections.Generic;
4 | using System.Threading.Tasks;
5 | using Microsoft.ComponentDetection.Contracts.TypedComponent;
6 |
7 | public interface IPythonCommandService
8 | {
9 | Task PythonExistsAsync(string pythonPath = null);
10 |
11 | Task> ParseFileAsync(string path, string pythonPath = null);
12 |
13 | Task GetPythonVersionAsync(string pythonPath = null);
14 |
15 | ///
16 | /// Gets the os type using: https://docs.python.org/3/library/sys.html#sys.platform .
17 | ///
18 | /// OS type where the python script runs.
19 | Task GetOsTypeAsync(string pythonPath = null);
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/ISimplePyPiClient.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System;
4 | using System.IO;
5 | using System.Threading.Tasks;
6 |
7 | public interface ISimplePyPiClient
8 | {
9 | ///
10 | /// Uses the release url to retrieve the project file.
11 | ///
12 | /// The url to fetch dependencies from.
13 | /// Returns a project from the simplepypi api.
14 | Task FetchPackageFileStreamAsync(Uri releaseUrl);
15 |
16 | ///
17 | /// Calls simplepypi and retrieves the project specified with the spec name.
18 | ///
19 | /// The PipDependencySpecification for the project.
20 | /// Returns a project from the simplepypi api.
21 | Task GetSimplePypiProjectAsync(PipDependencySpecification spec);
22 | }
23 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/ISimplePythonResolver.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System.Collections.Generic;
4 | using System.Threading.Tasks;
5 | using Microsoft.ComponentDetection.Contracts;
6 |
7 | public interface ISimplePythonResolver
8 | {
9 | ///
10 | /// Resolves the root Python packages from the initial list of packages.
11 | ///
12 | /// The component recorder for file that is been processed.
13 | /// The initial list of packages.
14 | /// The root packages, with dependencies associated as children.
15 | Task> ResolveRootsAsync(ISingleFileComponentRecorder singleFileComponentRecorder, IList initialPackages);
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipGraphNode.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System.Collections.Generic;
4 | using Microsoft.ComponentDetection.Contracts.TypedComponent;
5 |
6 | ///
7 | /// Internal state used by PipDetector to hold intermediate structure info until the final
8 | /// combination of dependencies and relationships is determined and can be returned.
9 | ///
10 | public class PipGraphNode
11 | {
12 | public PipGraphNode(PipComponent value) => this.Value = value;
13 |
14 | public PipComponent Value { get; set; }
15 |
16 | public List Children { get; } = [];
17 |
18 | public List Parents { get; } = [];
19 | }
20 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReport.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System.Collections.Generic;
4 | using Newtonsoft.Json;
5 |
6 | ///
7 | /// See https://pip.pypa.io/en/stable/reference/installation-report/#specification.
8 | ///
9 | public sealed record PipInstallationReport
10 | {
11 | ///
12 | /// Version of the installation report specification. Currently 1, but will be incremented if the format changes.
13 | ///
14 | [JsonProperty("version")]
15 | public string Version { get; set; }
16 |
17 | ///
18 | /// Version of pip used to produce the report.
19 | ///
20 | [JsonProperty("pip_version")]
21 | public string PipVersion { get; set; }
22 |
23 | ///
24 | /// Distribution packages (to be) installed.
25 | ///
26 | [JsonProperty("install")]
27 | public PipInstallationReportItem[] InstallItems { get; set; }
28 |
29 | ///
30 | /// Environment metadata for the report. See https://peps.python.org/pep-0508/#environment-markers.
31 | ///
32 | [JsonProperty("environment")]
33 | public IDictionary Environment { get; set; }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipReportGraphNode.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System.Collections.Generic;
4 | using Microsoft.ComponentDetection.Contracts.TypedComponent;
5 |
6 | ///
7 | /// Internal state used by PipReportDetector to hold intermediate structure info until the final
8 | /// combination of dependencies and relationships is determined and can be returned.
9 | ///
10 | public sealed record PipReportGraphNode
11 | {
12 | public PipReportGraphNode(PipComponent value, bool requested)
13 | {
14 | this.Value = value;
15 | this.Requested = requested;
16 | }
17 |
18 | public PipComponent Value { get; set; }
19 |
20 | public List Children { get; } = [];
21 |
22 | public List Parents { get; } = [];
23 |
24 | public bool Requested { get; set; }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProject.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System.Collections.Generic;
4 |
5 | ///
6 | /// A project on pypi.
7 | ///
8 | public class PythonProject
9 | {
10 | public SortedDictionary> Releases { get; set; }
11 |
12 | #nullable enable
13 | public PythonProjectInfo? Info { get; set; }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectInfo.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System.Collections.Generic;
4 | using Newtonsoft.Json;
5 |
6 | public class PythonProjectInfo
7 | {
8 | public string Author { get; set; }
9 |
10 | [JsonProperty("author_email")]
11 | public string AuthorEmail { get; set; }
12 |
13 | public List Classifiers { get; set; }
14 |
15 | public string License { get; set; }
16 |
17 | public string Maintainer { get; set; }
18 |
19 | [JsonProperty("maintainer_email")]
20 | public string MaintainerEmail { get; set; }
21 |
22 | // Add other properties from the "info" object as needed
23 | }
24 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonProjectRelease.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System;
4 | using Newtonsoft.Json;
5 |
6 | ///
7 | /// A specific release of a project on pypy.
8 | ///
9 | public class PythonProjectRelease
10 | {
11 | public string PackageType { get; set; }
12 |
13 | [JsonProperty("python_version")]
14 | public string PythonVersion { get; set; }
15 |
16 | public double Size { get; set; }
17 |
18 | public Uri Url { get; set; }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PythonResolverState.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 |
6 | public class PythonResolverState
7 | {
8 | public IDictionary>> ValidVersionMap { get; }
9 | = new Dictionary>>(StringComparer.OrdinalIgnoreCase);
10 |
11 | public Queue<(string PackageName, PipDependencySpecification Package)> ProcessingQueue { get; } = new Queue<(string, PipDependencySpecification)>();
12 |
13 | public IDictionary NodeReferences { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase);
14 |
15 | public IList Roots { get; } = [];
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/PythonNotFoundException.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System;
4 |
5 | public class PythonNotFoundException : Exception
6 | {
7 | public PythonNotFoundException(string message)
8 | : base(message)
9 | {
10 | }
11 |
12 | public PythonNotFoundException(string message, Exception innerException)
13 | : base(message, innerException)
14 | {
15 | }
16 |
17 | public PythonNotFoundException()
18 | {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/PythonVersionComparer.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System.Collections.Generic;
4 |
5 | public class PythonVersionComparer : IComparer
6 | {
7 | public int Compare(string x, string y)
8 | {
9 | var xVer = PythonVersion.Create(x);
10 | var yVer = PythonVersion.Create(y);
11 |
12 | return xVer.CompareTo(yVer);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/SimplePypiProject.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System.Collections.Generic;
4 | using System.Text.Json.Serialization;
5 |
6 | ///
7 | /// A project from the new simple pypi api.
8 | ///
9 | public sealed record SimplePypiProject
10 | {
11 | [JsonPropertyName("files")]
12 | public IList Files { get; init; }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pip/SimplePypiProjectRelease.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pip;
2 |
3 | using System;
4 | using System.Text.Json.Serialization;
5 |
6 | ///
7 | /// A specific release of a project from the new simple pypi api.
8 | ///
9 | public sealed record SimplePypiProjectRelease
10 | {
11 | [JsonPropertyName("filename")]
12 | public string FileName { get; init; }
13 |
14 | [JsonPropertyName("size")]
15 | public double Size { get; init; }
16 |
17 | [JsonPropertyName("url")]
18 | public Uri Url { get; init; }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/Contracts/Package.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using System.Collections.Generic;
4 | using YamlDotNet.Serialization;
5 |
6 | public class Package
7 | {
8 | [YamlMember(Alias = "dependencies")]
9 | public Dictionary Dependencies { get; set; }
10 |
11 | [YamlMember(Alias = "dev")]
12 | public string Dev { get; set; }
13 |
14 | [YamlMember(Alias = "name")]
15 | public string Name { get; set; }
16 |
17 | [YamlMember(Alias = "resolution")]
18 | public Dictionary Resolution { get; set; }
19 |
20 | [YamlMember(Alias = "version")]
21 | public string Version { get; set; }
22 |
23 | public override string ToString()
24 | {
25 | return this.Name;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/Contracts/PnpmYaml.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using YamlDotNet.Serialization;
4 |
5 | ///
6 | /// Base class for all Pnpm lockfiles. Used for parsing the lockfile version.
7 | ///
8 | public class PnpmYaml
9 | {
10 | [YamlMember(Alias = "lockfileVersion")]
11 | public string LockfileVersion { get; set; }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/Contracts/PnpmYamlV5.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using System.Collections.Generic;
4 | using YamlDotNet.Serialization;
5 |
6 | ///
7 | /// Format for a Pnpm lock file version 5 as defined in https://github.com/pnpm/spec/blob/master/lockfile/5.md.
8 | ///
9 | public class PnpmYamlV5 : PnpmYaml
10 | {
11 | [YamlMember(Alias = "dependencies")]
12 | public Dictionary Dependencies { get; set; }
13 |
14 | [YamlMember(Alias = "packages")]
15 | public Dictionary Packages { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/Contracts/V6/PnpmHasDependenciesV6.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using System.Collections.Generic;
4 | using YamlDotNet.Serialization;
5 |
6 | public class PnpmHasDependenciesV6 : PnpmYaml
7 | {
8 | [YamlMember(Alias = "dependencies")]
9 | public Dictionary Dependencies { get; set; }
10 |
11 | [YamlMember(Alias = "devDependencies")]
12 | public Dictionary DevDependencies { get; set; }
13 |
14 | [YamlMember(Alias = "optionalDependencies")]
15 | public Dictionary OptionalDependencies { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/Contracts/V6/PnpmYamlV6.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using System.Collections.Generic;
4 | using YamlDotNet.Serialization;
5 |
6 | ///
7 | /// Format for a Pnpm lock file version 6 as defined in https://github.com/pnpm/spec/blob/master/lockfile/6.0.md.
8 | ///
9 | /// This handles both the "dedicated shrinkwrap" and "shared shrinkwrap" usages.
10 | /// In the "dedicated shrinkwrap", the inherited members from PnpmHasDependenciesV6 will be used.
11 | /// In the "shared shrinkwrap", the importers member will be used.
12 | ///
13 | public class PnpmYamlV6 : PnpmHasDependenciesV6
14 | {
15 | [YamlMember(Alias = "importers")]
16 | public Dictionary Importers { get; set; }
17 |
18 | [YamlMember(Alias = "packages")]
19 | public Dictionary Packages { get; set; }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/Contracts/V6/PnpmYamlV6Dependency.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using YamlDotNet.Serialization;
4 |
5 | public class PnpmYamlV6Dependency
6 | {
7 | [YamlMember(Alias = "version")]
8 | public string Version { get; set; }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/Contracts/V9/PnpmHasDependenciesV9.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using System.Collections.Generic;
4 | using YamlDotNet.Serialization;
5 |
6 | public class PnpmHasDependenciesV9 : PnpmYaml
7 | {
8 | [YamlMember(Alias = "dependencies")]
9 | public Dictionary Dependencies { get; set; }
10 |
11 | [YamlMember(Alias = "devDependencies")]
12 | public Dictionary DevDependencies { get; set; }
13 |
14 | [YamlMember(Alias = "optionalDependencies")]
15 | public Dictionary OptionalDependencies { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/Contracts/V9/PnpmYamlV9.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using System.Collections.Generic;
4 | using YamlDotNet.Serialization;
5 |
6 | ///
7 | /// There is still no official docs for the new v9 lock if format, so these parsing contracts are empirically based.
8 | /// Issue tracking v9 specs: https://github.com/pnpm/spec/issues/6
9 | /// Format should eventually get updated here: https://github.com/pnpm/spec/blob/master/lockfile/6.0.md.
10 | ///
11 | public class PnpmYamlV9 : PnpmHasDependenciesV9
12 | {
13 | [YamlMember(Alias = "importers")]
14 | public Dictionary Importers { get; set; }
15 |
16 | [YamlMember(Alias = "packages")]
17 | public Dictionary Packages { get; set; }
18 |
19 | [YamlMember(Alias = "snapshots")]
20 | public Dictionary Snapshots { get; set; }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/Contracts/V9/PnpmYamlV9Dependency.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using YamlDotNet.Serialization;
4 |
5 | public class PnpmYamlV9Dependency
6 | {
7 | [YamlMember(Alias = "version")]
8 | public string Version { get; set; }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/IPnpmDetector.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using Microsoft.ComponentDetection.Contracts;
4 |
5 | ///
6 | /// Interface that represents a version of the pnpm detector.
7 | ///
8 | public interface IPnpmDetector
9 | {
10 | ///
11 | /// Parses a yaml file content in pnmp format into the dependecy graph.
12 | ///
13 | /// Content of the yaml file that contains the pnpm dependencies.
14 | /// Component recorder to which to write the dependency graph.
15 | public void RecordDependencyGraphFromFile(string yamlFileContent, ISingleFileComponentRecorder singleFileComponentRecorder);
16 | }
17 |
18 | ///
19 | /// Constants used in Pnpm Detectors.
20 | ///
21 | public static class PnpmConstants
22 | {
23 | public const string PnpmFileDependencyPath = "file:";
24 |
25 | public const string PnpmLinkDependencyPath = "link:";
26 | public const string PnpmHttpDependencyPath = "http:";
27 | public const string PnpmHttpsDependencyPath = "https:";
28 | }
29 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/pnpm/ParsingUtilities/PnpmParsingUtilitiesFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Pnpm;
2 |
3 | using System.IO;
4 | using YamlDotNet.Serialization;
5 |
6 | public static class PnpmParsingUtilitiesFactory
7 | {
8 | public static PnpmParsingUtilitiesBase Create()
9 | where T : PnpmYaml
10 | {
11 | return typeof(T).Name switch
12 | {
13 | nameof(PnpmYamlV5) => new PnpmV5ParsingUtilities(),
14 | nameof(PnpmYamlV6) => new PnpmV6ParsingUtilities(),
15 | nameof(PnpmYamlV9) => new PnpmV9ParsingUtilities(),
16 | _ => new PnpmV5ParsingUtilities(),
17 | };
18 | }
19 |
20 | public static string DeserializePnpmYamlFileVersion(string fileContent)
21 | {
22 | var deserializer = new DeserializerBuilder()
23 | .IgnoreUnmatchedProperties()
24 | .Build();
25 | return deserializer.Deserialize(new StringReader(fileContent))?.LockfileVersion;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/poetry/Contracts/PoetryLock.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Poetry.Contracts;
2 |
3 | using System.Collections.Generic;
4 | using System.Runtime.Serialization;
5 |
6 | // Represents Poetry.Lock file structure.
7 | [DataContract]
8 | public class PoetryLock
9 | {
10 | [DataMember(Name = "Package")]
11 | public List Package { get; set; }
12 |
13 | [DataMember(Name = "metadata")]
14 | public Dictionary Metadata { get; set; }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/poetry/Contracts/PoetryPackage.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Poetry.Contracts;
2 |
3 | using System.Collections.Generic;
4 | using System.Runtime.Serialization;
5 |
6 | [DataContract]
7 | public class PoetryPackage
8 | {
9 | [DataMember(Name = "name")]
10 | public string Name { get; set; }
11 |
12 | [DataMember(Name = "version")]
13 | public string Version { get; set; }
14 |
15 | [DataMember(Name = "source")]
16 | public PoetrySource Source { get; set; }
17 |
18 | [DataMember(Name = "dependencies")]
19 | public Dictionary Dependencies { get; set; }
20 |
21 | [DataMember(Name = "extras")]
22 | public Dictionary Extras { get; set; }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/poetry/Contracts/PoetrySource.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Poetry.Contracts;
2 |
3 | using System.Runtime.Serialization;
4 |
5 | public class PoetrySource
6 | {
7 | [DataMember(Name = "type")]
8 | public string Type { get; set; }
9 |
10 | [DataMember(Name = "url")]
11 | public string Url { get; set; }
12 |
13 | [DataMember(Name = "reference")]
14 | public string Reference { get; set; }
15 |
16 | [DataMember(Name = "resolved_reference")]
17 | public string ResolvedReference { get; set; }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/rust/CargoDependencyData.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Rust;
2 |
3 | using System.Collections.Generic;
4 |
5 | public class CargoDependencyData
6 | {
7 | public CargoDependencyData()
8 | {
9 | this.CargoWorkspaces = [];
10 | this.CargoWorkspaceExclusions = [];
11 | this.NonDevDependencies = [];
12 | this.DevDependencies = [];
13 | }
14 |
15 | public HashSet CargoWorkspaces { get; set; }
16 |
17 | public HashSet CargoWorkspaceExclusions { get; set; }
18 |
19 | public IList NonDevDependencies { get; set; }
20 |
21 | public IList DevDependencies { get; set; }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/rust/Contracts/CargoLock.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Rust.Contracts;
2 |
3 | using System.Collections.Generic;
4 | using System.Runtime.Serialization;
5 |
6 | // Represents Cargo.Lock file structure.
7 | [DataContract]
8 | public class CargoLock
9 | {
10 | [DataMember(Name = "package")]
11 | public List Package { get; set; }
12 |
13 | [DataMember(Name = "metadata")]
14 | public Dictionary Metadata { get; set; }
15 |
16 | [DataMember(Name = "version")]
17 | public int Version { get; set; }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/rust/Contracts/CargoToml.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Rust.Contracts;
2 |
3 | using System.Runtime.Serialization;
4 |
5 | public class CargoToml
6 | {
7 | [DataMember(Name = "package")]
8 | public CargoPackage Package { get; set; }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/rust/InvalidRustTomlFileException.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Rust;
2 |
3 | using System;
4 |
5 | public class InvalidRustTomlFileException : Exception
6 | {
7 | public InvalidRustTomlFileException()
8 | {
9 | }
10 |
11 | public InvalidRustTomlFileException(string message)
12 | : base(message)
13 | {
14 | }
15 |
16 | public InvalidRustTomlFileException(string message, Exception innerException)
17 | : base(message, innerException)
18 | {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/vcpkg/Contracts/Annotation.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Vcpkg.Contracts;
2 |
3 | using System;
4 |
5 | public class Annotation
6 | {
7 | public DateTime Date { get; set; }
8 |
9 | public string Comment { get; set; }
10 |
11 | public string Type { get; set; }
12 |
13 | public string Annotator { get; set; }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/vcpkg/Contracts/Package.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Vcpkg.Contracts;
2 |
3 | public class Package
4 | {
5 | public string SPDXID { get; set; }
6 |
7 | public string VersionInfo { get; set; }
8 |
9 | public string DownloadLocation { get; set; }
10 |
11 | public string Filename { get; set; }
12 |
13 | public string Homepage { get; set; }
14 |
15 | public string Description { get; set; }
16 |
17 | public string Name { get; set; }
18 |
19 | public Annotation[] Annotations { get; set; }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/vcpkg/Contracts/VcpkgSBOM.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Vcpkg.Contracts;
2 |
3 | ///
4 | /// Matches a subset of https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json.
5 | ///
6 | public class VcpkgSBOM
7 | {
8 | public Package[] Packages { get; set; }
9 |
10 | public string Name { get; set; }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/Contracts/YarnBerryDependencyMeta.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn.Contracts;
2 |
3 | using YamlDotNet.Serialization;
4 |
5 | ///
6 | /// Represents the metadata of a dependency in the yarn.lock file for yarn v2+ (berry).
7 | ///
8 | public sealed record YarnBerryDependencyMeta
9 | {
10 | ///
11 | /// Whether the dependency is pre-built.
12 | ///
13 | [YamlMember(Alias = "built")]
14 | public bool? Built { get; init; }
15 |
16 | ///
17 | /// Whether the dependency is optional.
18 | ///
19 | [YamlMember(Alias = "optional")]
20 | public bool? Optional { get; init; }
21 |
22 | ///
23 | /// Whether the dependency is unplugged.
24 | /// This means that the dependency is not referenced directly through it's archive.
25 | /// Instead, it will be unpacked at install time into the `pnpUnplugged` folder.
26 | ///
27 | [YamlMember(Alias = "unplugged")]
28 | public bool? Unplugged { get; init; }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/Contracts/YarnBerryLockfile.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn.Contracts;
2 |
3 | using System.Collections.Generic;
4 | using YamlDotNet.Serialization;
5 |
6 | ///
7 | /// Represents the yarn.lock file for yarn v2+ (berry).
8 | /// There is no official documentation for the format of the yarn.lock file.
9 | /// This is based on the source code of https://github.com/yarnpkg/berry/blob/master/packages/yarnpkg-core/sources/Project.ts.
10 | ///
11 | public sealed record YarnBerryLockfile
12 | {
13 | ///
14 | /// Gets the metadata of the yarn.lock file.
15 | ///
16 | [YamlMember(Alias = "__metadata")]
17 | public YarnBerryLockfileMetadata Metadata { get; init; }
18 |
19 | ///
20 | /// Gets the entries of the yarn.lock file.
21 | ///
22 | public IDictionary Entries { get; init; }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/Contracts/YarnBerryLockfileMetadata.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn.Contracts;
2 |
3 | using YamlDotNet.Serialization;
4 |
5 | ///
6 | /// Represents the metadata of the yarn.lock file for yarn v2+.
7 | ///
8 | public sealed record YarnBerryLockfileMetadata
9 | {
10 | ///
11 | /// Gets the version of the yarn.lock file.
12 | ///
13 | [YamlMember(Alias = "version")]
14 | public string Version { get; set; }
15 |
16 | ///
17 | /// Gets the cache key of the yarn.lock file.
18 | ///
19 | [YamlMember(Alias = "cacheKey")]
20 | public string CacheKey { get; set; }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/Contracts/YarnBerryPeerDependencyMeta.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn.Contracts;
2 |
3 | using YamlDotNet.Serialization;
4 |
5 | ///
6 | /// Represents the metadata of a peer dependency in the yarn.lock file for yarn v2+ (berry).
7 | ///
8 | public sealed record YarnBerryPeerDependencyMeta
9 | {
10 | ///
11 | /// Whether the dependency is optional.
12 | ///
13 | [YamlMember(Alias = "optional")]
14 | public bool Optional { get; init; }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/IYarnLockFileFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn;
2 |
3 | using System.IO;
4 | using System.Threading.Tasks;
5 | using Microsoft.ComponentDetection.Contracts;
6 | using Microsoft.Extensions.Logging;
7 |
8 | public interface IYarnLockFileFactory
9 | {
10 | Task ParseYarnLockFileAsync(ISingleFileComponentRecorder singleFileComponentRecorder, Stream file, ILogger logger);
11 | }
12 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/IYarnLockParser.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn;
2 |
3 | using Microsoft.ComponentDetection.Contracts;
4 | using Microsoft.ComponentDetection.Detectors.Yarn.Parsers;
5 | using Microsoft.Extensions.Logging;
6 |
7 | public interface IYarnLockParser
8 | {
9 | bool CanParse(YarnLockVersion yarnLockVersion);
10 |
11 | YarnLockFile Parse(ISingleFileComponentRecorder singleFileComponentRecorder, IYarnBlockFile fileLines, ILogger logger);
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/InvalidYarnLockFileException.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn;
2 |
3 | using System;
4 |
5 | public class InvalidYarnLockFileException : Exception
6 | {
7 | public InvalidYarnLockFileException()
8 | {
9 | }
10 |
11 | public InvalidYarnLockFileException(string message)
12 | : base(message)
13 | {
14 | }
15 |
16 | public InvalidYarnLockFileException(string message, Exception innerException)
17 | : base(message, innerException)
18 | {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/Parsers/IYarnBlockFile.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn.Parsers;
2 |
3 | using System.Collections.Generic;
4 |
5 | public interface IYarnBlockFile : IEnumerable
6 | {
7 | YarnLockVersion YarnLockVersion { get; set; }
8 |
9 | ///
10 | /// The explicit version extracted from the `metadata` section of yarn lock files of .
11 | ///
12 | string LockfileVersion { get; set; }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/Parsers/YarnBlock.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn.Parsers;
2 |
3 | using System.Collections.Generic;
4 |
5 | public class YarnBlock
6 | {
7 | ///
8 | /// Gets or sets the first line of the block, without the semicolon.
9 | ///
10 | public string Title { get; set; }
11 |
12 | ///
13 | /// Gets the key/value pairs that the block contains.
14 | ///
15 | public IDictionary Values { get; } = new Dictionary();
16 |
17 | ///
18 | /// Gets child blocks, as dentoed by "{child}:".
19 | ///
20 | public IList Children { get; } = [];
21 | }
22 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/YarnDependency.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn;
2 |
3 | public class YarnDependency
4 | {
5 | public string LookupKey => $"{this.Name}@{this.Version}";
6 |
7 | public string Name { get; set; }
8 |
9 | public string Version { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/YarnLockFile.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn;
2 |
3 | using System.Collections.Generic;
4 |
5 | public class YarnLockFile
6 | {
7 | ///
8 | /// Gets or sets the declared Yarn Lock Version.
9 | ///
10 | public YarnLockVersion LockVersion { get; set; }
11 |
12 | ///
13 | /// The explicit lockfile version from the `metadata` section of the lock file. 1 if not present.
14 | ///
15 | public string LockfileVersion { get; set; } = "1";
16 |
17 | ///
18 | /// Gets or sets the component entries.
19 | ///
20 | public IEnumerable Entries { get; set; }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/YarnLockFileFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn;
2 |
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Threading.Tasks;
6 | using Microsoft.ComponentDetection.Contracts;
7 | using Microsoft.ComponentDetection.Detectors.Yarn.Parsers;
8 | using Microsoft.Extensions.Logging;
9 |
10 | public class YarnLockFileFactory : IYarnLockFileFactory
11 | {
12 | private readonly IEnumerable parsers;
13 |
14 | public YarnLockFileFactory(IEnumerable parsers) => this.parsers = parsers;
15 |
16 | public async Task ParseYarnLockFileAsync(ISingleFileComponentRecorder singleFileComponentRecorder, Stream file, ILogger logger)
17 | {
18 | var blockFile = await YarnBlockFile.CreateBlockFileAsync(file);
19 |
20 | foreach (var parser in this.parsers)
21 | {
22 | if (parser.CanParse(blockFile.YarnLockVersion))
23 | {
24 | return parser.Parse(singleFileComponentRecorder, blockFile, logger);
25 | }
26 | }
27 |
28 | throw new InvalidYarnLockFileException();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Detectors/yarn/YarnLockVersion.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Detectors.Yarn;
2 |
3 | public enum YarnLockVersion
4 | {
5 | Invalid = 0,
6 | V1 = 1,
7 |
8 | // Berry is the public codename for the Yarn v2 rewrite.
9 | // The lockfile has remained the same syntactically (YAML) since this rewrite,
10 | // and all minor changes to the lockfile (up to Yarn v4/lockfile v8) have been irrelevant to CD
11 | Berry = 2,
12 | }
13 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Commands/ListDetectorsSettings.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Commands;
2 |
3 | ///
4 | /// Settings for the ListDetectors command.
5 | ///
6 | public class ListDetectorsSettings : BaseSettings
7 | {
8 | }
9 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/DetectorRestrictions.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator;
2 |
3 | using System.Collections.Generic;
4 | using Microsoft.ComponentDetection.Contracts;
5 |
6 | public class DetectorRestrictions
7 | {
8 | public IEnumerable AllowedDetectorIds { get; set; }
9 |
10 | public IEnumerable ExplicitlyEnabledDetectorIds { get; set; }
11 |
12 | public IEnumerable AllowedDetectorCategories { get; set; }
13 |
14 | public IEnumerable DisabledDetectors { get; set; }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/DetectorRunResult.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator;
2 |
3 | using System;
4 |
5 | public class DetectorRunResult
6 | {
7 | public TimeSpan ExecutionTime { get; set; }
8 |
9 | public int ComponentsFoundCount { get; set; }
10 |
11 | public int ExplicitlyReferencedComponentCount { get; set; }
12 |
13 | public bool IsExperimental { get; set; }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Exceptions/InvalidDetectorCategoriesException.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Exceptions;
2 |
3 | using System;
4 |
5 | [Serializable]
6 | public class InvalidDetectorCategoriesException : Exception
7 | {
8 | public InvalidDetectorCategoriesException()
9 | {
10 | }
11 |
12 | public InvalidDetectorCategoriesException(string message)
13 | : base(message)
14 | {
15 | }
16 |
17 | public InvalidDetectorCategoriesException(string message, Exception innerException)
18 | : base(message, innerException)
19 | {
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Exceptions/InvalidDetectorFilterException.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Exceptions;
2 |
3 | using System;
4 |
5 | [Serializable]
6 | public class InvalidDetectorFilterException : Exception
7 | {
8 | public InvalidDetectorFilterException()
9 | {
10 | }
11 |
12 | public InvalidDetectorFilterException(string message)
13 | : base(message)
14 | {
15 | }
16 |
17 | public InvalidDetectorFilterException(string message, Exception innerException)
18 | : base(message, innerException)
19 | {
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Experiments/Configs/Go117DetectorExperiment.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Experiments.Configs;
2 |
3 | using Microsoft.ComponentDetection.Contracts;
4 | using Microsoft.ComponentDetection.Detectors.Go;
5 |
6 | ///
7 | /// Validating the Go detector for go mod 1.17+.
8 | ///
9 | public class Go117DetectorExperiment : IExperimentConfiguration
10 | {
11 | ///
12 | public string Name => "Go117Detector";
13 |
14 | ///
15 | public bool IsInControlGroup(IComponentDetector componentDetector) => componentDetector is GoComponentDetector;
16 |
17 | ///
18 | public bool IsInExperimentGroup(IComponentDetector componentDetector) => componentDetector is Go117ComponentDetector;
19 |
20 | ///
21 | public bool ShouldRecord(IComponentDetector componentDetector, int numComponents) => true;
22 | }
23 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Experiments/Configs/RustSbomVsCliExperiment.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Experiments.Configs;
2 |
3 | using Microsoft.ComponentDetection.Contracts;
4 | using Microsoft.ComponentDetection.Detectors.Rust;
5 |
6 | ///
7 | /// Validating the Rust SBOM detector against the Rust CLI detector.
8 | ///
9 | public class RustSbomVsCliExperiment : IExperimentConfiguration
10 | {
11 | ///
12 | public string Name => "RustSbomVsCliExperiment";
13 |
14 | ///
15 | public bool IsInControlGroup(IComponentDetector componentDetector) => componentDetector is RustCliDetector;
16 |
17 | ///
18 | public bool IsInExperimentGroup(IComponentDetector componentDetector) => componentDetector is RustSbomDetector;
19 |
20 | ///
21 | public bool ShouldRecord(IComponentDetector componentDetector, int numComponents) => true;
22 | }
23 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Experiments/Configs/RustSbomVsCrateExperiment.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Experiments.Configs;
2 |
3 | using Microsoft.ComponentDetection.Contracts;
4 | using Microsoft.ComponentDetection.Detectors.Rust;
5 |
6 | ///
7 | /// Validating the Rust SBOM detector against the Rust crate detector.
8 | ///
9 | public class RustSbomVsCrateExperiment : IExperimentConfiguration
10 | {
11 | ///
12 | public string Name => "RustSbomVsCrateExperiment";
13 |
14 | ///
15 | public bool IsInControlGroup(IComponentDetector componentDetector) => componentDetector is RustCrateDetector;
16 |
17 | ///
18 | public bool IsInExperimentGroup(IComponentDetector componentDetector) => componentDetector is RustSbomDetector;
19 |
20 | ///
21 | public bool ShouldRecord(IComponentDetector componentDetector, int numComponents) => true;
22 | }
23 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Experiments/Configs/SimplePipExperiment.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Experiments.Configs;
2 |
3 | using Microsoft.ComponentDetection.Contracts;
4 | using Microsoft.ComponentDetection.Detectors.Pip;
5 |
6 | ///
7 | /// Validating the .
8 | ///
9 | public class SimplePipExperiment : IExperimentConfiguration
10 | {
11 | ///
12 | public string Name => "NewPipDetector";
13 |
14 | ///
15 | public bool IsInControlGroup(IComponentDetector componentDetector) => componentDetector is PipComponentDetector;
16 |
17 | ///
18 | public bool IsInExperimentGroup(IComponentDetector componentDetector) => componentDetector is SimplePipComponentDetector;
19 |
20 | ///
21 | public bool ShouldRecord(IComponentDetector componentDetector, int numComponents) => true;
22 | }
23 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Experiments/DetectorExperiments.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Experiments;
2 |
3 | using System;
4 |
5 | ///
6 | /// Enables or disables detector experiments in Component Detection.
7 | ///
8 | public static class DetectorExperiments
9 | {
10 | ///
11 | /// Check to automatically proccess experiments.
12 | ///
13 | public static bool AutomaticallyProcessExperiments { get; set; } = true;
14 |
15 | ///
16 | /// Manually enables detector experiments.
17 | ///
18 | public static bool Enable { get; set; }
19 |
20 | private static bool EnvironmentEnabled =>
21 | !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CD_DETECTOR_EXPERIMENTS"));
22 |
23 | internal static bool AreExperimentsEnabled => Enable || EnvironmentEnabled;
24 | }
25 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Experiments/ExperimentComponentComparer.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Experiments;
2 |
3 | using System.Collections.Generic;
4 | using Microsoft.ComponentDetection.Orchestrator.Experiments.Models;
5 |
6 | ///
7 | /// Compares experiment components by their ID.
8 | ///
9 | public class ExperimentComponentComparer : IEqualityComparer
10 | {
11 | ///
12 | public bool Equals(ExperimentComponent x, ExperimentComponent y)
13 | {
14 | if (ReferenceEquals(x, y))
15 | {
16 | return true;
17 | }
18 |
19 | if (x is null)
20 | {
21 | return false;
22 | }
23 |
24 | if (y is null)
25 | {
26 | return false;
27 | }
28 |
29 | if (x.GetType() != y.GetType())
30 | {
31 | return false;
32 | }
33 |
34 | return x.Id == y.Id;
35 | }
36 |
37 | public int GetHashCode(ExperimentComponent obj) => obj.Id != null ? obj.Id.GetHashCode() : 0;
38 | }
39 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Experiments/IExperimentProcessor.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Experiments;
2 |
3 | using System.Threading.Tasks;
4 | using Microsoft.ComponentDetection.Orchestrator.Experiments.Configs;
5 | using Microsoft.ComponentDetection.Orchestrator.Experiments.Models;
6 |
7 | ///
8 | /// Processes the results of an experiment. Used to report the results of an experiment, such as by writing to a file.
9 | ///
10 | public interface IExperimentProcessor
11 | {
12 | ///
13 | /// Asynchronously processes the results of an experiment.
14 | ///
15 | /// The experiment configuration.
16 | /// The difference in components between two sets of detectors.
17 | /// A representing the asynchronous operation.
18 | Task ProcessExperimentAsync(IExperimentConfiguration config, ExperimentDiff diff);
19 | }
20 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Extensions/CommaDelimitedConverter.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Extensions;
2 |
3 | using System;
4 | using System.ComponentModel;
5 | using System.Globalization;
6 |
7 | ///
8 | /// Converts a comma separated string to an array of strings.
9 | ///
10 | public class CommaDelimitedConverter : TypeConverter
11 | {
12 | ///
13 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
14 | {
15 | if (value is string str)
16 | {
17 | return str.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
18 | }
19 |
20 | return base.ConvertFrom(context, culture, value);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Extensions/KeyValueDelimitedConverter.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Extensions;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.ComponentModel;
6 | using System.Globalization;
7 |
8 | ///
9 | /// Converts a comma separated string of key value pairs to a dictionary.
10 | ///
11 | public class KeyValueDelimitedConverter : TypeConverter
12 | {
13 | ///
14 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
15 | {
16 | if (value is string str)
17 | {
18 | var result = new Dictionary();
19 | var pairs = str.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
20 | foreach (var pair in pairs)
21 | {
22 | var keyValue = pair.Split('=', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
23 | if (keyValue.Length != 2)
24 | {
25 | throw new FormatException($"Invalid key value pair: {pair}");
26 | }
27 |
28 | result.Add(keyValue[0], keyValue[1]);
29 | }
30 |
31 | return result;
32 | }
33 |
34 | return base.ConvertFrom(context, culture, value);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Extensions/SemicolonDelimitedConverter.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Extensions;
2 |
3 | using System;
4 | using System.ComponentModel;
5 | using System.Globalization;
6 |
7 | ///
8 | /// Converts a semicolon separated string to an array of strings.
9 | ///
10 | public class SemicolonDelimitedConverter : TypeConverter
11 | {
12 | ///
13 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
14 | {
15 | if (value is string str)
16 | {
17 | return str.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
18 | }
19 |
20 | return base.ConvertFrom(context, culture, value);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/Extensions/TypeResolver.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator.Extensions;
2 |
3 | using System;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Spectre.Console.Cli;
6 |
7 | ///
8 | public sealed class TypeResolver : ITypeResolver, IDisposable
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The service provider.
14 | internal TypeResolver(ServiceProvider serviceProvider) => this.ServiceProvider = serviceProvider;
15 |
16 | internal ServiceProvider ServiceProvider { get; set; }
17 |
18 | ///
19 | public void Dispose() => this.ServiceProvider.Dispose();
20 |
21 | ///
22 | public object Resolve(Type type) => this.ServiceProvider.GetService(type) ?? Activator.CreateInstance(type);
23 | }
24 |
--------------------------------------------------------------------------------
/src/Microsoft.ComponentDetection.Orchestrator/IArgumentHelper.cs:
--------------------------------------------------------------------------------
1 | namespace Microsoft.ComponentDetection.Orchestrator;
2 |
3 | using CommandLine;
4 |
5 | public interface IArgumentHelper
6 | {
7 | ParserResult