feat: add initial dotnet-support (#951)

* feat: add initial dotnet-support

Signed-off-by: Christian Kotzbauer <git@ckotzbauer.de>

* fix: add path, sha512 and hashpath

Signed-off-by: Christian Kotzbauer <git@ckotzbauer.de>

* fix: add missing dot

Signed-off-by: Christian Kotzbauer <git@ckotzbauer.de>

* fix: lint warnings

Signed-off-by: Christian Kotzbauer <git@ckotzbauer.de>

* fix CLI test package counts to account for dotnet

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* fix: updated packagurl-go

Signed-off-by: Christian Kotzbauer <git@ckotzbauer.de>

* tidy go.sum

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* update json schema

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

Co-authored-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Christian Kotzbauer
2022-05-05 15:32:02 -04:00
committed by GitHub
co-authored by Alex Goodman
parent d2f053bc71
commit 1cea0ecd5c
28 changed files with 2170 additions and 11 deletions
+14
View File
@@ -0,0 +1,14 @@
package dotnet
import (
"github.com/anchore/syft/syft/pkg/cataloger/common"
)
// NewDotnetDepsCataloger returns a new Dotnet cataloger object base on deps json files.
func NewDotnetDepsCataloger() *common.GenericCataloger {
globParsers := map[string]common.ParserFn{
"**/*.deps.json": parseDotnetDeps,
}
return common.NewGenericCataloger(nil, globParsers, "dotnet-deps-cataloger")
}
@@ -0,0 +1,72 @@
package dotnet
import (
"encoding/json"
"fmt"
"io"
"strings"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/common"
)
// integrity check
var _ common.ParserFn = parseDotnetDeps
type dotnetDeps struct {
Libraries map[string]dotnetDepsLibrary `json:"libraries"`
}
type dotnetDepsLibrary struct {
Type string `json:"type"`
Path string `json:"path"`
Sha512 string `json:"sha512"`
HashPath string `json:"hashPath"`
}
func parseDotnetDeps(path string, reader io.Reader) ([]*pkg.Package, []artifact.Relationship, error) {
var packages []*pkg.Package
dec := json.NewDecoder(reader)
var p dotnetDeps
if err := dec.Decode(&p); err != nil {
return nil, nil, fmt.Errorf("failed to parse deps.json file: %w", err)
}
for nameVersion, lib := range p.Libraries {
dotnetPkg := newDotnetDepsPackage(nameVersion, lib)
if dotnetPkg != nil {
packages = append(packages, dotnetPkg)
}
}
return packages, nil, nil
}
func newDotnetDepsPackage(nameVersion string, lib dotnetDepsLibrary) *pkg.Package {
if lib.Type != "package" {
return nil
}
splitted := strings.Split(nameVersion, "/")
name := splitted[0]
version := splitted[1]
return &pkg.Package{
Name: name,
Version: version,
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: &pkg.DotnetDepsMetadata{
Name: name,
Version: version,
Path: lib.Path,
Sha512: lib.Sha512,
HashPath: lib.HashPath,
},
}
}
@@ -0,0 +1,199 @@
package dotnet
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/anchore/syft/syft/pkg"
)
func assertPackagesEqual(t *testing.T, actual []*pkg.Package, expected map[string]*pkg.Package) {
assert.Len(t, actual, len(expected))
}
func TestParseDotnetDeps(t *testing.T) {
expected := map[string]*pkg.Package{
"AWSSDK.Core": {
Name: "AWSSDK.Core",
Version: "3.7.10.6",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "AWSSDK.Core",
Version: "3.7.10.6",
Sha512: "sha512-kHBB+QmosVaG6DpngXQ8OlLVVNMzltNITfsRr68Z90qO7dSqJ2EHNd8dtBU1u3AQQLqqFHOY0lfmbpexeH6Pew==",
Path: "awssdk.core/3.7.10.6",
HashPath: "awssdk.core.3.7.10.6.nupkg.sha512",
},
},
"Microsoft.Extensions.DependencyInjection": {
Name: "Microsoft.Extensions.DependencyInjection",
Version: "6.0.0",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "Microsoft.Extensions.DependencyInjection",
Version: "6.0.0",
Sha512: "sha512-k6PWQMuoBDGGHOQTtyois2u4AwyVcIwL2LaSLlTZQm2CYcJ1pxbt6jfAnpWmzENA/wfrYRI/X9DTLoUkE4AsLw==",
Path: "microsoft.extensions.dependencyinjection/6.0.0",
HashPath: "microsoft.extensions.dependencyinjection.6.0.0.nupkg.sha512",
},
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
Name: "Microsoft.Extensions.DependencyInjection.Abstractions",
Version: "6.0.0",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "Microsoft.Extensions.DependencyInjection",
Version: "6.0.0",
Sha512: "sha512-xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg==",
Path: "microsoft.extensions.dependencyinjection.abstractions/6.0.0",
HashPath: "microsoft.extensions.dependencyinjection.abstractions.6.0.0.nupkg.sha512",
},
},
"Microsoft.Extensions.Logging": {
Name: "Microsoft.Extensions.Logging",
Version: "6.0.0",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "Microsoft.Extensions.Logging",
Version: "6.0.0",
Sha512: "sha512-eIbyj40QDg1NDz0HBW0S5f3wrLVnKWnDJ/JtZ+yJDFnDj90VoPuoPmFkeaXrtu+0cKm5GRAwoDf+dBWXK0TUdg==",
Path: "microsoft.extensions.logging/6.0.0",
HashPath: "microsoft.extensions.logging.6.0.0.nupkg.sha512",
},
},
"Microsoft.Extensions.Logging.Abstractions": {
Name: "Microsoft.Extensions.Logging.Abstractions",
Version: "6.0.0",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "Microsoft.Extensions.Logging",
Version: "6.0.0",
Sha512: "sha512-/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==",
Path: "microsoft.extensions.logging.abstractions/6.0.0",
HashPath: "microsoft.extensions.logging.abstractions.6.0.0.nupkg.sha512",
},
},
"Microsoft.Extensions.Options": {
Name: "Microsoft.Extensions.Options",
Version: "6.0.0",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "Microsoft.Extensions.Options",
Version: "6.0.0",
Sha512: "sha512-dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==",
Path: "microsoft.extensions.options/6.0.0",
HashPath: "microsoft.extensions.options.6.0.0.nupkg.sha512",
},
},
"Microsoft.Extensions.Primitives": {
Name: "Microsoft.Extensions.Primitives",
Version: "6.0.0",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "Microsoft.Extensions.Primitives",
Version: "6.0.0",
Sha512: "sha512-9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==",
Path: "microsoft.extensions.primitives/6.0.0",
HashPath: "microsoft.extensions.primitives.6.0.0.nupkg.sha512",
},
},
"Newtonsoft.Json": {
Name: "Newtonsoft.Json",
Version: "13.0.1",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "Newtonsoft.Json",
Version: "13.0.1",
Sha512: "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==",
Path: "newtonsoft.json/13.0.1",
HashPath: "newtonsoft.json.13.0.1.nupkg.sha512",
},
},
"Serilog": {
Name: "Serilog",
Version: "2.10.0",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "Serilog",
Version: "2.10.0",
Sha512: "sha512-+QX0hmf37a0/OZLxM3wL7V6/ADvC1XihXN4Kq/p6d8lCPfgkRdiuhbWlMaFjR9Av0dy5F0+MBeDmDdRZN/YwQA==",
Path: "serilog/2.10.0",
HashPath: "serilog.2.10.0.nupkg.sha512",
},
},
"Serilog.Sinks.Console": {
Name: "Serilog.Sinks.Console",
Version: "4.0.1",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "Serilog.Sinks.Console",
Version: "4.0.1",
Sha512: "sha512-apLOvSJQLlIbKlbx+Y2UDHSP05kJsV7mou+fvJoRGs/iR+jC22r8cuFVMjjfVxz/AD4B2UCltFhE1naRLXwKNw==",
Path: "serilog.sinks.console/4.0.1",
HashPath: "serilog.sinks.console.4.0.1.nupkg.sha512",
},
},
"System.Diagnostics.DiagnosticSource": {
Name: "System.Diagnostics.DiagnosticSource",
Version: "6.0.0",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "System.Diagnostics.DiagnosticSource",
Version: "6.0.0",
Sha512: "sha512-frQDfv0rl209cKm1lnwTgFPzNigy2EKk1BS3uAvHvlBVKe5cymGyHO+Sj+NLv5VF/AhHsqPIUUwya5oV4CHMUw==",
Path: "system.diagnostics.diagnosticsource/6.0.0",
HashPath: "system.diagnostics.diagnosticsource.6.0.0.nupkg.sha512",
},
},
"System.Runtime.CompilerServices.Unsafe": {
Name: "System.Runtime.CompilerServices.Unsafe",
Version: "6.0.0",
Language: pkg.Dotnet,
Type: pkg.DotnetPkg,
MetadataType: pkg.DotnetDepsMetadataType,
Metadata: pkg.DotnetDepsMetadata{
Name: "System.Runtime.CompilerServices.Unsafe",
Version: "6.0.0",
Sha512: "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==",
Path: "system.runtime.compilerservices.unsafe/6.0.0",
HashPath: "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512",
},
},
}
fixture, err := os.Open("test-fixtures/TestLibrary.deps.json")
if err != nil {
t.Fatalf("failed to open fixture: %+v", err)
}
actual, _, err := parseDotnetDeps(fixture.Name(), fixture)
if err != nil {
t.Fatalf("failed to parse deps.json: %+v", err)
}
assertPackagesEqual(t, actual, expected)
}
@@ -0,0 +1,235 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v6.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v6.0": {
"TestLibrary/1.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "6.0.0",
"Microsoft.Extensions.Logging": "6.0.0",
"Newtonsoft.Json": "13.0.1",
"Serilog": "2.10.0",
"Serilog.Sinks.Console": "4.0.1",
"TestCommon": "1.0.0"
},
"runtime": {
"TestLibrary.dll": {}
}
},
"AWSSDK.Core/3.7.10.6": {
"runtime": {
"lib/netcoreapp3.1/AWSSDK.Core.dll": {
"assemblyVersion": "3.3.0.0",
"fileVersion": "3.7.10.6"
}
}
},
"Microsoft.Extensions.DependencyInjection/6.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
},
"runtime": {
"lib/net6.0/Microsoft.Extensions.DependencyInjection.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/6.0.0": {
"runtime": {
"lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.Extensions.Logging/6.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "6.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
"Microsoft.Extensions.Logging.Abstractions": "6.0.0",
"Microsoft.Extensions.Options": "6.0.0",
"System.Diagnostics.DiagnosticSource": "6.0.0"
},
"runtime": {
"lib/netstandard2.1/Microsoft.Extensions.Logging.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.Extensions.Logging.Abstractions/6.0.0": {
"runtime": {
"lib/net6.0/Microsoft.Extensions.Logging.Abstractions.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.Extensions.Options/6.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
"Microsoft.Extensions.Primitives": "6.0.0"
},
"runtime": {
"lib/netstandard2.1/Microsoft.Extensions.Options.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.Extensions.Primitives/6.0.0": {
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
},
"runtime": {
"lib/net6.0/Microsoft.Extensions.Primitives.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Newtonsoft.Json/13.0.1": {
"runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {
"assemblyVersion": "13.0.0.0",
"fileVersion": "13.0.1.25517"
}
}
},
"Serilog/2.10.0": {
"runtime": {
"lib/netstandard2.1/Serilog.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.10.0.0"
}
}
},
"Serilog.Sinks.Console/4.0.1": {
"dependencies": {
"Serilog": "2.10.0"
},
"runtime": {
"lib/net5.0/Serilog.Sinks.Console.dll": {
"assemblyVersion": "4.0.1.0",
"fileVersion": "4.0.1.0"
}
}
},
"System.Diagnostics.DiagnosticSource/6.0.0": {
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Runtime.CompilerServices.Unsafe/6.0.0": {},
"TestCommon/1.0.0": {
"dependencies": {
"AWSSDK.Core": "3.7.10.6"
},
"runtime": {
"TestCommon.dll": {}
}
}
}
},
"libraries": {
"TestLibrary/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"AWSSDK.Core/3.7.10.6": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kHBB+QmosVaG6DpngXQ8OlLVVNMzltNITfsRr68Z90qO7dSqJ2EHNd8dtBU1u3AQQLqqFHOY0lfmbpexeH6Pew==",
"path": "awssdk.core/3.7.10.6",
"hashPath": "awssdk.core.3.7.10.6.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-k6PWQMuoBDGGHOQTtyois2u4AwyVcIwL2LaSLlTZQm2CYcJ1pxbt6jfAnpWmzENA/wfrYRI/X9DTLoUkE4AsLw==",
"path": "microsoft.extensions.dependencyinjection/6.0.0",
"hashPath": "microsoft.extensions.dependencyinjection.6.0.0.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection.Abstractions/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg==",
"path": "microsoft.extensions.dependencyinjection.abstractions/6.0.0",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.6.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Logging/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-eIbyj40QDg1NDz0HBW0S5f3wrLVnKWnDJ/JtZ+yJDFnDj90VoPuoPmFkeaXrtu+0cKm5GRAwoDf+dBWXK0TUdg==",
"path": "microsoft.extensions.logging/6.0.0",
"hashPath": "microsoft.extensions.logging.6.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Abstractions/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==",
"path": "microsoft.extensions.logging.abstractions/6.0.0",
"hashPath": "microsoft.extensions.logging.abstractions.6.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Options/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==",
"path": "microsoft.extensions.options/6.0.0",
"hashPath": "microsoft.extensions.options.6.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Primitives/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==",
"path": "microsoft.extensions.primitives/6.0.0",
"hashPath": "microsoft.extensions.primitives.6.0.0.nupkg.sha512"
},
"Newtonsoft.Json/13.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==",
"path": "newtonsoft.json/13.0.1",
"hashPath": "newtonsoft.json.13.0.1.nupkg.sha512"
},
"Serilog/2.10.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-+QX0hmf37a0/OZLxM3wL7V6/ADvC1XihXN4Kq/p6d8lCPfgkRdiuhbWlMaFjR9Av0dy5F0+MBeDmDdRZN/YwQA==",
"path": "serilog/2.10.0",
"hashPath": "serilog.2.10.0.nupkg.sha512"
},
"Serilog.Sinks.Console/4.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-apLOvSJQLlIbKlbx+Y2UDHSP05kJsV7mou+fvJoRGs/iR+jC22r8cuFVMjjfVxz/AD4B2UCltFhE1naRLXwKNw==",
"path": "serilog.sinks.console/4.0.1",
"hashPath": "serilog.sinks.console.4.0.1.nupkg.sha512"
},
"System.Diagnostics.DiagnosticSource/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-frQDfv0rl209cKm1lnwTgFPzNigy2EKk1BS3uAvHvlBVKe5cymGyHO+Sj+NLv5VF/AhHsqPIUUwya5oV4CHMUw==",
"path": "system.diagnostics.diagnosticsource/6.0.0",
"hashPath": "system.diagnostics.diagnosticsource.6.0.0.nupkg.sha512"
},
"System.Runtime.CompilerServices.Unsafe/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==",
"path": "system.runtime.compilerservices.unsafe/6.0.0",
"hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512"
},
"TestCommon/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}