renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
299 lines • 11.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractProxyUrls = extractProxyUrls;
exports.extractPackageFile = extractPackageFile;
exports.extractAllPackageFiles = extractAllPackageFiles;
const tslib_1 = require("tslib");
const good_enough_parser_1 = require("good-enough-parser");
const logger_1 = require("../../../logger");
const fs_1 = require("../../../util/fs");
const regex_1 = require("../../../util/regex");
const url_1 = require("../../../util/url");
const github_releases_1 = require("../../datasource/github-releases");
const maven_1 = require("../../datasource/maven");
const common_1 = require("../../datasource/maven/common");
const sbt_package_1 = require("../../datasource/sbt-package");
const sbt_plugin_1 = require("../../datasource/sbt-plugin");
const versioning_1 = require("../../versioning");
const mavenVersioning = tslib_1.__importStar(require("../../versioning/maven"));
const semverVersioning = tslib_1.__importStar(require("../../versioning/semver"));
const util_1 = require("./util");
const scala = good_enough_parser_1.lang.createLang('scala');
const sbtVersionRegex = (0, regex_1.regEx)('sbt\\.version *= *(?<version>\\d+\\.\\d+\\.\\d+)');
const sbtProxyUrlRegex = (0, regex_1.regEx)(/^\s*(?<repoName>\S+):\s+(?<proxy>https?:\/\/[\w./-]+)/);
const scalaVersionMatch = good_enough_parser_1.query
.sym('scalaVersion')
.op(':=')
.alt(good_enough_parser_1.query.str((ctx, { value: scalaVersion }) => ({ ...ctx, scalaVersion })), good_enough_parser_1.query.sym((ctx, { value: varName }) => {
const scalaVersion = ctx.vars[varName];
if (scalaVersion) {
ctx.scalaVersion = scalaVersion;
}
return ctx;
}))
.handler((ctx) => {
if (ctx.scalaVersion) {
const version = (0, versioning_1.get)(mavenVersioning.id);
let packageName = 'org.scala-lang:scala-library';
if (version.getMajor(ctx.scalaVersion) === 3) {
packageName = 'org.scala-lang:scala3-library_3';
}
const dep = {
datasource: maven_1.MavenDatasource.id,
depName: 'scala',
packageName,
currentValue: ctx.scalaVersion,
separateMinorPatch: true,
};
ctx.scalaVersion = (0, util_1.normalizeScalaVersion)(ctx.scalaVersion);
ctx.deps.push(dep);
}
return ctx;
});
const packageFileVersionMatch = good_enough_parser_1.query
.sym('version')
.op(':=')
.alt(good_enough_parser_1.query.str((ctx, { value: packageFileVersion }) => ({
...ctx,
packageFileVersion,
})), good_enough_parser_1.query.sym((ctx, { value: varName }) => {
const packageFileVersion = ctx.vars[varName];
if (packageFileVersion) {
ctx.packageFileVersion = packageFileVersion;
}
return ctx;
}));
const variableNameMatch = good_enough_parser_1.query
.sym((ctx, { value: varName }) => ({
...ctx,
currentVarName: varName,
}))
.opt(good_enough_parser_1.query.op(':').sym('String'));
const variableValueMatch = good_enough_parser_1.query.str((ctx, { value }) => {
ctx.vars[ctx.currentVarName] = value;
delete ctx.currentVarName;
return ctx;
});
const assignmentMatch = good_enough_parser_1.query.sym('val').join(variableNameMatch).op('=');
const variableDefinitionMatch = good_enough_parser_1.query
.alt(good_enough_parser_1.query.sym('lazy').join(assignmentMatch), assignmentMatch, variableNameMatch.op(':='))
.join(variableValueMatch);
const groupIdMatch = good_enough_parser_1.query.alt(good_enough_parser_1.query.sym((ctx, { value: varName }) => {
const currentGroupId = ctx.vars[varName];
if (currentGroupId) {
ctx.groupId = currentGroupId;
}
return ctx;
}), good_enough_parser_1.query.str((ctx, { value: groupId }) => ({ ...ctx, groupId })));
const artifactIdMatch = good_enough_parser_1.query.alt(good_enough_parser_1.query.sym((ctx, { value: varName }) => {
const artifactId = ctx.vars[varName];
if (artifactId) {
ctx.artifactId = artifactId;
}
return ctx;
}), good_enough_parser_1.query.str((ctx, { value: artifactId }) => ({ ...ctx, artifactId })));
const versionMatch = good_enough_parser_1.query.alt(good_enough_parser_1.query.sym((ctx, { value: varName }) => {
const currentValue = ctx.vars[varName];
if (currentValue) {
ctx.currentValue = currentValue;
ctx.variableName = varName;
}
return ctx;
}), good_enough_parser_1.query.str((ctx, { value: currentValue }) => ({ ...ctx, currentValue })));
const simpleDependencyMatch = groupIdMatch
.op('%')
.join(artifactIdMatch)
.op('%')
.join(versionMatch);
const versionedDependencyMatch = groupIdMatch
.op('%%')
.join(artifactIdMatch)
.handler((ctx) => ({ ...ctx, useScalaVersion: true }))
.op('%')
.join(versionMatch);
const crossDependencyMatch = groupIdMatch
.op('%%%')
.join(artifactIdMatch)
.handler((ctx) => ({ ...ctx, useScalaVersion: true }))
.op('%')
.join(versionMatch);
function depHandler(ctx) {
const { scalaVersion, groupId, artifactId, currentValue, useScalaVersion, depType, variableName, } = ctx;
delete ctx.groupId;
delete ctx.artifactId;
delete ctx.currentValue;
delete ctx.useScalaVersion;
delete ctx.depType;
delete ctx.variableName;
const depName = `${groupId}:${artifactId}`;
const dep = {
datasource: sbt_package_1.SbtPackageDatasource.id,
depName,
packageName: scalaVersion && useScalaVersion ? `${depName}_${scalaVersion}` : depName,
currentValue,
};
if (depType) {
dep.depType = depType;
}
if (depType === 'plugin') {
dep.datasource = sbt_plugin_1.SbtPluginDatasource.id;
}
if (variableName) {
dep.sharedVariableName = variableName;
dep.variableName = variableName;
}
ctx.deps.push(dep);
return ctx;
}
function depTypeHandler(ctx, { value: depType }) {
return { ...ctx, depType };
}
const sbtPackageMatch = good_enough_parser_1.query
.opt(good_enough_parser_1.query.opt(good_enough_parser_1.query.sym('lazy')).sym('val').sym().op('='))
.alt(crossDependencyMatch, simpleDependencyMatch, versionedDependencyMatch)
.opt(good_enough_parser_1.query.alt(good_enough_parser_1.query.sym('classifier').str(depTypeHandler), good_enough_parser_1.query.op('%').sym(depTypeHandler), good_enough_parser_1.query.op('%').str(depTypeHandler)))
.handler(depHandler);
const sbtPluginMatch = good_enough_parser_1.query
.sym((0, regex_1.regEx)(/^(?:addSbtPlugin|addCompilerPlugin)$/))
.tree({
type: 'wrapped-tree',
maxDepth: 1,
search: good_enough_parser_1.query
.begin()
.alt(simpleDependencyMatch, versionedDependencyMatch)
.end(),
})
.handler((ctx) => ({ ...ctx, depType: 'plugin' }))
.handler(depHandler);
const resolverMatch = good_enough_parser_1.query
.str()
.sym('at')
.str((ctx, { value }) => {
if ((0, url_1.parseUrl)(value)) {
ctx.registryUrls.push(value);
}
return ctx;
});
const addResolverMatch = good_enough_parser_1.query.sym('resolvers').alt(good_enough_parser_1.query.op('+=').join(resolverMatch), good_enough_parser_1.query.op('++=').sym('Seq').tree({
type: 'wrapped-tree',
maxDepth: 1,
search: resolverMatch,
}));
function registryUrlHandler(ctx) {
for (const dep of ctx.deps) {
dep.registryUrls = [...ctx.registryUrls];
}
return ctx;
}
const query = good_enough_parser_1.query.tree({
type: 'root-tree',
maxDepth: 32,
search: good_enough_parser_1.query.alt(scalaVersionMatch, packageFileVersionMatch, sbtPackageMatch, sbtPluginMatch, addResolverMatch, variableDefinitionMatch),
postHandler: registryUrlHandler,
});
function extractProxyUrls(content, packageFile) {
const extractedProxyUrls = [];
logger_1.logger.debug(`Parsing proxy repository file ${packageFile}`);
for (const line of content.split(regex_1.newlineRegex)) {
const extraction = sbtProxyUrlRegex.exec(line);
if (extraction?.groups?.proxy) {
extractedProxyUrls.push(extraction.groups.proxy);
}
else if (line.trim() === 'maven-central') {
extractedProxyUrls.push(common_1.MAVEN_REPO);
}
}
return extractedProxyUrls;
}
function extractPackageFile(content, packageFile) {
return extractPackageFileInternal(content, packageFile);
}
function extractPackageFileInternal(content, packageFile, ctxScalaVersion) {
if (packageFile === 'project/build.properties' ||
packageFile.endsWith('/project/build.properties')) {
const regexResult = sbtVersionRegex.exec(content);
const sbtVersion = regexResult?.groups?.version;
const matchString = regexResult?.[0];
if (sbtVersion) {
const sbtDependency = {
datasource: github_releases_1.GithubReleasesDatasource.id,
depName: 'sbt/sbt',
packageName: 'sbt/sbt',
versioning: semverVersioning.id,
currentValue: sbtVersion,
replaceString: matchString,
extractVersion: '^v(?<version>\\S+)',
registryUrls: [],
};
return {
deps: [sbtDependency],
};
}
else {
return null;
}
}
let parsedResult = null;
try {
parsedResult = scala.query(content, query, {
vars: {},
deps: [],
registryUrls: [],
scalaVersion: ctxScalaVersion,
});
}
catch (err) /* istanbul ignore next */ {
logger_1.logger.debug({ err, packageFile }, 'Sbt parsing error');
}
if (!parsedResult) {
return null;
}
const { deps, scalaVersion, packageFileVersion } = parsedResult;
if (!deps.length) {
return null;
}
return { deps, packageFileVersion, managerData: { scalaVersion } };
}
async function extractAllPackageFiles(_config, packageFiles) {
const packages = [];
const proxyUrls = [];
let ctxScalaVersion;
const sortedPackageFiles = (0, util_1.sortPackageFiles)(packageFiles);
for (const packageFile of sortedPackageFiles) {
const content = await (0, fs_1.readLocalFile)(packageFile, 'utf8');
if (!content) {
logger_1.logger.debug({ packageFile }, 'packageFile has no content');
continue;
}
if (packageFile === 'repositories') {
const urls = extractProxyUrls(content, packageFile);
proxyUrls.push(...urls);
}
else {
const pkg = extractPackageFileInternal(content, packageFile, ctxScalaVersion);
if (pkg) {
packages.push({ deps: pkg.deps, packageFile });
if (pkg.managerData?.scalaVersion) {
ctxScalaVersion = pkg.managerData.scalaVersion;
}
}
}
}
for (const pkg of packages) {
for (const dep of pkg.deps) {
if (dep.datasource !== github_releases_1.GithubReleasesDatasource.id) {
if (proxyUrls.length > 0) {
dep.registryUrls.unshift(...proxyUrls);
}
else if (dep.depType === 'plugin') {
dep.registryUrls.unshift(sbt_plugin_1.SBT_PLUGINS_REPO, common_1.MAVEN_REPO);
}
else {
dep.registryUrls.unshift(common_1.MAVEN_REPO);
}
}
}
}
return packages;
}
//# sourceMappingURL=extract.js.map