renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
180 lines • 7.75 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PdmProcessor = void 0;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const shlex_1 = require("shlex");
const error_messages_1 = require("../../../../constants/error-messages");
const logger_1 = require("../../../../logger");
const exec_1 = require("../../../../util/exec");
const fs_1 = require("../../../../util/fs");
const auth_1 = require("../../../../util/git/auth");
const result_1 = require("../../../../util/result");
const pypi_1 = require("../../../datasource/pypi");
const schema_1 = require("../schema");
const utils_1 = require("../utils");
const pdmUpdateCMD = 'pdm update --no-sync --update-eager';
class PdmProcessor {
process(project, deps) {
const pdm = project.tool?.pdm;
if (is_1.default.nullOrUndefined(pdm)) {
return deps;
}
deps.push(...(0, utils_1.parseDependencyGroupRecord)(utils_1.depTypes.pdmDevDependencies, pdm['dev-dependencies']));
const pdmSource = pdm.source;
if (is_1.default.nullOrUndefined(pdmSource)) {
return deps;
}
// add pypi default url, if there is no source declared with the name `pypi`. https://daobook.github.io/pdm/pyproject/tool-pdm/#specify-other-sources-for-finding-packages
const containsPyPiUrl = pdmSource.some((value) => value.name === 'pypi');
const registryUrls = [];
if (!containsPyPiUrl) {
registryUrls.push(pypi_1.PypiDatasource.defaultURL);
}
for (const source of pdmSource) {
registryUrls.push(source.url);
}
for (const dep of deps) {
if (dep.datasource === pypi_1.PypiDatasource.id) {
dep.registryUrls = [...registryUrls];
}
}
return deps;
}
async extractLockedVersions(project, deps, packageFile) {
if (is_1.default.nullOrUndefined(project.tool?.pdm) &&
project['build-system']?.['build-backend'] !== 'pdm.backend') {
return Promise.resolve(deps);
}
const lockFileName = (0, fs_1.getSiblingFileName)(packageFile, 'pdm.lock');
const lockFileContent = await (0, fs_1.readLocalFile)(lockFileName, 'utf8');
if (lockFileContent) {
const lockFileMapping = result_1.Result.parse(lockFileContent, schema_1.PdmLockfileSchema.transform(({ lock }) => lock)).unwrapOr({});
for (const dep of deps) {
const packageName = dep.packageName;
if (packageName && packageName in lockFileMapping) {
dep.lockedVersion = lockFileMapping[packageName];
}
}
}
return Promise.resolve(deps);
}
async updateArtifacts(updateArtifact, project) {
const { config, updatedDeps, packageFileName } = updateArtifact;
const { isLockFileMaintenance } = config;
// abort if no lockfile is defined
const lockFileName = (0, fs_1.getSiblingFileName)(packageFileName, 'pdm.lock');
try {
const existingLockFileContent = await (0, fs_1.readLocalFile)(lockFileName, 'utf8');
if (is_1.default.nullOrUndefined(existingLockFileContent)) {
logger_1.logger.debug('No pdm.lock found');
return null;
}
const pythonConstraint = {
toolName: 'python',
constraint: config.constraints?.python ?? project.project?.['requires-python'],
};
const pdmConstraint = {
toolName: 'pdm',
constraint: config.constraints?.pdm,
};
const extraEnv = {
...(0, auth_1.getGitEnvironmentVariables)(['pep621']),
};
const execOptions = {
cwdFile: packageFileName,
extraEnv,
docker: {},
toolConstraints: [pythonConstraint, pdmConstraint],
};
// on lockFileMaintenance do not specify any packages and update the complete lock file
// else only update specific packages
const cmds = [];
if (isLockFileMaintenance) {
cmds.push(pdmUpdateCMD);
}
else {
cmds.push(...generateCMDs(updatedDeps));
}
await (0, exec_1.exec)(cmds, execOptions);
// check for changes
const fileChanges = [];
const newLockContent = await (0, fs_1.readLocalFile)(lockFileName, 'utf8');
const isLockFileChanged = existingLockFileContent !== newLockContent;
if (isLockFileChanged) {
fileChanges.push({
file: {
type: 'addition',
path: lockFileName,
contents: newLockContent,
},
});
}
else {
logger_1.logger.debug('pdm.lock is unchanged');
}
return fileChanges.length ? fileChanges : null;
}
catch (err) {
// istanbul ignore if
if (err.message === error_messages_1.TEMPORARY_ERROR) {
throw err;
}
logger_1.logger.debug({ err }, 'Failed to update PDM lock file');
return [
{
artifactError: {
lockFile: lockFileName,
stderr: err.message,
},
},
];
}
}
}
exports.PdmProcessor = PdmProcessor;
function generateCMDs(updatedDeps) {
const cmds = [];
const packagesByCMD = {};
for (const dep of updatedDeps) {
switch (dep.depType) {
case utils_1.depTypes.optionalDependencies: {
if (is_1.default.nullOrUndefined(dep.managerData?.depGroup)) {
logger_1.logger.once.warn({ dep: dep.depName }, 'Unexpected optional dependency without group');
continue;
}
addPackageToCMDRecord(packagesByCMD, `${pdmUpdateCMD} -G ${(0, shlex_1.quote)(dep.managerData.depGroup)}`, dep.packageName);
break;
}
case utils_1.depTypes.dependencyGroups:
case utils_1.depTypes.pdmDevDependencies: {
if (is_1.default.nullOrUndefined(dep.managerData?.depGroup)) {
logger_1.logger.once.warn({ dep: dep.depName }, 'Unexpected dev dependency without group');
continue;
}
addPackageToCMDRecord(packagesByCMD, `${pdmUpdateCMD} -dG ${(0, shlex_1.quote)(dep.managerData.depGroup)}`, dep.packageName);
break;
}
case utils_1.depTypes.buildSystemRequires:
// build requirements are not locked in the lock files, no need to update.
// Reference: https://github.com/pdm-project/pdm/discussions/2869
break;
default: {
addPackageToCMDRecord(packagesByCMD, pdmUpdateCMD, dep.packageName);
}
}
}
for (const commandPrefix in packagesByCMD) {
const packageList = packagesByCMD[commandPrefix].map(shlex_1.quote).join(' ');
const cmd = `${commandPrefix} ${packageList}`;
cmds.push(cmd);
}
return cmds;
}
function addPackageToCMDRecord(packagesByCMD, commandPrefix, packageName) {
if (is_1.default.nullOrUndefined(packagesByCMD[commandPrefix])) {
packagesByCMD[commandPrefix] = [];
}
packagesByCMD[commandPrefix].push(packageName);
}
//# sourceMappingURL=pdm.js.map