diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 0cb702d4..47089705 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -36,6 +36,16 @@ jobs: java-version: 17 cache: maven + - name: setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + cache: 'pip' + - name: get Python location + id: python-location + run: | + echo "python-bin-location=$(echo $pythonLocation)/bin" >> $GITHUB_OUTPUT + - name: Install project modules run: npm ci @@ -43,6 +53,9 @@ jobs: run: npm run lint - name: Run unit tests + env: + EXHORT_PYTHON3_PATH: "${{steps.python-location.outputs.python-bin-location}}/python3" + EXHORT_PIP3_PATH: "${{steps.python-location.outputs.python-bin-location}}/pip3" run: npm run test - name: Compile project diff --git a/package-lock.json b/package-lock.json index cf25c199..cebdfc6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,7 @@ "dependencies": { "@cyclonedx/cyclonedx-library": "^4.0.0", "fast-xml-parser": "^4.2.4", - "get-root-path": "^2.0.2", "packageurl-js": "^1.0.2", - "properties-reader": "^2.3.0", "yargs": "^17.7.2" }, "bin": { @@ -903,14 +901,6 @@ "node": ">= 8" } }, - "node_modules/app-root-path": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.2.1.tgz", - "integrity": "sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==", - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -936,38 +926,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -987,6 +945,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -1059,11 +1018,6 @@ "readable-stream": "^3.4.0" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1184,6 +1138,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -1378,14 +1333,6 @@ "color-support": "bin.js" } }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1628,21 +1575,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1667,11 +1599,6 @@ "node": ">=8" } }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -1755,87 +1682,6 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "node_modules/es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -2232,6 +2078,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "dependencies": { "is-callable": "^1.1.3" } @@ -2310,32 +2157,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/gauge": { "version": "3.0.2", @@ -2378,6 +2201,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -2388,31 +2212,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-root-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-root-path/-/get-root-path-2.0.2.tgz", - "integrity": "sha512-dWjZ4oy14SDt7g11aGUGTiCe1X1Pd3xfEPzDndholvMTKoLnpmKPXlrSq0V9ATjG3N8Ywg5akq0NwFU4zu1aJA==", - "dependencies": { - "app-root-path": "^2.0.1", - "bluebird": "^3.4.7", - "mad-logs": "^3.1.1" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -2460,24 +2259,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -2510,6 +2296,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -2517,14 +2304,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2534,21 +2313,11 @@ "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -2560,6 +2329,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -2571,6 +2341,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -2729,19 +2500,6 @@ "node": ">=12.0.0" } }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -2758,30 +2516,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2794,39 +2528,11 @@ "node": ">=8" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, + "dev": true, "engines": { "node": ">= 0.4" }, @@ -2887,17 +2593,6 @@ "node": ">=8" } }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-node-process": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", @@ -2913,20 +2608,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -2945,64 +2626,11 @@ "node": ">=8" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-typed-array": { "version": "1.1.10", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -3029,17 +2657,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -3203,12 +2820,8 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.find": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", - "integrity": "sha512-yaRZoAV3Xq28F1iafWN1+a0rflOej93l1DQUejs3SZ41h2O9UJBoS9aueGjPDgAl4B6tPC0NuuchLKaDQQ3Isg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash.get": { "version": "4.4.2", @@ -3216,16 +2829,6 @@ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, - "node_modules/lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -3257,22 +2860,6 @@ "get-func-name": "^2.0.0" } }, - "node_modules/mad-logs": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/mad-logs/-/mad-logs-3.5.0.tgz", - "integrity": "sha512-Hv5qUc2S87zo2l44E0o1Qzr2wi48jeYz+kHfM5d9FnWSVD/5W6fjrUMG6zpxU+KAzh0QGCK+do81JZ1UDU9wyQ==", - "dependencies": { - "colors": "^1.1.2", - "detect-node": "^2.0.3", - "lodash.find": "^4.6.0", - "lodash.isfunction": "^3.0.8", - "lodash.isstring": "^4.0.1", - "string.prototype.padend": "^3.0.0" - }, - "peerDependencies": { - "lodash": "^4.17.2" - } - }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -3377,6 +2964,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -3750,39 +3338,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3972,21 +3527,6 @@ "node": ">= 0.8.0" } }, - "node_modules/properties-reader": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/properties-reader/-/properties-reader-2.3.0.tgz", - "integrity": "sha512-z597WicA7nDZxK12kZqHr2TcvwNU1GCfA5UwfDY/HDp3hXPoPlb5rlEx9bwGTiJnc0OqbBTkU975jDToth8Gxw==", - "dependencies": { - "mkdirp": "^1.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/steveukx/properties?sponsor=1" - } - }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -4082,22 +3622,6 @@ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", "dev": true }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4218,28 +3742,6 @@ "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", "dev": true }, - "node_modules/safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4260,19 +3762,6 @@ } ] }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -4357,19 +3846,6 @@ "node": ">=8" } }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -4484,64 +3960,6 @@ "node": ">=8" } }, - "node_modules/string.prototype.padend": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz", - "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4703,67 +4121,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typescript": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", @@ -4789,20 +4146,6 @@ "node": ">=8" } }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -4916,25 +4259,11 @@ "node": ">= 8" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/which-typed-array": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", diff --git a/package.json b/package.json index cb4567b2..6cf28db0 100644 --- a/package.json +++ b/package.json @@ -35,11 +35,9 @@ "lint": "eslint src test --ext js", "lint:fix": "eslint src test --ext js --fix", "test": "c8 npm run tests", - "prelocaltest": "find test/ | grep sbom | xargs -i sed -i 's/2023-08-07T00:00:00.000Z/2023-08-06T21:00:00.000Z/g' {} ", - "localtest": "c8 npm run tests", - "postlocaltest": "git restore test/providers/tst_manifests/* --worktree", + "localtest": "EXHORT_PIP3_PATH=/home/zgrinber/python3.9/bin/pip3 EXHORT_PYTHON3_PATH=/home/zgrinber/python3.9/bin/python3 c8 npm run tests", "tests": "mocha", - "tests:rep": "mocha --reporter json > unit-tests-result.json", + "tests:rep": "mocha --reporter-option maxDiffSize=0 --reporter json > unit-tests-result.json", "precompile": "rm -rf dist", "compile": "tsc -p tsconfig.json", "pregen:backend": "rm -rf generated", diff --git a/src/provider.js b/src/provider.js index f700305d..585df81e 100644 --- a/src/provider.js +++ b/src/provider.js @@ -1,6 +1,7 @@ import javaMvnProvider from './providers/java_maven.js' import javascriptNpmProvider from './providers/javascript_npm.js' import golangGomodulesProvider from './providers/golang_gomodules.js' +import pythonPipProvider from './providers/python_pip.js' import path from 'node:path' /** @typedef {{ecosystem: string, contentType: string, content: string}} Provided */ @@ -10,7 +11,7 @@ import path from 'node:path' * MUST include all providers here. * @type {[Provider]} */ -export const availableProviders = [javaMvnProvider,javascriptNpmProvider,golangGomodulesProvider] +export const availableProviders = [javaMvnProvider,javascriptNpmProvider,golangGomodulesProvider,pythonPipProvider] /** * Match a provider from a list or providers based on file type. diff --git a/src/providers/python_controller.js b/src/providers/python_controller.js new file mode 100644 index 00000000..b2c16e7f --- /dev/null +++ b/src/providers/python_controller.js @@ -0,0 +1,243 @@ +import {execSync} from "node:child_process"; +import fs from "node:fs"; +import path from 'node:path'; +import {EOL} from "os"; + + +/** @typedef {{name: string, version: string, dependencies: DependencyEntry[]}} DependencyEntry */ + + + +export default class Python_controller { + + pythonEnvDir + pathToPipBin + pathToPythonBin + realEnvironment + pathToRequirements + + /** + * Constructor to create new python controller instance to interact with pip package manager + * @param {boolean} realEnvironment - whether to use real environment supplied by client or to create virtual environment + * @param {string} pathToPip - path to pip package manager + * @param {string} pathToPython - path to python binary + * @param {string} pathToRequirements + * @ + */ + constructor(realEnvironment,pathToPip,pathToPython,pathToRequirements) { + this.pathToPythonBin = pathToPython + this.pathToPipBin = pathToPip + this.realEnvironment= realEnvironment + this.prepareEnvironment() + this.pathToRequirements = pathToRequirements + } + prepareEnvironment() + { + if(!this.realEnvironment) { + this.pythonEnvDir = path.join(path.sep,"tmp","exhort_env_js") + execSync(`${this.pathToPythonBin} -m venv ${this.pythonEnvDir} `, err => { + if (err) { + throw new Error('failed creating virtual python environment - ' + err.message) + } + }) + if(this.pathToPythonBin.includes("python3")) + { + this.pathToPipBin = path.join(this.pythonEnvDir,"bin","pip3"); + this.pathToPythonBin = path.join(this.pythonEnvDir,"bin","python3") + } + else { + this.pathToPipBin = path.join(this.pythonEnvDir,"bin","pip"); + this.pathToPythonBin = path.join(this.pythonEnvDir,"bin","python") + } + // upgrade pip version to latest + execSync(`${this.pathToPythonBin} -m pip install --upgrade pip `, err => { + if (err) { + throw new Error('failed upgrading pip version on virtual python environment - ' + err.message) + } + }) + } + else{ + if(this.pathToPythonBin.startsWith("python")) { + this.pythonEnvDir = process.cwd() + } + else + { + this.pythonEnvDir = path.dirname(this.pathToPythonBin) + } + } + } + + /** + * + * @param {boolean} includeTransitive - whether to return include in returned object transitive dependencies or not + * @return {[DependencyEntry]} + */ + getDependencies(includeTransitive) + { + if(!this.realEnvironment) { + execSync(`${this.pathToPipBin} install -r ${this.pathToRequirements}`, err =>{ + if (err) { + throw new Error('fail installing requirements.txt manifest in created virtual python environment --> ' + err.message) + } + }) + } + let dependencies = this.#getDependenciesImpl(includeTransitive) + this.#cleanEnvironment() + return dependencies + } + /** + * @private + */ + #cleanEnvironment() + { + if(!this.realEnvironment) + { + execSync(`${this.pathToPipBin} uninstall -y -r ${this.pathToRequirements}`, err =>{ + if (err) { + throw new Error('fail uninstalling requirements.txt in created virtual python environment --> ' + err.message) + } + }) + } + } + #getDependenciesImpl(includeTransitive) { + let dependencies = new Array() + let freezeOutput = execSync(`${this.pathToPipBin} freeze`, err =>{ + if (err) { + throw new Error('fail invoking pip freeze to fetch all installed dependencies in environment --> ' + err.message) + } + }).toString(); + let lines = freezeOutput.split(EOL) + let depNames = lines.map( line => getDependencyName(line)).join(" ") + let pipShowOutput = execSync(`${this.pathToPipBin} show ${depNames}`, err =>{ + if (err) { + throw new Error('fail invoking pip show to fetch all installed dependencies metadata --> ' + err.message) + } + }).toString(); + let allPipShowDeps = pipShowOutput.split("---"); + let linesOfRequirements = fs.readFileSync(this.pathToRequirements).toString().split(EOL).filter( (line) => !line.startsWith("#")).map(line => line.trim()) + let CachedEnvironmentDeps = {} + allPipShowDeps.forEach( (record) => { + let dependencyName = getDependencyNameShow(record).toLowerCase() + CachedEnvironmentDeps[dependencyName] = record + CachedEnvironmentDeps[dependencyName.replace("-","_")] = record + CachedEnvironmentDeps[dependencyName.replace("_","-")] = record + }) + linesOfRequirements.forEach( (dep) => { + bringAllDependencies(dependencies,getDependencyName(dep),CachedEnvironmentDeps,includeTransitive) + }) + dependencies.sort((dep1,dep2) =>{ + const DEP1 = dep1.name.toLowerCase() + const DEP2 = dep2.name.toLowerCase() + if(DEP1 < DEP2) { + return -1; + } + if(DEP1 > DEP2) + { + return 1; + } + return 0;}) + return dependencies + } +} + +/** + * + * @param {string} record - a record block from pip show + * @return {string} the name of the dependency of the pip show record. + */ +function getDependencyNameShow(record) { + let versionKeyIndex = record.indexOf("Name:") + let versionToken = record.substring(versionKeyIndex + 5) + let endOfLine = versionToken.indexOf(EOL) + return versionToken.substring(0,endOfLine).trim() +} + +/** + * + * @param {string} record - a record block from pip show + * @return {string} the name of the dependency of the pip show record. + */ +function getDependencyVersion(record) { + let versionKeyIndex = record.indexOf("Version:") + let versionToken = record.substring(versionKeyIndex + 8) + let endOfLine = versionToken.indexOf(EOL) + return versionToken.substring(0,endOfLine).trim() +} + +/** + * + * @param depLine the dependency with version/ version requirement as shown in requirements.txt + * @return {string} the name of dependency + */ +function getDependencyName(depLine) { + const regex = /[^\w\s-_]/g; + let endIndex = depLine.search(regex); + return depLine.substring(0,endIndex) ; +} + +/** + * + * @param record - a dependency record block from pip show + * @return {[string]} array of all direct deps names of that dependency + */ +function getDepsList(record) { + let requiresKeyIndex = record.indexOf("Requires:") + let requiresToken = record.substring(requiresKeyIndex + 9) + let endOfLine = requiresToken.indexOf(EOL) + let listOfDepsString = requiresToken.substring(0,endOfLine) + let list = listOfDepsString.split(",").filter(line => line.trim() !== "").map(line => line.trim()) + return list +} + +/** + * + * @param {[DependencyEntry]} dependencies + * @param dependencyName + * @param cachedEnvironmentDeps + * @param includeTransitive + */ +function bringAllDependencies(dependencies, dependencyName, cachedEnvironmentDeps, includeTransitive) { + if(dependencyName === null || dependencyName === undefined || dependencyName.trim() === "" ) { + return + } + let record = cachedEnvironmentDeps[dependencyName.toLowerCase()] + if(record === null || record === undefined) { + throw new Error(`Package name=>${dependencyName} is not installed on your python environment, + either install it ( better to install requirements.txt altogether) or turn on + environment variable EXHORT_PYTHON_VIRTUAL_ENV=true to automatically installs + it on virtual environment ( will slow down the analysis) `) + } + + let version = getDependencyVersion(record) + let directDeps = getDepsList(record) + let targetDeps = new Array() + + let entry = { "name" : getDependencyNameShow(record) , "version" : version, "dependencies" : [] } + dependencies.push(entry) + directDeps.forEach( (dep) => { + if(includeTransitive) { + bringAllDependencies(targetDeps,dep,cachedEnvironmentDeps,includeTransitive) + } + // sort ra + targetDeps.sort((dep1,dep2) =>{ + const DEP1 = dep1.name.toLowerCase() + const DEP2 = dep2.name.toLowerCase() + if(DEP1 < DEP2) { + return -1; + } + if(DEP1 > DEP2) + { + return 1; + } + return 0;}) + + entry["dependencies"] = targetDeps + }) +} + +/** + * + * @param includeTransitive + * @return {[DependencyEntry]} + */ + diff --git a/src/providers/python_pip.js b/src/providers/python_pip.js new file mode 100644 index 00000000..ebd7eae5 --- /dev/null +++ b/src/providers/python_pip.js @@ -0,0 +1,226 @@ + +import {execSync} from "node:child_process"; +import fs from 'node:fs' +import {getCustom, getCustomPath} from "../tools.js"; +import os from 'node:os' +import path from 'node:path' +import Sbom from '../sbom.js' +import {PackageURL} from 'packageurl-js' +import {EOL} from 'os' +import Python_controller from './python_controller.js' + +export default { isSupported, provideComponent, provideStack } + +const dummyVersionNotation = "dummy*=#?"; + +/** @typedef {{name: string, , version: string, dependencies: DependencyEntry[]}} DependencyEntry */ + +/** + * @type {string} ecosystem for python-pip is 'pip' + * @private + */ +const ecosystem = 'pip' + +/** + * @param {string} manifestName - the subject manifest name-type + * @returns {boolean} - return true if `requirements.txt` is the manifest name-type + */ +function isSupported(manifestName) { + return 'requirements.txt' === manifestName +} + +/** + * Provide content and content type for python-pip stack analysis. + * @param {string} manifest - the manifest path or name + * @param {{}} [opts={}] - optional various options to pass along the application + * @returns {Provided} + */ +function provideStack(manifest, opts = {}) { + return { + ecosystem, + content: createSbomStackAnalysis(manifest, opts), + contentType: 'application/vnd.cyclonedx+json' + } +} + +/** + * Provide content and content type for python-pip component analysis. + * @param {string} data - content of requirements.txt for component report + * @param {{}} [opts={}] - optional various options to pass along the application + * @returns {Provided} + */ +function provideComponent(data, opts = {}) { + return { + ecosystem, + content: getSbomForComponentAnalysis(data, opts), + contentType: 'application/vnd.cyclonedx+json' + } +} + +/** @typedef {{name: string, , version: string, dependencies: DependencyEntry[]}} DependencyEntry */ + +/** + * + * @param {PackageURL}source + * @param {DependencyEntry} dep + * @param {Sbom} sbom + * @private + */ +function addAllDependencies(source, dep, sbom) { + let targetPurl = toPurl(dep["name"],dep["version"]) + sbom.addDependency(sbom.purlToComponent(source),targetPurl) + let directDeps = dep["dependencies"] + if (directDeps !== undefined && directDeps.length > 0) { + directDeps.forEach( (dependency) =>{ addAllDependencies(toPurl(dep["name"],dep["version"]),dependency,sbom)}) + } + + +} + + + +/** + * + * @param nameVersion + * @return {string} + */ +function splitToNameVersion(nameVersion) +{ + let result = [] + if(nameVersion.includes("==")) { + result = nameVersion.split("==") + } + else { + const regex = /[^\w\s-_]/g; + let endIndex = nameVersion.search(regex); + result.push(nameVersion.substring(0,endIndex).trim()) + result.push(dummyVersionNotation) + } + + return `${result[0]};;${result[1]}` +} + +/** + * + * @param {string} requirementTxtContent + * @return {PackageURL []} + */ +function getIgnoredDependencies(requirementTxtContent) { + let requirementsLines = requirementTxtContent.split(EOL) + return requirementsLines + .filter(line => line.includes("#exhortignore") || line.includes("# exhortignore")) + .map((line) => line.substring(0,line.indexOf("#")).trim()) + .map((name) => { + let strings = splitToNameVersion(name).split(";;"); + return toPurl(strings[0],strings[1])}) +} + +/** + * + * @param {string} requirementTxtContent content of requirments.txt in string + * @param {Sbom} sbom object to filter out from it exhortignore dependencies. + * @private + */ +function handleIgnoredDependencies(requirementTxtContent, sbom) { + let ignoredDeps = getIgnoredDependencies(requirementTxtContent) + let ignoredDepsVersion = ignoredDeps + .filter(dep => !dep.toString().includes(dummyVersionNotation) ) + .map(dep => dep.toString()) + let ignoredDepsNoVersions = ignoredDeps + .filter(dep => dep.toString().includes(dummyVersionNotation)) + .map(dep => dep.name) + sbom.filterIgnoredDeps(ignoredDepsNoVersions) + sbom.filterIgnoredDepsIncludingVersion(ignoredDepsVersion) +} + +/** get python and pip binaries, python3/pip3 get precedence if exists on the system path + * @param {object}binaries + * @param {{}} [opts={}] + */ +function getPythonPipBinaries(binaries,opts) { + let python = getCustomPath("python3",opts) + let pip = getCustomPath("pip3",opts) + try { + execSync(`${python} --version`) + execSync(`${pip} --version`) + } catch (e) { + python = getCustomPath("python",opts) + pip = getCustomPath("pip",opts) + try { + execSync(`${python} --version`) + execSync(`${pip} --version`) + } catch (e) { + throw new Error(`Couldn't get python binaries from supplied environment variables ${e.getMessage}`) + } + } + binaries.pip = pip + binaries.python = python + + +} + +/** + * Create sbom json string out of a manifest path for stack analysis. + * @param {string} manifest - path for requirements.txt + * @param {{}} [opts={}] - optional various options to pass along the application + * @returns {string} the sbom json string content + * @private + */ +function createSbomStackAnalysis(manifest, opts = {}) { + let binaries = {} + getPythonPipBinaries(binaries,opts) + let createVirtualPythonEnv = getCustom("EXHORT_PYTHON_VIRTUAL_ENV","false",opts); + let pythonController = new Python_controller(createVirtualPythonEnv === "false",binaries.pip,binaries.python,manifest) + let dependencies = pythonController.getDependencies(true); + let sbom = new Sbom(); + sbom.addRoot(toPurl("root",undefined)) + dependencies.forEach(dep => { + addAllDependencies(sbom.getRoot(),dep,sbom) + }) + let requirementTxtContent = fs.readFileSync(manifest).toString(); + handleIgnoredDependencies(requirementTxtContent,sbom) + return sbom.getAsJsonString() + + + +} + +/** + * Create a sbom json string out of a manifest content for component analysis + * @param {string} data - content of requirements.txt + * @param {{}} [opts={}] - optional various options to pass along the application + * @returns {string} the sbom json string content + * @private + */ +function getSbomForComponentAnalysis(data, opts = {}) { + let binaries = {} + getPythonPipBinaries(binaries,opts) + let createVirtualPythonEnv = getCustom("EXHORT_PYTHON_VIRTUAL_ENV","false",opts); + let tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'exhort_')) + let tmpRequirementsPath = path.join(tmpDir, 'requirements.txt') + fs.writeFileSync(tmpRequirementsPath, data) + let pythonController = new Python_controller(createVirtualPythonEnv === "false",binaries.pip,binaries.python,tmpRequirementsPath) + let dependencies = pythonController.getDependencies(false); + let sbom = new Sbom(); + sbom.addRoot(toPurl("root",undefined)) + dependencies.forEach(dep => { + sbom.addDependency(sbom.getRoot(),toPurl(dep.name, dep.version)) + }) + fs.rmSync(tmpDir, { recursive: true, force: true }); + handleIgnoredDependencies(data,sbom) + return sbom.getAsJsonString() +} + + +/** + * Returns a PackageUrl For pip dependencies + * @param name + * @param version + * @return {PackageURL} + */ +function toPurl(name,version) +{ + return new PackageURL('pypi',undefined,name,version,undefined,undefined); +} + + diff --git a/test/providers/python_pip.test.js b/test/providers/python_pip.test.js new file mode 100644 index 00000000..861dd985 --- /dev/null +++ b/test/providers/python_pip.test.js @@ -0,0 +1,101 @@ +import { expect } from 'chai' +import fs from 'fs' +import {execSync} from "node:child_process"; +import sinon from "sinon"; +import pythonPip from "../../src/providers/python_pip.js" +import {getCustomPath } from "../../src/tools.js" + + + +let clock +suite('testing the python-pip data provider', () => { + [ + {name: 'requirements.txt', expected: true}, + {name: 'some_other.file', expected: false} + ].forEach(testCase => { + test(`verify isSupported returns ${testCase.expected} for ${testCase.name}`, () => + expect(pythonPip.isSupported(testCase.name)).to.equal(testCase.expected) + ) + }); + + [ + "pip_requirements_txt_no_ignore", + "pip_requirements_txt_ignore" + ].forEach(testCase => { + let scenario = testCase.replace('pip_requirements_', '').replaceAll('_', ' ') + test(`verify requirements.txt sbom provided for stack analysis with scenario ${scenario}`, async () => { + // load the expected graph for the scenario + let expectedSbom = fs.readFileSync(`test/providers/tst_manifests/pip/${testCase}/expected_stack_sbom.json`,).toString() + expectedSbom = JSON.stringify(JSON.parse(expectedSbom)) + // invoke sut stack analysis for scenario manifest + let pipPath = getCustomPath("pip3"); + execSync(`${pipPath} install -r test/providers/tst_manifests/pip/${testCase}/requirements.txt`, err => { + if (err) { + throw new Error('fail installing requirements.txt manifest in created virtual python environment --> ' + err.message) + } + }) + let providedDataForStack = await pythonPip.provideStack(`test/providers/tst_manifests/pip/${testCase}/requirements.txt`) + // new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date + + // providedDataForStack.content = providedDataForStack.content.replaceAll("\"timestamp\":\"[a-zA-Z0-9\\-\\:]+\"","") + // verify returned data matches expectation + expect(providedDataForStack).to.deep.equal({ + ecosystem: 'pip', + contentType: 'application/vnd.cyclonedx+json', + content: expectedSbom + }) + // these test cases takes ~2500-2700 ms each pr >10000 in CI (for the first test-case) + }).timeout(process.env.GITHUB_ACTIONS ? 30000 : 10000) + + test(`verify requirements.txt sbom provided for component analysis with scenario ${scenario}`, async () => { + // load the expected list for the scenario + let expectedSbom = fs.readFileSync(`test/providers/tst_manifests/pip/${testCase}/expected_component_sbom.json`,).toString().trim() + expectedSbom = JSON.stringify(JSON.parse(expectedSbom)) + // read target manifest file + let manifestContent = fs.readFileSync(`test/providers/tst_manifests/pip/${testCase}/requirements.txt`).toString() + // invoke sut stack analysis for scenario manifest + let providedDatForComponent = await pythonPip.provideComponent(manifestContent) + // verify returned data matches expectation + expect(providedDatForComponent).to.deep.equal({ + ecosystem: 'pip', + contentType: 'application/vnd.cyclonedx+json', + content: expectedSbom + }) + // these test cases takes ~1400-2000 ms each pr >10000 in CI (for the first test-case) + }).timeout(process.env.GITHUB_ACTIONS ? 15000 : 10000) + }); + +}).beforeAll(() => clock = sinon.useFakeTimers(new Date('2023-10-01T00:00:00.000Z'))).afterAll(()=> clock.restore()); + +suite('testing the python-pip data provider', () => { + [ + "pip_requirements_virtual_env_txt_no_ignore", + "pip_requirements_virtual_env_with_ignore" + ].forEach(testCase => { + let scenario = testCase.replace('pip_requirements_', '').replaceAll('_', ' ') + test(`verify requirements.txt sbom provided for stack analysis using virutal python environment, with scenario ${scenario}`, async () => { + // load the expected sbom stack analysis + let expectedSbom = fs.readFileSync(`test/providers/tst_manifests/pip/${testCase}/expected_stack_sbom.json`,).toString() + process.env["EXHORT_PYTHON_VIRTUAL_ENV"] = "true" + process.env["EXHORT_DEBUG"] = "true" + expectedSbom = JSON.stringify(JSON.parse(expectedSbom),null , 4) + // invoke sut stack analysis for scenario manifest + let providedDataForStack = await pythonPip.provideStack(`test/providers/tst_manifests/pip/${testCase}/requirements.txt`) + // new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date + + // providedDataForStack.content = providedDataForStack.content.replaceAll("\"timestamp\":\"[a-zA-Z0-9\\-\\:]+\"","") + // verify returned data matches expectation + providedDataForStack.content = JSON.stringify(JSON.parse(providedDataForStack.content),null , 4) + expect(providedDataForStack.content).to.deep.equal(expectedSbom) + // expect(providedDataForStack).to.deep.equal({ + // ecosystem: 'pip', + // contentType: 'application/vnd.cyclonedx+json', + // content: expectedSbom + // }) + // these test cases takes ~2500-2700 ms each pr >10000 in CI (for the first test-case) + }).timeout(process.env.GITHUB_ACTIONS ? 30000 : 15000) + + + }) + +}).beforeAll(() => {clock = sinon.useFakeTimers(new Date('2023-10-01T00:00:00.000Z'))}).afterAll(()=> clock.restore()); diff --git a/test/providers/tst_manifests/pip/pip_requirements_txt_ignore/expected_component_sbom.json b/test/providers/tst_manifests/pip/pip_requirements_txt_ignore/expected_component_sbom.json new file mode 100644 index 00000000..a6ea38ac --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_txt_ignore/expected_component_sbom.json @@ -0,0 +1,329 @@ +{ + "bomFormat" : "CycloneDX", + "specVersion" : "1.4", + "version" : 1, + "metadata" : { + "timestamp" : "2023-10-01T00:00:00.000Z", + "component" : { + "name" : "root", + "purl" : "pkg:pypi/root", + "type" : "application", + "bom-ref" : "pkg:pypi/root" + } + }, + "components" : [ + { + "name" : "root", + "purl" : "pkg:pypi/root", + "type" : "application", + "bom-ref" : "pkg:pypi/root" + }, + { + "name" : "anyio", + "version" : "3.6.2", + "purl" : "pkg:pypi/anyio@3.6.2", + "type" : "library", + "bom-ref" : "pkg:pypi/anyio@3.6.2" + }, + { + "name" : "asgiref", + "version" : "3.4.1", + "purl" : "pkg:pypi/asgiref@3.4.1", + "type" : "library", + "bom-ref" : "pkg:pypi/asgiref@3.4.1" + }, + { + "name" : "beautifulsoup4", + "version" : "4.12.2", + "purl" : "pkg:pypi/beautifulsoup4@4.12.2", + "type" : "library", + "bom-ref" : "pkg:pypi/beautifulsoup4@4.12.2" + }, + { + "name" : "certifi", + "version" : "2023.7.22", + "purl" : "pkg:pypi/certifi@2023.7.22", + "type" : "library", + "bom-ref" : "pkg:pypi/certifi@2023.7.22" + }, + { + "name" : "chardet", + "version" : "4.0.0", + "purl" : "pkg:pypi/chardet@4.0.0", + "type" : "library", + "bom-ref" : "pkg:pypi/chardet@4.0.0" + }, + { + "name" : "contextlib2", + "version" : "21.6.0", + "purl" : "pkg:pypi/contextlib2@21.6.0", + "type" : "library", + "bom-ref" : "pkg:pypi/contextlib2@21.6.0" + }, + { + "name" : "fastapi", + "version" : "0.75.1", + "purl" : "pkg:pypi/fastapi@0.75.1", + "type" : "library", + "bom-ref" : "pkg:pypi/fastapi@0.75.1" + }, + { + "name" : "flask", + "version" : "2.0.3", + "purl" : "pkg:pypi/flask@2.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/flask@2.0.3" + }, + { + "name" : "h11", + "version" : "0.13.0", + "purl" : "pkg:pypi/h11@0.13.0", + "type" : "library", + "bom-ref" : "pkg:pypi/h11@0.13.0" + }, + { + "name" : "idna", + "version" : "2.10", + "purl" : "pkg:pypi/idna@2.10", + "type" : "library", + "bom-ref" : "pkg:pypi/idna@2.10" + }, + { + "name" : "immutables", + "version" : "0.19", + "purl" : "pkg:pypi/immutables@0.19", + "type" : "library", + "bom-ref" : "pkg:pypi/immutables@0.19" + }, + { + "name" : "importlib-metadata", + "version" : "4.8.3", + "purl" : "pkg:pypi/importlib-metadata@4.8.3", + "type" : "library", + "bom-ref" : "pkg:pypi/importlib-metadata@4.8.3" + }, + { + "name" : "itsdangerous", + "version" : "2.0.1", + "purl" : "pkg:pypi/itsdangerous@2.0.1", + "type" : "library", + "bom-ref" : "pkg:pypi/itsdangerous@2.0.1" + }, + { + "name" : "jinja2", + "version" : "3.0.3", + "purl" : "pkg:pypi/jinja2@3.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/jinja2@3.0.3" + }, + { + "name" : "markupsafe", + "version" : "2.0.1", + "purl" : "pkg:pypi/markupsafe@2.0.1", + "type" : "library", + "bom-ref" : "pkg:pypi/markupsafe@2.0.1" + }, + { + "name" : "requests", + "version" : "2.25.1", + "purl" : "pkg:pypi/requests@2.25.1", + "type" : "library", + "bom-ref" : "pkg:pypi/requests@2.25.1" + }, + { + "name" : "six", + "version" : "1.16.0", + "purl" : "pkg:pypi/six@1.16.0", + "type" : "library", + "bom-ref" : "pkg:pypi/six@1.16.0" + }, + { + "name" : "sniffio", + "version" : "1.2.0", + "purl" : "pkg:pypi/sniffio@1.2.0", + "type" : "library", + "bom-ref" : "pkg:pypi/sniffio@1.2.0" + }, + { + "name" : "soupsieve", + "version" : "2.3.2.post1", + "purl" : "pkg:pypi/soupsieve@2.3.2.post1", + "type" : "library", + "bom-ref" : "pkg:pypi/soupsieve@2.3.2.post1" + }, + { + "name" : "starlette", + "version" : "0.17.1", + "purl" : "pkg:pypi/starlette@0.17.1", + "type" : "library", + "bom-ref" : "pkg:pypi/starlette@0.17.1" + }, + { + "name" : "typing-extensions", + "version" : "4.1.1", + "purl" : "pkg:pypi/typing-extensions@4.1.1", + "type" : "library", + "bom-ref" : "pkg:pypi/typing-extensions@4.1.1" + }, + { + "name" : "urllib3", + "version" : "1.26.16", + "purl" : "pkg:pypi/urllib3@1.26.16", + "type" : "library", + "bom-ref" : "pkg:pypi/urllib3@1.26.16" + }, + { + "name" : "uvicorn", + "version" : "0.17.0", + "purl" : "pkg:pypi/uvicorn@0.17.0", + "type" : "library", + "bom-ref" : "pkg:pypi/uvicorn@0.17.0" + }, + { + "name" : "werkzeug", + "version" : "2.0.3", + "purl" : "pkg:pypi/werkzeug@2.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/werkzeug@2.0.3" + }, + { + "name" : "zipp", + "version" : "3.6.0", + "purl" : "pkg:pypi/zipp@3.6.0", + "type" : "library", + "bom-ref" : "pkg:pypi/zipp@3.6.0" + } + ], + "dependencies" : [ + { + "ref" : "pkg:pypi/root", + "dependsOn" : [ + "pkg:pypi/anyio@3.6.2", + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/beautifulsoup4@4.12.2", + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/contextlib2@21.6.0", + "pkg:pypi/fastapi@0.75.1", + "pkg:pypi/flask@2.0.3", + "pkg:pypi/h11@0.13.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/immutables@0.19", + "pkg:pypi/importlib-metadata@4.8.3", + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/markupsafe@2.0.1", + "pkg:pypi/requests@2.25.1", + "pkg:pypi/six@1.16.0", + "pkg:pypi/sniffio@1.2.0", + "pkg:pypi/soupsieve@2.3.2.post1", + "pkg:pypi/starlette@0.17.1", + "pkg:pypi/typing-extensions@4.1.1", + "pkg:pypi/urllib3@1.26.16", + "pkg:pypi/uvicorn@0.17.0", + "pkg:pypi/werkzeug@2.0.3", + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref" : "pkg:pypi/anyio@3.6.2", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/asgiref@3.4.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/beautifulsoup4@4.12.2", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/certifi@2023.7.22", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/chardet@4.0.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/contextlib2@21.6.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/fastapi@0.75.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/flask@2.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/h11@0.13.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/idna@2.10", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/immutables@0.19", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/importlib-metadata@4.8.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/itsdangerous@2.0.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/jinja2@3.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/markupsafe@2.0.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/requests@2.25.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/six@1.16.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/sniffio@1.2.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/soupsieve@2.3.2.post1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/starlette@0.17.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/typing-extensions@4.1.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/urllib3@1.26.16", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/uvicorn@0.17.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/werkzeug@2.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/zipp@3.6.0", + "dependsOn" : [ ] + } + ] +} diff --git a/test/providers/tst_manifests/pip/pip_requirements_txt_ignore/expected_stack_sbom.json b/test/providers/tst_manifests/pip/pip_requirements_txt_ignore/expected_stack_sbom.json new file mode 100644 index 00000000..46d43c3b --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_txt_ignore/expected_stack_sbom.json @@ -0,0 +1,354 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-10-01T00:00:00.000Z", + "component": { + "name": "root", + "purl": "pkg:pypi/root", + "type": "application", + "bom-ref": "pkg:pypi/root" + } + }, + "components": [ + { + "name": "root", + "purl": "pkg:pypi/root", + "type": "application", + "bom-ref": "pkg:pypi/root" + }, + { + "name": "anyio", + "version": "3.6.2", + "purl": "pkg:pypi/anyio@3.6.2", + "type": "library", + "bom-ref": "pkg:pypi/anyio@3.6.2" + }, + { + "name": "idna", + "version": "2.10", + "purl": "pkg:pypi/idna@2.10", + "type": "library", + "bom-ref": "pkg:pypi/idna@2.10" + }, + { + "name": "sniffio", + "version": "1.2.0", + "purl": "pkg:pypi/sniffio@1.2.0", + "type": "library", + "bom-ref": "pkg:pypi/sniffio@1.2.0" + }, + { + "name": "asgiref", + "version": "3.4.1", + "purl": "pkg:pypi/asgiref@3.4.1", + "type": "library", + "bom-ref": "pkg:pypi/asgiref@3.4.1" + }, + { + "name": "beautifulsoup4", + "version": "4.12.2", + "purl": "pkg:pypi/beautifulsoup4@4.12.2", + "type": "library", + "bom-ref": "pkg:pypi/beautifulsoup4@4.12.2" + }, + { + "name": "soupsieve", + "version": "2.3.2.post1", + "purl": "pkg:pypi/soupsieve@2.3.2.post1", + "type": "library", + "bom-ref": "pkg:pypi/soupsieve@2.3.2.post1" + }, + { + "name": "certifi", + "version": "2023.7.22", + "purl": "pkg:pypi/certifi@2023.7.22", + "type": "library", + "bom-ref": "pkg:pypi/certifi@2023.7.22" + }, + { + "name": "chardet", + "version": "4.0.0", + "purl": "pkg:pypi/chardet@4.0.0", + "type": "library", + "bom-ref": "pkg:pypi/chardet@4.0.0" + }, + { + "name": "contextlib2", + "version": "21.6.0", + "purl": "pkg:pypi/contextlib2@21.6.0", + "type": "library", + "bom-ref": "pkg:pypi/contextlib2@21.6.0" + }, + { + "name": "fastapi", + "version": "0.75.1", + "purl": "pkg:pypi/fastapi@0.75.1", + "type": "library", + "bom-ref": "pkg:pypi/fastapi@0.75.1" + }, + { + "name": "typing-extensions", + "version": "4.1.1", + "purl": "pkg:pypi/typing-extensions@4.1.1", + "type": "library", + "bom-ref": "pkg:pypi/typing-extensions@4.1.1" + }, + { + "name": "starlette", + "version": "0.17.1", + "purl": "pkg:pypi/starlette@0.17.1", + "type": "library", + "bom-ref": "pkg:pypi/starlette@0.17.1" + }, + { + "name": "flask", + "version": "2.0.3", + "purl": "pkg:pypi/flask@2.0.3", + "type": "library", + "bom-ref": "pkg:pypi/flask@2.0.3" + }, + { + "name": "itsdangerous", + "version": "2.0.1", + "purl": "pkg:pypi/itsdangerous@2.0.1", + "type": "library", + "bom-ref": "pkg:pypi/itsdangerous@2.0.1" + }, + { + "name": "jinja2", + "version": "3.0.3", + "purl": "pkg:pypi/jinja2@3.0.3", + "type": "library", + "bom-ref": "pkg:pypi/jinja2@3.0.3" + }, + { + "name": "markupsafe", + "version": "2.0.1", + "purl": "pkg:pypi/markupsafe@2.0.1", + "type": "library", + "bom-ref": "pkg:pypi/markupsafe@2.0.1" + }, + { + "name": "werkzeug", + "version": "2.0.3", + "purl": "pkg:pypi/werkzeug@2.0.3", + "type": "library", + "bom-ref": "pkg:pypi/werkzeug@2.0.3" + }, + { + "name": "h11", + "version": "0.13.0", + "purl": "pkg:pypi/h11@0.13.0", + "type": "library", + "bom-ref": "pkg:pypi/h11@0.13.0" + }, + { + "name": "immutables", + "version": "0.19", + "purl": "pkg:pypi/immutables@0.19", + "type": "library", + "bom-ref": "pkg:pypi/immutables@0.19" + }, + { + "name": "importlib-metadata", + "version": "4.8.3", + "purl": "pkg:pypi/importlib-metadata@4.8.3", + "type": "library", + "bom-ref": "pkg:pypi/importlib-metadata@4.8.3" + }, + { + "name": "zipp", + "version": "3.6.0", + "purl": "pkg:pypi/zipp@3.6.0", + "type": "library", + "bom-ref": "pkg:pypi/zipp@3.6.0" + }, + { + "name": "requests", + "version": "2.25.1", + "purl": "pkg:pypi/requests@2.25.1", + "type": "library", + "bom-ref": "pkg:pypi/requests@2.25.1" + }, + { + "name": "urllib3", + "version": "1.26.16", + "purl": "pkg:pypi/urllib3@1.26.16", + "type": "library", + "bom-ref": "pkg:pypi/urllib3@1.26.16" + }, + { + "name": "six", + "version": "1.16.0", + "purl": "pkg:pypi/six@1.16.0", + "type": "library", + "bom-ref": "pkg:pypi/six@1.16.0" + }, + { + "name": "uvicorn", + "version": "0.17.0", + "purl": "pkg:pypi/uvicorn@0.17.0", + "type": "library", + "bom-ref": "pkg:pypi/uvicorn@0.17.0" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/root", + "dependsOn": [ + "pkg:pypi/anyio@3.6.2", + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/beautifulsoup4@4.12.2", + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/contextlib2@21.6.0", + "pkg:pypi/fastapi@0.75.1", + "pkg:pypi/flask@2.0.3", + "pkg:pypi/h11@0.13.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/immutables@0.19", + "pkg:pypi/importlib-metadata@4.8.3", + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/markupsafe@2.0.1", + "pkg:pypi/requests@2.25.1", + "pkg:pypi/six@1.16.0", + "pkg:pypi/sniffio@1.2.0", + "pkg:pypi/soupsieve@2.3.2.post1", + "pkg:pypi/starlette@0.17.1", + "pkg:pypi/typing-extensions@4.1.1", + "pkg:pypi/urllib3@1.26.16", + "pkg:pypi/uvicorn@0.17.0", + "pkg:pypi/werkzeug@2.0.3", + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref": "pkg:pypi/anyio@3.6.2", + "dependsOn": [ + "pkg:pypi/idna@2.10", + "pkg:pypi/sniffio@1.2.0" + ] + }, + { + "ref": "pkg:pypi/idna@2.10", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/sniffio@1.2.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/asgiref@3.4.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/beautifulsoup4@4.12.2", + "dependsOn": [ + "pkg:pypi/soupsieve@2.3.2.post1" + ] + }, + { + "ref": "pkg:pypi/soupsieve@2.3.2.post1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/certifi@2023.7.22", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/chardet@4.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/contextlib2@21.6.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/fastapi@0.75.1", + "dependsOn": [ + "pkg:pypi/starlette@0.17.1" + ] + }, + { + "ref": "pkg:pypi/typing-extensions@4.1.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/starlette@0.17.1", + "dependsOn": [ + "pkg:pypi/anyio@3.6.2" + ] + }, + { + "ref": "pkg:pypi/flask@2.0.3", + "dependsOn": [ + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/werkzeug@2.0.3" + ] + }, + { + "ref": "pkg:pypi/itsdangerous@2.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/jinja2@3.0.3", + "dependsOn": [ + "pkg:pypi/markupsafe@2.0.1" + ] + }, + { + "ref": "pkg:pypi/markupsafe@2.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/werkzeug@2.0.3", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/h11@0.13.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/immutables@0.19", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/importlib-metadata@4.8.3", + "dependsOn": [ + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref": "pkg:pypi/zipp@3.6.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/requests@2.25.1", + "dependsOn": [ + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/urllib3@1.26.16" + ] + }, + { + "ref": "pkg:pypi/urllib3@1.26.16", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/six@1.16.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/uvicorn@0.17.0", + "dependsOn": [ + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/h11@0.13.0" + ] + } + ] +} diff --git a/test/providers/tst_manifests/pip/pip_requirements_txt_ignore/requirements.txt b/test/providers/tst_manifests/pip/pip_requirements_txt_ignore/requirements.txt new file mode 100644 index 00000000..94093732 --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_txt_ignore/requirements.txt @@ -0,0 +1,27 @@ +anyio==3.6.2 +asgiref==3.4.1 +beautifulsoup4==4.12.2 +certifi==2023.7.22 +chardet==4.0.0 +click==8.0.4 #exhortignore +contextlib2==21.6.0 +fastapi==0.75.1 +Flask==2.0.3 +h11==0.13.0 +idna==2.10 +immutables==0.19 +importlib-metadata==4.8.3 +itsdangerous==2.0.1 +Jinja2==3.0.3 +MarkupSafe==2.0.1 +pydantic==1.9.2 # exhortignore +requests==2.25.1 +six==1.16.0 +sniffio==1.2.0 +soupsieve==2.3.2.post1 +starlette==0.17.1 +typing_extensions==4.1.1 +urllib3==1.26.16 +uvicorn==0.17.0 +Werkzeug==2.0.3 +zipp==3.6.0 diff --git a/test/providers/tst_manifests/pip/pip_requirements_txt_no_ignore/expected_component_sbom.json b/test/providers/tst_manifests/pip/pip_requirements_txt_no_ignore/expected_component_sbom.json new file mode 100644 index 00000000..d25c54c5 --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_txt_no_ignore/expected_component_sbom.json @@ -0,0 +1,353 @@ +{ + "bomFormat" : "CycloneDX", + "specVersion" : "1.4", + "version" : 1, + "metadata" : { + "timestamp" : "2023-10-01T00:00:00.000Z", + "component" : { + "name" : "root", + "purl" : "pkg:pypi/root", + "type" : "application", + "bom-ref" : "pkg:pypi/root" + } + }, + "components" : [ + { + "name" : "root", + "purl" : "pkg:pypi/root", + "type" : "application", + "bom-ref" : "pkg:pypi/root" + }, + { + "name" : "anyio", + "version" : "3.6.2", + "purl" : "pkg:pypi/anyio@3.6.2", + "type" : "library", + "bom-ref" : "pkg:pypi/anyio@3.6.2" + }, + { + "name" : "asgiref", + "version" : "3.4.1", + "purl" : "pkg:pypi/asgiref@3.4.1", + "type" : "library", + "bom-ref" : "pkg:pypi/asgiref@3.4.1" + }, + { + "name" : "beautifulsoup4", + "version" : "4.12.2", + "purl" : "pkg:pypi/beautifulsoup4@4.12.2", + "type" : "library", + "bom-ref" : "pkg:pypi/beautifulsoup4@4.12.2" + }, + { + "name" : "certifi", + "version" : "2023.7.22", + "purl" : "pkg:pypi/certifi@2023.7.22", + "type" : "library", + "bom-ref" : "pkg:pypi/certifi@2023.7.22" + }, + { + "name" : "chardet", + "version" : "4.0.0", + "purl" : "pkg:pypi/chardet@4.0.0", + "type" : "library", + "bom-ref" : "pkg:pypi/chardet@4.0.0" + }, + { + "name" : "click", + "version" : "8.0.4", + "purl" : "pkg:pypi/click@8.0.4", + "type" : "library", + "bom-ref" : "pkg:pypi/click@8.0.4" + }, + { + "name" : "contextlib2", + "version" : "21.6.0", + "purl" : "pkg:pypi/contextlib2@21.6.0", + "type" : "library", + "bom-ref" : "pkg:pypi/contextlib2@21.6.0" + }, + { + "name" : "fastapi", + "version" : "0.75.1", + "purl" : "pkg:pypi/fastapi@0.75.1", + "type" : "library", + "bom-ref" : "pkg:pypi/fastapi@0.75.1" + }, + { + "name" : "flask", + "version" : "2.0.3", + "purl" : "pkg:pypi/flask@2.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/flask@2.0.3" + }, + { + "name" : "h11", + "version" : "0.13.0", + "purl" : "pkg:pypi/h11@0.13.0", + "type" : "library", + "bom-ref" : "pkg:pypi/h11@0.13.0" + }, + { + "name" : "idna", + "version" : "2.10", + "purl" : "pkg:pypi/idna@2.10", + "type" : "library", + "bom-ref" : "pkg:pypi/idna@2.10" + }, + { + "name" : "immutables", + "version" : "0.19", + "purl" : "pkg:pypi/immutables@0.19", + "type" : "library", + "bom-ref" : "pkg:pypi/immutables@0.19" + }, + { + "name" : "importlib-metadata", + "version" : "4.8.3", + "purl" : "pkg:pypi/importlib-metadata@4.8.3", + "type" : "library", + "bom-ref" : "pkg:pypi/importlib-metadata@4.8.3" + }, + { + "name" : "itsdangerous", + "version" : "2.0.1", + "purl" : "pkg:pypi/itsdangerous@2.0.1", + "type" : "library", + "bom-ref" : "pkg:pypi/itsdangerous@2.0.1" + }, + { + "name" : "jinja2", + "version" : "3.0.3", + "purl" : "pkg:pypi/jinja2@3.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/jinja2@3.0.3" + }, + { + "name" : "markupsafe", + "version" : "2.0.1", + "purl" : "pkg:pypi/markupsafe@2.0.1", + "type" : "library", + "bom-ref" : "pkg:pypi/markupsafe@2.0.1" + }, + { + "name" : "pydantic", + "version" : "1.9.2", + "purl" : "pkg:pypi/pydantic@1.9.2", + "type" : "library", + "bom-ref" : "pkg:pypi/pydantic@1.9.2" + }, + { + "name" : "requests", + "version" : "2.25.1", + "purl" : "pkg:pypi/requests@2.25.1", + "type" : "library", + "bom-ref" : "pkg:pypi/requests@2.25.1" + }, + { + "name" : "six", + "version" : "1.16.0", + "purl" : "pkg:pypi/six@1.16.0", + "type" : "library", + "bom-ref" : "pkg:pypi/six@1.16.0" + }, + { + "name" : "sniffio", + "version" : "1.2.0", + "purl" : "pkg:pypi/sniffio@1.2.0", + "type" : "library", + "bom-ref" : "pkg:pypi/sniffio@1.2.0" + }, + { + "name" : "soupsieve", + "version" : "2.3.2.post1", + "purl" : "pkg:pypi/soupsieve@2.3.2.post1", + "type" : "library", + "bom-ref" : "pkg:pypi/soupsieve@2.3.2.post1" + }, + { + "name" : "starlette", + "version" : "0.17.1", + "purl" : "pkg:pypi/starlette@0.17.1", + "type" : "library", + "bom-ref" : "pkg:pypi/starlette@0.17.1" + }, + { + "name" : "typing-extensions", + "version" : "4.1.1", + "purl" : "pkg:pypi/typing-extensions@4.1.1", + "type" : "library", + "bom-ref" : "pkg:pypi/typing-extensions@4.1.1" + }, + { + "name" : "urllib3", + "version" : "1.26.16", + "purl" : "pkg:pypi/urllib3@1.26.16", + "type" : "library", + "bom-ref" : "pkg:pypi/urllib3@1.26.16" + }, + { + "name" : "uvicorn", + "version" : "0.17.0", + "purl" : "pkg:pypi/uvicorn@0.17.0", + "type" : "library", + "bom-ref" : "pkg:pypi/uvicorn@0.17.0" + }, + { + "name" : "werkzeug", + "version" : "2.0.3", + "purl" : "pkg:pypi/werkzeug@2.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/werkzeug@2.0.3" + }, + { + "name" : "zipp", + "version" : "3.6.0", + "purl" : "pkg:pypi/zipp@3.6.0", + "type" : "library", + "bom-ref" : "pkg:pypi/zipp@3.6.0" + } + ], + "dependencies" : [ + { + "ref" : "pkg:pypi/root", + "dependsOn" : [ + "pkg:pypi/anyio@3.6.2", + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/beautifulsoup4@4.12.2", + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/click@8.0.4", + "pkg:pypi/contextlib2@21.6.0", + "pkg:pypi/fastapi@0.75.1", + "pkg:pypi/flask@2.0.3", + "pkg:pypi/h11@0.13.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/immutables@0.19", + "pkg:pypi/importlib-metadata@4.8.3", + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/markupsafe@2.0.1", + "pkg:pypi/pydantic@1.9.2", + "pkg:pypi/requests@2.25.1", + "pkg:pypi/six@1.16.0", + "pkg:pypi/sniffio@1.2.0", + "pkg:pypi/soupsieve@2.3.2.post1", + "pkg:pypi/starlette@0.17.1", + "pkg:pypi/typing-extensions@4.1.1", + "pkg:pypi/urllib3@1.26.16", + "pkg:pypi/uvicorn@0.17.0", + "pkg:pypi/werkzeug@2.0.3", + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref" : "pkg:pypi/anyio@3.6.2", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/asgiref@3.4.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/beautifulsoup4@4.12.2", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/certifi@2023.7.22", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/chardet@4.0.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/click@8.0.4", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/contextlib2@21.6.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/fastapi@0.75.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/flask@2.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/h11@0.13.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/idna@2.10", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/immutables@0.19", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/importlib-metadata@4.8.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/itsdangerous@2.0.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/jinja2@3.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/markupsafe@2.0.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/pydantic@1.9.2", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/requests@2.25.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/six@1.16.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/sniffio@1.2.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/soupsieve@2.3.2.post1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/starlette@0.17.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/typing-extensions@4.1.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/urllib3@1.26.16", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/uvicorn@0.17.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/werkzeug@2.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/zipp@3.6.0", + "dependsOn" : [ ] + } + ] +} diff --git a/test/providers/tst_manifests/pip/pip_requirements_txt_no_ignore/expected_stack_sbom.json b/test/providers/tst_manifests/pip/pip_requirements_txt_no_ignore/expected_stack_sbom.json new file mode 100644 index 00000000..305e1d2c --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_txt_no_ignore/expected_stack_sbom.json @@ -0,0 +1,383 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-10-01T00:00:00.000Z", + "component": { + "name": "root", + "purl": "pkg:pypi/root", + "type": "application", + "bom-ref": "pkg:pypi/root" + } + }, + "components": [ + { + "name": "root", + "purl": "pkg:pypi/root", + "type": "application", + "bom-ref": "pkg:pypi/root" + }, + { + "name": "anyio", + "version": "3.6.2", + "purl": "pkg:pypi/anyio@3.6.2", + "type": "library", + "bom-ref": "pkg:pypi/anyio@3.6.2" + }, + { + "name": "idna", + "version": "2.10", + "purl": "pkg:pypi/idna@2.10", + "type": "library", + "bom-ref": "pkg:pypi/idna@2.10" + }, + { + "name": "sniffio", + "version": "1.2.0", + "purl": "pkg:pypi/sniffio@1.2.0", + "type": "library", + "bom-ref": "pkg:pypi/sniffio@1.2.0" + }, + { + "name": "asgiref", + "version": "3.4.1", + "purl": "pkg:pypi/asgiref@3.4.1", + "type": "library", + "bom-ref": "pkg:pypi/asgiref@3.4.1" + }, + { + "name": "beautifulsoup4", + "version": "4.12.2", + "purl": "pkg:pypi/beautifulsoup4@4.12.2", + "type": "library", + "bom-ref": "pkg:pypi/beautifulsoup4@4.12.2" + }, + { + "name": "soupsieve", + "version": "2.3.2.post1", + "purl": "pkg:pypi/soupsieve@2.3.2.post1", + "type": "library", + "bom-ref": "pkg:pypi/soupsieve@2.3.2.post1" + }, + { + "name": "certifi", + "version": "2023.7.22", + "purl": "pkg:pypi/certifi@2023.7.22", + "type": "library", + "bom-ref": "pkg:pypi/certifi@2023.7.22" + }, + { + "name": "chardet", + "version": "4.0.0", + "purl": "pkg:pypi/chardet@4.0.0", + "type": "library", + "bom-ref": "pkg:pypi/chardet@4.0.0" + }, + { + "name": "click", + "version": "8.0.4", + "purl": "pkg:pypi/click@8.0.4", + "type": "library", + "bom-ref": "pkg:pypi/click@8.0.4" + }, + { + "name": "contextlib2", + "version": "21.6.0", + "purl": "pkg:pypi/contextlib2@21.6.0", + "type": "library", + "bom-ref": "pkg:pypi/contextlib2@21.6.0" + }, + { + "name": "fastapi", + "version": "0.75.1", + "purl": "pkg:pypi/fastapi@0.75.1", + "type": "library", + "bom-ref": "pkg:pypi/fastapi@0.75.1" + }, + { + "name": "pydantic", + "version": "1.9.2", + "purl": "pkg:pypi/pydantic@1.9.2", + "type": "library", + "bom-ref": "pkg:pypi/pydantic@1.9.2" + }, + { + "name": "typing-extensions", + "version": "4.1.1", + "purl": "pkg:pypi/typing-extensions@4.1.1", + "type": "library", + "bom-ref": "pkg:pypi/typing-extensions@4.1.1" + }, + { + "name": "starlette", + "version": "0.17.1", + "purl": "pkg:pypi/starlette@0.17.1", + "type": "library", + "bom-ref": "pkg:pypi/starlette@0.17.1" + }, + { + "name": "flask", + "version": "2.0.3", + "purl": "pkg:pypi/flask@2.0.3", + "type": "library", + "bom-ref": "pkg:pypi/flask@2.0.3" + }, + { + "name": "itsdangerous", + "version": "2.0.1", + "purl": "pkg:pypi/itsdangerous@2.0.1", + "type": "library", + "bom-ref": "pkg:pypi/itsdangerous@2.0.1" + }, + { + "name": "jinja2", + "version": "3.0.3", + "purl": "pkg:pypi/jinja2@3.0.3", + "type": "library", + "bom-ref": "pkg:pypi/jinja2@3.0.3" + }, + { + "name": "markupsafe", + "version": "2.0.1", + "purl": "pkg:pypi/markupsafe@2.0.1", + "type": "library", + "bom-ref": "pkg:pypi/markupsafe@2.0.1" + }, + { + "name": "werkzeug", + "version": "2.0.3", + "purl": "pkg:pypi/werkzeug@2.0.3", + "type": "library", + "bom-ref": "pkg:pypi/werkzeug@2.0.3" + }, + { + "name": "h11", + "version": "0.13.0", + "purl": "pkg:pypi/h11@0.13.0", + "type": "library", + "bom-ref": "pkg:pypi/h11@0.13.0" + }, + { + "name": "immutables", + "version": "0.19", + "purl": "pkg:pypi/immutables@0.19", + "type": "library", + "bom-ref": "pkg:pypi/immutables@0.19" + }, + { + "name": "importlib-metadata", + "version": "4.8.3", + "purl": "pkg:pypi/importlib-metadata@4.8.3", + "type": "library", + "bom-ref": "pkg:pypi/importlib-metadata@4.8.3" + }, + { + "name": "zipp", + "version": "3.6.0", + "purl": "pkg:pypi/zipp@3.6.0", + "type": "library", + "bom-ref": "pkg:pypi/zipp@3.6.0" + }, + { + "name": "requests", + "version": "2.25.1", + "purl": "pkg:pypi/requests@2.25.1", + "type": "library", + "bom-ref": "pkg:pypi/requests@2.25.1" + }, + { + "name": "urllib3", + "version": "1.26.16", + "purl": "pkg:pypi/urllib3@1.26.16", + "type": "library", + "bom-ref": "pkg:pypi/urllib3@1.26.16" + }, + { + "name": "six", + "version": "1.16.0", + "purl": "pkg:pypi/six@1.16.0", + "type": "library", + "bom-ref": "pkg:pypi/six@1.16.0" + }, + { + "name": "uvicorn", + "version": "0.17.0", + "purl": "pkg:pypi/uvicorn@0.17.0", + "type": "library", + "bom-ref": "pkg:pypi/uvicorn@0.17.0" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/root", + "dependsOn": [ + "pkg:pypi/anyio@3.6.2", + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/beautifulsoup4@4.12.2", + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/click@8.0.4", + "pkg:pypi/contextlib2@21.6.0", + "pkg:pypi/fastapi@0.75.1", + "pkg:pypi/flask@2.0.3", + "pkg:pypi/h11@0.13.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/immutables@0.19", + "pkg:pypi/importlib-metadata@4.8.3", + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/markupsafe@2.0.1", + "pkg:pypi/pydantic@1.9.2", + "pkg:pypi/requests@2.25.1", + "pkg:pypi/six@1.16.0", + "pkg:pypi/sniffio@1.2.0", + "pkg:pypi/soupsieve@2.3.2.post1", + "pkg:pypi/starlette@0.17.1", + "pkg:pypi/typing-extensions@4.1.1", + "pkg:pypi/urllib3@1.26.16", + "pkg:pypi/uvicorn@0.17.0", + "pkg:pypi/werkzeug@2.0.3", + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref": "pkg:pypi/anyio@3.6.2", + "dependsOn": [ + "pkg:pypi/idna@2.10", + "pkg:pypi/sniffio@1.2.0" + ] + }, + { + "ref": "pkg:pypi/idna@2.10", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/sniffio@1.2.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/asgiref@3.4.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/beautifulsoup4@4.12.2", + "dependsOn": [ + "pkg:pypi/soupsieve@2.3.2.post1" + ] + }, + { + "ref": "pkg:pypi/soupsieve@2.3.2.post1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/certifi@2023.7.22", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/chardet@4.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/click@8.0.4", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/contextlib2@21.6.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/fastapi@0.75.1", + "dependsOn": [ + "pkg:pypi/pydantic@1.9.2", + "pkg:pypi/starlette@0.17.1" + ] + }, + { + "ref": "pkg:pypi/pydantic@1.9.2", + "dependsOn": [ + "pkg:pypi/typing-extensions@4.1.1" + ] + }, + { + "ref": "pkg:pypi/typing-extensions@4.1.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/starlette@0.17.1", + "dependsOn": [ + "pkg:pypi/anyio@3.6.2" + ] + }, + { + "ref": "pkg:pypi/flask@2.0.3", + "dependsOn": [ + "pkg:pypi/click@8.0.4", + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/werkzeug@2.0.3" + ] + }, + { + "ref": "pkg:pypi/itsdangerous@2.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/jinja2@3.0.3", + "dependsOn": [ + "pkg:pypi/markupsafe@2.0.1" + ] + }, + { + "ref": "pkg:pypi/markupsafe@2.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/werkzeug@2.0.3", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/h11@0.13.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/immutables@0.19", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/importlib-metadata@4.8.3", + "dependsOn": [ + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref": "pkg:pypi/zipp@3.6.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/requests@2.25.1", + "dependsOn": [ + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/urllib3@1.26.16" + ] + }, + { + "ref": "pkg:pypi/urllib3@1.26.16", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/six@1.16.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/uvicorn@0.17.0", + "dependsOn": [ + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/click@8.0.4", + "pkg:pypi/h11@0.13.0" + ] + } + ] +} diff --git a/test/providers/tst_manifests/pip/pip_requirements_txt_no_ignore/requirements.txt b/test/providers/tst_manifests/pip/pip_requirements_txt_no_ignore/requirements.txt new file mode 100644 index 00000000..4f0d690d --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_txt_no_ignore/requirements.txt @@ -0,0 +1,27 @@ +anyio==3.6.2 +asgiref==3.4.1 +beautifulsoup4==4.12.2 +certifi==2023.7.22 +chardet==4.0.0 +click==8.0.4 +contextlib2==21.6.0 +fastapi==0.75.1 +Flask==2.0.3 +h11==0.13.0 +idna==2.10 +immutables==0.19 +importlib-metadata==4.8.3 +itsdangerous==2.0.1 +Jinja2==3.0.3 +MarkupSafe==2.0.1 +pydantic==1.9.2 +requests==2.25.1 +six==1.16.0 +sniffio==1.2.0 +soupsieve==2.3.2.post1 +starlette==0.17.1 +typing_extensions==4.1.1 +urllib3==1.26.16 +uvicorn==0.17.0 +Werkzeug==2.0.3 +zipp==3.6.0 diff --git a/test/providers/tst_manifests/pip/pip_requirements_virtual_env_txt_no_ignore/expected_component_sbom.json b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_txt_no_ignore/expected_component_sbom.json new file mode 100644 index 00000000..d25c54c5 --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_txt_no_ignore/expected_component_sbom.json @@ -0,0 +1,353 @@ +{ + "bomFormat" : "CycloneDX", + "specVersion" : "1.4", + "version" : 1, + "metadata" : { + "timestamp" : "2023-10-01T00:00:00.000Z", + "component" : { + "name" : "root", + "purl" : "pkg:pypi/root", + "type" : "application", + "bom-ref" : "pkg:pypi/root" + } + }, + "components" : [ + { + "name" : "root", + "purl" : "pkg:pypi/root", + "type" : "application", + "bom-ref" : "pkg:pypi/root" + }, + { + "name" : "anyio", + "version" : "3.6.2", + "purl" : "pkg:pypi/anyio@3.6.2", + "type" : "library", + "bom-ref" : "pkg:pypi/anyio@3.6.2" + }, + { + "name" : "asgiref", + "version" : "3.4.1", + "purl" : "pkg:pypi/asgiref@3.4.1", + "type" : "library", + "bom-ref" : "pkg:pypi/asgiref@3.4.1" + }, + { + "name" : "beautifulsoup4", + "version" : "4.12.2", + "purl" : "pkg:pypi/beautifulsoup4@4.12.2", + "type" : "library", + "bom-ref" : "pkg:pypi/beautifulsoup4@4.12.2" + }, + { + "name" : "certifi", + "version" : "2023.7.22", + "purl" : "pkg:pypi/certifi@2023.7.22", + "type" : "library", + "bom-ref" : "pkg:pypi/certifi@2023.7.22" + }, + { + "name" : "chardet", + "version" : "4.0.0", + "purl" : "pkg:pypi/chardet@4.0.0", + "type" : "library", + "bom-ref" : "pkg:pypi/chardet@4.0.0" + }, + { + "name" : "click", + "version" : "8.0.4", + "purl" : "pkg:pypi/click@8.0.4", + "type" : "library", + "bom-ref" : "pkg:pypi/click@8.0.4" + }, + { + "name" : "contextlib2", + "version" : "21.6.0", + "purl" : "pkg:pypi/contextlib2@21.6.0", + "type" : "library", + "bom-ref" : "pkg:pypi/contextlib2@21.6.0" + }, + { + "name" : "fastapi", + "version" : "0.75.1", + "purl" : "pkg:pypi/fastapi@0.75.1", + "type" : "library", + "bom-ref" : "pkg:pypi/fastapi@0.75.1" + }, + { + "name" : "flask", + "version" : "2.0.3", + "purl" : "pkg:pypi/flask@2.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/flask@2.0.3" + }, + { + "name" : "h11", + "version" : "0.13.0", + "purl" : "pkg:pypi/h11@0.13.0", + "type" : "library", + "bom-ref" : "pkg:pypi/h11@0.13.0" + }, + { + "name" : "idna", + "version" : "2.10", + "purl" : "pkg:pypi/idna@2.10", + "type" : "library", + "bom-ref" : "pkg:pypi/idna@2.10" + }, + { + "name" : "immutables", + "version" : "0.19", + "purl" : "pkg:pypi/immutables@0.19", + "type" : "library", + "bom-ref" : "pkg:pypi/immutables@0.19" + }, + { + "name" : "importlib-metadata", + "version" : "4.8.3", + "purl" : "pkg:pypi/importlib-metadata@4.8.3", + "type" : "library", + "bom-ref" : "pkg:pypi/importlib-metadata@4.8.3" + }, + { + "name" : "itsdangerous", + "version" : "2.0.1", + "purl" : "pkg:pypi/itsdangerous@2.0.1", + "type" : "library", + "bom-ref" : "pkg:pypi/itsdangerous@2.0.1" + }, + { + "name" : "jinja2", + "version" : "3.0.3", + "purl" : "pkg:pypi/jinja2@3.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/jinja2@3.0.3" + }, + { + "name" : "markupsafe", + "version" : "2.0.1", + "purl" : "pkg:pypi/markupsafe@2.0.1", + "type" : "library", + "bom-ref" : "pkg:pypi/markupsafe@2.0.1" + }, + { + "name" : "pydantic", + "version" : "1.9.2", + "purl" : "pkg:pypi/pydantic@1.9.2", + "type" : "library", + "bom-ref" : "pkg:pypi/pydantic@1.9.2" + }, + { + "name" : "requests", + "version" : "2.25.1", + "purl" : "pkg:pypi/requests@2.25.1", + "type" : "library", + "bom-ref" : "pkg:pypi/requests@2.25.1" + }, + { + "name" : "six", + "version" : "1.16.0", + "purl" : "pkg:pypi/six@1.16.0", + "type" : "library", + "bom-ref" : "pkg:pypi/six@1.16.0" + }, + { + "name" : "sniffio", + "version" : "1.2.0", + "purl" : "pkg:pypi/sniffio@1.2.0", + "type" : "library", + "bom-ref" : "pkg:pypi/sniffio@1.2.0" + }, + { + "name" : "soupsieve", + "version" : "2.3.2.post1", + "purl" : "pkg:pypi/soupsieve@2.3.2.post1", + "type" : "library", + "bom-ref" : "pkg:pypi/soupsieve@2.3.2.post1" + }, + { + "name" : "starlette", + "version" : "0.17.1", + "purl" : "pkg:pypi/starlette@0.17.1", + "type" : "library", + "bom-ref" : "pkg:pypi/starlette@0.17.1" + }, + { + "name" : "typing-extensions", + "version" : "4.1.1", + "purl" : "pkg:pypi/typing-extensions@4.1.1", + "type" : "library", + "bom-ref" : "pkg:pypi/typing-extensions@4.1.1" + }, + { + "name" : "urllib3", + "version" : "1.26.16", + "purl" : "pkg:pypi/urllib3@1.26.16", + "type" : "library", + "bom-ref" : "pkg:pypi/urllib3@1.26.16" + }, + { + "name" : "uvicorn", + "version" : "0.17.0", + "purl" : "pkg:pypi/uvicorn@0.17.0", + "type" : "library", + "bom-ref" : "pkg:pypi/uvicorn@0.17.0" + }, + { + "name" : "werkzeug", + "version" : "2.0.3", + "purl" : "pkg:pypi/werkzeug@2.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/werkzeug@2.0.3" + }, + { + "name" : "zipp", + "version" : "3.6.0", + "purl" : "pkg:pypi/zipp@3.6.0", + "type" : "library", + "bom-ref" : "pkg:pypi/zipp@3.6.0" + } + ], + "dependencies" : [ + { + "ref" : "pkg:pypi/root", + "dependsOn" : [ + "pkg:pypi/anyio@3.6.2", + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/beautifulsoup4@4.12.2", + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/click@8.0.4", + "pkg:pypi/contextlib2@21.6.0", + "pkg:pypi/fastapi@0.75.1", + "pkg:pypi/flask@2.0.3", + "pkg:pypi/h11@0.13.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/immutables@0.19", + "pkg:pypi/importlib-metadata@4.8.3", + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/markupsafe@2.0.1", + "pkg:pypi/pydantic@1.9.2", + "pkg:pypi/requests@2.25.1", + "pkg:pypi/six@1.16.0", + "pkg:pypi/sniffio@1.2.0", + "pkg:pypi/soupsieve@2.3.2.post1", + "pkg:pypi/starlette@0.17.1", + "pkg:pypi/typing-extensions@4.1.1", + "pkg:pypi/urllib3@1.26.16", + "pkg:pypi/uvicorn@0.17.0", + "pkg:pypi/werkzeug@2.0.3", + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref" : "pkg:pypi/anyio@3.6.2", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/asgiref@3.4.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/beautifulsoup4@4.12.2", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/certifi@2023.7.22", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/chardet@4.0.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/click@8.0.4", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/contextlib2@21.6.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/fastapi@0.75.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/flask@2.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/h11@0.13.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/idna@2.10", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/immutables@0.19", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/importlib-metadata@4.8.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/itsdangerous@2.0.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/jinja2@3.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/markupsafe@2.0.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/pydantic@1.9.2", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/requests@2.25.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/six@1.16.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/sniffio@1.2.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/soupsieve@2.3.2.post1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/starlette@0.17.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/typing-extensions@4.1.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/urllib3@1.26.16", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/uvicorn@0.17.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/werkzeug@2.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/zipp@3.6.0", + "dependsOn" : [ ] + } + ] +} diff --git a/test/providers/tst_manifests/pip/pip_requirements_virtual_env_txt_no_ignore/expected_stack_sbom.json b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_txt_no_ignore/expected_stack_sbom.json new file mode 100644 index 00000000..305e1d2c --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_txt_no_ignore/expected_stack_sbom.json @@ -0,0 +1,383 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-10-01T00:00:00.000Z", + "component": { + "name": "root", + "purl": "pkg:pypi/root", + "type": "application", + "bom-ref": "pkg:pypi/root" + } + }, + "components": [ + { + "name": "root", + "purl": "pkg:pypi/root", + "type": "application", + "bom-ref": "pkg:pypi/root" + }, + { + "name": "anyio", + "version": "3.6.2", + "purl": "pkg:pypi/anyio@3.6.2", + "type": "library", + "bom-ref": "pkg:pypi/anyio@3.6.2" + }, + { + "name": "idna", + "version": "2.10", + "purl": "pkg:pypi/idna@2.10", + "type": "library", + "bom-ref": "pkg:pypi/idna@2.10" + }, + { + "name": "sniffio", + "version": "1.2.0", + "purl": "pkg:pypi/sniffio@1.2.0", + "type": "library", + "bom-ref": "pkg:pypi/sniffio@1.2.0" + }, + { + "name": "asgiref", + "version": "3.4.1", + "purl": "pkg:pypi/asgiref@3.4.1", + "type": "library", + "bom-ref": "pkg:pypi/asgiref@3.4.1" + }, + { + "name": "beautifulsoup4", + "version": "4.12.2", + "purl": "pkg:pypi/beautifulsoup4@4.12.2", + "type": "library", + "bom-ref": "pkg:pypi/beautifulsoup4@4.12.2" + }, + { + "name": "soupsieve", + "version": "2.3.2.post1", + "purl": "pkg:pypi/soupsieve@2.3.2.post1", + "type": "library", + "bom-ref": "pkg:pypi/soupsieve@2.3.2.post1" + }, + { + "name": "certifi", + "version": "2023.7.22", + "purl": "pkg:pypi/certifi@2023.7.22", + "type": "library", + "bom-ref": "pkg:pypi/certifi@2023.7.22" + }, + { + "name": "chardet", + "version": "4.0.0", + "purl": "pkg:pypi/chardet@4.0.0", + "type": "library", + "bom-ref": "pkg:pypi/chardet@4.0.0" + }, + { + "name": "click", + "version": "8.0.4", + "purl": "pkg:pypi/click@8.0.4", + "type": "library", + "bom-ref": "pkg:pypi/click@8.0.4" + }, + { + "name": "contextlib2", + "version": "21.6.0", + "purl": "pkg:pypi/contextlib2@21.6.0", + "type": "library", + "bom-ref": "pkg:pypi/contextlib2@21.6.0" + }, + { + "name": "fastapi", + "version": "0.75.1", + "purl": "pkg:pypi/fastapi@0.75.1", + "type": "library", + "bom-ref": "pkg:pypi/fastapi@0.75.1" + }, + { + "name": "pydantic", + "version": "1.9.2", + "purl": "pkg:pypi/pydantic@1.9.2", + "type": "library", + "bom-ref": "pkg:pypi/pydantic@1.9.2" + }, + { + "name": "typing-extensions", + "version": "4.1.1", + "purl": "pkg:pypi/typing-extensions@4.1.1", + "type": "library", + "bom-ref": "pkg:pypi/typing-extensions@4.1.1" + }, + { + "name": "starlette", + "version": "0.17.1", + "purl": "pkg:pypi/starlette@0.17.1", + "type": "library", + "bom-ref": "pkg:pypi/starlette@0.17.1" + }, + { + "name": "flask", + "version": "2.0.3", + "purl": "pkg:pypi/flask@2.0.3", + "type": "library", + "bom-ref": "pkg:pypi/flask@2.0.3" + }, + { + "name": "itsdangerous", + "version": "2.0.1", + "purl": "pkg:pypi/itsdangerous@2.0.1", + "type": "library", + "bom-ref": "pkg:pypi/itsdangerous@2.0.1" + }, + { + "name": "jinja2", + "version": "3.0.3", + "purl": "pkg:pypi/jinja2@3.0.3", + "type": "library", + "bom-ref": "pkg:pypi/jinja2@3.0.3" + }, + { + "name": "markupsafe", + "version": "2.0.1", + "purl": "pkg:pypi/markupsafe@2.0.1", + "type": "library", + "bom-ref": "pkg:pypi/markupsafe@2.0.1" + }, + { + "name": "werkzeug", + "version": "2.0.3", + "purl": "pkg:pypi/werkzeug@2.0.3", + "type": "library", + "bom-ref": "pkg:pypi/werkzeug@2.0.3" + }, + { + "name": "h11", + "version": "0.13.0", + "purl": "pkg:pypi/h11@0.13.0", + "type": "library", + "bom-ref": "pkg:pypi/h11@0.13.0" + }, + { + "name": "immutables", + "version": "0.19", + "purl": "pkg:pypi/immutables@0.19", + "type": "library", + "bom-ref": "pkg:pypi/immutables@0.19" + }, + { + "name": "importlib-metadata", + "version": "4.8.3", + "purl": "pkg:pypi/importlib-metadata@4.8.3", + "type": "library", + "bom-ref": "pkg:pypi/importlib-metadata@4.8.3" + }, + { + "name": "zipp", + "version": "3.6.0", + "purl": "pkg:pypi/zipp@3.6.0", + "type": "library", + "bom-ref": "pkg:pypi/zipp@3.6.0" + }, + { + "name": "requests", + "version": "2.25.1", + "purl": "pkg:pypi/requests@2.25.1", + "type": "library", + "bom-ref": "pkg:pypi/requests@2.25.1" + }, + { + "name": "urllib3", + "version": "1.26.16", + "purl": "pkg:pypi/urllib3@1.26.16", + "type": "library", + "bom-ref": "pkg:pypi/urllib3@1.26.16" + }, + { + "name": "six", + "version": "1.16.0", + "purl": "pkg:pypi/six@1.16.0", + "type": "library", + "bom-ref": "pkg:pypi/six@1.16.0" + }, + { + "name": "uvicorn", + "version": "0.17.0", + "purl": "pkg:pypi/uvicorn@0.17.0", + "type": "library", + "bom-ref": "pkg:pypi/uvicorn@0.17.0" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/root", + "dependsOn": [ + "pkg:pypi/anyio@3.6.2", + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/beautifulsoup4@4.12.2", + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/click@8.0.4", + "pkg:pypi/contextlib2@21.6.0", + "pkg:pypi/fastapi@0.75.1", + "pkg:pypi/flask@2.0.3", + "pkg:pypi/h11@0.13.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/immutables@0.19", + "pkg:pypi/importlib-metadata@4.8.3", + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/markupsafe@2.0.1", + "pkg:pypi/pydantic@1.9.2", + "pkg:pypi/requests@2.25.1", + "pkg:pypi/six@1.16.0", + "pkg:pypi/sniffio@1.2.0", + "pkg:pypi/soupsieve@2.3.2.post1", + "pkg:pypi/starlette@0.17.1", + "pkg:pypi/typing-extensions@4.1.1", + "pkg:pypi/urllib3@1.26.16", + "pkg:pypi/uvicorn@0.17.0", + "pkg:pypi/werkzeug@2.0.3", + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref": "pkg:pypi/anyio@3.6.2", + "dependsOn": [ + "pkg:pypi/idna@2.10", + "pkg:pypi/sniffio@1.2.0" + ] + }, + { + "ref": "pkg:pypi/idna@2.10", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/sniffio@1.2.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/asgiref@3.4.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/beautifulsoup4@4.12.2", + "dependsOn": [ + "pkg:pypi/soupsieve@2.3.2.post1" + ] + }, + { + "ref": "pkg:pypi/soupsieve@2.3.2.post1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/certifi@2023.7.22", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/chardet@4.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/click@8.0.4", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/contextlib2@21.6.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/fastapi@0.75.1", + "dependsOn": [ + "pkg:pypi/pydantic@1.9.2", + "pkg:pypi/starlette@0.17.1" + ] + }, + { + "ref": "pkg:pypi/pydantic@1.9.2", + "dependsOn": [ + "pkg:pypi/typing-extensions@4.1.1" + ] + }, + { + "ref": "pkg:pypi/typing-extensions@4.1.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/starlette@0.17.1", + "dependsOn": [ + "pkg:pypi/anyio@3.6.2" + ] + }, + { + "ref": "pkg:pypi/flask@2.0.3", + "dependsOn": [ + "pkg:pypi/click@8.0.4", + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/werkzeug@2.0.3" + ] + }, + { + "ref": "pkg:pypi/itsdangerous@2.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/jinja2@3.0.3", + "dependsOn": [ + "pkg:pypi/markupsafe@2.0.1" + ] + }, + { + "ref": "pkg:pypi/markupsafe@2.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/werkzeug@2.0.3", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/h11@0.13.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/immutables@0.19", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/importlib-metadata@4.8.3", + "dependsOn": [ + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref": "pkg:pypi/zipp@3.6.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/requests@2.25.1", + "dependsOn": [ + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/urllib3@1.26.16" + ] + }, + { + "ref": "pkg:pypi/urllib3@1.26.16", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/six@1.16.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/uvicorn@0.17.0", + "dependsOn": [ + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/click@8.0.4", + "pkg:pypi/h11@0.13.0" + ] + } + ] +} diff --git a/test/providers/tst_manifests/pip/pip_requirements_virtual_env_txt_no_ignore/requirements.txt b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_txt_no_ignore/requirements.txt new file mode 100644 index 00000000..4f0d690d --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_txt_no_ignore/requirements.txt @@ -0,0 +1,27 @@ +anyio==3.6.2 +asgiref==3.4.1 +beautifulsoup4==4.12.2 +certifi==2023.7.22 +chardet==4.0.0 +click==8.0.4 +contextlib2==21.6.0 +fastapi==0.75.1 +Flask==2.0.3 +h11==0.13.0 +idna==2.10 +immutables==0.19 +importlib-metadata==4.8.3 +itsdangerous==2.0.1 +Jinja2==3.0.3 +MarkupSafe==2.0.1 +pydantic==1.9.2 +requests==2.25.1 +six==1.16.0 +sniffio==1.2.0 +soupsieve==2.3.2.post1 +starlette==0.17.1 +typing_extensions==4.1.1 +urllib3==1.26.16 +uvicorn==0.17.0 +Werkzeug==2.0.3 +zipp==3.6.0 diff --git a/test/providers/tst_manifests/pip/pip_requirements_virtual_env_with_ignore/expected_component_sbom.json b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_with_ignore/expected_component_sbom.json new file mode 100644 index 00000000..a6ea38ac --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_with_ignore/expected_component_sbom.json @@ -0,0 +1,329 @@ +{ + "bomFormat" : "CycloneDX", + "specVersion" : "1.4", + "version" : 1, + "metadata" : { + "timestamp" : "2023-10-01T00:00:00.000Z", + "component" : { + "name" : "root", + "purl" : "pkg:pypi/root", + "type" : "application", + "bom-ref" : "pkg:pypi/root" + } + }, + "components" : [ + { + "name" : "root", + "purl" : "pkg:pypi/root", + "type" : "application", + "bom-ref" : "pkg:pypi/root" + }, + { + "name" : "anyio", + "version" : "3.6.2", + "purl" : "pkg:pypi/anyio@3.6.2", + "type" : "library", + "bom-ref" : "pkg:pypi/anyio@3.6.2" + }, + { + "name" : "asgiref", + "version" : "3.4.1", + "purl" : "pkg:pypi/asgiref@3.4.1", + "type" : "library", + "bom-ref" : "pkg:pypi/asgiref@3.4.1" + }, + { + "name" : "beautifulsoup4", + "version" : "4.12.2", + "purl" : "pkg:pypi/beautifulsoup4@4.12.2", + "type" : "library", + "bom-ref" : "pkg:pypi/beautifulsoup4@4.12.2" + }, + { + "name" : "certifi", + "version" : "2023.7.22", + "purl" : "pkg:pypi/certifi@2023.7.22", + "type" : "library", + "bom-ref" : "pkg:pypi/certifi@2023.7.22" + }, + { + "name" : "chardet", + "version" : "4.0.0", + "purl" : "pkg:pypi/chardet@4.0.0", + "type" : "library", + "bom-ref" : "pkg:pypi/chardet@4.0.0" + }, + { + "name" : "contextlib2", + "version" : "21.6.0", + "purl" : "pkg:pypi/contextlib2@21.6.0", + "type" : "library", + "bom-ref" : "pkg:pypi/contextlib2@21.6.0" + }, + { + "name" : "fastapi", + "version" : "0.75.1", + "purl" : "pkg:pypi/fastapi@0.75.1", + "type" : "library", + "bom-ref" : "pkg:pypi/fastapi@0.75.1" + }, + { + "name" : "flask", + "version" : "2.0.3", + "purl" : "pkg:pypi/flask@2.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/flask@2.0.3" + }, + { + "name" : "h11", + "version" : "0.13.0", + "purl" : "pkg:pypi/h11@0.13.0", + "type" : "library", + "bom-ref" : "pkg:pypi/h11@0.13.0" + }, + { + "name" : "idna", + "version" : "2.10", + "purl" : "pkg:pypi/idna@2.10", + "type" : "library", + "bom-ref" : "pkg:pypi/idna@2.10" + }, + { + "name" : "immutables", + "version" : "0.19", + "purl" : "pkg:pypi/immutables@0.19", + "type" : "library", + "bom-ref" : "pkg:pypi/immutables@0.19" + }, + { + "name" : "importlib-metadata", + "version" : "4.8.3", + "purl" : "pkg:pypi/importlib-metadata@4.8.3", + "type" : "library", + "bom-ref" : "pkg:pypi/importlib-metadata@4.8.3" + }, + { + "name" : "itsdangerous", + "version" : "2.0.1", + "purl" : "pkg:pypi/itsdangerous@2.0.1", + "type" : "library", + "bom-ref" : "pkg:pypi/itsdangerous@2.0.1" + }, + { + "name" : "jinja2", + "version" : "3.0.3", + "purl" : "pkg:pypi/jinja2@3.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/jinja2@3.0.3" + }, + { + "name" : "markupsafe", + "version" : "2.0.1", + "purl" : "pkg:pypi/markupsafe@2.0.1", + "type" : "library", + "bom-ref" : "pkg:pypi/markupsafe@2.0.1" + }, + { + "name" : "requests", + "version" : "2.25.1", + "purl" : "pkg:pypi/requests@2.25.1", + "type" : "library", + "bom-ref" : "pkg:pypi/requests@2.25.1" + }, + { + "name" : "six", + "version" : "1.16.0", + "purl" : "pkg:pypi/six@1.16.0", + "type" : "library", + "bom-ref" : "pkg:pypi/six@1.16.0" + }, + { + "name" : "sniffio", + "version" : "1.2.0", + "purl" : "pkg:pypi/sniffio@1.2.0", + "type" : "library", + "bom-ref" : "pkg:pypi/sniffio@1.2.0" + }, + { + "name" : "soupsieve", + "version" : "2.3.2.post1", + "purl" : "pkg:pypi/soupsieve@2.3.2.post1", + "type" : "library", + "bom-ref" : "pkg:pypi/soupsieve@2.3.2.post1" + }, + { + "name" : "starlette", + "version" : "0.17.1", + "purl" : "pkg:pypi/starlette@0.17.1", + "type" : "library", + "bom-ref" : "pkg:pypi/starlette@0.17.1" + }, + { + "name" : "typing-extensions", + "version" : "4.1.1", + "purl" : "pkg:pypi/typing-extensions@4.1.1", + "type" : "library", + "bom-ref" : "pkg:pypi/typing-extensions@4.1.1" + }, + { + "name" : "urllib3", + "version" : "1.26.16", + "purl" : "pkg:pypi/urllib3@1.26.16", + "type" : "library", + "bom-ref" : "pkg:pypi/urllib3@1.26.16" + }, + { + "name" : "uvicorn", + "version" : "0.17.0", + "purl" : "pkg:pypi/uvicorn@0.17.0", + "type" : "library", + "bom-ref" : "pkg:pypi/uvicorn@0.17.0" + }, + { + "name" : "werkzeug", + "version" : "2.0.3", + "purl" : "pkg:pypi/werkzeug@2.0.3", + "type" : "library", + "bom-ref" : "pkg:pypi/werkzeug@2.0.3" + }, + { + "name" : "zipp", + "version" : "3.6.0", + "purl" : "pkg:pypi/zipp@3.6.0", + "type" : "library", + "bom-ref" : "pkg:pypi/zipp@3.6.0" + } + ], + "dependencies" : [ + { + "ref" : "pkg:pypi/root", + "dependsOn" : [ + "pkg:pypi/anyio@3.6.2", + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/beautifulsoup4@4.12.2", + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/contextlib2@21.6.0", + "pkg:pypi/fastapi@0.75.1", + "pkg:pypi/flask@2.0.3", + "pkg:pypi/h11@0.13.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/immutables@0.19", + "pkg:pypi/importlib-metadata@4.8.3", + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/markupsafe@2.0.1", + "pkg:pypi/requests@2.25.1", + "pkg:pypi/six@1.16.0", + "pkg:pypi/sniffio@1.2.0", + "pkg:pypi/soupsieve@2.3.2.post1", + "pkg:pypi/starlette@0.17.1", + "pkg:pypi/typing-extensions@4.1.1", + "pkg:pypi/urllib3@1.26.16", + "pkg:pypi/uvicorn@0.17.0", + "pkg:pypi/werkzeug@2.0.3", + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref" : "pkg:pypi/anyio@3.6.2", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/asgiref@3.4.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/beautifulsoup4@4.12.2", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/certifi@2023.7.22", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/chardet@4.0.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/contextlib2@21.6.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/fastapi@0.75.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/flask@2.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/h11@0.13.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/idna@2.10", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/immutables@0.19", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/importlib-metadata@4.8.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/itsdangerous@2.0.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/jinja2@3.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/markupsafe@2.0.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/requests@2.25.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/six@1.16.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/sniffio@1.2.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/soupsieve@2.3.2.post1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/starlette@0.17.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/typing-extensions@4.1.1", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/urllib3@1.26.16", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/uvicorn@0.17.0", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/werkzeug@2.0.3", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:pypi/zipp@3.6.0", + "dependsOn" : [ ] + } + ] +} diff --git a/test/providers/tst_manifests/pip/pip_requirements_virtual_env_with_ignore/expected_stack_sbom.json b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_with_ignore/expected_stack_sbom.json new file mode 100644 index 00000000..46d43c3b --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_with_ignore/expected_stack_sbom.json @@ -0,0 +1,354 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-10-01T00:00:00.000Z", + "component": { + "name": "root", + "purl": "pkg:pypi/root", + "type": "application", + "bom-ref": "pkg:pypi/root" + } + }, + "components": [ + { + "name": "root", + "purl": "pkg:pypi/root", + "type": "application", + "bom-ref": "pkg:pypi/root" + }, + { + "name": "anyio", + "version": "3.6.2", + "purl": "pkg:pypi/anyio@3.6.2", + "type": "library", + "bom-ref": "pkg:pypi/anyio@3.6.2" + }, + { + "name": "idna", + "version": "2.10", + "purl": "pkg:pypi/idna@2.10", + "type": "library", + "bom-ref": "pkg:pypi/idna@2.10" + }, + { + "name": "sniffio", + "version": "1.2.0", + "purl": "pkg:pypi/sniffio@1.2.0", + "type": "library", + "bom-ref": "pkg:pypi/sniffio@1.2.0" + }, + { + "name": "asgiref", + "version": "3.4.1", + "purl": "pkg:pypi/asgiref@3.4.1", + "type": "library", + "bom-ref": "pkg:pypi/asgiref@3.4.1" + }, + { + "name": "beautifulsoup4", + "version": "4.12.2", + "purl": "pkg:pypi/beautifulsoup4@4.12.2", + "type": "library", + "bom-ref": "pkg:pypi/beautifulsoup4@4.12.2" + }, + { + "name": "soupsieve", + "version": "2.3.2.post1", + "purl": "pkg:pypi/soupsieve@2.3.2.post1", + "type": "library", + "bom-ref": "pkg:pypi/soupsieve@2.3.2.post1" + }, + { + "name": "certifi", + "version": "2023.7.22", + "purl": "pkg:pypi/certifi@2023.7.22", + "type": "library", + "bom-ref": "pkg:pypi/certifi@2023.7.22" + }, + { + "name": "chardet", + "version": "4.0.0", + "purl": "pkg:pypi/chardet@4.0.0", + "type": "library", + "bom-ref": "pkg:pypi/chardet@4.0.0" + }, + { + "name": "contextlib2", + "version": "21.6.0", + "purl": "pkg:pypi/contextlib2@21.6.0", + "type": "library", + "bom-ref": "pkg:pypi/contextlib2@21.6.0" + }, + { + "name": "fastapi", + "version": "0.75.1", + "purl": "pkg:pypi/fastapi@0.75.1", + "type": "library", + "bom-ref": "pkg:pypi/fastapi@0.75.1" + }, + { + "name": "typing-extensions", + "version": "4.1.1", + "purl": "pkg:pypi/typing-extensions@4.1.1", + "type": "library", + "bom-ref": "pkg:pypi/typing-extensions@4.1.1" + }, + { + "name": "starlette", + "version": "0.17.1", + "purl": "pkg:pypi/starlette@0.17.1", + "type": "library", + "bom-ref": "pkg:pypi/starlette@0.17.1" + }, + { + "name": "flask", + "version": "2.0.3", + "purl": "pkg:pypi/flask@2.0.3", + "type": "library", + "bom-ref": "pkg:pypi/flask@2.0.3" + }, + { + "name": "itsdangerous", + "version": "2.0.1", + "purl": "pkg:pypi/itsdangerous@2.0.1", + "type": "library", + "bom-ref": "pkg:pypi/itsdangerous@2.0.1" + }, + { + "name": "jinja2", + "version": "3.0.3", + "purl": "pkg:pypi/jinja2@3.0.3", + "type": "library", + "bom-ref": "pkg:pypi/jinja2@3.0.3" + }, + { + "name": "markupsafe", + "version": "2.0.1", + "purl": "pkg:pypi/markupsafe@2.0.1", + "type": "library", + "bom-ref": "pkg:pypi/markupsafe@2.0.1" + }, + { + "name": "werkzeug", + "version": "2.0.3", + "purl": "pkg:pypi/werkzeug@2.0.3", + "type": "library", + "bom-ref": "pkg:pypi/werkzeug@2.0.3" + }, + { + "name": "h11", + "version": "0.13.0", + "purl": "pkg:pypi/h11@0.13.0", + "type": "library", + "bom-ref": "pkg:pypi/h11@0.13.0" + }, + { + "name": "immutables", + "version": "0.19", + "purl": "pkg:pypi/immutables@0.19", + "type": "library", + "bom-ref": "pkg:pypi/immutables@0.19" + }, + { + "name": "importlib-metadata", + "version": "4.8.3", + "purl": "pkg:pypi/importlib-metadata@4.8.3", + "type": "library", + "bom-ref": "pkg:pypi/importlib-metadata@4.8.3" + }, + { + "name": "zipp", + "version": "3.6.0", + "purl": "pkg:pypi/zipp@3.6.0", + "type": "library", + "bom-ref": "pkg:pypi/zipp@3.6.0" + }, + { + "name": "requests", + "version": "2.25.1", + "purl": "pkg:pypi/requests@2.25.1", + "type": "library", + "bom-ref": "pkg:pypi/requests@2.25.1" + }, + { + "name": "urllib3", + "version": "1.26.16", + "purl": "pkg:pypi/urllib3@1.26.16", + "type": "library", + "bom-ref": "pkg:pypi/urllib3@1.26.16" + }, + { + "name": "six", + "version": "1.16.0", + "purl": "pkg:pypi/six@1.16.0", + "type": "library", + "bom-ref": "pkg:pypi/six@1.16.0" + }, + { + "name": "uvicorn", + "version": "0.17.0", + "purl": "pkg:pypi/uvicorn@0.17.0", + "type": "library", + "bom-ref": "pkg:pypi/uvicorn@0.17.0" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/root", + "dependsOn": [ + "pkg:pypi/anyio@3.6.2", + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/beautifulsoup4@4.12.2", + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/contextlib2@21.6.0", + "pkg:pypi/fastapi@0.75.1", + "pkg:pypi/flask@2.0.3", + "pkg:pypi/h11@0.13.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/immutables@0.19", + "pkg:pypi/importlib-metadata@4.8.3", + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/markupsafe@2.0.1", + "pkg:pypi/requests@2.25.1", + "pkg:pypi/six@1.16.0", + "pkg:pypi/sniffio@1.2.0", + "pkg:pypi/soupsieve@2.3.2.post1", + "pkg:pypi/starlette@0.17.1", + "pkg:pypi/typing-extensions@4.1.1", + "pkg:pypi/urllib3@1.26.16", + "pkg:pypi/uvicorn@0.17.0", + "pkg:pypi/werkzeug@2.0.3", + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref": "pkg:pypi/anyio@3.6.2", + "dependsOn": [ + "pkg:pypi/idna@2.10", + "pkg:pypi/sniffio@1.2.0" + ] + }, + { + "ref": "pkg:pypi/idna@2.10", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/sniffio@1.2.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/asgiref@3.4.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/beautifulsoup4@4.12.2", + "dependsOn": [ + "pkg:pypi/soupsieve@2.3.2.post1" + ] + }, + { + "ref": "pkg:pypi/soupsieve@2.3.2.post1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/certifi@2023.7.22", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/chardet@4.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/contextlib2@21.6.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/fastapi@0.75.1", + "dependsOn": [ + "pkg:pypi/starlette@0.17.1" + ] + }, + { + "ref": "pkg:pypi/typing-extensions@4.1.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/starlette@0.17.1", + "dependsOn": [ + "pkg:pypi/anyio@3.6.2" + ] + }, + { + "ref": "pkg:pypi/flask@2.0.3", + "dependsOn": [ + "pkg:pypi/itsdangerous@2.0.1", + "pkg:pypi/jinja2@3.0.3", + "pkg:pypi/werkzeug@2.0.3" + ] + }, + { + "ref": "pkg:pypi/itsdangerous@2.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/jinja2@3.0.3", + "dependsOn": [ + "pkg:pypi/markupsafe@2.0.1" + ] + }, + { + "ref": "pkg:pypi/markupsafe@2.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/werkzeug@2.0.3", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/h11@0.13.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/immutables@0.19", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/importlib-metadata@4.8.3", + "dependsOn": [ + "pkg:pypi/zipp@3.6.0" + ] + }, + { + "ref": "pkg:pypi/zipp@3.6.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/requests@2.25.1", + "dependsOn": [ + "pkg:pypi/certifi@2023.7.22", + "pkg:pypi/chardet@4.0.0", + "pkg:pypi/idna@2.10", + "pkg:pypi/urllib3@1.26.16" + ] + }, + { + "ref": "pkg:pypi/urllib3@1.26.16", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/six@1.16.0", + "dependsOn": [] + }, + { + "ref": "pkg:pypi/uvicorn@0.17.0", + "dependsOn": [ + "pkg:pypi/asgiref@3.4.1", + "pkg:pypi/h11@0.13.0" + ] + } + ] +} diff --git a/test/providers/tst_manifests/pip/pip_requirements_virtual_env_with_ignore/requirements.txt b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_with_ignore/requirements.txt new file mode 100644 index 00000000..94093732 --- /dev/null +++ b/test/providers/tst_manifests/pip/pip_requirements_virtual_env_with_ignore/requirements.txt @@ -0,0 +1,27 @@ +anyio==3.6.2 +asgiref==3.4.1 +beautifulsoup4==4.12.2 +certifi==2023.7.22 +chardet==4.0.0 +click==8.0.4 #exhortignore +contextlib2==21.6.0 +fastapi==0.75.1 +Flask==2.0.3 +h11==0.13.0 +idna==2.10 +immutables==0.19 +importlib-metadata==4.8.3 +itsdangerous==2.0.1 +Jinja2==3.0.3 +MarkupSafe==2.0.1 +pydantic==1.9.2 # exhortignore +requests==2.25.1 +six==1.16.0 +sniffio==1.2.0 +soupsieve==2.3.2.post1 +starlette==0.17.1 +typing_extensions==4.1.1 +urllib3==1.26.16 +uvicorn==0.17.0 +Werkzeug==2.0.3 +zipp==3.6.0