Skip to content

Commit

Permalink
Merge pull request #1244 from snyk/feat/add-sbt-to-auto-discovery
Browse files Browse the repository at this point in the history
Feat/add sbt to auto discovery
  • Loading branch information
dkontorovskyy committed Jun 30, 2020
2 parents af8c0a5 + a7eca08 commit 09e0e31
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 14 deletions.
14 changes: 14 additions & 0 deletions .circleci/config.yml
Expand Up @@ -42,11 +42,23 @@ commands:
description: Install maven
steps:
- run: choco install maven
install_sbt_windows:
description: Install SBT
steps:
- run: choco install sbt
install_maven_unix:
description: Install maven
steps:
- run: sudo apt update
- run: sudo apt install -y maven
install_sbt_unix:
description: Install SBT
steps:
- run: sudo apt install apt-transport-https ca-certificates
- run: echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
- run: curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add
- run: sudo apt update
- run: sudo apt install -y sbt
install_node_npm:
description: Install correct Node version
parameters:
Expand Down Expand Up @@ -105,6 +117,7 @@ jobs:
steps:
- run: git config --global core.autocrlf false
- install_maven_windows
- install_sbt_windows
- install_node_npm:
node_version: << parameters.node_version >>
- show_node_version
Expand All @@ -129,6 +142,7 @@ jobs:
- image: circleci/node:<< parameters.node_version >>
steps:
- install_maven_unix
- install_sbt_unix
- show_node_version
- checkout
- attach_workspace:
Expand Down
1 change: 1 addition & 0 deletions src/lib/detect.ts
Expand Up @@ -51,6 +51,7 @@ export const AUTO_DETECTABLE_FILES: string[] = [
'vendor.json',
'Pipfile',
'requirements.txt',
'build.sbt',
];

// when file is specified with --file, we look it up here
Expand Down
31 changes: 23 additions & 8 deletions test/acceptance/cli-monitor/cli-monitor.all-projects.spec.ts
Expand Up @@ -76,6 +76,7 @@ export const AllProjectsTests: AcceptanceTests = {
t.ok(loadPlugin.withArgs('nuget').calledOnce, 'calls nuget plugin');
t.ok(loadPlugin.withArgs('paket').calledOnce, 'calls nuget plugin');
t.ok(loadPlugin.withArgs('pip').calledOnce, 'calls pip plugin');
t.ok(loadPlugin.withArgs('sbt').calledOnce, 'calls sbt plugin');

t.match(
result,
Expand All @@ -87,23 +88,25 @@ export const AllProjectsTests: AcceptanceTests = {
t.match(result, 'nuget/some/project-id', 'nuget project in output');
t.match(result, 'paket/some/project-id', 'paket project in output');
t.match(result, 'pip/some/project-id', 'python project in output ');
t.match(result, 'sbt/graph/some/project-id', 'sbt project in output ');

// Pop all calls to server and filter out calls to `featureFlag` endpoint
const requests = params.server
.popRequests(7)
.popRequests(9)
.filter((req) => req.url.includes('/monitor/'));
t.equal(requests.length, 6, 'correct amount of monitor requests');
t.equal(requests.length, 7, 'correct amount of monitor requests');

const pluginsWithoutTargetFileInBody = [
'snyk-nodejs-lockfile-parser',
'bundled:maven',
'bundled:rubygems',
'snyk:sbt',
];

requests.forEach((req) => {
t.match(
req.url,
/\/api\/v1\/monitor\/(npm\/graph|rubygems|maven|nuget|paket|pip)/,
/\/api\/v1\/monitor\/(npm\/graph|rubygems|maven|nuget|paket|pip|sbt)/,
'puts at correct url',
);
if (pluginsWithoutTargetFileInBody.includes(req.body.meta.pluginName)) {
Expand Down Expand Up @@ -244,7 +247,7 @@ export const AllProjectsTests: AcceptanceTests = {

// Pop all calls to server and filter out calls to `featureFlag` endpoint
const requests = params.server
.popRequests(7)
.popRequests(9)
.filter((req) => req.url.includes('/monitor/'));
// find each type of request
const rubyAll = requests.find((req) => req.url.indexOf('rubygems') > -1);
Expand All @@ -253,6 +256,7 @@ export const AllProjectsTests: AcceptanceTests = {
const nugetAll = requests.find((req) => req.url.indexOf('nuget') > -1);
const paketAll = requests.find((req) => req.url.indexOf('paket') > -1);
const mavenAll = requests.find((req) => req.url.indexOf('maven') > -1);
const sbtAll = requests.find((req) => req.url.indexOf('sbt') > -1);

await params.cli.monitor('mono-repo-project', {
file: 'Gemfile.lock',
Expand Down Expand Up @@ -287,6 +291,11 @@ export const AllProjectsTests: AcceptanceTests = {
});
const mavenFile = params.server.popRequest();

await params.cli.monitor('mono-repo-project', {
file: 'build.sbt',
});
const sbtFile = params.server.popRequest();

t.same(
rubyAll.body,
rubyFile.body,
Expand Down Expand Up @@ -322,6 +331,12 @@ export const AllProjectsTests: AcceptanceTests = {
mavenFile.body,
'same body for --all-projects and --file=pom.xml',
);

t.same(
sbtAll.body,
sbtFile.body,
'same body for --all-projects and --file=build.sbt',
);
},
'`monitor composer-app with --all-projects sends same payload as --file`': (
params,
Expand Down Expand Up @@ -379,15 +394,15 @@ export const AllProjectsTests: AcceptanceTests = {
detectionDepth: 1,
});

const requests = params.server.popRequests(7);
const ffRequests = params.server.popRequests(3);
const requests = params.server.popRequests(9);
const ffRequests = params.server.popRequests(4);

t.equal(
ffRequests.every((req) => req.url.includes('experimentalDepGraph')),
true,
'all left requests are feature flag requests',
);
t.equal(requests.length, 7, 'sends expected # requests'); // extra feature-flags request
t.equal(requests.length, 9, 'sends expected # requests'); // extra feature-flags request
t.equal(
params.server._reqLog.length,
0,
Expand All @@ -397,7 +412,7 @@ export const AllProjectsTests: AcceptanceTests = {
const jsonResponse = JSON.parse(response);
t.equal(
jsonResponse.length,
6,
7,
'json response array has expected # elements',
);

Expand Down
40 changes: 34 additions & 6 deletions test/acceptance/cli-test/cli-test.all-projects.spec.ts
Expand Up @@ -74,7 +74,7 @@ export const AllProjectsTests: AcceptanceTests = {
) => async (t) => {
utils.chdirWorkspaces();

// mock python plugin becuase CI tooling doesn't have pipenv installed
// mock python plugin because CI tooling doesn't have pipenv installed
const mockPlugin = {
async inspect() {
return {
Expand Down Expand Up @@ -102,8 +102,9 @@ export const AllProjectsTests: AcceptanceTests = {
t.ok(loadPlugin.withArgs('nuget').calledOnce, 'calls nuget plugin');
t.ok(loadPlugin.withArgs('paket').calledOnce, 'calls nuget plugin');
t.ok(loadPlugin.withArgs('pip').calledOnce, 'calls pip plugin');
t.ok(loadPlugin.withArgs('sbt').calledOnce, 'calls pip plugin');

params.server.popRequests(6).forEach((req) => {
params.server.popRequests(7).forEach((req) => {
t.equal(req.method, 'POST', 'makes POST request');
t.equal(
req.headers['x-snyk-cli-version'],
Expand All @@ -114,7 +115,7 @@ export const AllProjectsTests: AcceptanceTests = {
t.ok(req.body.depGraph, 'body contains depGraph');
t.match(
req.body.depGraph.pkgManager.name,
/(npm|rubygems|maven|nuget|paket|pip)/,
/(npm|rubygems|maven|nuget|paket|pip|sbt)/,
'depGraph has package manager',
);
});
Expand Down Expand Up @@ -160,6 +161,11 @@ export const AllProjectsTests: AcceptanceTests = {
'Target file: Pipfile',
'contains target file Pipfile',
);
t.match(
result.getDisplayResults(),
'Target file: build.sbt',
'contains target file build.sbt',
);
},

'`test mono-repo-project --all-projects --detection-depth=3`': (
Expand Down Expand Up @@ -219,9 +225,10 @@ export const AllProjectsTests: AcceptanceTests = {
t.ok(loadPlugin.withArgs('maven').calledOnce, 'calls maven plugin');
t.ok(loadPlugin.withArgs('nuget').calledOnce, 'calls nuget plugin');
t.ok(loadPlugin.withArgs('paket').calledOnce, 'calls nuget plugin');
t.ok(loadPlugin.withArgs('sbt').calledOnce, 'calls sbt plugin');
t.equals(loadPlugin.withArgs('pip').callCount, 2, 'calls pip plugin');

params.server.popRequests(9).forEach((req) => {
params.server.popRequests(10).forEach((req) => {
t.equal(req.method, 'POST', 'makes POST request');
t.equal(
req.headers['x-snyk-cli-version'],
Expand All @@ -232,7 +239,7 @@ export const AllProjectsTests: AcceptanceTests = {
t.ok(req.body.depGraph, 'body contains depGraph');
t.match(
req.body.depGraph.pkgManager.name,
/(npm|rubygems|maven|nuget|paket|pip)/,
/(npm|rubygems|maven|nuget|paket|pip|sbt)/,
'depGraph has package manager',
);
});
Expand Down Expand Up @@ -333,6 +340,13 @@ export const AllProjectsTests: AcceptanceTests = {
`Target file: python-app-with-req-file${path.sep}requirements.txt`,
`contains target file python-app-with-req-file${path.sep}requirements.txt`,
);

// sbt
t.match(
result.getDisplayResults(),
'Target file: build.sbt',
'contains target file build.sbt',
);
},

'`test mono-repo-project --all-projects and --file payloads are the same`': (
Expand Down Expand Up @@ -363,7 +377,7 @@ export const AllProjectsTests: AcceptanceTests = {
detectionDepth: 1,
});

const requests = params.server.popRequests(6);
const requests = params.server.popRequests(7);

// find each type of request
const rubyAll = requests.find(
Expand All @@ -384,6 +398,9 @@ export const AllProjectsTests: AcceptanceTests = {
const mavenAll = requests.find(
(req) => req.body.depGraph.pkgManager.name === 'maven',
);
const sbtAll = requests.find(
(req) => req.body.depGraph.pkgManager.name === 'sbt',
);

await params.cli.test('mono-repo-project', {
file: 'Gemfile.lock',
Expand Down Expand Up @@ -415,6 +432,11 @@ export const AllProjectsTests: AcceptanceTests = {
});
const mavenFile = params.server.popRequest();

await params.cli.test('mono-repo-project', {
file: 'build.sbt',
});
const sbtFile = params.server.popRequest();

t.same(
pipAll.body,
pipFile.body,
Expand Down Expand Up @@ -449,6 +471,12 @@ export const AllProjectsTests: AcceptanceTests = {
mavenFile.body,
'Same body for --all-projects and --file=pom.xml',
);

t.same(
sbtAll.body,
sbtFile.body,
'Same body for --all-projects and --file=build.sbt',
);
},

'`test maven-multi-app --all-projects --detection-depth=2`': (
Expand Down
2 changes: 2 additions & 0 deletions test/acceptance/workspaces/mono-repo-project/.gitignore
@@ -0,0 +1,2 @@
target
project/target
9 changes: 9 additions & 0 deletions test/acceptance/workspaces/mono-repo-project/build.sbt
@@ -0,0 +1,9 @@
name := "small-app"

version := "1.0-SNAPSHOT"

scalaVersion := "2.10.4"

libraryDependencies ++= Seq(
"org.apache.struts" % "struts2-core" % "2.3.20"
)
@@ -0,0 +1 @@
sbt.version=1.2.8
@@ -0,0 +1 @@
addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.0")

0 comments on commit 09e0e31

Please sign in to comment.