Files
ruff/src/utils/pyproject.ts
T
Simon BergerandGitHub 400ab365db Add support for reading the ruff version from Poetry groups (#127)
Not sure if this is a desired feature since this was requested already
(https://github.com/astral-sh/ruff-action/issues/40#issuecomment-2581207691)
without any sort of response.
Unfortunately Poetry doesn't yet support PEP 735
(https://github.com/python-poetry/poetry/issues/9751) and it doesn't
make sense to add ruff as a project dependency.
2025-04-27 12:37:48 +00:00

91 lines
2.7 KiB
TypeScript

import * as fs from "node:fs";
import * as core from "@actions/core";
import * as toml from "smol-toml";
function getRuffVersionFromAllDependencies(
allDependencies: string[],
): string | undefined {
const ruffVersionDefinition = allDependencies.find((dep: string) =>
dep.startsWith("ruff"),
);
if (ruffVersionDefinition) {
const ruffVersion = ruffVersionDefinition
.match(/^ruff([^A-Z0-9._-]+.*)$/)?.[1]
.trim();
if (ruffVersion?.startsWith("==")) {
return ruffVersion.slice(2);
}
core.info(`Found ruff version in pyproject.toml: ${ruffVersion}`);
return ruffVersion;
}
return undefined;
}
interface Pyproject {
project?: {
dependencies?: string[];
"optional-dependencies"?: Record<string, string[]>;
};
"dependency-groups"?: Record<string, Array<string | object>>;
tool?: {
poetry?: {
group?: Record<string, { dependencies: Record<string, string | object> }>;
};
};
}
function parsePyproject(pyprojectContent: string): string | undefined {
const pyproject: Pyproject = toml.parse(pyprojectContent);
const dependencies: string[] = pyproject?.project?.dependencies || [];
const optionalDependencies: string[] = Object.values(
pyproject?.project?.["optional-dependencies"] || {},
).flat();
const devDependencies: string[] = Object.values(
pyproject?.["dependency-groups"] || {},
)
.flat()
.filter((item: string | object) => typeof item === "string");
return (
getRuffVersionFromAllDependencies(
dependencies.concat(optionalDependencies, devDependencies),
) || getRuffVersionFromPoetryGroups(pyproject)
);
}
function getRuffVersionFromPoetryGroups(
pyproject: Pyproject,
): string | undefined {
// Special handling for Poetry until it supports PEP 735
// See: <https://github.com/python-poetry/poetry/issues/9751>
const poetryGroups = Object.values(pyproject?.tool?.poetry?.group || {});
return poetryGroups
.flatMap((group) => Object.entries(group.dependencies))
.map(([name, spec]) => {
if (name === "ruff" && typeof spec === "string") return spec;
return undefined;
})
.find((version) => version !== undefined);
}
export function getRuffVersionFromRequirementsFile(
filePath: string,
): string | undefined {
if (!fs.existsSync(filePath)) {
core.warning(`Could not find file: ${filePath}`);
return undefined;
}
const pyprojectContent = fs.readFileSync(filePath, "utf-8");
if (filePath.endsWith(".txt")) {
return getRuffVersionFromAllDependencies(pyprojectContent.split("\n"));
}
try {
return parsePyproject(pyprojectContent);
} catch (err) {
const message = (err as Error).message;
core.warning(`Error while parsing ${filePath}: ${message}`);
return undefined;
}
}