mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-27 07:50:47 +00:00
c5a87efec8
* chore(types): correct JSDoc * chore(types): add missing `ConstraintName` enforcement * fixup! chore(types): add missing `ConstraintName` enforcement By simplifying this case, which should never happen, as the types wouldn't allow it. * chore: reorder for typechecking simplicity * fixup! chore(types): add missing `ConstraintName` enforcement
106 lines
2.8 KiB
TypeScript
106 lines
2.8 KiB
TypeScript
import { logger } from '../../../logger/index.ts';
|
|
import type { ConstraintName } from '../../../util/exec/types.ts';
|
|
import {
|
|
massage as massageToml,
|
|
parse as parseToml,
|
|
} from '../../../util/toml.ts';
|
|
import { PythonVersionDatasource } from '../../datasource/python-version/index.ts';
|
|
import * as pep440 from '../../versioning/pep440/index.ts';
|
|
import type {
|
|
ExtractConfig,
|
|
PackageDependency,
|
|
PackageFileContent,
|
|
} from '../types.ts';
|
|
import { processors } from './processors/index.ts';
|
|
import { PyProject } from './schema.ts';
|
|
|
|
export function parsePyProject(
|
|
content: string,
|
|
packageFile?: string,
|
|
): PyProject | null {
|
|
try {
|
|
const jsonMap = parseToml(massageToml(content));
|
|
return PyProject.parse(jsonMap);
|
|
} catch (err) {
|
|
logger.debug(
|
|
{ packageFile, err },
|
|
`Failed to parse and validate pyproject file`,
|
|
);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function extractPackageFile(
|
|
content: string,
|
|
packageFile: string,
|
|
_config?: ExtractConfig,
|
|
): Promise<PackageFileContent | null> {
|
|
logger.trace(`pep621.extractPackageFile(${packageFile})`);
|
|
|
|
const def = parsePyProject(content, packageFile);
|
|
if (!def) {
|
|
return null;
|
|
}
|
|
|
|
const deps: PackageDependency[] = [];
|
|
|
|
const pythonConstraint = def.project?.['requires-python'];
|
|
const extractedConstraints: Partial<Record<ConstraintName, string>> = {};
|
|
if (pythonConstraint) {
|
|
extractedConstraints.python = pythonConstraint;
|
|
deps.push({
|
|
packageName: 'python',
|
|
depType: 'requires-python',
|
|
currentValue: pythonConstraint,
|
|
commitMessageTopic: 'Python',
|
|
datasource: PythonVersionDatasource.id,
|
|
versioning: pep440.id,
|
|
});
|
|
}
|
|
|
|
const projectDependencies = def.project?.dependencies;
|
|
if (projectDependencies) {
|
|
deps.push(...projectDependencies);
|
|
}
|
|
|
|
const dependencyGroups = def['dependency-groups'];
|
|
if (dependencyGroups) {
|
|
deps.push(...dependencyGroups);
|
|
}
|
|
|
|
const projectOptionalDependencies = def.project?.['optional-dependencies'];
|
|
if (projectOptionalDependencies) {
|
|
deps.push(...projectOptionalDependencies);
|
|
}
|
|
|
|
const buildSystemRequires = def['build-system']?.requires;
|
|
if (buildSystemRequires) {
|
|
deps.push(...buildSystemRequires);
|
|
}
|
|
|
|
// process specific tool sets
|
|
let processedDeps = deps;
|
|
const lockFiles: string[] = [];
|
|
for (const processor of processors) {
|
|
processedDeps = processor.process(def, processedDeps);
|
|
processedDeps = await processor.extractLockedVersions(
|
|
def,
|
|
processedDeps,
|
|
packageFile,
|
|
);
|
|
|
|
const processedLockFiles = await processor.getLockfiles(def, packageFile);
|
|
lockFiles.push(...processedLockFiles);
|
|
}
|
|
|
|
const packageFileVersion = def.project?.version;
|
|
return processedDeps.length || lockFiles.length
|
|
? {
|
|
extractedConstraints,
|
|
deps: processedDeps,
|
|
packageFileVersion,
|
|
lockFiles,
|
|
}
|
|
: null;
|
|
}
|