From 5ed002e1a9ccebbc0e33e11e3925f5a64a640471 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Fri, 4 Nov 2022 13:51:59 -0400 Subject: [PATCH] Update swift cataloger to generic cataloger (#1324) * port swift cataloger to new generic cataloger pattern Signed-off-by: Alex Goodman * add cocopods metadata to json schema defs Signed-off-by: Alex Goodman * update json test fixture with latest schema version Signed-off-by: Alex Goodman Signed-off-by: Alex Goodman --- internal/constants.go | 2 +- schema/json/generate.go | 37 +- schema/json/schema-5.0.1.json | 1589 +++++++++++++++++ .../snapshot/TestDirectoryEncoder.golden | 4 +- .../TestEncodeFullJSONDocument.golden | 4 +- .../snapshot/TestImageEncoder.golden | 4 +- syft/pkg/cataloger/swift/cataloger.go | 11 +- syft/pkg/cataloger/swift/package.go | 39 + syft/pkg/cataloger/swift/package_test.go | 33 + .../pkg/cataloger/swift/parse_podfile_lock.go | 52 +- .../swift/parse_podfile_lock_test.go | 163 +- syft/pkg/cocoapods_metadata.go | 24 +- syft/pkg/url_test.go | 15 +- 13 files changed, 1791 insertions(+), 186 deletions(-) create mode 100644 schema/json/schema-5.0.1.json create mode 100644 syft/pkg/cataloger/swift/package.go create mode 100644 syft/pkg/cataloger/swift/package_test.go diff --git a/internal/constants.go b/internal/constants.go index 8fc123235..cf55707cb 100644 --- a/internal/constants.go +++ b/internal/constants.go @@ -6,5 +6,5 @@ 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 = "5.0.0" + JSONSchemaVersion = "5.0.1" ) diff --git a/schema/json/generate.go b/schema/json/generate.go index 4175ca29b..ed4753ff6 100644 --- a/schema/json/generate.go +++ b/schema/json/generate.go @@ -28,24 +28,25 @@ can be extended to include specific package metadata struct shapes in the future // When a new package metadata definition is created it will need to be manually added here. The variable name does // not matter as long as it is exported. type artifactMetadataContainer struct { - Apk pkg.ApkMetadata - Alpm pkg.AlpmMetadata - Dpkg pkg.DpkgMetadata - Gem pkg.GemMetadata - Java pkg.JavaMetadata - Npm pkg.NpmPackageJSONMetadata - Python pkg.PythonPackageMetadata - Rpm pkg.RpmMetadata - Cargo pkg.CargoPackageMetadata - Go pkg.GolangBinMetadata - Php pkg.PhpComposerJSONMetadata - Dart pkg.DartPubMetadata - Dotnet pkg.DotnetDepsMetadata - Portage pkg.PortageMetadata - Conan pkg.ConanMetadata - ConanLock pkg.ConanLockMetadata - KbPackage pkg.KbPackageMetadata - Hackage pkg.HackageMetadata + Apk pkg.ApkMetadata + Alpm pkg.AlpmMetadata + Dpkg pkg.DpkgMetadata + Gem pkg.GemMetadata + Java pkg.JavaMetadata + Npm pkg.NpmPackageJSONMetadata + Python pkg.PythonPackageMetadata + Rpm pkg.RpmMetadata + Cargo pkg.CargoPackageMetadata + Go pkg.GolangBinMetadata + Php pkg.PhpComposerJSONMetadata + Dart pkg.DartPubMetadata + Dotnet pkg.DotnetDepsMetadata + Portage pkg.PortageMetadata + Conan pkg.ConanMetadata + ConanLock pkg.ConanLockMetadata + KbPackage pkg.KbPackageMetadata + Hackage pkg.HackageMetadata + SwiftCocopods pkg.CocoapodsMetadata } func main() { diff --git a/schema/json/schema-5.0.1.json b/schema/json/schema-5.0.1.json new file mode 100644 index 000000000..93209b144 --- /dev/null +++ b/schema/json/schema-5.0.1.json @@ -0,0 +1,1589 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Document", + "definitions": { + "AlpmFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "type": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "gid": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + }, + "size": { + "type": "string" + }, + "link": { + "type": "string" + }, + "digest": { + "items": { + "$ref": "#/definitions/Digest" + }, + "type": "array" + } + }, + "additionalProperties": true, + "type": "object" + }, + "AlpmMetadata": { + "required": [ + "basepackage", + "package", + "version", + "description", + "architecture", + "size", + "packager", + "license", + "url", + "validation", + "reason", + "files", + "backup" + ], + "properties": { + "basepackage": { + "type": "string" + }, + "package": { + "type": "string" + }, + "version": { + "type": "string" + }, + "description": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "packager": { + "type": "string" + }, + "license": { + "type": "string" + }, + "url": { + "type": "string" + }, + "validation": { + "type": "string" + }, + "reason": { + "type": "integer" + }, + "files": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/AlpmFileRecord" + }, + "type": "array" + }, + "backup": { + "items": { + "$ref": "#/definitions/AlpmFileRecord" + }, + "type": "array" + } + }, + "additionalProperties": true, + "type": "object" + }, + "ApkFileRecord": { + "required": [ + "path" + ], + "properties": { + "path": { + "type": "string" + }, + "ownerUid": { + "type": "string" + }, + "ownerGid": { + "type": "string" + }, + "permissions": { + "type": "string" + }, + "digest": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Digest" + } + }, + "additionalProperties": true, + "type": "object" + }, + "ApkMetadata": { + "required": [ + "package", + "originPackage", + "maintainer", + "version", + "license", + "architecture", + "url", + "description", + "size", + "installedSize", + "pullDependencies", + "pullChecksum", + "gitCommitOfApkPort", + "files" + ], + "properties": { + "package": { + "type": "string" + }, + "originPackage": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "version": { + "type": "string" + }, + "license": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "url": { + "type": "string" + }, + "description": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "installedSize": { + "type": "integer" + }, + "pullDependencies": { + "type": "string" + }, + "pullChecksum": { + "type": "string" + }, + "gitCommitOfApkPort": { + "type": "string" + }, + "files": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/ApkFileRecord" + }, + "type": "array" + } + }, + "additionalProperties": true, + "type": "object" + }, + "CargoPackageMetadata": { + "required": [ + "name", + "version", + "source", + "checksum", + "dependencies" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "type": "string" + }, + "checksum": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "additionalProperties": true, + "type": "object" + }, + "Classification": { + "required": [ + "class", + "virtual_path", + "metadata" + ], + "properties": { + "class": { + "type": "string" + }, + "virtual_path": { + "type": "string" + }, + "metadata": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "additionalProperties": true, + "type": "object" + }, + "CocoapodsMetadata": { + "required": [ + "checksum" + ], + "properties": { + "checksum": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "ConanLockMetadata": { + "required": [ + "ref" + ], + "properties": { + "ref": { + "type": "string" + }, + "package_id": { + "type": "string" + }, + "prev": { + "type": "string" + }, + "requires": { + "type": "string" + }, + "build_requires": { + "type": "string" + }, + "py_requires": { + "type": "string" + }, + "options": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "path": { + "type": "string" + }, + "context": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "ConanMetadata": { + "required": [ + "ref" + ], + "properties": { + "ref": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "Coordinates": { + "required": [ + "path" + ], + "properties": { + "path": { + "type": "string" + }, + "layerID": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "DartPubMetadata": { + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "hosted_url": { + "type": "string" + }, + "vcs_url": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "Descriptor": { + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "configuration": { + "additionalProperties": true + } + }, + "additionalProperties": true, + "type": "object" + }, + "Digest": { + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "Document": { + "required": [ + "artifacts", + "artifactRelationships", + "source", + "distro", + "descriptor", + "schema" + ], + "properties": { + "artifacts": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Package" + }, + "type": "array" + }, + "artifactRelationships": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Relationship" + }, + "type": "array" + }, + "files": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/File" + }, + "type": "array" + }, + "secrets": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Secrets" + }, + "type": "array" + }, + "source": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Source" + }, + "distro": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/LinuxRelease" + }, + "descriptor": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Descriptor" + }, + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Schema" + } + }, + "additionalProperties": true, + "type": "object" + }, + "DotnetDepsMetadata": { + "required": [ + "name", + "version", + "path", + "sha512", + "hashPath" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "path": { + "type": "string" + }, + "sha512": { + "type": "string" + }, + "hashPath": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "DpkgFileRecord": { + "required": [ + "path", + "isConfigFile" + ], + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/definitions/Digest" + }, + "isConfigFile": { + "type": "boolean" + } + }, + "additionalProperties": true, + "type": "object" + }, + "DpkgMetadata": { + "required": [ + "package", + "source", + "version", + "sourceVersion", + "architecture", + "maintainer", + "installedSize", + "files" + ], + "properties": { + "package": { + "type": "string" + }, + "source": { + "type": "string" + }, + "version": { + "type": "string" + }, + "sourceVersion": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "installedSize": { + "type": "integer" + }, + "files": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/DpkgFileRecord" + }, + "type": "array" + } + }, + "additionalProperties": true, + "type": "object" + }, + "File": { + "required": [ + "id", + "location" + ], + "properties": { + "id": { + "type": "string" + }, + "location": { + "$ref": "#/definitions/Coordinates" + }, + "metadata": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/FileMetadataEntry" + }, + "contents": { + "type": "string" + }, + "digests": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Digest" + }, + "type": "array" + }, + "classifications": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Classification" + }, + "type": "array" + } + }, + "additionalProperties": true, + "type": "object" + }, + "FileMetadataEntry": { + "required": [ + "mode", + "type", + "userID", + "groupID", + "mimeType" + ], + "properties": { + "mode": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "linkDestination": { + "type": "string" + }, + "userID": { + "type": "integer" + }, + "groupID": { + "type": "integer" + }, + "mimeType": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "GemMetadata": { + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "files": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "licenses": { + "items": { + "type": "string" + }, + "type": "array" + }, + "homepage": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "GolangBinMetadata": { + "required": [ + "goCompiledVersion", + "architecture" + ], + "properties": { + "goBuildSettings": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "goCompiledVersion": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "h1Digest": { + "type": "string" + }, + "mainModule": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "HackageMetadata": { + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "snapshotURL": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "JavaManifest": { + "properties": { + "main": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "namedSections": { + "patternProperties": { + ".*": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "additionalProperties": true, + "type": "object" + }, + "JavaMetadata": { + "required": [ + "virtualPath" + ], + "properties": { + "virtualPath": { + "type": "string" + }, + "manifest": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/JavaManifest" + }, + "pomProperties": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/PomProperties" + }, + "pomProject": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/PomProject" + }, + "digest": { + "items": { + "$ref": "#/definitions/Digest" + }, + "type": "array" + } + }, + "additionalProperties": true, + "type": "object" + }, + "KbPackageMetadata": { + "required": [ + "product_id", + "kb" + ], + "properties": { + "product_id": { + "type": "string" + }, + "kb": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "LinuxRelease": { + "properties": { + "prettyName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "idLike": { + "items": { + "type": "string" + }, + "type": "array" + }, + "version": { + "type": "string" + }, + "versionID": { + "type": "string" + }, + "versionCodename": { + "type": "string" + }, + "buildID": { + "type": "string" + }, + "imageID": { + "type": "string" + }, + "imageVersion": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "variantID": { + "type": "string" + }, + "homeURL": { + "type": "string" + }, + "supportURL": { + "type": "string" + }, + "bugReportURL": { + "type": "string" + }, + "privacyPolicyURL": { + "type": "string" + }, + "cpeName": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "NpmPackageJSONMetadata": { + "required": [ + "name", + "version", + "author", + "licenses", + "homepage", + "description", + "url", + "private" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "files": { + "items": { + "type": "string" + }, + "type": "array" + }, + "author": { + "type": "string" + }, + "licenses": { + "items": { + "type": "string" + }, + "type": "array" + }, + "homepage": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "private": { + "type": "boolean" + } + }, + "additionalProperties": true, + "type": "object" + }, + "Package": { + "required": [ + "id", + "name", + "version", + "type", + "foundBy", + "locations", + "licenses", + "language", + "cpes", + "purl" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "type": { + "type": "string" + }, + "foundBy": { + "type": "string" + }, + "locations": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/Coordinates" + }, + "type": "array" + }, + "licenses": { + "items": { + "type": "string" + }, + "type": "array" + }, + "language": { + "type": "string" + }, + "cpes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "purl": { + "type": "string" + }, + "metadataType": { + "type": "string" + }, + "metadata": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#/definitions/AlpmMetadata" + }, + { + "$ref": "#/definitions/ApkMetadata" + }, + { + "$ref": "#/definitions/CargoPackageMetadata" + }, + { + "$ref": "#/definitions/CocoapodsMetadata" + }, + { + "$ref": "#/definitions/ConanLockMetadata" + }, + { + "$ref": "#/definitions/ConanMetadata" + }, + { + "$ref": "#/definitions/DartPubMetadata" + }, + { + "$ref": "#/definitions/DotnetDepsMetadata" + }, + { + "$ref": "#/definitions/DpkgMetadata" + }, + { + "$ref": "#/definitions/GemMetadata" + }, + { + "$ref": "#/definitions/GolangBinMetadata" + }, + { + "$ref": "#/definitions/HackageMetadata" + }, + { + "$ref": "#/definitions/JavaMetadata" + }, + { + "$ref": "#/definitions/KbPackageMetadata" + }, + { + "$ref": "#/definitions/NpmPackageJSONMetadata" + }, + { + "$ref": "#/definitions/PhpComposerJSONMetadata" + }, + { + "$ref": "#/definitions/PortageMetadata" + }, + { + "$ref": "#/definitions/PythonPackageMetadata" + }, + { + "$ref": "#/definitions/RpmMetadata" + } + ] + } + }, + "additionalProperties": true, + "type": "object" + }, + "PhpComposerAuthors": { + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "homepage": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PhpComposerExternalReference": { + "required": [ + "type", + "url", + "reference" + ], + "properties": { + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "shasum": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PhpComposerJSONMetadata": { + "required": [ + "name", + "version", + "source", + "dist" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/PhpComposerExternalReference" + }, + "dist": { + "$ref": "#/definitions/PhpComposerExternalReference" + }, + "require": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "provide": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "require-dev": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "suggest": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "type": { + "type": "string" + }, + "notification-url": { + "type": "string" + }, + "bin": { + "items": { + "type": "string" + }, + "type": "array" + }, + "license": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/PhpComposerAuthors" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "keywords": { + "items": { + "type": "string" + }, + "type": "array" + }, + "time": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PomParent": { + "required": [ + "groupId", + "artifactId", + "version" + ], + "properties": { + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PomProject": { + "required": [ + "path", + "groupId", + "artifactId", + "version", + "name" + ], + "properties": { + "path": { + "type": "string" + }, + "parent": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/PomParent" + }, + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PomProperties": { + "required": [ + "path", + "name", + "groupId", + "artifactId", + "version", + "extraFields" + ], + "properties": { + "path": { + "type": "string" + }, + "name": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + }, + "extraFields": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PortageFileRecord": { + "required": [ + "path" + ], + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/definitions/Digest" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PortageMetadata": { + "required": [ + "installedSize", + "files" + ], + "properties": { + "installedSize": { + "type": "integer" + }, + "files": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/PortageFileRecord" + }, + "type": "array" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PythonDirectURLOriginInfo": { + "required": [ + "url" + ], + "properties": { + "url": { + "type": "string" + }, + "commitId": { + "type": "string" + }, + "vcs": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PythonFileDigest": { + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PythonFileRecord": { + "required": [ + "path" + ], + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/PythonFileDigest" + }, + "size": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "PythonPackageMetadata": { + "required": [ + "name", + "version", + "license", + "author", + "authorEmail", + "platform", + "sitePackagesRootPath" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "license": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorEmail": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "files": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/PythonFileRecord" + }, + "type": "array" + }, + "sitePackagesRootPath": { + "type": "string" + }, + "topLevelPackages": { + "items": { + "type": "string" + }, + "type": "array" + }, + "directUrlOrigin": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/PythonDirectURLOriginInfo" + } + }, + "additionalProperties": true, + "type": "object" + }, + "Relationship": { + "required": [ + "parent", + "child", + "type" + ], + "properties": { + "parent": { + "type": "string" + }, + "child": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": { + "additionalProperties": true + } + }, + "additionalProperties": true, + "type": "object" + }, + "RpmMetadata": { + "required": [ + "name", + "version", + "epoch", + "architecture", + "release", + "sourceRpm", + "size", + "license", + "vendor", + "modularityLabel", + "files" + ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "epoch": { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "architecture": { + "type": "string" + }, + "release": { + "type": "string" + }, + "sourceRpm": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "license": { + "type": "string" + }, + "vendor": { + "type": "string" + }, + "modularityLabel": { + "type": "string" + }, + "files": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/RpmdbFileRecord" + }, + "type": "array" + } + }, + "additionalProperties": true, + "type": "object" + }, + "RpmdbFileRecord": { + "required": [ + "path", + "mode", + "size", + "digest", + "userName", + "groupName", + "flags" + ], + "properties": { + "path": { + "type": "string" + }, + "mode": { + "type": "integer" + }, + "size": { + "type": "integer" + }, + "digest": { + "$ref": "#/definitions/Digest" + }, + "userName": { + "type": "string" + }, + "groupName": { + "type": "string" + }, + "flags": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "Schema": { + "required": [ + "version", + "url" + ], + "properties": { + "version": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "SearchResult": { + "required": [ + "classification", + "lineNumber", + "lineOffset", + "seekPosition", + "length" + ], + "properties": { + "classification": { + "type": "string" + }, + "lineNumber": { + "type": "integer" + }, + "lineOffset": { + "type": "integer" + }, + "seekPosition": { + "type": "integer" + }, + "length": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "additionalProperties": true, + "type": "object" + }, + "Secrets": { + "required": [ + "location", + "secrets" + ], + "properties": { + "location": { + "$ref": "#/definitions/Coordinates" + }, + "secrets": { + "items": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/SearchResult" + }, + "type": "array" + } + }, + "additionalProperties": true, + "type": "object" + }, + "Source": { + "required": [ + "id", + "type", + "target" + ], + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "target": { + "additionalProperties": true + } + }, + "additionalProperties": true, + "type": "object" + } + } +} diff --git a/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden b/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden index 522f4b946..6e9f1514d 100644 --- a/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden +++ b/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden @@ -89,7 +89,7 @@ } }, "schema": { - "version": "5.0.0", - "url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-5.0.0.json" + "version": "5.0.1", + "url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-5.0.1.json" } } diff --git a/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden b/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden index d1a493146..10f7f7422 100644 --- a/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden +++ b/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden @@ -185,7 +185,7 @@ } }, "schema": { - "version": "5.0.0", - "url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-5.0.0.json" + "version": "5.0.1", + "url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-5.0.1.json" } } diff --git a/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden b/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden index 8b4d657a4..1daf6a0e0 100644 --- a/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden +++ b/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden @@ -112,7 +112,7 @@ } }, "schema": { - "version": "5.0.0", - "url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-5.0.0.json" + "version": "5.0.1", + "url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-5.0.1.json" } } diff --git a/syft/pkg/cataloger/swift/cataloger.go b/syft/pkg/cataloger/swift/cataloger.go index d0c073408..5ce504b74 100644 --- a/syft/pkg/cataloger/swift/cataloger.go +++ b/syft/pkg/cataloger/swift/cataloger.go @@ -4,14 +4,11 @@ Package swift provides a concrete Cataloger implementation for Podfile.lock file package swift import ( - "github.com/anchore/syft/syft/pkg/cataloger/common" + "github.com/anchore/syft/syft/pkg/cataloger/generic" ) // NewCocoapodsCataloger returns a new Swift Cocoapods lock file cataloger object. -func NewCocoapodsCataloger() *common.GenericCataloger { - globParsers := map[string]common.ParserFn{ - "**/Podfile.lock": parsePodfileLock, - } - - return common.NewGenericCataloger(nil, globParsers, "cocoapods-cataloger") +func NewCocoapodsCataloger() *generic.Cataloger { + return generic.NewCataloger("cocoapods-cataloger"). + WithParserByGlobs(parsePodfileLock, "**/Podfile.lock") } diff --git a/syft/pkg/cataloger/swift/package.go b/syft/pkg/cataloger/swift/package.go new file mode 100644 index 000000000..0e1c1ce4a --- /dev/null +++ b/syft/pkg/cataloger/swift/package.go @@ -0,0 +1,39 @@ +package swift + +import ( + "github.com/anchore/packageurl-go" + "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/source" +) + +func newPackage(name, version, hash string, locations ...source.Location) pkg.Package { + p := pkg.Package{ + Name: name, + Version: version, + PURL: packageURL(name, version), + Locations: source.NewLocationSet(locations...), + Type: pkg.CocoapodsPkg, + Language: pkg.Swift, + MetadataType: pkg.CocoapodsMetadataType, + Metadata: pkg.CocoapodsMetadata{ + Checksum: hash, + }, + } + + p.SetID() + + return p +} + +func packageURL(name, version string) string { + var qualifiers packageurl.Qualifiers + + return packageurl.NewPackageURL( + packageurl.TypeCocoapods, + "", + name, + version, + qualifiers, + "", + ).ToString() +} diff --git a/syft/pkg/cataloger/swift/package_test.go b/syft/pkg/cataloger/swift/package_test.go new file mode 100644 index 000000000..388379226 --- /dev/null +++ b/syft/pkg/cataloger/swift/package_test.go @@ -0,0 +1,33 @@ +package swift + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_packageURL(t *testing.T) { + type args struct { + name string + version string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "go case", + args: args{ + name: "name", + version: "v0.1.0", + }, + want: "pkg:cocoapods/name@v0.1.0", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, packageURL(tt.args.name, tt.args.version)) + }) + } +} diff --git a/syft/pkg/cataloger/swift/parse_podfile_lock.go b/syft/pkg/cataloger/swift/parse_podfile_lock.go index 0bde98ece..4b6409bff 100644 --- a/syft/pkg/cataloger/swift/parse_podfile_lock.go +++ b/syft/pkg/cataloger/swift/parse_podfile_lock.go @@ -9,36 +9,34 @@ import ( "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/pkg" - "github.com/anchore/syft/syft/pkg/cataloger/common" + "github.com/anchore/syft/syft/pkg/cataloger/generic" + "github.com/anchore/syft/syft/source" ) -// integrity check -var _ common.ParserFn = parsePodfileLock +var _ generic.Parser = parsePodfileLock + +type podfileLock struct { + Pods []interface{} `yaml:"PODS"` + Dependencies []string `yaml:"DEPENDENCIES"` + SpecRepos map[string][]string `yaml:"SPEC REPOS"` + SpecChecksums map[string]string `yaml:"SPEC CHECKSUMS"` + PodfileChecksum string `yaml:"PODFILE CHECKSUM"` + Cocopods string `yaml:"COCOAPODS"` +} // parsePodfileLock is a parser function for Podfile.lock contents, returning all cocoapods pods discovered. -func parsePodfileLock(_ string, reader io.Reader) ([]*pkg.Package, []artifact.Relationship, error) { +func parsePodfileLock(_ source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { bytes, err := io.ReadAll(reader) if err != nil { return nil, nil, fmt.Errorf("unable to read file: %w", err) } - var podfile map[string]interface{} + var podfile podfileLock if err = yaml.Unmarshal(bytes, &podfile); err != nil { return nil, nil, fmt.Errorf("unable to parse yaml: %w", err) } - c, exists := podfile["SPEC CHECKSUMS"] - if !exists { - return nil, nil, fmt.Errorf("malformed podfile.lock: missing checksums") - } - checksums := c.(map[string]interface{}) - p, exists := podfile["PODS"] - if !exists { - return nil, nil, fmt.Errorf("malformed podfile.lock: missing checksums") - } - pods := p.([]interface{}) - - pkgs := []*pkg.Package{} - for _, podInterface := range pods { + var pkgs []pkg.Package + for _, podInterface := range podfile.Pods { var podBlob string switch v := podInterface.(type) { case map[string]interface{}: @@ -54,22 +52,14 @@ func parsePodfileLock(_ string, reader io.Reader) ([]*pkg.Package, []artifact.Re podName := splits[0] podVersion := strings.TrimSuffix(strings.TrimPrefix(splits[1], "("), ")") podRootPkg := strings.Split(podName, "/")[0] - pkgHash, exists := checksums[podRootPkg] + + var pkgHash string + pkgHash, exists := podfile.SpecChecksums[podRootPkg] if !exists { return nil, nil, fmt.Errorf("malformed podfile.lock: incomplete checksums") } - pkgs = append(pkgs, &pkg.Package{ - Name: podName, - Version: podVersion, - Type: pkg.CocoapodsPkg, - Language: pkg.Swift, - MetadataType: pkg.CocoapodsMetadataType, - Metadata: pkg.CocoapodsMetadata{ - Name: podName, - Version: podVersion, - PkgHash: pkgHash.(string), - }, - }) + + pkgs = append(pkgs, newPackage(podName, podVersion, pkgHash, reader.Location)) } return pkgs, nil, nil diff --git a/syft/pkg/cataloger/swift/parse_podfile_lock_test.go b/syft/pkg/cataloger/swift/parse_podfile_lock_test.go index a434d904e..ef4c7d2c4 100644 --- a/syft/pkg/cataloger/swift/parse_podfile_lock_test.go +++ b/syft/pkg/cataloger/swift/parse_podfile_lock_test.go @@ -1,307 +1,298 @@ package swift import ( - "os" "testing" - "github.com/go-test/deep" - + "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" + "github.com/anchore/syft/syft/source" ) func TestParsePodfileLock(t *testing.T) { - expected := []*pkg.Package{ + fixture := "test-fixtures/Podfile.lock" + locations := source.NewLocationSet(source.NewLocation(fixture)) + expectedPkgs := []pkg.Package{ { Name: "GlossButtonNode", Version: "3.1.2", + PURL: "pkg:cocoapods/GlossButtonNode@3.1.2", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "GlossButtonNode", - Version: "3.1.2", - PkgHash: "4ea1197a744f2fb5fb875fe31caf17ded4762e8f", + Checksum: "4ea1197a744f2fb5fb875fe31caf17ded4762e8f", }, }, { Name: "PINCache", Version: "3.0.3", + PURL: "pkg:cocoapods/PINCache@3.0.3", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "PINCache", - Version: "3.0.3", - PkgHash: "7a8fc1a691173d21dbddbf86cd515de6efa55086", + Checksum: "7a8fc1a691173d21dbddbf86cd515de6efa55086", }, }, { Name: "PINCache/Arc-exception-safe", Version: "3.0.3", + PURL: "pkg:cocoapods/PINCache/Arc-exception-safe@3.0.3", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "PINCache/Arc-exception-safe", - Version: "3.0.3", - PkgHash: "7a8fc1a691173d21dbddbf86cd515de6efa55086", + Checksum: "7a8fc1a691173d21dbddbf86cd515de6efa55086", }, }, { Name: "PINCache/Core", Version: "3.0.3", + PURL: "pkg:cocoapods/PINCache/Core@3.0.3", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "PINCache/Core", - Version: "3.0.3", - PkgHash: "7a8fc1a691173d21dbddbf86cd515de6efa55086", + Checksum: "7a8fc1a691173d21dbddbf86cd515de6efa55086", }, }, { Name: "PINOperation", Version: "1.2.1", + PURL: "pkg:cocoapods/PINOperation@1.2.1", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "PINOperation", - Version: "1.2.1", - PkgHash: "00c935935f1e8cf0d1e2d6b542e75b88fc3e5e20", + Checksum: "00c935935f1e8cf0d1e2d6b542e75b88fc3e5e20", }, }, { Name: "PINRemoteImage/Core", Version: "3.0.3", + PURL: "pkg:cocoapods/PINRemoteImage/Core@3.0.3", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "PINRemoteImage/Core", - Version: "3.0.3", - PkgHash: "f1295b29f8c5e640e25335a1b2bd9d805171bd01", + Checksum: "f1295b29f8c5e640e25335a1b2bd9d805171bd01", }, }, { Name: "PINRemoteImage/iOS", Version: "3.0.3", + PURL: "pkg:cocoapods/PINRemoteImage/iOS@3.0.3", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "PINRemoteImage/iOS", - Version: "3.0.3", - PkgHash: "f1295b29f8c5e640e25335a1b2bd9d805171bd01", + Checksum: "f1295b29f8c5e640e25335a1b2bd9d805171bd01", }, }, { Name: "PINRemoteImage/PINCache", Version: "3.0.3", + PURL: "pkg:cocoapods/PINRemoteImage/PINCache@3.0.3", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "PINRemoteImage/PINCache", - Version: "3.0.3", - PkgHash: "f1295b29f8c5e640e25335a1b2bd9d805171bd01", + Checksum: "f1295b29f8c5e640e25335a1b2bd9d805171bd01", }, }, { Name: "Reveal-SDK", Version: "33", + PURL: "pkg:cocoapods/Reveal-SDK@33", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "Reveal-SDK", - Version: "33", - PkgHash: "effba1c940b8337195563c425a6b5862ec875caa", + Checksum: "effba1c940b8337195563c425a6b5862ec875caa", }, }, { Name: "SwiftGen", Version: "6.5.1", + PURL: "pkg:cocoapods/SwiftGen@6.5.1", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "SwiftGen", - Version: "6.5.1", - PkgHash: "a6d22010845f08fe18fbdf3a07a8e380fd22e0ea", + Checksum: "a6d22010845f08fe18fbdf3a07a8e380fd22e0ea", }, }, { Name: "Texture", Version: "3.1.0", + PURL: "pkg:cocoapods/Texture@3.1.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "Texture", - Version: "3.1.0", - PkgHash: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", + Checksum: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", }, }, { Name: "Texture/AssetsLibrary", Version: "3.1.0", + PURL: "pkg:cocoapods/Texture/AssetsLibrary@3.1.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "Texture/AssetsLibrary", - Version: "3.1.0", - PkgHash: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", + Checksum: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", }, }, { Name: "Texture/Core", Version: "3.1.0", + PURL: "pkg:cocoapods/Texture/Core@3.1.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "Texture/Core", - Version: "3.1.0", - PkgHash: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", + Checksum: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", }, }, { Name: "Texture/MapKit", Version: "3.1.0", + PURL: "pkg:cocoapods/Texture/MapKit@3.1.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "Texture/MapKit", - Version: "3.1.0", - PkgHash: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", + Checksum: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", }, }, { Name: "Texture/Photos", Version: "3.1.0", + PURL: "pkg:cocoapods/Texture/Photos@3.1.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "Texture/Photos", - Version: "3.1.0", - PkgHash: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", + Checksum: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", }, }, { Name: "Texture/PINRemoteImage", Version: "3.1.0", + PURL: "pkg:cocoapods/Texture/PINRemoteImage@3.1.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "Texture/PINRemoteImage", - Version: "3.1.0", - PkgHash: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", + Checksum: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", }, }, { Name: "Texture/Video", Version: "3.1.0", + PURL: "pkg:cocoapods/Texture/Video@3.1.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "Texture/Video", - Version: "3.1.0", - PkgHash: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", + Checksum: "2e8ab2519452515f7f5a520f5a8f7e0a413abfa3", }, }, { Name: "TextureSwiftSupport", Version: "3.13.0", + PURL: "pkg:cocoapods/TextureSwiftSupport@3.13.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "TextureSwiftSupport", - Version: "3.13.0", - PkgHash: "c515c7927fab92d0d9485f49b885b8c5de34fbfb", + Checksum: "c515c7927fab92d0d9485f49b885b8c5de34fbfb", }, }, { Name: "TextureSwiftSupport/Components", Version: "3.13.0", + PURL: "pkg:cocoapods/TextureSwiftSupport/Components@3.13.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "TextureSwiftSupport/Components", - Version: "3.13.0", - PkgHash: "c515c7927fab92d0d9485f49b885b8c5de34fbfb", + Checksum: "c515c7927fab92d0d9485f49b885b8c5de34fbfb", }, }, { Name: "TextureSwiftSupport/Experiments", Version: "3.13.0", + PURL: "pkg:cocoapods/TextureSwiftSupport/Experiments@3.13.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "TextureSwiftSupport/Experiments", - Version: "3.13.0", - PkgHash: "c515c7927fab92d0d9485f49b885b8c5de34fbfb", + Checksum: "c515c7927fab92d0d9485f49b885b8c5de34fbfb", }, }, { Name: "TextureSwiftSupport/Extensions", Version: "3.13.0", + PURL: "pkg:cocoapods/TextureSwiftSupport/Extensions@3.13.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "TextureSwiftSupport/Extensions", - Version: "3.13.0", - PkgHash: "c515c7927fab92d0d9485f49b885b8c5de34fbfb", + Checksum: "c515c7927fab92d0d9485f49b885b8c5de34fbfb", }, }, { Name: "TextureSwiftSupport/LayoutSpecBuilders", Version: "3.13.0", + PURL: "pkg:cocoapods/TextureSwiftSupport/LayoutSpecBuilders@3.13.0", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "TextureSwiftSupport/LayoutSpecBuilders", - Version: "3.13.0", - PkgHash: "c515c7927fab92d0d9485f49b885b8c5de34fbfb", + Checksum: "c515c7927fab92d0d9485f49b885b8c5de34fbfb", }, }, { Name: "TinyConstraints", Version: "4.0.2", + PURL: "pkg:cocoapods/TinyConstraints@4.0.2", + Locations: locations, Language: pkg.Swift, Type: pkg.CocoapodsPkg, MetadataType: pkg.CocoapodsMetadataType, Metadata: pkg.CocoapodsMetadata{ - Name: "TinyConstraints", - Version: "4.0.2", - PkgHash: "7b7ccc0c485bb3bb47082138ff28bc33cd49897f", + Checksum: "7b7ccc0c485bb3bb47082138ff28bc33cd49897f", }, }, } - fixture, err := os.Open("test-fixtures/Podfile.lock") - if err != nil { - t.Fatalf("failed to open fixture: %+v", err) - } - // TODO: no relationships are under test yet - actual, _, err := parsePodfileLock(fixture.Name(), fixture) - if err != nil { - t.Error(err) - } + var expectedRelationships []artifact.Relationship - differences := deep.Equal(expected, actual) - if differences != nil { - t.Errorf("returned package list differed from expectation: %+v", differences) - } + pkgtest.TestFileParser(t, fixture, parsePodfileLock, expectedPkgs, expectedRelationships) } diff --git a/syft/pkg/cocoapods_metadata.go b/syft/pkg/cocoapods_metadata.go index bad5708f7..6fdc9026a 100644 --- a/syft/pkg/cocoapods_metadata.go +++ b/syft/pkg/cocoapods_metadata.go @@ -1,27 +1,5 @@ package pkg -import ( - "github.com/anchore/packageurl-go" - "github.com/anchore/syft/syft/linux" -) - -var _ urlIdentifier = (*CocoapodsMetadata)(nil) - type CocoapodsMetadata struct { - Name string `mapstructure:"name" json:"name"` - Version string `mapstructure:"version" json:"version"` - PkgHash string `mapstructure:"pkgHash" json:"pkgHash"` -} - -func (m CocoapodsMetadata) PackageURL(_ *linux.Release) string { - var qualifiers packageurl.Qualifiers - - return packageurl.NewPackageURL( - packageurl.TypeCocoapods, - "", - m.Name, - m.Version, - qualifiers, - "", - ).ToString() + Checksum string `mapstructure:"checksum" json:"checksum"` } diff --git a/syft/pkg/url_test.go b/syft/pkg/url_test.go index 44eb977b0..eaab158d0 100644 --- a/syft/pkg/url_test.go +++ b/syft/pkg/url_test.go @@ -45,20 +45,6 @@ func TestPackageURL(t *testing.T) { expected: "pkg:maven/g.id/a@v", }, - { - name: "cocoapods", - pkg: Package{ - Name: "GlossButtonNode", - Version: "3.1.2", - Language: Swift, - Type: CocoapodsPkg, - Metadata: CocoapodsMetadata{ - Name: "GlossButtonNode", - Version: "3.1.2", - }, - }, - expected: "pkg:cocoapods/GlossButtonNode@3.1.2", - }, } var pkgTypes []string @@ -85,6 +71,7 @@ func TestPackageURL(t *testing.T) { expectedTypes.Remove(string(GemPkg)) expectedTypes.Remove(string(NpmPkg)) expectedTypes.Remove(string(RustPkg)) + expectedTypes.Remove(string(CocoapodsPkg)) for _, test := range tests { t.Run(test.name, func(t *testing.T) {