Skip to content

Commit 6b6bc1a

Browse files
authored
Merge pull request #1497 from snyk/feat/add-poetry-support
Feat: add poetry support
2 parents dfc67b6 + 352d1b0 commit 6b6bc1a

File tree

15 files changed

+301
-3
lines changed

15 files changed

+301
-3
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
"snyk-nuget-plugin": "1.19.3",
8787
"snyk-php-plugin": "1.9.2",
8888
"snyk-policy": "1.14.1",
89-
"snyk-python-plugin": "1.17.1",
89+
"snyk-python-plugin": "1.18.0",
9090
"snyk-resolve": "1.0.1",
9191
"snyk-resolve-deps": "4.4.0",
9292
"snyk-sbt-plugin": "2.11.0",

src/lib/detect.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ const DETECTABLE_FILES: string[] = [
2929
'composer.lock',
3030
'Podfile',
3131
'Podfile.lock',
32+
'pyproject.toml',
33+
'poetry.lock',
3234
];
3335

3436
export const AUTO_DETECTABLE_FILES: string[] = [
@@ -53,6 +55,8 @@ export const AUTO_DETECTABLE_FILES: string[] = [
5355
'build.sbt',
5456
'build.gradle',
5557
'build.gradle.kts',
58+
'pyproject.toml',
59+
'poetry.lock',
5660
];
5761

5862
// when file is specified with --file, we look it up here
@@ -86,6 +90,8 @@ const DETECTABLE_PACKAGE_MANAGERS: {
8690
'CocoaPods.podfile.yaml': 'cocoapods',
8791
'CocoaPods.podfile': 'cocoapods',
8892
Podfile: 'cocoapods',
93+
'pyproject.toml': 'poetry',
94+
'poetry.lock': 'poetry',
8995
};
9096

9197
export function isPathToPackageFile(path) {

src/lib/find-files.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,15 @@ function chooseBestManifest(
305305
);
306306
return defaultManifest.path;
307307
}
308+
case 'poetry': {
309+
const defaultManifest = files.filter((path) =>
310+
['pyproject.toml'].includes(path.base),
311+
)[0];
312+
debug(
313+
`Encountered multiple poetry manifest files, defaulting to ${defaultManifest.path}`,
314+
);
315+
return defaultManifest.path;
316+
}
308317
default: {
309318
return null;
310319
}

src/lib/package-managers.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export type SupportedPackageManagers =
1212
| 'nuget'
1313
| 'paket'
1414
| 'composer'
15-
| 'cocoapods';
15+
| 'cocoapods'
16+
| 'poetry';
1617

1718
export const SUPPORTED_PACKAGE_MANAGER_NAME: {
1819
readonly [packageManager in SupportedPackageManagers]: string;
@@ -31,6 +32,7 @@ export const SUPPORTED_PACKAGE_MANAGER_NAME: {
3132
paket: 'Paket',
3233
composer: 'Composer',
3334
cocoapods: 'CocoaPods',
35+
poetry: 'Poetry',
3436
};
3537

3638
export const WIZARD_SUPPORTED_PACKAGE_MANAGERS: SupportedPackageManagers[] = [
@@ -46,6 +48,7 @@ export const GRAPH_SUPPORTED_PACKAGE_MANAGERS: SupportedPackageManagers[] = [
4648
'sbt',
4749
'yarn',
4850
'rubygems',
51+
'poetry',
4952
];
5053
// For ecosystems with a flat set of libraries (e.g. Python, JVM), one can
5154
// "pin" a transitive dependency

src/lib/plugins/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ export function loadPlugin(
3434
case 'yarn': {
3535
return nodejsPlugin;
3636
}
37-
case 'pip': {
37+
case 'pip':
38+
case 'poetry': {
3839
return pythonPlugin;
3940
}
4041
case 'golangdep':

test/acceptance/cli-monitor/cli-monitor.acceptance.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,22 @@ if (!isWindows) {
923923
);
924924
});
925925

926+
test('`monitor poetry-app`', async (t) => {
927+
chdirWorkspaces();
928+
await cli.monitor('poetry-app');
929+
const req = server.popRequest();
930+
t.equal(req.method, 'PUT', 'makes PUT request');
931+
t.equal(
932+
req.headers['x-snyk-cli-version'],
933+
versionNumber,
934+
'sends version number',
935+
);
936+
t.match(req.url, '/monitor/poetry/graph', 'puts at correct url');
937+
t.equal(req.body.targetFile, 'pyproject.toml', 'sends targetFile');
938+
const depGraphJSON = req.body.depGraphJSON;
939+
t.ok(depGraphJSON);
940+
});
941+
926942
test('`monitor pip-app --file=requirements.txt`', async (t) => {
927943
chdirWorkspaces();
928944
const plugin = {

test/acceptance/cli-monitor/cli-monitor.all-projects.spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,5 +944,38 @@ export const AllProjectsTests: AcceptanceTests = {
944944
);
945945
});
946946
},
947+
'`monitor mono-repo-poetry with --all-projects --detection-depth=2`': (
948+
params,
949+
utils,
950+
) => async (t) => {
951+
utils.chdirWorkspaces();
952+
const result = await params.cli.monitor('mono-repo-poetry', {
953+
allProjects: true,
954+
detectionDepth: 2,
955+
});
956+
t.match(
957+
result,
958+
'npm/graph/some/project-id',
959+
'npm project was monitored ',
960+
);
961+
t.match(
962+
result,
963+
'poetry/graph/some/project-id',
964+
'poetry project was monitored ',
965+
);
966+
const requests = params.server.popRequests(2);
967+
requests.forEach((request) => {
968+
const urlOk =
969+
request.url === '/api/v1/monitor/npm' ||
970+
'/api/v1/monitor/poetry/graph';
971+
t.ok(urlOk, 'puts at correct url');
972+
t.equal(request.method, 'PUT', 'makes PUT request');
973+
t.equal(
974+
request.headers['x-snyk-cli-version'],
975+
params.versionNumber,
976+
'sends version number',
977+
);
978+
});
979+
},
947980
},
948981
};

test/acceptance/cli-test/cli-test.all-projects.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,5 +1154,26 @@ export const AllProjectsTests: AcceptanceTests = {
11541154
'Go dep package manager',
11551155
);
11561156
},
1157+
'`test mono-repo-poetry --all-projects`': (params, utils) => async (t) => {
1158+
utils.chdirWorkspaces();
1159+
const res: CommandResult = await params.cli.test('mono-repo-poetry', {
1160+
allProjects: true,
1161+
});
1162+
t.match(
1163+
res.getDisplayResults(),
1164+
/Tested 2 projects, no vulnerable paths were found./,
1165+
'Two projects tested',
1166+
);
1167+
t.match(
1168+
res.getDisplayResults(),
1169+
'Package manager: npm',
1170+
'Npm package manager',
1171+
);
1172+
t.match(
1173+
res.getDisplayResults(),
1174+
'Package manager: poetry',
1175+
'Poetry package manager',
1176+
);
1177+
},
11571178
},
11581179
};

test/acceptance/cli-test/cli-test.python.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,5 +279,22 @@ export const PythonTests: AcceptanceTests = {
279279
'calls python plugin',
280280
);
281281
},
282+
'`test poetry-app with pyproject.toml and poetry.lock`': (
283+
params,
284+
utils,
285+
) => async (t) => {
286+
utils.chdirWorkspaces();
287+
await params.cli.test('poetry-app', {});
288+
const req = params.server.popRequest();
289+
t.equal(req.method, 'POST', 'makes POST request');
290+
t.equal(
291+
req.headers['x-snyk-cli-version'],
292+
params.versionNumber,
293+
'sends version number',
294+
);
295+
t.match(req.url, '/test-dep-graph', 'posts to correct url');
296+
t.equal(req.body.targetFile, 'pyproject.toml', 'specifies target');
297+
t.equal(req.body.depGraph.pkgManager.name, 'poetry');
298+
},
282299
},
283300
};

test/acceptance/workspaces/mono-repo-poetry/package-lock.json

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "shallow-goof",
3+
"version": "0.0.1",
4+
"description": "A vulnerable demo application",
5+
"homepage": "https://snyk.io/",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/Snyk/shallow-goof"
9+
},
10+
"dependencies": {
11+
"qs": "0.0.6",
12+
"node-uuid": "1.4.0"
13+
}
14+
}

test/acceptance/workspaces/mono-repo-poetry/python/poetry.lock

Lines changed: 67 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[tool.poetry]
2+
name = "poetry-fixtures-project"
3+
version = "0.1.0"
4+
description = ""
5+
authors = []
6+
7+
[tool.poetry.dependencies]
8+
python = "~2.7 || ^3.5"
9+
jinja2 = "^2.11"
10+
11+
[build-system]
12+
requires = ["poetry>=0.12"]
13+
build-backend = "poetry.masonry.api"

test/acceptance/workspaces/poetry-app/poetry.lock

Lines changed: 67 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)