UNPKG

renovate

Version:

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

186 lines • 6.87 kB
"use strict"; 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 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 hostRules = tslib_1.__importStar(require("../../../util/host-rules")); const regex_1 = require("../../../util/regex"); const hexRepoUrl = 'https://hex.pm/'; const hexRepoOrgUrlRegex = (0, regex_1.regEx)(`^https://hex\\.pm/api/repos/(?<organization>[a-z0-9_]+)/$`); async function updateArtifacts({ packageFileName, updatedDeps, newPackageFileContent, config, }) { logger_1.logger.debug(`mix.getArtifacts(${packageFileName})`); const { isLockFileMaintenance } = config; if (is_1.default.emptyArray(updatedDeps) && !isLockFileMaintenance) { logger_1.logger.debug('No updated mix deps'); return null; } let lockFileName = (0, fs_1.getSiblingFileName)(packageFileName, 'mix.lock'); let isUmbrella = false; let existingLockFileContent = await (0, fs_1.readLocalFile)(lockFileName, 'utf8'); if (!existingLockFileContent) { const lockFileError = await checkLockFileReadError(lockFileName); if (lockFileError) { return lockFileError; } const parentLockFileName = await (0, fs_1.findLocalSiblingOrParent)(packageFileName, 'mix.lock'); existingLockFileContent = parentLockFileName && (await (0, fs_1.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_1.logger.debug('Cannot use lockFileMaintenance in an umbrella project, see https://docs.renovatebot.com/modules/manager/mix/#lockFileMaintenance'); return null; } if (isLockFileMaintenance && !existingLockFileContent) { logger_1.logger.debug('Cannot use lockFileMaintenance when no mix.lock file is present'); return null; } try { await (0, fs_1.writeLocalFile)(packageFileName, newPackageFileContent); if (isLockFileMaintenance) { await (0, fs_1.deleteLocalFile)(lockFileName); } } catch (err) { logger_1.logger.warn({ err }, 'mix.exs could not be written'); return [ { artifactError: { lockFile: lockFileName, stderr: err.message, }, }, ]; } if (!existingLockFileContent) { logger_1.logger.debug('No mix.lock found'); return null; } const organizations = new Set(); const hexHostRulesWithMatchHost = hostRules .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 url = `${hexRepoUrl}api/repos/${organization}/`; const { token } = hostRules.find({ url }); if (token) { logger_1.logger.debug(`Authenticating to hex organization ${organization}`); const authCommand = `mix hex.organization auth ${organization} --key ${token}`; return [...acc, authCommand]; } return acc; }, []); const execOptions = { extraEnv: { // https://hexdocs.pm/mix/1.15.0/Mix.Tasks.Archive.html // TODO: should include a version constraint MIX_ARCHIVES: await (0, fs_1.ensureCacheDir)('mix_archives'), }, cwdFile: packageFileName, docker: {}, toolConstraints: [ { toolName: 'erlang', // https://hexdocs.pm/elixir/1.14.5/compatibility-and-deprecations.html#compatibility-between-elixir-and-erlang-otp 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(is_1.default.string) .map((dep) => (0, shlex_1.quote)(dep)), ].join(' '); } try { await (0, exec_1.exec)(command, execOptions); } catch (err) { /* v8 ignore next 3 */ if (err.message === error_messages_1.TEMPORARY_ERROR) { throw err; } logger_1.logger.debug({ err, message: err.message, command }, 'Failed to update Mix lock file'); return [ { artifactError: { lockFile: lockFileName, stderr: err.message, }, }, ]; } const newMixLockContent = await (0, fs_1.readLocalFile)(lockFileName, 'utf8'); if (existingLockFileContent === newMixLockContent) { logger_1.logger.debug('mix.lock is unchanged'); return null; } logger_1.logger.debug('Returning updated mix.lock'); return [ { file: { type: 'addition', path: lockFileName, contents: newMixLockContent, }, }, ]; } async function checkLockFileReadError(lockFileName) { if (await (0, fs_1.localPathExists)(lockFileName)) { return [ { artifactError: { lockFile: lockFileName, stderr: `Error reading ${lockFileName}`, }, }, ]; } return null; } //# sourceMappingURL=artifacts.js.map