Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions lib/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ import {
} from "node:fs";
import { homedir, platform, tmpdir } from "node:os";
import path, {
basename,
delimiter as _delimiter,
sep as _sep,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was pnpm lint doing these rearrangements?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes it was due to pnpm lint I guess I just ran devenv prepare for pr task not pnpm directly

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not happening in my devenv setup. The existing sort order is unchanged.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@prabhu Did all the changes as reviewed by you just this one is remaining. Should I do something or could it be managed at your end more easily?

basename,
dirname,
extname,
join,
resolve,
relative,
sep as _sep,
resolve,
} from "node:path";
import process from "node:process";
import { URL, fileURLToPath } from "node:url";
Expand Down Expand Up @@ -4902,6 +4902,7 @@ export function parsePyProjectTomlFile(tomlFile) {
}
}

let poetryV2Mode = false;
let poetryMode = false;
let uvMode = false;
let hatchMode = false;
Expand All @@ -4924,6 +4925,17 @@ export function parsePyProjectTomlFile(tomlFile) {
) {
poetryMode = true;
}

const buildRequires = tomlData?.["build-system"]?.["requires"];
if (buildRequires && Array.isArray(buildRequires)) {
for (const req of buildRequires) {
if (req.startsWith("poetry-core") && req.includes(">=2.0")) {
poetryV2Mode = true;
break;
}
}
}

if (tomlData?.tool?.uv) {
uvMode = true;
}
Expand Down Expand Up @@ -5027,6 +5039,7 @@ export function parsePyProjectTomlFile(tomlFile) {
return {
parentComponent: pkg,
poetryMode,
poetryV2Mode,
uvMode,
hatchMode,
workspacePaths,
Expand Down Expand Up @@ -13526,6 +13539,23 @@ export function getPipFrozenTree(
});
thoughtLog("Performing poetry install");
let poetryInstallArgs = ["-m", "poetry", "install", "-n", "--no-root"];

// Storing pyProjectpath after checking the existence of pyproject.toml file
const pyprojectpath = safeExistsSync(join(basePath, "pyproject.toml"))
? join(basePath, "pyproject.toml")
: null;
let poetryV2Mode = false;
// Check if the pyproject.toml is not null
if (pyprojectpath) {
poetryV2Mode =
parsePyProjectTomlFile(pyprojectpath).poetryV2Mode || false;
}
// checking if poetryV2 is true or not
if (poetryV2Mode) {
// Include all dependency groups and extras (Poetry v2+)
poetryInstallArgs.push("--all-groups", "--all-extras");
}

// Attempt to perform poetry install
result = safeSpawnSync(PYTHON_CMD, poetryInstallArgs, {
cwd: basePath,
Expand All @@ -13539,6 +13569,11 @@ export function getPipFrozenTree(
"Hmm, poetry doesn't seem to be available as a module. Perhaps it was installed directly 🤔?",
);
poetryInstallArgs = ["install", "-n", "--no-root"];

if (poetryV2Mode) {
// Also include flags when calling poetry directly
poetryInstallArgs.push("--all-groups", "--all-extras");
}
// Attempt to perform poetry install
result = safeSpawnSync("poetry", poetryInstallArgs, {
cwd: basePath,
Expand Down
34 changes: 32 additions & 2 deletions lib/helpers/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ import {
findLicenseId,
getCratesMetadata,
getDartMetadata,
getGoPkgLicense,
getLicenses,
getMvnMetadata,
getNugetMetadata,
getPyMetadata,
getRepoLicense,
guessPypiMatchingVersion,
hasAnyProjectType,
isPackageManagerAllowed,
Expand Down Expand Up @@ -4979,6 +4977,38 @@ test("parse pyproject.toml", () => {
});
});

test("parse pyproject.toml with poetryv2 requirement", () => {
const retMap = parsePyProjectTomlFile("./test/data/pyproject_poetryv2.toml");
expect(retMap.parentComponent).toEqual({
name: "blint",
version: "2.4.2",
description: "Linter and SBOM generator for binary files.",
license: "MIT",
authors: [{ name: "Team AppThreat", email: "[email protected]" }],
homepage: { url: "https://github.com/owasp-dep-scan/blint" },
repository: { url: "https://github.com/owasp-dep-scan/blint" },
tags: ["binary", "linter", "sast", "security"],
properties: [{ name: "cdx:pypi:requiresPython", value: ">=3.10,<3.14" }],
type: "application",
"bom-ref": "pkg:pypi/[email protected]",
purl: "pkg:pypi/[email protected]",
evidence: {
identity: {
field: "purl",
confidence: 1,
methods: [
{
technique: "manifest-analysis",
confidence: 1,
value: "./test/data/pyproject_poetryv2.toml",
},
],
},
},
});
expect(retMap.poetryV2Mode).toBeTruthy();
});

test("parse pyproject.toml with custom poetry source", () => {
const retMap = parsePyProjectTomlFile(
"./test/data/pyproject_with_custom_poetry_source.toml",
Expand Down
81 changes: 81 additions & 0 deletions test/data/pyproject_poetryv2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
[project]
name = "blint"
version = "2.4.2"
description = "Linter and SBOM generator for binary files."
authors = [
{name= "Team AppThreat", email = "[email protected]"},
]
dependencies = [
"lief>=0.16.6",
"rich>=14.0.0",
"PyYAML>=6.0.2",
"defusedxml>=0.7.1",
"pydantic[email]>=2.11.3",
"orjson>=3.10.16",
"symbolic==10.2.1",
"ar>=1.0.0",
"custom-json-diff>=2.1.6",
"appdirs>=1.4.4",
"apsw>=3.49.1.0",
"packageurl-python>=0.16.0",
"oras>=0.2.28",
]
license = "MIT"
readme = "README.md"
homepage = "https://github.com/owasp-dep-scan/blint"
repository = "https://github.com/owasp-dep-scan/blint"
keywords = ["linter", "binary", "security", "sast"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: System Administrators",
"Topic :: Utilities",
"Topic :: Security",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Operating System :: OS Independent",
]
requires-python = ">=3.10,<3.14"
include = ["blint/data/*.yml"]

[project.urls]
"CI" = "https://github.com/owasp-dep-scan/blint/actions"

[project.scripts]
blint = 'blint.cli:main'

[project.optional-dependencies]
dev = [
"pytest>=8.3.5",
"black>=25.1.0",
"flake8>=7.2.0",
"pylint>=3.3.6",
"pytest-cov>=6.1.1",
"pyinstaller>=6.12.0"
]

[tool.black]
line-length = 99

[build-system]
requires = ["poetry-core>=2.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.pytest.ini_options]
addopts = "--verbose --cov-append --cov-report term --cov blint"

[tool.pylint]
generated-members = ["lief", "orjson"]
ignore-paths = ["blint/cyclonedx/*", "tests/*"]
# Let's not fuss about long strings
ignore-long-lines = "[r|f]\""
disable = ["missing-module-docstring", "logging-fstring-interpolation"]

[tool.pylint.format]
max-line-length = 99

[tool.pylint.design]
max-args = 6
max-nested-blocks = 6
Loading