diff --git a/cliv2/go.mod b/cliv2/go.mod index 978899c579..ad7b17c111 100644 --- a/cliv2/go.mod +++ b/cliv2/go.mod @@ -9,9 +9,9 @@ require ( github.com/google/uuid v1.3.1 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.30.0 - github.com/snyk/cli-extension-dep-graph v0.0.0-20230831101913-402a467e32e7 + github.com/snyk/cli-extension-dep-graph v0.0.0-20230926124856-b0fdf1ee6f73 github.com/snyk/cli-extension-iac-rules v0.0.0-20230601153200-c572cfce46ce - github.com/snyk/cli-extension-sbom v0.0.0-20230831113416-7ffac8738181 + github.com/snyk/cli-extension-sbom v0.0.0-20230926124903-9705d7d47d8f github.com/snyk/container-cli v0.0.0-20230920093251-fe865879a91f github.com/snyk/go-application-framework v0.0.0-20230915105125-18e4f97ef870 github.com/snyk/go-httpauth v0.0.0-20230726132335-d454674305a7 diff --git a/cliv2/go.sum b/cliv2/go.sum index a629a3f259..900d89f48e 100644 --- a/cliv2/go.sum +++ b/cliv2/go.sum @@ -647,12 +647,16 @@ github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKl github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/snyk/cli-extension-dep-graph v0.0.0-20230831101913-402a467e32e7 h1:V5b1Yz4Qjufs14bFoYBH6BRtfzTTCHeW32rV/9TiUY8= -github.com/snyk/cli-extension-dep-graph v0.0.0-20230831101913-402a467e32e7/go.mod h1:QF3v8HBpOpyudYNCuR8LqfULutO76c91sBdLzD+pBJU= +github.com/snyk/cli-extension-dep-graph v0.0.0-20230922071321-a8eaea422883 h1:bqZyuSGW2+TISA+JPHChXbvLnI7WqJehhUzlgcqdKNU= +github.com/snyk/cli-extension-dep-graph v0.0.0-20230922071321-a8eaea422883/go.mod h1:QF3v8HBpOpyudYNCuR8LqfULutO76c91sBdLzD+pBJU= +github.com/snyk/cli-extension-dep-graph v0.0.0-20230926124856-b0fdf1ee6f73 h1:rwdJzpPWkWWf7csbv871GoKgRGwJ4GVNXMSsO0cRuLk= +github.com/snyk/cli-extension-dep-graph v0.0.0-20230926124856-b0fdf1ee6f73/go.mod h1:QF3v8HBpOpyudYNCuR8LqfULutO76c91sBdLzD+pBJU= github.com/snyk/cli-extension-iac-rules v0.0.0-20230601153200-c572cfce46ce h1:WchwuyPX4mEr7tFCGD6EsjwTDipFWfLxs4Wps6KB3b4= github.com/snyk/cli-extension-iac-rules v0.0.0-20230601153200-c572cfce46ce/go.mod h1:5/IYYTgf32pST7St4GhS3KNz32WE17Ys+Hdb5Pqxex0= -github.com/snyk/cli-extension-sbom v0.0.0-20230831113416-7ffac8738181 h1:BMiPwr4/sD71Jfrvorgy+L2E7PCkbT36c4wo2N+BKPg= -github.com/snyk/cli-extension-sbom v0.0.0-20230831113416-7ffac8738181/go.mod h1:O/cjwCbKhJQWyXHPmNbZ7ToQKnhyw0VUp1Qhim3WEcw= +github.com/snyk/cli-extension-sbom v0.0.0-20230922073642-696d9b18f8b5 h1:7vgI617kK0aI0evjnAYv/HoSJUrHo2CKWjznxgekwXs= +github.com/snyk/cli-extension-sbom v0.0.0-20230922073642-696d9b18f8b5/go.mod h1:O/cjwCbKhJQWyXHPmNbZ7ToQKnhyw0VUp1Qhim3WEcw= +github.com/snyk/cli-extension-sbom v0.0.0-20230926124903-9705d7d47d8f h1:U3DQ9wnHJzs8NcM+kkjxDkOa/zkqLeiUs+eL/dLHsic= +github.com/snyk/cli-extension-sbom v0.0.0-20230926124903-9705d7d47d8f/go.mod h1:O/cjwCbKhJQWyXHPmNbZ7ToQKnhyw0VUp1Qhim3WEcw= github.com/snyk/container-cli v0.0.0-20230920093251-fe865879a91f h1:ghajT5PEiLP8XNFIdc7Yn4Th74RH/9Q++dDOp6Cb9eo= github.com/snyk/container-cli v0.0.0-20230920093251-fe865879a91f/go.mod h1:38w+dcAQp9eG3P5t2eNS9eG0reut10AeJjLv5lJ5lpM= github.com/snyk/go-application-framework v0.0.0-20230915105125-18e4f97ef870 h1:R8xLYCVSC8aBVWlIevP4tBOHFdUr6UzWNYzuZqAEzJE= diff --git a/test/acceptance/workspaces/pip-app-private/requirements.txt b/test/acceptance/workspaces/pip-app-private/requirements.txt new file mode 100644 index 0000000000..2a2ad64c87 --- /dev/null +++ b/test/acceptance/workspaces/pip-app-private/requirements.txt @@ -0,0 +1 @@ +some-package-that-only-exists-in-a-private-repository==0.0.1 diff --git a/test/jest/acceptance/snyk-sbom/gradle-options.spec.ts b/test/jest/acceptance/snyk-sbom/gradle-options.spec.ts index a95ffb37ec..85ef75f9b9 100644 --- a/test/jest/acceptance/snyk-sbom/gradle-options.spec.ts +++ b/test/jest/acceptance/snyk-sbom/gradle-options.spec.ts @@ -8,7 +8,7 @@ describe('snyk sbom: gradle options (mocked server only)', () => { let env: Record; beforeAll((done) => { - const port = process.env.PORT || process.env.SNYK_PORT || '58584'; + const port = process.env.PORT || process.env.SNYK_PORT || '58586'; const baseApi = '/api/v1'; env = { ...process.env, diff --git a/test/jest/acceptance/snyk-sbom/maven-options.spec.ts b/test/jest/acceptance/snyk-sbom/maven-options.spec.ts index 776afd3056..208ea59406 100644 --- a/test/jest/acceptance/snyk-sbom/maven-options.spec.ts +++ b/test/jest/acceptance/snyk-sbom/maven-options.spec.ts @@ -8,7 +8,7 @@ describe('snyk sbom: maven options (mocked server only)', () => { let env: Record; beforeAll((done) => { - const port = process.env.PORT || process.env.SNYK_PORT || '58584'; + const port = process.env.PORT || process.env.SNYK_PORT || '58587'; const baseApi = '/api/v1'; env = { ...process.env, diff --git a/test/jest/acceptance/snyk-sbom/pip-options.spec.ts b/test/jest/acceptance/snyk-sbom/pip-options.spec.ts new file mode 100644 index 0000000000..8c83a15102 --- /dev/null +++ b/test/jest/acceptance/snyk-sbom/pip-options.spec.ts @@ -0,0 +1,102 @@ +import * as os from 'os'; + +import { createProjectFromWorkspace } from '../../util/createProject'; +import { runSnykCLI } from '../../util/runSnykCLI'; +import { fakeServer } from '../../../acceptance/fake-server'; + +jest.setTimeout(1000 * 60 * 5); + +describe('snyk sbom --command (mocked server only)', () => { + let server; + let env: Record; + + beforeAll( + () => + new Promise((res) => { + const port = process.env.PORT || process.env.SNYK_PORT || '58588'; + const baseApi = '/api/v1'; + env = { + ...process.env, + SNYK_API: 'http://localhost:' + port + baseApi, + SNYK_HOST: 'http://localhost:' + port, + SNYK_TOKEN: '123456789', + SNYK_DISABLE_ANALYTICS: '1', + }; + server = fakeServer(baseApi, env.SNYK_TOKEN); + server.listen(port, res); + }), + ); + + afterEach(() => { + jest.resetAllMocks(); + server.restore(); + }); + + afterAll( + () => + new Promise((res) => { + server.close(res); + }), + ); + + test('`sbom pip-app` generates an SBOM with a specified python command', async () => { + const project = await createProjectFromWorkspace('pip-app'); + const command = + os.platform().indexOf('win') === 0 ? 'python3.11.exe' : 'python3'; + + const { code, stdout } = await runSnykCLI( + `sbom --org aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee --format cyclonedx1.4+json --debug --command=${command}`, + { + cwd: project.path(), + env, + }, + ); + let bom; + + expect(code).toEqual(0); + expect(() => { + bom = JSON.parse(stdout); + }).not.toThrow(); + expect(bom.metadata.component.name).toEqual('pip-app'); + expect(bom.components).toHaveLength(3); + }); + + test('`sbom pip-app-custom` generates an SBOM with pip for custom manifest names', async () => { + const project = await createProjectFromWorkspace('pip-app-custom'); + + const { code, stdout } = await runSnykCLI( + `sbom --org aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee --format cyclonedx1.4+json --debug --package-manager=pip --file=base.txt`, + { + cwd: project.path(), + env, + }, + ); + let bom; + + expect(code).toEqual(0); + expect(() => { + bom = JSON.parse(stdout); + }).not.toThrow(); + expect(bom.metadata.component.name).toEqual('pip-app-custom'); + expect(bom.components).toHaveLength(3); + }); + + test('`sbom pip-app-private` generates an SBOM and skips unresolved packages', async () => { + const project = await createProjectFromWorkspace('pip-app-private'); + + const { code, stdout } = await runSnykCLI( + `sbom --org aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee --format cyclonedx1.4+json --debug --skip-unresolved=true`, + { + cwd: project.path(), + env, + }, + ); + let bom; + + expect(code).toEqual(0); + expect(() => { + bom = JSON.parse(stdout); + }).not.toThrow(); + expect(bom.metadata.component.name).toEqual('pip-app-private'); + }); +}); diff --git a/test/jest/acceptance/snyk-sbom/yarn-options.spec.ts b/test/jest/acceptance/snyk-sbom/yarn-options.spec.ts new file mode 100644 index 0000000000..cc0c0b46ee --- /dev/null +++ b/test/jest/acceptance/snyk-sbom/yarn-options.spec.ts @@ -0,0 +1,59 @@ +import { createProjectFromWorkspace } from '../../util/createProject'; +import { runSnykCLI } from '../../util/runSnykCLI'; +import { fakeServer } from '../../../acceptance/fake-server'; + +jest.setTimeout(1000 * 60 * 5); + +describe('snyk sbom --yarn-workspaces (mocked server only)', () => { + let server; + let env: Record; + + beforeAll( + () => + new Promise((res) => { + const port = process.env.PORT || process.env.SNYK_PORT || '58589'; + const baseApi = '/api/v1'; + env = { + ...process.env, + SNYK_API: 'http://localhost:' + port + baseApi, + SNYK_HOST: 'http://localhost:' + port, + SNYK_TOKEN: '123456789', + SNYK_DISABLE_ANALYTICS: '1', + }; + server = fakeServer(baseApi, env.SNYK_TOKEN); + server.listen(port, res); + }), + ); + + afterEach(() => { + jest.resetAllMocks(); + server.restore(); + }); + + afterAll( + () => + new Promise((res) => { + server.close(res); + }), + ); + + test('`sbom yarn-workspaces` generates an SBOM for multiple yarn workspaces', async () => { + const project = await createProjectFromWorkspace('yarn-workspaces'); + + const { code, stdout } = await runSnykCLI( + `sbom --org aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee --format cyclonedx1.4+json --debug --yarn-workspaces`, + { + cwd: project.path(), + env, + }, + ); + let bom; + + expect(code).toEqual(0); + expect(() => { + bom = JSON.parse(stdout); + }).not.toThrow(); + expect(bom.metadata.component.name).toEqual('yarn-workspaces'); + expect(bom.components).toHaveLength(9); + }); +});