renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
198 lines • 7.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.findLockFile = findLockFile;
exports.readLockFile = readLockFile;
exports.extractLocks = extractLocks;
exports.isPinnedVersion = isPinnedVersion;
exports.writeLockUpdates = writeLockUpdates;
exports.massageNewValue = massageNewValue;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const fs_1 = require("../../../../util/fs");
const regex_1 = require("../../../../util/regex");
const versioning_1 = require("../../../versioning");
const providerStartLineRegex = (0, regex_1.regEx)(`^provider "(?<registryUrl>[^/]*)/(?<namespace>[^/]*)/(?<depName>[^/]*)"`);
const versionLineRegex = (0, regex_1.regEx)(`^(?<prefix>[\\s]*version[\\s]*=[\\s]*")(?<version>[^"']+)(?<suffix>".*)$`);
const constraintLineRegex = (0, regex_1.regEx)(`^(?<prefix>[\\s]*constraints[\\s]*=[\\s]*")(?<constraint>[^"']+)(?<suffix>".*)$`);
const hashLineRegex = (0, regex_1.regEx)(`^(?<prefix>\\s*")(?<hash>[^"]+)(?<suffix>",.*)$`);
const lockFile = '.terraform.lock.hcl';
function findLockFile(packageFilePath) {
return (0, fs_1.findLocalSiblingOrParent)(packageFilePath, lockFile);
}
function readLockFile(lockFilePath) {
return (0, fs_1.readLocalFile)(lockFilePath, 'utf8');
}
function extractLocks(lockFileContent) {
const lines = lockFileContent.split(regex_1.newlineRegex);
const blockStarts = [];
// get first lines of blocks
lines.forEach((line, index) => {
if (line.startsWith('provider "')) {
blockStarts.push(index);
}
});
// sort ascending
const sortedStarts = blockStarts.sort((a, b) => a - b);
const contentSlices = sortedStarts.map((start, index, array) => {
let end;
if (index < array.length - 1) {
end = array[index + 1];
}
else {
end = lines.length - 1;
}
const slice = {
lines: lines.slice(start, end),
block: {
start,
end,
},
};
return slice;
});
// generate Lock objects from slices
const locks = contentSlices.map((slice) => {
let packageName = '';
let registryUrl = '';
let version = '';
let constraints = '';
const relativeLineNumbers = {
block: slice.block,
hashes: {
start: -1,
end: -1,
},
};
const hashes = [];
slice.lines.forEach((line, index) => {
const hashLineResult = hashLineRegex.exec(line);
if (hashLineResult?.groups) {
hashes.push(hashLineResult.groups.hash);
relativeLineNumbers.hashes.start =
relativeLineNumbers.hashes.start === -1
? index
: relativeLineNumbers.hashes.start;
relativeLineNumbers.hashes.end = index;
return;
}
const providerStartLineResult = providerStartLineRegex.exec(line);
if (providerStartLineResult?.groups) {
packageName = `${providerStartLineResult.groups.namespace}/${providerStartLineResult.groups.depName}`;
registryUrl = providerStartLineResult.groups.registryUrl;
return;
}
const versionLineResult = versionLineRegex.exec(line);
if (versionLineResult?.groups) {
version = versionLineResult.groups.version;
relativeLineNumbers.version = index;
return;
}
const constraintLineResult = constraintLineRegex.exec(line);
if (constraintLineResult?.groups) {
constraints = constraintLineResult.groups.constraint;
relativeLineNumbers.constraint = index;
}
});
const lock = {
packageName,
registryUrl: `https://${registryUrl}`,
version,
constraints,
hashes,
lineNumbers: relativeLineNumbers,
};
return lock;
});
if (locks.length === 0) {
return null;
}
return locks;
}
function isPinnedVersion(value) {
const versioning = (0, versioning_1.get)('hashicorp');
return !!value && !!versioning.isSingleVersion(value);
}
function writeLockUpdates(updates, lockFilePath, oldLockFileContent) {
const lines = oldLockFileContent.split(regex_1.newlineRegex);
const sections = [];
// sort updates in order of appearance in the lockfile
// TODO #22198
updates.sort((a, b) => a.lineNumbers.block.start - b.lineNumbers.block.start);
updates.forEach((update, index, array) => {
// re add leading whitespace
let startWhitespace;
if (index > 0) {
// get end of the
// TODO #22198
startWhitespace = array[index - 1].lineNumbers.block.end;
}
const leadingNonRelevantLines = lines.slice(startWhitespace,
// TODO #22198
update.lineNumbers.block.start);
sections.push(leadingNonRelevantLines);
const providerBlockLines = lines.slice(
// TODO #22198
update.lineNumbers.block.start, update.lineNumbers.block.end);
const newProviderBlockLines = [];
let hashLinePrefix = '';
let hashLineSuffix = '';
providerBlockLines.forEach((providerBlockLine, providerBlockIndex) => {
const versionLine = providerBlockLine.replace(versionLineRegex, `$<prefix>${update.newVersion}$<suffix>`);
if (versionLine !== providerBlockLine) {
newProviderBlockLines.push(versionLine);
return;
}
const constraintLine = providerBlockLine.replace(constraintLineRegex, `$<prefix>${update.newConstraint}$<suffix>`);
if (constraintLine !== providerBlockLine) {
newProviderBlockLines.push(constraintLine);
return;
}
const hashLineRegexResult = hashLineRegex.exec(providerBlockLine);
if (hashLineRegexResult?.groups) {
// skip hash line but safe the whitespace
hashLinePrefix = hashLineRegexResult.groups.prefix;
hashLineSuffix = hashLineRegexResult.groups.suffix;
return;
}
newProviderBlockLines.push(providerBlockLine);
});
const hashesWithWhitespace = update.newHashes.map((value) => `${hashLinePrefix}${value}${hashLineSuffix}`);
newProviderBlockLines.splice(
// TODO #22198
update.lineNumbers.hashes.start, 0, ...hashesWithWhitespace);
sections.push(newProviderBlockLines);
});
const trailingNotUpdatedLines = lines.slice(updates[updates.length - 1].lineNumbers.block?.end);
sections.push(trailingNotUpdatedLines);
const newLines = sections.reduce((previousValue, currentValue) => previousValue.concat(currentValue));
const newContent = newLines.join('\n');
return {
file: {
type: 'addition',
path: lockFilePath,
contents: newContent,
},
};
}
function massageNewValue(value) {
if (is_1.default.nullOrUndefined(value)) {
return value;
}
const elements = value.split(',');
const massagedElements = [];
for (const element of elements) {
// these constraints are allowed to miss precision
if (element.includes('~>')) {
massagedElements.push(element);
continue;
}
const missing0s = 3 - element.split('.').length;
let massagedElement = element;
for (let i = 0; i < missing0s; i++) {
massagedElement = `${massagedElement}.0`;
}
massagedElements.push(massagedElement);
}
return massagedElements.join(',');
}
//# sourceMappingURL=util.js.map