UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

142 lines (141 loc) • 7.08 kB
import "../../../constants/error-messages.js"; import { regEx } from "../../../util/regex.js"; import { GlobalConfig } from "../../../config/global.js"; import { logger } from "../../../logger/index.js"; import { findUpLocal, readLocalFile, writeLocalFile } from "../../../util/fs/index.js"; import { exec, getToolSettingsOptions, gradleJvmArg } from "../../../util/exec/index.js"; import { getFiles, getRepoStatus } from "../../../util/git/index.js"; import { scm } from "../../platform/scm.js"; import { isGradleBuildFile } from "./utils.js"; import { extraEnv, extractGradleVersion, getJavaConstraint, gradleWrapperFileName, prepareGradleCommand } from "../gradle-wrapper/utils.js"; import { isGcvLockFile, isGcvPropsFile } from "./extract/consistent-versions-plugin.js"; import { isNonEmptyStringAndNotWhitespace } from "@sindresorhus/is"; import { quote } from "shlex"; import upath from "upath"; //#region lib/modules/manager/gradle/artifacts.ts function isGradleExecutionAllowed(command) { if (!GlobalConfig.get("allowedUnsafeExecutions").includes("gradleWrapper")) { logger.once.warn(`Gradle wrapper command, \`${command}\`, was requested to run, but \`gradleWrapper\` is not permitted in the allowedUnsafeExecutions`); return false; } return true; } function isLockFile(fileName) { return fileName.endsWith(".lockfile") || isGcvLockFile(fileName); } async function getUpdatedLockfiles(oldLockFileContentMap) { const res = []; const status = await getRepoStatus(); for (const modifiedFile of status.modified) if (isLockFile(modifiedFile) || modifiedFile.endsWith("gradle/verification-metadata.xml")) { const newContent = await 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 = [""]; const subprojectsRegex = regEx(/^[ \t]*subprojects: \[(?<subprojects>.+)\]/m); const subprojectsMatch = (await exec(`${cmd} properties`, execOptions)).stdout.match(subprojectsRegex); if (subprojectsMatch?.groups?.subprojects) { const projectRegex = 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 extractResult = extractGradleVersion(await readLocalFile(upath.join(upath.dirname(gradlewFile), "gradle/wrapper/gradle-wrapper.properties"), "utf8") ?? ""); return extractResult ? extractResult.version : null; } async function buildUpdateVerificationMetadataCmd(verificationMetadataFile, baseCmd) { if (!verificationMetadataFile) return null; const verificationMetadata = await 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.debug("Dependency metadata verification enabled or checksums present - generating checksums"); if ((verifiesChecksums || verifiesSignatures) && !hashTypes.length) hashTypes.push("sha256"); if (verifiesSignatures) { 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.debug(`gradle.updateArtifacts(${packageFileName})`); const fileList = await 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.debug("No Gradle dependency lockfiles or verification metadata found - skipping update"); return null; } const gradlewName = gradleWrapperFileName(); const gradlewFile = await findUpLocal(gradlewName, upath.dirname(packageFileName)); if (!gradlewFile) { logger.debug("Found Gradle dependency lockfiles but no gradlew - aborting update"); return null; } if (config.isLockFileMaintenance && (!isGradleBuildFile(packageFileName) || upath.dirname(packageFileName) !== upath.dirname(gradlewFile))) { logger.trace("No build.gradle(.kts) file or not in root project - skipping lock file maintenance"); return null; } if (!isGradleExecutionAllowed(gradlewFile)) { logger.trace("Not allowed to execute gradle due to allowedUnsafeExecutions - aborting update"); return null; } logger.debug("Updating found Gradle dependency lockfiles"); try { const oldLockFileContentMap = await getFiles(lockFiles); await prepareGradleCommand(gradlewFile); const baseCmd = `${gradlewName}${gradleJvmArg(getToolSettingsOptions(config.toolSettings))} --console=plain --dependency-verification lenient -q`; const execOptions = { cwdFile: gradlewFile, docker: {}, extraEnv, toolConstraints: [{ toolName: "java", constraint: config.constraints?.java ?? await getJavaConstraint(await getGradleVersion(gradlewFile), gradlewFile) }] }; const cmds = []; if (lockFiles.length) { let lockfileCmd = `${baseCmd} ${(await getSubProjectList(baseCmd, execOptions)).map((project) => `${project}:dependencies`).map(quote).join(" ")}`; if (config.isLockFileMaintenance === true || !updatedDeps.length || isGcvPropsFile(packageFileName)) lockfileCmd += " --write-locks"; else { const updatedDepNames = updatedDeps.map(({ depName, packageName }) => packageName ?? depName).filter(isNonEmptyStringAndNotWhitespace); lockfileCmd += ` --update-locks ${updatedDepNames.map(quote).join(",")}`; } cmds.push(lockfileCmd); } const updateVerificationMetadataCmd = await buildUpdateVerificationMetadataCmd(verificationMetadataFile, baseCmd); if (updateVerificationMetadataCmd) cmds.push(updateVerificationMetadataCmd); if (!cmds.length) { logger.debug("No lockfile or verification metadata update necessary"); return null; } await writeLocalFile(packageFileName, newPackageFileContent); await exec(cmds, { ...execOptions, ignoreStdout: true }); const res = await getUpdatedLockfiles(oldLockFileContentMap); logger.debug("Returning updated Gradle dependency lockfiles"); return res.length > 0 ? res : null; } catch (err) { if (err.message === "temporary-error") throw err; logger.debug({ err }, "Error while updating Gradle dependency lockfiles"); return [{ artifactError: { fileName: packageFileName, stderr: err.message } }]; } } //#endregion export { isGradleExecutionAllowed, updateArtifacts }; //# sourceMappingURL=artifacts.js.map