UNPKG

renovate

Version:

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

136 lines (135 loc) 5.01 kB
import "../../../constants/error-messages.js"; import { regEx } from "../../../util/regex.js"; import { logger } from "../../../logger/index.js"; import { find, getAll } from "../../../util/host-rules.js"; import { deleteLocalFile, ensureCacheDir, findLocalSiblingOrParent, getSiblingFileName, localPathExists, readLocalFile, writeLocalFile } from "../../../util/fs/index.js"; import { exec } from "../../../util/exec/index.js"; import { isEmptyArray, isString } from "@sindresorhus/is"; import { quote } from "shlex"; //#region lib/modules/manager/mix/artifacts.ts const hexRepoUrl = "https://hex.pm/"; const hexRepoOrgUrlRegex = regEx(`^https://hex\\.pm/api/repos/(?<organization>[a-z0-9_]+)/$`); async function updateArtifacts({ packageFileName, updatedDeps, newPackageFileContent, config }) { logger.debug(`mix.getArtifacts(${packageFileName})`); const { isLockFileMaintenance } = config; if (isEmptyArray(updatedDeps) && !isLockFileMaintenance) { logger.debug("No updated mix deps"); return null; } let lockFileName = getSiblingFileName(packageFileName, "mix.lock"); let isUmbrella = false; let existingLockFileContent = await readLocalFile(lockFileName, "utf8"); if (!existingLockFileContent) { const lockFileError = await checkLockFileReadError(lockFileName); if (lockFileError) return lockFileError; const parentLockFileName = await findLocalSiblingOrParent(packageFileName, "mix.lock"); existingLockFileContent = parentLockFileName && await readLocalFile(parentLockFileName, "utf8"); if (parentLockFileName && existingLockFileContent) { lockFileName = parentLockFileName; isUmbrella = true; } else if (parentLockFileName) { const lockFileError = await checkLockFileReadError(parentLockFileName); if (lockFileError) return lockFileError; } } if (isLockFileMaintenance && isUmbrella) { logger.debug("Cannot use lockFileMaintenance in an umbrella project, see https://docs.renovatebot.com/modules/manager/mix/#lockFileMaintenance"); return null; } if (isLockFileMaintenance && !existingLockFileContent) { logger.debug("Cannot use lockFileMaintenance when no mix.lock file is present"); return null; } try { await writeLocalFile(packageFileName, newPackageFileContent); if (isLockFileMaintenance) await deleteLocalFile(lockFileName); } catch (err) { logger.warn({ err }, "mix.exs could not be written"); return [{ artifactError: { fileName: lockFileName, stderr: err.message } }]; } if (!existingLockFileContent) { logger.debug("No mix.lock found"); return null; } const organizations = /* @__PURE__ */ new Set(); const hexHostRulesWithMatchHost = getAll().filter((hostRule) => !!hostRule.matchHost && hexRepoOrgUrlRegex.test(hostRule.matchHost)); for (const { matchHost } of hexHostRulesWithMatchHost) if (matchHost) { const result = hexRepoOrgUrlRegex.exec(matchHost); if (result?.groups) { const { organization } = result.groups; organizations.add(organization); } } for (const { packageName } of updatedDeps) if (packageName) { const [, organization] = packageName.split(":"); if (organization) organizations.add(organization); } const preCommands = Array.from(organizations).reduce((acc, organization) => { const { token } = find({ url: `${hexRepoUrl}api/repos/${organization}/` }); if (token) { logger.debug(`Authenticating to hex organization ${organization}`); const authCommand = `mix hex.organization auth ${organization} --key ${token}`; return [...acc, authCommand]; } return acc; }, []); const execOptions = { extraEnv: { MIX_ARCHIVES: await ensureCacheDir("mix_archives") }, cwdFile: packageFileName, docker: {}, toolConstraints: [{ toolName: "erlang", constraint: config.constraints?.erlang ?? "^26" }, { toolName: "elixir", constraint: config.constraints?.elixir }], preCommands }; let command; if (isLockFileMaintenance) command = "mix deps.get"; else command = [ "mix", "deps.update", ...updatedDeps.map((dep) => dep.depName).filter(isString).map((dep) => quote(dep)) ].join(" "); try { await exec(command, execOptions); } catch (err) { /* v8 ignore next 3 */ if (err.message === "temporary-error") throw err; logger.debug({ err, message: err.message, command }, "Failed to update Mix lock file"); return [{ artifactError: { fileName: lockFileName, stderr: err.message } }]; } const newMixLockContent = await readLocalFile(lockFileName, "utf8"); if (existingLockFileContent === newMixLockContent) { logger.debug("mix.lock is unchanged"); return null; } logger.debug("Returning updated mix.lock"); return [{ file: { type: "addition", path: lockFileName, contents: newMixLockContent } }]; } async function checkLockFileReadError(lockFileName) { if (await localPathExists(lockFileName)) return [{ artifactError: { fileName: lockFileName, stderr: `Error reading ${lockFileName}` } }]; return null; } //#endregion export { updateArtifacts }; //# sourceMappingURL=artifacts.js.map