renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
177 lines • 8.43 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateArtifacts = updateArtifacts;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const shlex_1 = require("shlex");
const upath_1 = tslib_1.__importDefault(require("upath"));
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 git_1 = require("../../../util/git");
const regex_1 = require("../../../util/regex");
const scm_1 = require("../../platform/scm");
const utils_1 = require("../gradle-wrapper/utils");
const consistent_versions_plugin_1 = require("./extract/consistent-versions-plugin");
const utils_2 = require("./utils");
// .lockfile is gradle default lockfile, /versions.lock is gradle-consistent-versions plugin lockfile
function isLockFile(fileName) {
return fileName.endsWith('.lockfile') || (0, consistent_versions_plugin_1.isGcvLockFile)(fileName);
}
async function getUpdatedLockfiles(oldLockFileContentMap) {
const res = [];
const status = await (0, git_1.getRepoStatus)();
for (const modifiedFile of status.modified) {
if (isLockFile(modifiedFile) ||
modifiedFile.endsWith('gradle/verification-metadata.xml')) {
const newContent = await (0, fs_1.readLocalFile)(modifiedFile, 'utf8');
if (oldLockFileContentMap[modifiedFile] !== newContent) {
res.push({
file: {
type: 'addition',
path: modifiedFile,
contents: newContent,
},
});
}
}
}
return res;
}
async function getSubProjectList(cmd, execOptions) {
const subprojects = ['']; // = root project
const subprojectsRegex = (0, regex_1.regEx)(/^[ \t]*subprojects: \[(?<subprojects>.+)\]/m);
const gradleProperties = await (0, exec_1.exec)(`${cmd} properties`, execOptions);
const subprojectsMatch = gradleProperties.stdout.match(subprojectsRegex);
if (subprojectsMatch?.groups?.subprojects) {
const projectRegex = (0, regex_1.regEx)(/project '(?<name>.+?)'/g);
const matches = subprojectsMatch.groups.subprojects.matchAll(projectRegex);
for (const match of matches) {
if (match?.groups?.name) {
subprojects.push(match.groups.name);
}
}
}
return subprojects;
}
async function getGradleVersion(gradlewFile) {
const propertiesFile = upath_1.default.join(upath_1.default.dirname(gradlewFile), 'gradle/wrapper/gradle-wrapper.properties');
const properties = await (0, fs_1.readLocalFile)(propertiesFile, 'utf8');
const extractResult = (0, utils_1.extractGradleVersion)(properties ?? '');
return extractResult ? extractResult.version : null;
}
async function buildUpdateVerificationMetadataCmd(verificationMetadataFile, baseCmd) {
if (!verificationMetadataFile) {
return null;
}
const verificationMetadata = await (0, fs_1.readLocalFile)(verificationMetadataFile);
const verifiesChecksums = verificationMetadata?.includes('<verify-metadata>true</verify-metadata>');
const verifiesSignatures = verificationMetadata?.includes('<verify-signatures>true</verify-signatures>');
const hashTypes = ['sha256', 'sha512'].filter((type) => verificationMetadata?.includes(`<${type} `));
if (verifiesChecksums || hashTypes.length) {
logger_1.logger.debug('Dependency metadata verification enabled or checksums present - generating checksums');
}
if ((verifiesChecksums || verifiesSignatures) && !hashTypes.length) {
// fallback algorithm for pgp and in case a weak algorithm (md5, sha1) is used for checksums
hashTypes.push('sha256');
}
if (verifiesSignatures) {
logger_1.logger.debug('Dependency signature verification enabled - generating PGP signatures');
hashTypes.push('pgp');
}
if (!hashTypes.length) {
return null;
}
return `${baseCmd} --write-verification-metadata ${hashTypes.join(',')} dependencies`;
}
async function updateArtifacts({ packageFileName, updatedDeps, newPackageFileContent, config, }) {
logger_1.logger.debug(`gradle.updateArtifacts(${packageFileName})`);
const fileList = await scm_1.scm.getFileList();
const lockFiles = fileList.filter((file) => isLockFile(file));
const verificationMetadataFile = fileList.find((fileName) => fileName.endsWith('gradle/verification-metadata.xml'));
if (!lockFiles.length && !verificationMetadataFile) {
logger_1.logger.debug('No Gradle dependency lockfiles or verification metadata found - skipping update');
return null;
}
const gradlewName = (0, utils_1.gradleWrapperFileName)();
const gradlewFile = await (0, fs_1.findUpLocal)(gradlewName, upath_1.default.dirname(packageFileName));
if (!gradlewFile) {
logger_1.logger.debug('Found Gradle dependency lockfiles but no gradlew - aborting update');
return null;
}
if (config.isLockFileMaintenance &&
(!(0, utils_2.isGradleBuildFile)(packageFileName) ||
upath_1.default.dirname(packageFileName) !== upath_1.default.dirname(gradlewFile))) {
logger_1.logger.trace('No build.gradle(.kts) file or not in root project - skipping lock file maintenance');
return null;
}
logger_1.logger.debug('Updating found Gradle dependency lockfiles');
try {
const oldLockFileContentMap = await (0, git_1.getFiles)(lockFiles);
await (0, utils_1.prepareGradleCommand)(gradlewFile);
const baseCmd = `${gradlewName} --console=plain --dependency-verification lenient -q`;
const execOptions = {
cwdFile: gradlewFile,
docker: {},
extraEnv: utils_1.extraEnv,
toolConstraints: [
{
toolName: 'java',
constraint: config.constraints?.java ??
(await (0, utils_1.getJavaConstraint)(await getGradleVersion(gradlewFile), gradlewFile)),
},
],
};
const cmds = [];
if (lockFiles.length) {
const subprojects = await getSubProjectList(baseCmd, execOptions);
let lockfileCmd = `${baseCmd} ${subprojects
.map((project) => `${project}:dependencies`)
.map(shlex_1.quote)
.join(' ')}`;
if (config.isLockFileMaintenance === true ||
!updatedDeps.length ||
(0, consistent_versions_plugin_1.isGcvPropsFile)(packageFileName)) {
lockfileCmd += ' --write-locks';
}
else {
const updatedDepNames = updatedDeps
.map(({ depName, packageName }) => packageName ?? depName)
.filter(is_1.default.nonEmptyStringAndNotWhitespace);
lockfileCmd += ` --update-locks ${updatedDepNames
.map(shlex_1.quote)
.join(',')}`;
}
cmds.push(lockfileCmd);
}
const updateVerificationMetadataCmd = await buildUpdateVerificationMetadataCmd(verificationMetadataFile, baseCmd);
if (updateVerificationMetadataCmd) {
cmds.push(updateVerificationMetadataCmd);
}
if (!cmds.length) {
logger_1.logger.debug('No lockfile or verification metadata update necessary');
return null;
}
await (0, fs_1.writeLocalFile)(packageFileName, newPackageFileContent);
await (0, exec_1.exec)(cmds, { ...execOptions, ignoreStdout: true });
const res = await getUpdatedLockfiles(oldLockFileContentMap);
logger_1.logger.debug('Returning updated Gradle dependency lockfiles');
return res.length > 0 ? res : null;
}
catch (err) {
if (err.message === error_messages_1.TEMPORARY_ERROR) {
throw err;
}
logger_1.logger.debug({ err }, 'Error while updating Gradle dependency lockfiles');
return [
{
artifactError: {
lockFile: packageFileName,
stderr: err.message,
},
},
];
}
}
//# sourceMappingURL=artifacts.js.map