mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
finalize json output & add schema (#118)
This commit is contained in:
parent
2560266e38
commit
e2a874a277
19
Makefile
19
Makefile
@ -140,6 +140,19 @@ fixtures:
|
|||||||
$(call title,Generating test fixtures)
|
$(call title,Generating test fixtures)
|
||||||
cd syft/cataloger/java/test-fixtures/java-builds && make
|
cd syft/cataloger/java/test-fixtures/java-builds && make
|
||||||
|
|
||||||
|
.PHONY: generate-json-schema
|
||||||
|
generate-json-schema: clean-json-schema-examples integration ## Generate a new json schema for the json presenter, derived from integration test cases
|
||||||
|
docker run \
|
||||||
|
-i \
|
||||||
|
--rm \
|
||||||
|
-v $(shell pwd)/json-schema:/work \
|
||||||
|
-w /work \
|
||||||
|
python:3.8 \
|
||||||
|
bash -x -c "\
|
||||||
|
pip install -r requirements.txt && \
|
||||||
|
python generate.py \
|
||||||
|
"
|
||||||
|
|
||||||
.PHONY: clear-test-cache
|
.PHONY: clear-test-cache
|
||||||
clear-test-cache: ## Delete all test cache (built docker image tars)
|
clear-test-cache: ## Delete all test cache (built docker image tars)
|
||||||
find . -type f -wholename "**/test-fixtures/tar-cache/*.tar" -delete
|
find . -type f -wholename "**/test-fixtures/tar-cache/*.tar" -delete
|
||||||
@ -215,7 +228,7 @@ release: clean-dist ## Build and publish final binaries and packages
|
|||||||
.github/scripts/update-version-file.sh "$(DISTDIR)" "$(VERSION)"
|
.github/scripts/update-version-file.sh "$(DISTDIR)" "$(VERSION)"
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: clean-dist clean-snapshot ## Remove previous builds and result reports
|
clean: clean-dist clean-snapshot clean-json-schema-examples ## Remove previous builds and result reports
|
||||||
rm -rf $(RESULTSDIR)/*
|
rm -rf $(RESULTSDIR)/*
|
||||||
|
|
||||||
.PHONY: clean-snapshot
|
.PHONY: clean-snapshot
|
||||||
@ -225,3 +238,7 @@ clean-snapshot:
|
|||||||
.PHONY: clean-dist
|
.PHONY: clean-dist
|
||||||
clean-dist:
|
clean-dist:
|
||||||
rm -rf $(DISTDIR) $(TEMPDIR)/goreleaser.yaml
|
rm -rf $(DISTDIR) $(TEMPDIR)/goreleaser.yaml
|
||||||
|
|
||||||
|
.PHONY: clean-json-schema-examples
|
||||||
|
clean-json-schema-examples:
|
||||||
|
rm json-schema/examples/*
|
||||||
1
go.mod
1
go.mod
@ -29,6 +29,7 @@ require (
|
|||||||
github.com/wagoodman/go-rpmdb v0.0.0-20200719223757-ce54a4b0607b
|
github.com/wagoodman/go-rpmdb v0.0.0-20200719223757-ce54a4b0607b
|
||||||
github.com/wagoodman/jotframe v0.0.0-20200730190914-3517092dd163
|
github.com/wagoodman/jotframe v0.0.0-20200730190914-3517092dd163
|
||||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2
|
github.com/x-cray/logrus-prefixed-formatter v0.5.2
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0
|
||||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
||||||
golang.org/x/sys v0.0.0-20200610111108-226ff32320da // indirect
|
golang.org/x/sys v0.0.0-20200610111108-226ff32320da // indirect
|
||||||
google.golang.org/genproto v0.0.0-20200615140333-fd031eab31e7 // indirect
|
google.golang.org/genproto v0.0.0-20200615140333-fd031eab31e7 // indirect
|
||||||
|
|||||||
6
go.sum
6
go.sum
@ -841,6 +841,12 @@ github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7V
|
|||||||
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||||
github.com/xanzy/go-gitlab v0.32.0 h1:tBm+OXv1t+KBsqlXkSDFz+YUjRM0GFsjpOWYOod3Ebs=
|
github.com/xanzy/go-gitlab v0.32.0 h1:tBm+OXv1t+KBsqlXkSDFz+YUjRM0GFsjpOWYOod3Ebs=
|
||||||
github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||||
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
|||||||
1
json-schema/.gitignore
vendored
Normal file
1
json-schema/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
examples/
|
||||||
30
json-schema/generate.py
Normal file
30
json-schema/generate.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/env/bin python3
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import json
|
||||||
|
|
||||||
|
from genson import SchemaBuilder
|
||||||
|
|
||||||
|
EXAMPLES_DIR = "examples/"
|
||||||
|
OUTPUT = "schema.json"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
builder = SchemaBuilder()
|
||||||
|
|
||||||
|
print("Generating new Syft json schema...")
|
||||||
|
for filepath in glob.glob(os.path.join(EXAMPLES_DIR, '*.json')):
|
||||||
|
with open(filepath, 'r') as f:
|
||||||
|
print(f" adding {filepath}")
|
||||||
|
builder.add_object(json.loads(f.read()))
|
||||||
|
|
||||||
|
print("Building schema...")
|
||||||
|
new_schema = builder.to_schema()
|
||||||
|
with open(OUTPUT, 'w') as f:
|
||||||
|
f.write(json.dumps(new_schema, sort_keys=True, indent=4))
|
||||||
|
|
||||||
|
print(f"New schema written to '{OUTPUT}'")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
1
json-schema/requirements.txt
Normal file
1
json-schema/requirements.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
genson
|
||||||
523
json-schema/schema.json
Normal file
523
json-schema/schema.json
Normal file
@ -0,0 +1,523 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/schema#",
|
||||||
|
"properties": {
|
||||||
|
"artifacts": {
|
||||||
|
"items": {
|
||||||
|
"properties": {
|
||||||
|
"metadata": {
|
||||||
|
"properties": {
|
||||||
|
"architecture": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"epoch": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"items": {
|
||||||
|
"properties": {
|
||||||
|
"checksum": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"owner-gid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"owner-uid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"permissions": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"checksum",
|
||||||
|
"owner-gid",
|
||||||
|
"owner-uid",
|
||||||
|
"path",
|
||||||
|
"permissions"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"git-commit-of-apk-port": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"installed-size": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"maintainer": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"manifest": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"extra-fields": {
|
||||||
|
"properties": {
|
||||||
|
"Archiver-Version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Build-Jdk": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Built-By": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Created-By": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Extension-Name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Group-Id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Hudson-Version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Jenkins-Version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Long-Name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Main-Class": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Minimum-Java-Version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-Dependencies": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-Developers": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-License-Name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-License-Url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-ScmUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-Version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Short-Name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"Archiver-Version",
|
||||||
|
"Build-Jdk",
|
||||||
|
"Built-By",
|
||||||
|
"Created-By"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"implementation-title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"implementation-vendor": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"implementation-version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"manifest-version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"specification-title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"specification-vendor": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"specification-version": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"extra-fields",
|
||||||
|
"implementation-title",
|
||||||
|
"implementation-vendor",
|
||||||
|
"implementation-version",
|
||||||
|
"manifest-version",
|
||||||
|
"name",
|
||||||
|
"specification-title",
|
||||||
|
"specification-vendor",
|
||||||
|
"specification-version"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"origin-package": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"package": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"parent-package": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"found-by": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"language": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"licenses": {
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
"manifest": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"properties": {
|
||||||
|
"manifest": {
|
||||||
|
"properties": {
|
||||||
|
"extra-fields": {
|
||||||
|
"properties": {
|
||||||
|
"Archiver-Version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Build-Jdk": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Built-By": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Created-By": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Extension-Name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Group-Id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Hudson-Version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Jenkins-Version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Long-Name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Main-Class": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Minimum-Java-Version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-Dependencies": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-Developers": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-License-Name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-License-Url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-ScmUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Plugin-Version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Short-Name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"Archiver-Version",
|
||||||
|
"Build-Jdk",
|
||||||
|
"Built-By",
|
||||||
|
"Created-By"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"implementation-title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"implementation-vendor": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"implementation-version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"manifest-version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"specification-title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"specification-vendor": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"specification-version": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"extra-fields",
|
||||||
|
"implementation-title",
|
||||||
|
"implementation-vendor",
|
||||||
|
"implementation-version",
|
||||||
|
"manifest-version",
|
||||||
|
"name",
|
||||||
|
"specification-title",
|
||||||
|
"specification-vendor",
|
||||||
|
"specification-version"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"parent-package": {
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
"pom-properties": {
|
||||||
|
"properties": {
|
||||||
|
"Path": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"artifact-id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"extra-fields": {
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
"group-id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"Path",
|
||||||
|
"artifact-id",
|
||||||
|
"extra-fields",
|
||||||
|
"group-id",
|
||||||
|
"name",
|
||||||
|
"version"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"manifest",
|
||||||
|
"parent-package",
|
||||||
|
"pom-properties"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"sources": {
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"found-by",
|
||||||
|
"language",
|
||||||
|
"licenses",
|
||||||
|
"manifest",
|
||||||
|
"metadata",
|
||||||
|
"sources",
|
||||||
|
"type",
|
||||||
|
"version"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pom-properties": {
|
||||||
|
"properties": {
|
||||||
|
"Path": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"artifact-id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"extra-fields": {
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
"group-id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"Path",
|
||||||
|
"artifact-id",
|
||||||
|
"extra-fields",
|
||||||
|
"group-id",
|
||||||
|
"name",
|
||||||
|
"version"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"pull-checksum": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"pull-dependencies": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"sources": {
|
||||||
|
"items": {
|
||||||
|
"properties": {
|
||||||
|
"found-by": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"locations": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"found-by",
|
||||||
|
"locations"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"sources",
|
||||||
|
"type",
|
||||||
|
"version"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"directory": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"properties": {
|
||||||
|
"digest": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"layers": {
|
||||||
|
"items": {
|
||||||
|
"properties": {
|
||||||
|
"digest": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"media-type": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"digest",
|
||||||
|
"media-type",
|
||||||
|
"size"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"media-type": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"digest",
|
||||||
|
"layers",
|
||||||
|
"media-type",
|
||||||
|
"size",
|
||||||
|
"tags"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"artifacts"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
@ -4,9 +4,11 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/internal/log"
|
||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
@ -52,10 +54,14 @@ func parseApkDB(_ string, reader io.Reader) ([]pkg.Package, error) {
|
|||||||
return packages, nil
|
return packages, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint:funlen
|
||||||
func parseApkDBEntry(reader io.Reader) (*pkg.ApkMetadata, error) {
|
func parseApkDBEntry(reader io.Reader) (*pkg.ApkMetadata, error) {
|
||||||
var entry pkg.ApkMetadata
|
var entry pkg.ApkMetadata
|
||||||
pkgFields := make(map[string]interface{})
|
pkgFields := make(map[string]interface{})
|
||||||
files := make([]string, 0)
|
files := make([]pkg.ApkFileRecord, 0)
|
||||||
|
|
||||||
|
var fileRecord *pkg.ApkFileRecord
|
||||||
|
lastFile := "/"
|
||||||
|
|
||||||
scanner := bufio.NewScanner(reader)
|
scanner := bufio.NewScanner(reader)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
@ -70,9 +76,33 @@ func parseApkDBEntry(reader io.Reader) (*pkg.ApkMetadata, error) {
|
|||||||
|
|
||||||
switch key {
|
switch key {
|
||||||
case "F":
|
case "F":
|
||||||
// extract all file entries, don't store in map
|
lastFile = "/" + value
|
||||||
files = append(files, value)
|
|
||||||
continue
|
continue
|
||||||
|
case "R":
|
||||||
|
newFileRecord := pkg.ApkFileRecord{
|
||||||
|
Path: path.Join(lastFile, value),
|
||||||
|
}
|
||||||
|
files = append(files, newFileRecord)
|
||||||
|
fileRecord = &files[len(files)-1]
|
||||||
|
case "a":
|
||||||
|
ownershipFields := strings.Split(value, ":")
|
||||||
|
if len(ownershipFields) != 3 {
|
||||||
|
log.Errorf("unexpected APK ownership field: %q", value)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if fileRecord == nil {
|
||||||
|
log.Errorf("ownership field with no parent record: %q", value)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fileRecord.OwnerUID = ownershipFields[0]
|
||||||
|
fileRecord.OwnerGUI = ownershipFields[1]
|
||||||
|
fileRecord.Permissions = ownershipFields[2]
|
||||||
|
case "Z":
|
||||||
|
if fileRecord == nil {
|
||||||
|
log.Errorf("checksum field with no parent record: %q", value)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fileRecord.Checksum = value
|
||||||
case "I", "S":
|
case "I", "S":
|
||||||
// coerce to integer
|
// coerce to integer
|
||||||
iVal, err := strconv.Atoi(value)
|
iVal, err := strconv.Atoi(value)
|
||||||
|
|||||||
@ -31,7 +31,43 @@ func TestSinglePackage(t *testing.T) {
|
|||||||
PullDependencies: "scanelf so:libc.musl-x86_64.so.1",
|
PullDependencies: "scanelf so:libc.musl-x86_64.so.1",
|
||||||
PullChecksum: "Q1bTtF5526tETKfL+lnigzIDvm+2o=",
|
PullChecksum: "Q1bTtF5526tETKfL+lnigzIDvm+2o=",
|
||||||
GitCommitOfAport: "4024cc3b29ad4c65544ad068b8f59172b5494306",
|
GitCommitOfAport: "4024cc3b29ad4c65544ad068b8f59172b5494306",
|
||||||
Files: []string{"sbin", "usr", "usr/bin"},
|
Files: []pkg.ApkFileRecord{
|
||||||
|
{
|
||||||
|
Path: "/sbin/ldconfig",
|
||||||
|
OwnerUID: "0",
|
||||||
|
OwnerGUI: "0",
|
||||||
|
Permissions: "755",
|
||||||
|
Checksum: "Q1Kja2+POZKxEkUOZqwSjC6kmaED4=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/usr/bin/iconv",
|
||||||
|
OwnerUID: "0",
|
||||||
|
OwnerGUI: "0",
|
||||||
|
Permissions: "755",
|
||||||
|
Checksum: "Q1CVmFbdY+Hv6/jAHl1gec2Kbx1EY=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/usr/bin/ldd",
|
||||||
|
OwnerUID: "0",
|
||||||
|
OwnerGUI: "0",
|
||||||
|
Permissions: "755",
|
||||||
|
Checksum: "Q1yFAhGggmL7ERgbIA7KQxyTzf3ks=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/usr/bin/getconf",
|
||||||
|
OwnerUID: "0",
|
||||||
|
OwnerGUI: "0",
|
||||||
|
Permissions: "755",
|
||||||
|
Checksum: "Q1dAdYK8M/INibRQF5B3Rw7cmNDDA=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/usr/bin/getent",
|
||||||
|
OwnerUID: "0",
|
||||||
|
OwnerGUI: "0",
|
||||||
|
Permissions: "755",
|
||||||
|
Checksum: "Q1eR2Dz/WylabgbWMTkd2+hGmEya4=",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -92,7 +128,7 @@ func TestMultiplePackages(t *testing.T) {
|
|||||||
PullChecksum: "Q1p78yvTLG094tHE1+dToJGbmYzQE=",
|
PullChecksum: "Q1p78yvTLG094tHE1+dToJGbmYzQE=",
|
||||||
GitCommitOfAport: "97b1c2842faa3bfa30f5811ffbf16d5ff9f1a479",
|
GitCommitOfAport: "97b1c2842faa3bfa30f5811ffbf16d5ff9f1a479",
|
||||||
PullDependencies: "musl-utils",
|
PullDependencies: "musl-utils",
|
||||||
Files: []string{},
|
Files: []pkg.ApkFileRecord{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -114,7 +150,43 @@ func TestMultiplePackages(t *testing.T) {
|
|||||||
PullDependencies: "scanelf so:libc.musl-x86_64.so.1",
|
PullDependencies: "scanelf so:libc.musl-x86_64.so.1",
|
||||||
PullChecksum: "Q1bTtF5526tETKfL+lnigzIDvm+2o=",
|
PullChecksum: "Q1bTtF5526tETKfL+lnigzIDvm+2o=",
|
||||||
GitCommitOfAport: "4024cc3b29ad4c65544ad068b8f59172b5494306",
|
GitCommitOfAport: "4024cc3b29ad4c65544ad068b8f59172b5494306",
|
||||||
Files: []string{"sbin", "usr", "usr/bin"},
|
Files: []pkg.ApkFileRecord{
|
||||||
|
{
|
||||||
|
Path: "/sbin/ldconfig",
|
||||||
|
OwnerUID: "0",
|
||||||
|
OwnerGUI: "0",
|
||||||
|
Permissions: "755",
|
||||||
|
Checksum: "Q1Kja2+POZKxEkUOZqwSjC6kmaED4=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/usr/bin/iconv",
|
||||||
|
OwnerUID: "0",
|
||||||
|
OwnerGUI: "0",
|
||||||
|
Permissions: "755",
|
||||||
|
Checksum: "Q1CVmFbdY+Hv6/jAHl1gec2Kbx1EY=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/usr/bin/ldd",
|
||||||
|
OwnerUID: "0",
|
||||||
|
OwnerGUI: "0",
|
||||||
|
Permissions: "755",
|
||||||
|
Checksum: "Q1yFAhGggmL7ERgbIA7KQxyTzf3ks=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/usr/bin/getconf",
|
||||||
|
OwnerUID: "0",
|
||||||
|
OwnerGUI: "0",
|
||||||
|
Permissions: "755",
|
||||||
|
Checksum: "Q1dAdYK8M/INibRQF5B3Rw7cmNDDA=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/usr/bin/getent",
|
||||||
|
OwnerUID: "0",
|
||||||
|
OwnerGUI: "0",
|
||||||
|
Permissions: "755",
|
||||||
|
Checksum: "Q1eR2Dz/WylabgbWMTkd2+hGmEya4=",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,61 +1,70 @@
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
// TODO: consider keeping the remaining values as an embedded map
|
|
||||||
// Available fields are described at http://manpages.ubuntu.com/manpages/xenial/man1/dpkg-query.1.html
|
// Available fields are described at http://manpages.ubuntu.com/manpages/xenial/man1/dpkg-query.1.html
|
||||||
// in the --showformat section
|
// in the --showformat section
|
||||||
type DpkgMetadata struct {
|
type DpkgMetadata struct {
|
||||||
Package string `mapstructure:"Package"`
|
Package string `mapstructure:"Package" json:"package"`
|
||||||
Source string `mapstructure:"Source"`
|
Source string `mapstructure:"Source" json:"source"`
|
||||||
Version string `mapstructure:"Version"`
|
Version string `mapstructure:"Version" json:"version"`
|
||||||
|
// TODO: consider keeping the remaining values as an embedded map
|
||||||
}
|
}
|
||||||
|
|
||||||
type RpmMetadata struct {
|
type RpmMetadata struct {
|
||||||
Epoch int `mapstructure:"Epoch"`
|
Epoch int `mapstructure:"Epoch" json:"epoch"`
|
||||||
Arch string `mapstructure:"Arch"`
|
Arch string `mapstructure:"Arch" json:"architecture"`
|
||||||
Release string `mapstructure:"Release"`
|
Release string `mapstructure:"Release" json:"release"`
|
||||||
|
// TODO: consider keeping the remaining values as an embedded map
|
||||||
}
|
}
|
||||||
|
|
||||||
type JavaManifest struct {
|
type JavaManifest struct {
|
||||||
Name string `mapstructure:"Name"`
|
Name string `mapstructure:"Name" json:"name"`
|
||||||
ManifestVersion string `mapstructure:"Manifest-Version"`
|
ManifestVersion string `mapstructure:"Manifest-Version" json:"manifest-version"`
|
||||||
SpecTitle string `mapstructure:"Specification-Title"`
|
SpecTitle string `mapstructure:"Specification-Title" json:"specification-title"`
|
||||||
SpecVersion string `mapstructure:"Specification-Version"`
|
SpecVersion string `mapstructure:"Specification-Version" json:"specification-version"`
|
||||||
SpecVendor string `mapstructure:"Specification-Vendor"`
|
SpecVendor string `mapstructure:"Specification-Vendor" json:"specification-vendor"`
|
||||||
ImplTitle string `mapstructure:"Implementation-Title"`
|
ImplTitle string `mapstructure:"Implementation-Title" json:"implementation-title"`
|
||||||
ImplVersion string `mapstructure:"Implementation-Version"`
|
ImplVersion string `mapstructure:"Implementation-Version" json:"implementation-version"`
|
||||||
ImplVendor string `mapstructure:"Implementation-Vendor"`
|
ImplVendor string `mapstructure:"Implementation-Vendor" json:"implementation-vendor"`
|
||||||
Extra map[string]string `mapstructure:",remain"`
|
Extra map[string]string `mapstructure:",remain" json:"extra-fields"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PomProperties struct {
|
type PomProperties struct {
|
||||||
Path string
|
Path string
|
||||||
Name string `mapstructure:"name"`
|
Name string `mapstructure:"name" json:"name"`
|
||||||
GroupID string `mapstructure:"groupId"`
|
GroupID string `mapstructure:"groupId" json:"group-id"`
|
||||||
ArtifactID string `mapstructure:"artifactId"`
|
ArtifactID string `mapstructure:"artifactId" json:"artifact-id"`
|
||||||
Version string `mapstructure:"version"`
|
Version string `mapstructure:"version" json:"version"`
|
||||||
Extra map[string]string `mapstructure:",remain"`
|
Extra map[string]string `mapstructure:",remain" json:"extra-fields"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type JavaMetadata struct {
|
type JavaMetadata struct {
|
||||||
Manifest *JavaManifest `mapstructure:"Manifest"`
|
Manifest *JavaManifest `mapstructure:"Manifest" json:"manifest"`
|
||||||
PomProperties *PomProperties `mapstructure:"PomProperties"`
|
PomProperties *PomProperties `mapstructure:"PomProperties" json:"pom-properties"`
|
||||||
Parent *Package
|
Parent *Package `json:"parent-package"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// source: https://wiki.alpinelinux.org/wiki/Apk_spec
|
// source: https://wiki.alpinelinux.org/wiki/Apk_spec
|
||||||
type ApkMetadata struct {
|
type ApkMetadata struct {
|
||||||
Package string `mapstructure:"P"`
|
Package string `mapstructure:"P" json:"package"`
|
||||||
OriginPackage string `mapstructure:"o"`
|
OriginPackage string `mapstructure:"o" json:"origin-package"`
|
||||||
Maintainer string `mapstructure:"m"`
|
Maintainer string `mapstructure:"m" json:"maintainer"`
|
||||||
Version string `mapstructure:"V"`
|
Version string `mapstructure:"V" json:"version"`
|
||||||
License string `mapstructure:"L"`
|
License string `mapstructure:"L" json:"license"`
|
||||||
Architecture string `mapstructure:"A"`
|
Architecture string `mapstructure:"A" json:"architecture"`
|
||||||
URL string `mapstructure:"U"`
|
URL string `mapstructure:"U" json:"url"`
|
||||||
Description string `mapstructure:"T"`
|
Description string `mapstructure:"T" json:"description"`
|
||||||
Size int `mapstructure:"S"`
|
Size int `mapstructure:"S" json:"size"`
|
||||||
InstalledSize int `mapstructure:"I"`
|
InstalledSize int `mapstructure:"I" json:"installed-size"`
|
||||||
PullDependencies string `mapstructure:"D"`
|
PullDependencies string `mapstructure:"D" json:"pull-dependencies"`
|
||||||
PullChecksum string `mapstructure:"C"`
|
PullChecksum string `mapstructure:"C" json:"pull-checksum"`
|
||||||
GitCommitOfAport string `mapstructure:"c"`
|
GitCommitOfAport string `mapstructure:"c" json:"git-commit-of-apk-port"`
|
||||||
Files []string
|
Files []ApkFileRecord `json:"files"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApkFileRecord struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
OwnerUID string `json:"owner-uid"`
|
||||||
|
OwnerGUI string `json:"owner-gid"`
|
||||||
|
Permissions string `json:"permissions"`
|
||||||
|
Checksum string `json:"checksum"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,15 +12,15 @@ type ID int64
|
|||||||
|
|
||||||
// Package represents an application or library that has been bundled into a distributable format
|
// Package represents an application or library that has been bundled into a distributable format
|
||||||
type Package struct {
|
type Package struct {
|
||||||
id ID // this is set when a package is added to the catalog
|
id ID // this is set when a package is added to the catalog
|
||||||
Name string
|
Name string `json:"manifest"`
|
||||||
Version string
|
Version string `json:"version"`
|
||||||
FoundBy string
|
FoundBy string `json:"found-by"`
|
||||||
Source []file.Reference
|
Source []file.Reference `json:"sources"`
|
||||||
Licenses []string
|
Licenses []string `json:"licenses"` // TODO: should we move this into metadata?
|
||||||
Language Language // TODO: should this support multiple languages as a slice?
|
Language Language `json:"language"` // TODO: should this support multiple languages as a slice?
|
||||||
Type Type
|
Type Type `json:"type"`
|
||||||
Metadata interface{}
|
Metadata interface{} `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Package) ID() ID {
|
func (p Package) ID() ID {
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/anchore/syft/internal/log"
|
|
||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
"github.com/anchore/syft/syft/scope"
|
"github.com/anchore/syft/syft/scope"
|
||||||
)
|
)
|
||||||
@ -24,36 +23,35 @@ func NewPresenter(catalog *pkg.Catalog, s scope.Scope) *Presenter {
|
|||||||
|
|
||||||
type document struct {
|
type document struct {
|
||||||
Artifacts []artifact `json:"artifacts"`
|
Artifacts []artifact `json:"artifacts"`
|
||||||
Image image `json:"image"`
|
Image *image `json:"image,omitempty"`
|
||||||
Source string
|
Directory *string `json:"directory,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type image struct {
|
type image struct {
|
||||||
Layers []layer `json:"layers"`
|
Layers []layer `json:"layers"`
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
Digest string `json:"digest"`
|
Digest string `json:"digest"`
|
||||||
MediaType string `json:"mediaType"`
|
MediaType string `json:"media-type"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type layer struct {
|
type layer struct {
|
||||||
MediaType string `json:"mediaType"`
|
MediaType string `json:"media-type"`
|
||||||
Digest string `json:"digest"`
|
Digest string `json:"digest"`
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type source struct {
|
type source struct {
|
||||||
FoundBy string `json:"foundBy"`
|
FoundBy string `json:"found-by"`
|
||||||
Effects []string `json:"effects"`
|
Locations []string `json:"locations"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type artifact struct {
|
type artifact struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Cataloger string `json:"cataloger"`
|
Sources []source `json:"sources"`
|
||||||
Sources []source `json:"sources"`
|
Metadata interface{} `json:"metadata,omitempty"`
|
||||||
Metadata interface{} `json:"metadata,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pres *Presenter) Present(output io.Writer) error {
|
func (pres *Presenter) Present(output io.Writer) error {
|
||||||
@ -69,15 +67,25 @@ func (pres *Presenter) Present(output io.Writer) error {
|
|||||||
for idx, tag := range src.Img.Metadata.Tags {
|
for idx, tag := range src.Img.Metadata.Tags {
|
||||||
tags[idx] = tag.String()
|
tags[idx] = tag.String()
|
||||||
}
|
}
|
||||||
doc.Image = image{
|
doc.Image = &image{
|
||||||
Digest: src.Img.Metadata.Digest,
|
Digest: src.Img.Metadata.Digest,
|
||||||
Size: src.Img.Metadata.Size,
|
Size: src.Img.Metadata.Size,
|
||||||
MediaType: string(src.Img.Metadata.MediaType),
|
MediaType: string(src.Img.Metadata.MediaType),
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
Layers: make([]layer, len(src.Img.Layers)),
|
Layers: make([]layer, len(src.Img.Layers)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// populate image metadata
|
||||||
|
for idx, l := range src.Img.Layers {
|
||||||
|
doc.Image.Layers[idx] = layer{
|
||||||
|
MediaType: string(l.Metadata.MediaType),
|
||||||
|
Digest: l.Metadata.Digest,
|
||||||
|
Size: l.Metadata.Size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case scope.DirSource:
|
case scope.DirSource:
|
||||||
doc.Source = pres.scope.DirSrc.Path
|
doc.Directory = &pres.scope.DirSrc.Path
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported source: %T", src)
|
return fmt.Errorf("unsupported source: %T", src)
|
||||||
}
|
}
|
||||||
@ -93,8 +101,8 @@ func (pres *Presenter) Present(output io.Writer) error {
|
|||||||
|
|
||||||
for idx := range p.Source {
|
for idx := range p.Source {
|
||||||
srcObj := source{
|
srcObj := source{
|
||||||
FoundBy: p.FoundBy,
|
FoundBy: p.FoundBy,
|
||||||
Effects: []string{}, // TODO
|
Locations: []string{string(p.Source[idx].Path)},
|
||||||
}
|
}
|
||||||
art.Sources[idx] = srcObj
|
art.Sources[idx] = srcObj
|
||||||
}
|
}
|
||||||
@ -102,11 +110,9 @@ func (pres *Presenter) Present(output io.Writer) error {
|
|||||||
doc.Artifacts = append(doc.Artifacts, art)
|
doc.Artifacts = append(doc.Artifacts, art)
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes, err := json.Marshal(&doc)
|
enc := json.NewEncoder(output)
|
||||||
if err != nil {
|
// prevent > and < from being escaped in the payload
|
||||||
log.Errorf("failed to marshal json (presenter=json): %w", err)
|
enc.SetEscapeHTML(false)
|
||||||
}
|
enc.SetIndent("", " ")
|
||||||
|
return enc.Encode(&doc)
|
||||||
_, err = output.Write(bytes)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,7 +109,4 @@ func TestJsonImgsPresenter(t *testing.T) {
|
|||||||
diffs := dmp.DiffMain(string(actual), string(expected), true)
|
diffs := dmp.DiffMain(string(actual), string(expected), true)
|
||||||
t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
|
t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add me back in when there is a JSON schema
|
|
||||||
// validateAgainstV1Schema(t, string(actual))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1,17 @@
|
|||||||
{"artifacts":[{"name":"package-1","version":"1.0.1","type":"deb","cataloger":"","sources":[]},{"name":"package-2","version":"2.0.1","type":"deb","cataloger":"","sources":[]}],"image":{"layers":null,"size":0,"digest":"","mediaType":"","tags":null},"Source":"/some/path"}
|
{
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"name": "package-1",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"type": "deb",
|
||||||
|
"sources": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "package-2",
|
||||||
|
"version": "2.0.1",
|
||||||
|
"type": "deb",
|
||||||
|
"sources": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directory": "/some/path"
|
||||||
|
}
|
||||||
|
|||||||
@ -1 +1,55 @@
|
|||||||
{"artifacts":[{"name":"package-1","version":"1.0.1","type":"deb","cataloger":"","sources":[{"foundBy":"","effects":[]}]},{"name":"package-2","version":"2.0.1","type":"deb","cataloger":"","sources":[{"foundBy":"","effects":[]}]}],"image":{"layers":[{"mediaType":"","digest":"","size":0},{"mediaType":"","digest":"","size":0},{"mediaType":"","digest":"","size":0}],"size":65,"digest":"sha256:3c53d2d891940f8d8e95acb77b58752f54dc5de9d91d19dd90ced2db76256cea","mediaType":"application/vnd.docker.distribution.manifest.v2+json","tags":["anchore-fixture-image-simple:04e16e44161c8888a1a963720fd0443cbf7eef8101434c431de8725cd98cc9f7"]},"Source":""}
|
{
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"name": "package-1",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"type": "deb",
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"found-by": "",
|
||||||
|
"locations": [
|
||||||
|
"/somefile-1.txt"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "package-2",
|
||||||
|
"version": "2.0.1",
|
||||||
|
"type": "deb",
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"found-by": "",
|
||||||
|
"locations": [
|
||||||
|
"/somefile-2.txt"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"image": {
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"media-type": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||||
|
"digest": "sha256:056c0789fa9ad629ceae6d09713fb035f84115af3c4a88a43aa60f13bc683053",
|
||||||
|
"size": 22
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"media-type": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||||
|
"digest": "sha256:b461c48116592c570a66fed71d5b09662a8172e168b7938cf317af47872cdc9b",
|
||||||
|
"size": 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"media-type": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||||
|
"digest": "sha256:00b80053e05c01da485015610d288ce3185fac00d251e2ada02b45a7a7c5f589",
|
||||||
|
"size": 27
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"size": 65,
|
||||||
|
"digest": "sha256:3c53d2d891940f8d8e95acb77b58752f54dc5de9d91d19dd90ced2db76256cea",
|
||||||
|
"media-type": "application/vnd.docker.distribution.manifest.v2+json",
|
||||||
|
"tags": [
|
||||||
|
"anchore-fixture-image-simple:04e16e44161c8888a1a963720fd0443cbf7eef8101434c431de8725cd98cc9f7"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -62,7 +62,4 @@ func TestTablePresenter(t *testing.T) {
|
|||||||
diffs := dmp.DiffMain(string(actual), string(expected), true)
|
diffs := dmp.DiffMain(string(actual), string(expected), true)
|
||||||
t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
|
t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add me back in when there is a JSON schema
|
|
||||||
// validateAgainstV1Schema(t, string(actual))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/sergi/go-diff/diffmatchpatch"
|
"github.com/sergi/go-diff/diffmatchpatch"
|
||||||
)
|
)
|
||||||
|
|
||||||
var update = flag.Bool("update", false, "update the *.golden files for json presenters")
|
var update = flag.Bool("update", false, "update the *.golden files for text presenters")
|
||||||
|
|
||||||
func TestTextDirPresenter(t *testing.T) {
|
func TestTextDirPresenter(t *testing.T) {
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
|
|||||||
121
test/integration/json_schema_test.go
Normal file
121
test/integration/json_schema_test.go
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
// +build integration
|
||||||
|
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"github.com/anchore/go-testutils"
|
||||||
|
"github.com/anchore/syft/syft"
|
||||||
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
"github.com/anchore/syft/syft/presenter"
|
||||||
|
"github.com/anchore/syft/syft/scope"
|
||||||
|
"github.com/xeipuuv/gojsonschema"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const jsonSchemaExamplesPath = "json-schema/examples"
|
||||||
|
|
||||||
|
func repoRoot(t *testing.T) string {
|
||||||
|
t.Helper()
|
||||||
|
repoRoot, err := exec.Command("git", "rev-parse", "--show-toplevel").Output()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to find repo root dir: %+v", err)
|
||||||
|
}
|
||||||
|
absRepoRoot, err := filepath.Abs(strings.TrimSpace(string(repoRoot)))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("unable to get abs path to repo root:", err)
|
||||||
|
}
|
||||||
|
return absRepoRoot
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateAgainstV1Schema(t *testing.T, json string) {
|
||||||
|
fullSchemaPath := path.Join(repoRoot(t), "json-schema", "schema.json")
|
||||||
|
schemaLoader := gojsonschema.NewReferenceLoader(fmt.Sprintf("file://%s", fullSchemaPath))
|
||||||
|
documentLoader := gojsonschema.NewStringLoader(json)
|
||||||
|
|
||||||
|
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("unable to validate json schema:", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if !result.Valid() {
|
||||||
|
t.Errorf("failed json schema validation:")
|
||||||
|
for _, desc := range result.Errors() {
|
||||||
|
t.Errorf(" - %s\n", desc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testJsonSchema(t *testing.T, catalog *pkg.Catalog, theScope *scope.Scope, prefix string) {
|
||||||
|
// make the json output example dir if it does not exist
|
||||||
|
absJsonSchemaExamplesPath := path.Join(repoRoot(t), jsonSchemaExamplesPath)
|
||||||
|
if _, err := os.Stat(absJsonSchemaExamplesPath); os.IsNotExist(err) {
|
||||||
|
os.Mkdir(absJsonSchemaExamplesPath, 0755)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := bytes.NewBufferString("")
|
||||||
|
|
||||||
|
p := presenter.GetPresenter(presenter.JSONPresenter, *theScope, catalog)
|
||||||
|
if p == nil {
|
||||||
|
t.Fatal("unable to get presenter")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := p.Present(output)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to present: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// we use the examples dir as a way to use integration tests to drive what valid examples are in case we
|
||||||
|
// want to update the json schema. We do not want to validate the output of the presentation format as the
|
||||||
|
// contents may change regularly, making the integration tests brittle.
|
||||||
|
testFileName := prefix + "_" + path.Base(t.Name()) + ".json"
|
||||||
|
testFilePath := path.Join(absJsonSchemaExamplesPath, testFileName)
|
||||||
|
|
||||||
|
fh, err := os.OpenFile(testFilePath, os.O_WRONLY|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to open json example path: %+v", err)
|
||||||
|
}
|
||||||
|
_, err = fh.WriteString(output.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to write json example: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
validateAgainstV1Schema(t, output.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJsonSchemaImg(t *testing.T) {
|
||||||
|
fixtureImageName := "image-pkg-coverage"
|
||||||
|
_, cleanup := testutils.GetFixtureImage(t, "docker-archive", fixtureImageName)
|
||||||
|
tarPath := testutils.GetFixtureImageTarPath(t, fixtureImageName)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
catalog, theScope, _, err := syft.Catalog("docker-archive://"+tarPath, scope.AllLayersScope)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to catalog image: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
testJsonSchema(t, catalog, theScope, "img")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJsonSchemaDirs(t *testing.T) {
|
||||||
|
catalog, theScope, _, err := syft.Catalog("dir://test-fixtures/image-pkg-coverage", scope.AllLayersScope)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unable to create scope from dir: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
testJsonSchema(t, catalog, theScope, "dir")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
161
test/integration/pkg_cases.go
Normal file
161
test/integration/pkg_cases.go
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
// +build integration
|
||||||
|
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import "github.com/anchore/syft/syft/pkg"
|
||||||
|
|
||||||
|
var cases = []struct {
|
||||||
|
name string
|
||||||
|
pkgType pkg.Type
|
||||||
|
pkgLanguage pkg.Language
|
||||||
|
pkgInfo map[string]string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "find rpmdb packages",
|
||||||
|
pkgType: pkg.RpmPkg,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"dive": "0.9.2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find dpkg packages",
|
||||||
|
pkgType: pkg.DebPkg,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"apt": "1.8.2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find java packages",
|
||||||
|
pkgType: pkg.JavaPkg,
|
||||||
|
pkgLanguage: pkg.Java,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"example-java-app-maven": "0.1.0",
|
||||||
|
"example-jenkins-plugin": "1.0-SNAPSHOT", // the jenkins HPI file has a nested JAR of the same name
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find jenkins plugins",
|
||||||
|
pkgType: pkg.JenkinsPluginPkg,
|
||||||
|
pkgLanguage: pkg.Java,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"example-jenkins-plugin": "1.0-SNAPSHOT",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find python wheel packages",
|
||||||
|
pkgType: pkg.WheelPkg,
|
||||||
|
pkgLanguage: pkg.Python,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"Pygments": "2.6.1",
|
||||||
|
"requests": "2.10.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find javascript npm packages",
|
||||||
|
pkgType: pkg.NpmPkg,
|
||||||
|
pkgLanguage: pkg.JavaScript,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"get-stdin": "8.0.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find javascript yarn packages",
|
||||||
|
pkgType: pkg.YarnPkg,
|
||||||
|
pkgLanguage: pkg.JavaScript,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"@babel/code-frame": "7.10.4",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find python egg packages",
|
||||||
|
pkgType: pkg.EggPkg,
|
||||||
|
pkgLanguage: pkg.Python,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"requests": "2.22.0",
|
||||||
|
"otherpkg": "2.19.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find python packages",
|
||||||
|
pkgType: pkg.PythonRequirementsPkg,
|
||||||
|
pkgLanguage: pkg.Python,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"flask": "4.0.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find bundler packages",
|
||||||
|
pkgType: pkg.BundlerPkg,
|
||||||
|
pkgLanguage: pkg.Ruby,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"actionmailer": "4.1.1",
|
||||||
|
"actionpack": "4.1.1",
|
||||||
|
"actionview": "4.1.1",
|
||||||
|
"activemodel": "4.1.1",
|
||||||
|
"activerecord": "4.1.1",
|
||||||
|
"activesupport": "4.1.1",
|
||||||
|
"arel": "5.0.1.20140414130214",
|
||||||
|
"bootstrap-sass": "3.1.1.1",
|
||||||
|
"builder": "3.2.2",
|
||||||
|
"coffee-rails": "4.0.1",
|
||||||
|
"coffee-script": "2.2.0",
|
||||||
|
"coffee-script-source": "1.7.0",
|
||||||
|
"erubis": "2.7.0",
|
||||||
|
"execjs": "2.0.2",
|
||||||
|
"hike": "1.2.3",
|
||||||
|
"i18n": "0.6.9",
|
||||||
|
"jbuilder": "2.0.7",
|
||||||
|
"jquery-rails": "3.1.0",
|
||||||
|
"json": "1.8.1",
|
||||||
|
"kgio": "2.9.2",
|
||||||
|
"libv8": "3.16.14.3",
|
||||||
|
"mail": "2.5.4",
|
||||||
|
"mime-types": "1.25.1",
|
||||||
|
"minitest": "5.3.4",
|
||||||
|
"multi_json": "1.10.1",
|
||||||
|
"mysql2": "0.3.16",
|
||||||
|
"polyglot": "0.3.4",
|
||||||
|
"rack": "1.5.2",
|
||||||
|
"rack-test": "0.6.2",
|
||||||
|
"rails": "4.1.1",
|
||||||
|
"railties": "4.1.1",
|
||||||
|
"raindrops": "0.13.0",
|
||||||
|
"rake": "10.3.2",
|
||||||
|
"rdoc": "4.1.1",
|
||||||
|
"ref": "1.0.5",
|
||||||
|
"sass": "3.2.19",
|
||||||
|
"sass-rails": "4.0.3",
|
||||||
|
"sdoc": "0.4.0",
|
||||||
|
"spring": "1.1.3",
|
||||||
|
"sprockets": "2.11.0",
|
||||||
|
"sprockets-rails": "2.1.3",
|
||||||
|
"sqlite3": "1.3.9",
|
||||||
|
"therubyracer": "0.12.1",
|
||||||
|
"thor": "0.19.1",
|
||||||
|
"thread_safe": "0.3.3",
|
||||||
|
"tilt": "1.4.1",
|
||||||
|
"treetop": "1.4.15",
|
||||||
|
"turbolinks": "2.2.2",
|
||||||
|
"tzinfo": "1.2.0",
|
||||||
|
"uglifier": "2.5.0",
|
||||||
|
"unicorn": "4.8.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
|
||||||
|
name: "find apkdb packages",
|
||||||
|
pkgType: pkg.ApkPkg,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"musl-utils": "1.1.24-r2",
|
||||||
|
"libc-utils": "0.7.2-r0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find golang modules",
|
||||||
|
pkgType: pkg.GoModulePkg,
|
||||||
|
pkgLanguage: pkg.Go,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"github.com/bmatcuk/doublestar": "v1.3.1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -14,162 +14,6 @@ import (
|
|||||||
"github.com/anchore/syft/syft/scope"
|
"github.com/anchore/syft/syft/scope"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cases = []struct {
|
|
||||||
name string
|
|
||||||
pkgType pkg.Type
|
|
||||||
pkgLanguage pkg.Language
|
|
||||||
pkgInfo map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "find rpmdb packages",
|
|
||||||
pkgType: pkg.RpmPkg,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"dive": "0.9.2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find dpkg packages",
|
|
||||||
pkgType: pkg.DebPkg,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"apt": "1.8.2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find java packages",
|
|
||||||
pkgType: pkg.JavaPkg,
|
|
||||||
pkgLanguage: pkg.Java,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"example-java-app-maven": "0.1.0",
|
|
||||||
"example-jenkins-plugin": "1.0-SNAPSHOT", // the jenkins HPI file has a nested JAR of the same name
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find jenkins plugins",
|
|
||||||
pkgType: pkg.JenkinsPluginPkg,
|
|
||||||
pkgLanguage: pkg.Java,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"example-jenkins-plugin": "1.0-SNAPSHOT",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find python wheel packages",
|
|
||||||
pkgType: pkg.WheelPkg,
|
|
||||||
pkgLanguage: pkg.Python,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"Pygments": "2.6.1",
|
|
||||||
"requests": "2.10.0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find javascript npm packages",
|
|
||||||
pkgType: pkg.NpmPkg,
|
|
||||||
pkgLanguage: pkg.JavaScript,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"get-stdin": "8.0.0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find javascript yarn packages",
|
|
||||||
pkgType: pkg.YarnPkg,
|
|
||||||
pkgLanguage: pkg.JavaScript,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"@babel/code-frame": "7.10.4",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find python egg packages",
|
|
||||||
pkgType: pkg.EggPkg,
|
|
||||||
pkgLanguage: pkg.Python,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"requests": "2.22.0",
|
|
||||||
"otherpkg": "2.19.0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find python packages",
|
|
||||||
pkgType: pkg.PythonRequirementsPkg,
|
|
||||||
pkgLanguage: pkg.Python,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"flask": "4.0.0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find bundler packages",
|
|
||||||
pkgType: pkg.BundlerPkg,
|
|
||||||
pkgLanguage: pkg.Ruby,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"actionmailer": "4.1.1",
|
|
||||||
"actionpack": "4.1.1",
|
|
||||||
"actionview": "4.1.1",
|
|
||||||
"activemodel": "4.1.1",
|
|
||||||
"activerecord": "4.1.1",
|
|
||||||
"activesupport": "4.1.1",
|
|
||||||
"arel": "5.0.1.20140414130214",
|
|
||||||
"bootstrap-sass": "3.1.1.1",
|
|
||||||
"builder": "3.2.2",
|
|
||||||
"coffee-rails": "4.0.1",
|
|
||||||
"coffee-script": "2.2.0",
|
|
||||||
"coffee-script-source": "1.7.0",
|
|
||||||
"erubis": "2.7.0",
|
|
||||||
"execjs": "2.0.2",
|
|
||||||
"hike": "1.2.3",
|
|
||||||
"i18n": "0.6.9",
|
|
||||||
"jbuilder": "2.0.7",
|
|
||||||
"jquery-rails": "3.1.0",
|
|
||||||
"json": "1.8.1",
|
|
||||||
"kgio": "2.9.2",
|
|
||||||
"libv8": "3.16.14.3",
|
|
||||||
"mail": "2.5.4",
|
|
||||||
"mime-types": "1.25.1",
|
|
||||||
"minitest": "5.3.4",
|
|
||||||
"multi_json": "1.10.1",
|
|
||||||
"mysql2": "0.3.16",
|
|
||||||
"polyglot": "0.3.4",
|
|
||||||
"rack": "1.5.2",
|
|
||||||
"rack-test": "0.6.2",
|
|
||||||
"rails": "4.1.1",
|
|
||||||
"railties": "4.1.1",
|
|
||||||
"raindrops": "0.13.0",
|
|
||||||
"rake": "10.3.2",
|
|
||||||
"rdoc": "4.1.1",
|
|
||||||
"ref": "1.0.5",
|
|
||||||
"sass": "3.2.19",
|
|
||||||
"sass-rails": "4.0.3",
|
|
||||||
"sdoc": "0.4.0",
|
|
||||||
"spring": "1.1.3",
|
|
||||||
"sprockets": "2.11.0",
|
|
||||||
"sprockets-rails": "2.1.3",
|
|
||||||
"sqlite3": "1.3.9",
|
|
||||||
"therubyracer": "0.12.1",
|
|
||||||
"thor": "0.19.1",
|
|
||||||
"thread_safe": "0.3.3",
|
|
||||||
"tilt": "1.4.1",
|
|
||||||
"treetop": "1.4.15",
|
|
||||||
"turbolinks": "2.2.2",
|
|
||||||
"tzinfo": "1.2.0",
|
|
||||||
"uglifier": "2.5.0",
|
|
||||||
"unicorn": "4.8.3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
|
|
||||||
name: "find apkdb packages",
|
|
||||||
pkgType: pkg.ApkPkg,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"musl-utils": "1.1.24-r2",
|
|
||||||
"libc-utils": "0.7.2-r0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find golang modules",
|
|
||||||
pkgType: pkg.GoModulePkg,
|
|
||||||
pkgLanguage: pkg.Go,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"github.com/bmatcuk/doublestar": "v1.3.1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPkgCoverageImage(t *testing.T) {
|
func TestPkgCoverageImage(t *testing.T) {
|
||||||
fixtureImageName := "image-pkg-coverage"
|
fixtureImageName := "image-pkg-coverage"
|
||||||
_, cleanup := testutils.GetFixtureImage(t, "docker-archive", fixtureImageName)
|
_, cleanup := testutils.GetFixtureImage(t, "docker-archive", fixtureImageName)
|
||||||
File diff suppressed because one or more lines are too long
@ -1,256 +0,0 @@
|
|||||||
[Path: test-fixtures]
|
|
||||||
[actionmailer]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[actionpack]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[actionview]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[activemodel]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[activerecord]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[activesupport]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[arel]
|
|
||||||
Version: 5.0.1.20140414130214
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[bootstrap-sass]
|
|
||||||
Version: 3.1.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[builder]
|
|
||||||
Version: 3.2.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[coffee-rails]
|
|
||||||
Version: 4.0.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[coffee-script]
|
|
||||||
Version: 2.2.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[coffee-script-source]
|
|
||||||
Version: 1.7.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[erubis]
|
|
||||||
Version: 2.7.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[execjs]
|
|
||||||
Version: 2.0.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[hike]
|
|
||||||
Version: 1.2.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[i18n]
|
|
||||||
Version: 0.6.9
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[jbuilder]
|
|
||||||
Version: 2.0.7
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[jquery-rails]
|
|
||||||
Version: 3.1.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[json]
|
|
||||||
Version: 1.8.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[kgio]
|
|
||||||
Version: 2.9.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[libv8]
|
|
||||||
Version: 3.16.14.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[mail]
|
|
||||||
Version: 2.5.4
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[mime-types]
|
|
||||||
Version: 1.25.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[minitest]
|
|
||||||
Version: 5.3.4
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[multi_json]
|
|
||||||
Version: 1.10.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[mysql2]
|
|
||||||
Version: 0.3.16
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[polyglot]
|
|
||||||
Version: 0.3.4
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[rack]
|
|
||||||
Version: 1.5.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[rack-test]
|
|
||||||
Version: 0.6.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[rails]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[railties]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[raindrops]
|
|
||||||
Version: 0.13.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[rake]
|
|
||||||
Version: 10.3.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[rdoc]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[ref]
|
|
||||||
Version: 1.0.5
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sass]
|
|
||||||
Version: 3.2.19
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sass-rails]
|
|
||||||
Version: 4.0.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sdoc]
|
|
||||||
Version: 0.4.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[spring]
|
|
||||||
Version: 1.1.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sprockets]
|
|
||||||
Version: 2.11.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sprockets-rails]
|
|
||||||
Version: 2.1.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sqlite3]
|
|
||||||
Version: 1.3.9
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[therubyracer]
|
|
||||||
Version: 0.12.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[thor]
|
|
||||||
Version: 0.19.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[thread_safe]
|
|
||||||
Version: 0.3.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[tilt]
|
|
||||||
Version: 1.4.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[treetop]
|
|
||||||
Version: 1.4.15
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[turbolinks]
|
|
||||||
Version: 2.2.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[tzinfo]
|
|
||||||
Version: 1.2.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[uglifier]
|
|
||||||
Version: 2.5.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[unicorn]
|
|
||||||
Version: 4.8.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user