mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
Adding metadata fields when parsing yarn.lock and poetry.lock (#2350)
* Adding the resolved and integrity fields of yarn.lock to the parsed metadata. This addition is similar to the metadata added when parsing package-lock.json. Signed-off-by: asi-cider <88270351+asi-cider@users.noreply.github.com> * fix comment Signed-off-by: asi-cider <88270351+asi-cider@users.noreply.github.com> * Adding the Index field to metadeta when parsing poetry.lock similarly to the existing Pipfile metadata Signed-off-by: asi-cider <88270351+asi-cider@users.noreply.github.com> * fixing struct accoding to tests Signed-off-by: asi-cider <88270351+asi-cider@users.noreply.github.com> * remove old schema change Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * remove empty constants Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * re-generate JSON schema Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update document ref Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix linting Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: asi-cider <88270351+asi-cider@users.noreply.github.com> Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
d7b9cc70b0
commit
98de2e2f62
@ -3,5 +3,5 @@ package internal
|
||||
const (
|
||||
// JSONSchemaVersion is the current schema version output by the JSON encoder
|
||||
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
|
||||
JSONSchemaVersion = "16.0.1"
|
||||
JSONSchemaVersion = "16.0.2"
|
||||
)
|
||||
|
||||
2252
schema/json/schema-16.0.2.json
Normal file
2252
schema/json/schema-16.0.2.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -36,6 +36,7 @@ func AllTypes() []any {
|
||||
pkg.PortageEntry{},
|
||||
pkg.PythonPackage{},
|
||||
pkg.PythonPipfileLockEntry{},
|
||||
pkg.PythonPoetryLockEntry{},
|
||||
pkg.PythonRequirementsEntry{},
|
||||
pkg.RDescription{},
|
||||
pkg.RpmArchive{},
|
||||
@ -44,5 +45,6 @@ func AllTypes() []any {
|
||||
pkg.RustBinaryAuditEntry{},
|
||||
pkg.RustCargoLockEntry{},
|
||||
pkg.SwiftPackageManagerResolvedEntry{},
|
||||
pkg.YarnLockEntry{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,11 +86,13 @@ var jsonTypes = makeJSONTypes(
|
||||
jsonNames(pkg.NixStoreEntry{}, "nix-store-entry", "NixStoreMetadata"),
|
||||
jsonNames(pkg.NpmPackage{}, "javascript-npm-package", "NpmPackageJsonMetadata"),
|
||||
jsonNames(pkg.NpmPackageLockEntry{}, "javascript-npm-package-lock-entry", "NpmPackageLockJsonMetadata"),
|
||||
jsonNames(pkg.YarnLockEntry{}, "javascript-yarn-lock-entry", "YarnLockJsonMetadata"),
|
||||
jsonNames(pkg.PhpComposerLockEntry{}, "php-composer-lock-entry", "PhpComposerJsonMetadata"),
|
||||
jsonNamesWithoutLookup(pkg.PhpComposerInstalledEntry{}, "php-composer-installed-entry", "PhpComposerJsonMetadata"), // the legacy value is split into two types, where the other is preferred
|
||||
jsonNames(pkg.PortageEntry{}, "portage-db-entry", "PortageMetadata"),
|
||||
jsonNames(pkg.PythonPackage{}, "python-package", "PythonPackageMetadata"),
|
||||
jsonNames(pkg.PythonPipfileLockEntry{}, "python-pipfile-lock-entry", "PythonPipfileLockMetadata"),
|
||||
jsonNames(pkg.PythonPoetryLockEntry{}, "python-poetry-lock-entry", "PythonPoetryLockMetadata"),
|
||||
jsonNames(pkg.PythonRequirementsEntry{}, "python-pip-requirements-entry", "PythonRequirementsMetadata"),
|
||||
jsonNames(pkg.ErlangRebarLockEntry{}, "erlang-rebar-lock-entry", "RebarLockMetadataType"),
|
||||
jsonNames(pkg.RDescription{}, "r-description", "RDescriptionFileMetadataType"),
|
||||
|
||||
@ -110,7 +110,7 @@ func newPnpmPackage(resolver file.Resolver, location file.Location, name, versio
|
||||
)
|
||||
}
|
||||
|
||||
func newYarnLockPackage(cfg CatalogerConfig, resolver file.Resolver, location file.Location, name, version string) pkg.Package {
|
||||
func newYarnLockPackage(cfg CatalogerConfig, resolver file.Resolver, location file.Location, name, version string, resolved string, integrity string) pkg.Package {
|
||||
var licenseSet pkg.LicenseSet
|
||||
|
||||
if cfg.SearchRemoteLicenses {
|
||||
@ -123,7 +123,6 @@ func newYarnLockPackage(cfg CatalogerConfig, resolver file.Resolver, location fi
|
||||
log.Warnf("unable to extract licenses from javascript yarn.lock for package %s:%s: %+v", name, version, err)
|
||||
}
|
||||
}
|
||||
|
||||
return finalizeLockPkg(
|
||||
resolver,
|
||||
location,
|
||||
@ -135,6 +134,7 @@ func newYarnLockPackage(cfg CatalogerConfig, resolver file.Resolver, location fi
|
||||
PURL: packageURL(name, version),
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{Resolved: resolved, Integrity: integrity},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@ -34,11 +34,18 @@ var (
|
||||
// `resolved "https://registry.yarnpkg.com/@4lolo/resize-observer-polyfill/-/resize-observer-polyfill-1.5.2.tgz#58868fc7224506236b5550d0c68357f0a874b84b"`
|
||||
// would return "@4lolo/resize-observer-polyfill" and "1.5.2"
|
||||
packageURLExp = regexp.MustCompile(`^\s+resolved\s+"https://registry\.(?:yarnpkg\.com|npmjs\.org)/(.+?)/-/(?:.+?)-(\d+\..+?)\.tgz`)
|
||||
)
|
||||
|
||||
const (
|
||||
noPackage = ""
|
||||
noVersion = ""
|
||||
// resolvedExp matches the resolved of the dependency in yarn.lock
|
||||
// For example:
|
||||
// resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
// would return "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
resolvedExp = regexp.MustCompile(`^\s+resolved\s+"(.+?)"`)
|
||||
|
||||
// integrityExp matches the integrity of the dependency in yarn.lock
|
||||
// For example:
|
||||
// integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
// would return "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==""
|
||||
integrityExp = regexp.MustCompile(`^\s+integrity\s+([^\s]+)`)
|
||||
)
|
||||
|
||||
type genericYarnLockAdapter struct {
|
||||
@ -59,37 +66,43 @@ func (a genericYarnLockAdapter) parseYarnLock(_ context.Context, resolver file.R
|
||||
}
|
||||
|
||||
var pkgs []pkg.Package
|
||||
var currentPackage, currentVersion, currentResolved, currentIntegrity string
|
||||
|
||||
scanner := bufio.NewScanner(reader)
|
||||
parsedPackages := strset.New()
|
||||
currentPackage := noPackage
|
||||
currentVersion := noVersion
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
if packageName := findPackageName(line); packageName != noPackage {
|
||||
if packageName := findPackageName(line); packageName != "" {
|
||||
// When we find a new package, check if we have unsaved identifiers
|
||||
if currentPackage != noPackage && currentVersion != noVersion && !parsedPackages.Has(currentPackage+"@"+currentVersion) {
|
||||
pkgs = append(pkgs, newYarnLockPackage(a.cfg, resolver, reader.Location, currentPackage, currentVersion))
|
||||
if currentPackage != "" && currentVersion != "" && !parsedPackages.Has(currentPackage+"@"+currentVersion) {
|
||||
pkgs = append(pkgs, newYarnLockPackage(a.cfg, resolver, reader.Location, currentPackage, currentVersion, currentResolved, currentIntegrity))
|
||||
parsedPackages.Add(currentPackage + "@" + currentVersion)
|
||||
}
|
||||
|
||||
currentPackage = packageName
|
||||
} else if version := findPackageVersion(line); version != noVersion {
|
||||
} else if version := findPackageVersion(line); version != "" {
|
||||
currentVersion = version
|
||||
} else if packageName, version := findPackageAndVersion(line); packageName != noPackage && version != noVersion && !parsedPackages.Has(packageName+"@"+version) {
|
||||
pkgs = append(pkgs, newYarnLockPackage(a.cfg, resolver, reader.Location, packageName, version))
|
||||
parsedPackages.Add(packageName + "@" + version)
|
||||
} else if packageName, version, resolved := findResolvedPackageAndVersion(line); packageName != "" && version != "" && resolved != "" {
|
||||
currentResolved = resolved
|
||||
currentPackage = packageName
|
||||
currentVersion = version
|
||||
} else if integrity := findIntegrity(line); integrity != "" && !parsedPackages.Has(currentPackage+"@"+currentVersion) {
|
||||
pkgs = append(pkgs, newYarnLockPackage(a.cfg, resolver, reader.Location, currentPackage, currentVersion, currentResolved, integrity))
|
||||
parsedPackages.Add(currentPackage + "@" + currentVersion)
|
||||
|
||||
// Cleanup to indicate no unsaved identifiers
|
||||
currentPackage = noPackage
|
||||
currentVersion = noVersion
|
||||
currentPackage = ""
|
||||
currentVersion = ""
|
||||
currentResolved = ""
|
||||
currentIntegrity = ""
|
||||
}
|
||||
}
|
||||
|
||||
// check if we have valid unsaved data after end-of-file has reached
|
||||
if currentPackage != noPackage && currentVersion != noVersion && !parsedPackages.Has(currentPackage+"@"+currentVersion) {
|
||||
pkgs = append(pkgs, newYarnLockPackage(a.cfg, resolver, reader.Location, currentPackage, currentVersion))
|
||||
if currentPackage != "" && currentVersion != "" && !parsedPackages.Has(currentPackage+"@"+currentVersion) {
|
||||
pkgs = append(pkgs, newYarnLockPackage(a.cfg, resolver, reader.Location, currentPackage, currentVersion, currentResolved, currentIntegrity))
|
||||
parsedPackages.Add(currentPackage + "@" + currentVersion)
|
||||
}
|
||||
|
||||
@ -107,7 +120,7 @@ func findPackageName(line string) string {
|
||||
return matches[1]
|
||||
}
|
||||
|
||||
return noPackage
|
||||
return ""
|
||||
}
|
||||
|
||||
func findPackageVersion(line string) string {
|
||||
@ -115,13 +128,25 @@ func findPackageVersion(line string) string {
|
||||
return matches[1]
|
||||
}
|
||||
|
||||
return noVersion
|
||||
return ""
|
||||
}
|
||||
|
||||
func findPackageAndVersion(line string) (string, string) {
|
||||
func findResolvedPackageAndVersion(line string) (string, string, string) {
|
||||
var resolved string
|
||||
if matches := resolvedExp.FindStringSubmatch(line); len(matches) >= 2 {
|
||||
resolved = matches[1]
|
||||
}
|
||||
if matches := packageURLExp.FindStringSubmatch(line); len(matches) >= 2 {
|
||||
return matches[1], matches[2]
|
||||
return matches[1], matches[2], resolved
|
||||
}
|
||||
|
||||
return noPackage, noVersion
|
||||
return "", "", ""
|
||||
}
|
||||
|
||||
func findIntegrity(line string) string {
|
||||
if matches := integrityExp.FindStringSubmatch(line); len(matches) >= 2 {
|
||||
return matches[1]
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ func TestParseYarnBerry(t *testing.T) {
|
||||
PURL: "pkg:npm/%40babel/code-frame@7.10.4",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{},
|
||||
},
|
||||
{
|
||||
Name: "@types/minimatch",
|
||||
@ -36,6 +37,7 @@ func TestParseYarnBerry(t *testing.T) {
|
||||
PURL: "pkg:npm/%40types/minimatch@3.0.3",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{},
|
||||
},
|
||||
{
|
||||
Name: "@types/qs",
|
||||
@ -44,6 +46,7 @@ func TestParseYarnBerry(t *testing.T) {
|
||||
PURL: "pkg:npm/%40types/qs@6.9.4",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{},
|
||||
},
|
||||
{
|
||||
Name: "ajv",
|
||||
@ -52,6 +55,7 @@ func TestParseYarnBerry(t *testing.T) {
|
||||
PURL: "pkg:npm/ajv@6.12.3",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{},
|
||||
},
|
||||
{
|
||||
Name: "asn1.js",
|
||||
@ -60,6 +64,7 @@ func TestParseYarnBerry(t *testing.T) {
|
||||
PURL: "pkg:npm/asn1.js@4.10.1",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{},
|
||||
},
|
||||
{
|
||||
Name: "atob",
|
||||
@ -68,6 +73,7 @@ func TestParseYarnBerry(t *testing.T) {
|
||||
PURL: "pkg:npm/atob@2.1.2",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{},
|
||||
},
|
||||
{
|
||||
Name: "aws-sdk",
|
||||
@ -76,6 +82,7 @@ func TestParseYarnBerry(t *testing.T) {
|
||||
Locations: locations,
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{},
|
||||
},
|
||||
{
|
||||
Name: "c0n-fab_u.laTION",
|
||||
@ -84,6 +91,7 @@ func TestParseYarnBerry(t *testing.T) {
|
||||
PURL: "pkg:npm/c0n-fab_u.laTION@7.7.7",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{},
|
||||
},
|
||||
{
|
||||
Name: "jhipster-core",
|
||||
@ -92,6 +100,7 @@ func TestParseYarnBerry(t *testing.T) {
|
||||
PURL: "pkg:npm/jhipster-core@7.3.4",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{},
|
||||
},
|
||||
}
|
||||
|
||||
@ -112,6 +121,10 @@ func TestParseYarnLock(t *testing.T) {
|
||||
PURL: "pkg:npm/%40babel/code-frame@7.10.4",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a",
|
||||
Integrity: "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "@types/minimatch",
|
||||
@ -120,6 +133,10 @@ func TestParseYarnLock(t *testing.T) {
|
||||
PURL: "pkg:npm/%40types/minimatch@3.0.3",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d",
|
||||
Integrity: "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "@types/qs",
|
||||
@ -128,6 +145,10 @@ func TestParseYarnLock(t *testing.T) {
|
||||
PURL: "pkg:npm/%40types/qs@6.9.4",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a",
|
||||
Integrity: "sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ==",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ajv",
|
||||
@ -136,6 +157,10 @@ func TestParseYarnLock(t *testing.T) {
|
||||
PURL: "pkg:npm/ajv@6.12.3",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706",
|
||||
Integrity: "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "asn1.js",
|
||||
@ -144,6 +169,10 @@ func TestParseYarnLock(t *testing.T) {
|
||||
PURL: "pkg:npm/asn1.js@4.10.1",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0",
|
||||
Integrity: "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "atob",
|
||||
@ -153,6 +182,10 @@ func TestParseYarnLock(t *testing.T) {
|
||||
PURL: "pkg:npm/atob@2.1.2",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9",
|
||||
Integrity: "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "aws-sdk",
|
||||
@ -161,6 +194,10 @@ func TestParseYarnLock(t *testing.T) {
|
||||
PURL: "pkg:npm/aws-sdk@2.706.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.706.0.tgz#09f65e9a91ecac5a635daf934082abae30eca953",
|
||||
Integrity: "sha512-7GT+yrB5Wb/zOReRdv/Pzkb2Qt+hz6B/8FGMVaoysX3NryHvQUdz7EQWi5yhg9CxOjKxdw5lFwYSs69YlSp1KA==",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "jhipster-core",
|
||||
@ -169,8 +206,11 @@ func TestParseYarnLock(t *testing.T) {
|
||||
PURL: "pkg:npm/jhipster-core@7.3.4",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "https://registry.yarnpkg.com/jhipster-core/-/jhipster-core-7.3.4.tgz#c34b8c97c7f4e8b7518dae015517e2112c73cc80",
|
||||
Integrity: "sha512-AUhT69kNkqppaJZVfan/xnKG4Gs9Ggj7YLtTZFVe+xg+THrbMb5Ng7PL07PDlDw4KAEA33GMCwuAf65E8EpC4g==",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Name: "something-i-made-up",
|
||||
Version: "7.7.7",
|
||||
@ -178,6 +218,10 @@ func TestParseYarnLock(t *testing.T) {
|
||||
PURL: "pkg:npm/something-i-made-up@7.7.7",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "https://registry.yarnpkg.com/something-i-made-up/-/c0n-fab_u.laTION-7.7.7.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0",
|
||||
Integrity: "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -221,6 +265,10 @@ func TestSearchYarnForLicenses(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")),
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a",
|
||||
Integrity: "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -25,7 +25,7 @@ func newPackageForIndex(name, version string, locations ...file.Location) pkg.Pa
|
||||
return p
|
||||
}
|
||||
|
||||
func newPackageForIndexWithMetadata(name, version string, metadata pkg.PythonPipfileLockEntry, locations ...file.Location) pkg.Package {
|
||||
func newPackageForIndexWithMetadata(name, version string, metadata interface{}, locations ...file.Location) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
|
||||
@ -62,7 +62,7 @@ func parsePipfileLock(_ context.Context, _ file.Resolver, _ *generic.Environment
|
||||
if pkgMeta.Index != "" {
|
||||
index = sourcesMap[pkgMeta.Index]
|
||||
} else {
|
||||
// https://pipenv.pypa.io/en/latest/advanced/#specifying-package-indexes
|
||||
// https://pipenv.pypa.io/en/latest/indexes.html
|
||||
index = "https://pypi.org/simple"
|
||||
}
|
||||
version := strings.TrimPrefix(pkgMeta.Version, "==")
|
||||
|
||||
@ -15,13 +15,18 @@ import (
|
||||
// integrity check
|
||||
var _ generic.Parser = parsePoetryLock
|
||||
|
||||
type poetryMetadata struct {
|
||||
type poetryPackageSource struct {
|
||||
URL string `toml:"url"`
|
||||
}
|
||||
|
||||
type poetryPackages struct {
|
||||
Packages []struct {
|
||||
Name string `toml:"name"`
|
||||
Version string `toml:"version"`
|
||||
Category string `toml:"category"`
|
||||
Description string `toml:"description"`
|
||||
Optional bool `toml:"optional"`
|
||||
Name string `toml:"name"`
|
||||
Version string `toml:"version"`
|
||||
Category string `toml:"category"`
|
||||
Description string `toml:"description"`
|
||||
Optional bool `toml:"optional"`
|
||||
Source poetryPackageSource `toml:"source"`
|
||||
} `toml:"package"`
|
||||
}
|
||||
|
||||
@ -32,7 +37,7 @@ func parsePoetryLock(_ context.Context, _ file.Resolver, _ *generic.Environment,
|
||||
return nil, nil, fmt.Errorf("unable to load poetry.lock for parsing: %w", err)
|
||||
}
|
||||
|
||||
metadata := poetryMetadata{}
|
||||
metadata := poetryPackages{}
|
||||
err = tree.Unmarshal(&metadata)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to parse poetry.lock: %w", err)
|
||||
@ -40,11 +45,19 @@ func parsePoetryLock(_ context.Context, _ file.Resolver, _ *generic.Environment,
|
||||
|
||||
var pkgs []pkg.Package
|
||||
for _, p := range metadata.Packages {
|
||||
var index string
|
||||
if p.Source.URL != "" {
|
||||
index = p.Source.URL
|
||||
} else {
|
||||
// https://python-poetry.org/docs/repositories/
|
||||
index = "https://pypi.org/simple"
|
||||
}
|
||||
pkgs = append(
|
||||
pkgs,
|
||||
newPackageForIndex(
|
||||
newPackageForIndexWithMetadata(
|
||||
p.Name,
|
||||
p.Version,
|
||||
pkg.PythonPoetryLockEntry{Index: index},
|
||||
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
)
|
||||
|
||||
@ -20,6 +20,7 @@ func TestParsePoetryLock(t *testing.T) {
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonPoetryLockEntry{Index: "https://test.pypi.org/simple"},
|
||||
},
|
||||
{
|
||||
Name: "alabaster",
|
||||
@ -28,6 +29,7 @@ func TestParsePoetryLock(t *testing.T) {
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonPoetryLockEntry{Index: "https://pypi.org/simple"},
|
||||
},
|
||||
{
|
||||
Name: "appnope",
|
||||
@ -36,6 +38,7 @@ func TestParsePoetryLock(t *testing.T) {
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonPoetryLockEntry{Index: "https://pypi.org/simple"},
|
||||
},
|
||||
{
|
||||
Name: "asciitree",
|
||||
@ -44,6 +47,7 @@ func TestParsePoetryLock(t *testing.T) {
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonPoetryLockEntry{Index: "https://pypi.org/simple"},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,11 @@ natsort = "*"
|
||||
six = "*"
|
||||
sphinx = "*"
|
||||
|
||||
[package.source]
|
||||
type = "legacy"
|
||||
url = "https://test.pypi.org/simple"
|
||||
reference = "test"
|
||||
|
||||
[package.extras]
|
||||
deploy = ["bumpversion", "twine", "wheel"]
|
||||
docs = ["sphinx", "sphinx-rtd-theme"]
|
||||
|
||||
@ -16,3 +16,9 @@ type NpmPackageLockEntry struct {
|
||||
Resolved string `mapstructure:"resolved" json:"resolved"`
|
||||
Integrity string `mapstructure:"integrity" json:"integrity"`
|
||||
}
|
||||
|
||||
// YarnLockEntry represents a single entry section of a yarn.lock file.
|
||||
type YarnLockEntry struct {
|
||||
Resolved string `mapstructure:"resolved" json:"resolved"`
|
||||
Integrity string `mapstructure:"integrity" json:"integrity"`
|
||||
}
|
||||
|
||||
@ -61,6 +61,11 @@ type PythonPipfileLockEntry struct {
|
||||
Index string `mapstructure:"index" json:"index"`
|
||||
}
|
||||
|
||||
// PythonPoetryLockEntry represents a single package entry within a Pipfile.lock file.
|
||||
type PythonPoetryLockEntry struct {
|
||||
Index string `mapstructure:"index" json:"index"`
|
||||
}
|
||||
|
||||
// PythonRequirementsEntry represents a single entry within a [*-]requirements.txt file.
|
||||
type PythonRequirementsEntry struct {
|
||||
Name string `json:"name" mapstruct:"Name"`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user