UNPKG

renovate

Version:

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

232 lines • 10.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SbtPackageDatasource = void 0; const tslib_1 = require("tslib"); const upath = tslib_1.__importStar(require("upath")); const xmldoc_1 = require("xmldoc"); const logger_1 = require("../../../logger"); const packageCache = tslib_1.__importStar(require("../../../util/cache/package")); const decorator_1 = require("../../../util/cache/package/decorator"); const http_1 = require("../../../util/http"); const regex_1 = require("../../../util/regex"); const timestamp_1 = require("../../../util/timestamp"); const url_1 = require("../../../util/url"); const ivyVersioning = tslib_1.__importStar(require("../../versioning/ivy")); const compare_1 = require("../../versioning/maven/compare"); const maven_1 = require("../maven"); const common_1 = require("../maven/common"); const util_1 = require("../maven/util"); const util_2 = require("./util"); class SbtPackageDatasource extends maven_1.MavenDatasource { static id = 'sbt-package'; defaultRegistryUrls = [common_1.MAVEN_REPO]; defaultVersioning = ivyVersioning.id; registryStrategy = 'hunt'; sourceUrlSupport = 'package'; sourceUrlNote = 'The source URL is determined from the `scm` tags in the results.'; constructor(id = SbtPackageDatasource.id) { super(id); this.http = new http_1.Http('sbt'); } static parseDepCoordinate(packageName) { const [groupId, javaArtifactId] = packageName.split(':'); const [artifactId, scalaVersion] = javaArtifactId.split('_'); return { groupId, artifactId, scalaVersion }; } async getSbtReleases(registryUrl, packageName) { const { groupId, artifactId, scalaVersion } = SbtPackageDatasource.parseDepCoordinate(packageName); const groupIdSplit = groupId.split('.'); const repoRootUrl = (0, url_1.ensureTrailingSlash)(registryUrl); const validRootUrlKey = `valid-root-url:${registryUrl}:${packageName}`; const validRootUrl = await packageCache.get('datasource-sbt-package', validRootUrlKey); const packageRootUrls = []; // istanbul ignore if: not easily testable if (validRootUrl) { packageRootUrls.push(validRootUrl); } else { const packageRootUrlWith = (sep) => `${repoRootUrl}${groupIdSplit.join(sep)}`; packageRootUrls.push((0, url_1.ensureTrailingSlash)(packageRootUrlWith('/'))); packageRootUrls.push((0, url_1.ensureTrailingSlash)(packageRootUrlWith('.'))); } let dependencyUrl; let packageUrls; for (const packageRootUrl of packageRootUrls) { const packageRootContent = await (0, util_1.downloadHttpContent)(this.http, packageRootUrl); if (!packageRootContent) { continue; } await packageCache.set('datasource-sbt-package', validRootUrlKey, packageRootUrl, 30 * 24 * 60); dependencyUrl = (0, url_1.trimTrailingSlash)(packageRootUrl); const rootPath = new URL(packageRootUrl).pathname; const artifactSubdirs = (0, util_2.extractPageLinks)(packageRootContent, (href) => { const path = href.replace(rootPath, ''); if (path.startsWith(`${artifactId}_native`) || path.startsWith(`${artifactId}_sjs`)) { return null; } if (path === artifactId || path.startsWith(`${artifactId}_`)) { return (0, url_1.ensureTrailingSlash)(`${packageRootUrl}${path}`); } return null; }); if (scalaVersion) { const scalaSubdir = artifactSubdirs.find((x) => x.endsWith(`/${artifactId}_${scalaVersion}/`)); if (scalaSubdir) { packageUrls = [scalaSubdir]; break; } } packageUrls = artifactSubdirs; break; } if (!packageUrls) { return null; } const invalidPackageUrlsKey = `invalid-package-urls:${registryUrl}:${packageName}`; const invalidPackageUrls = new Set(await packageCache.get('datasource-sbt-package', invalidPackageUrlsKey)); packageUrls = packageUrls.filter((url) => !invalidPackageUrls.has(url)); const allVersions = new Set(); for (const pkgUrl of packageUrls) { const packageContent = await (0, util_1.downloadHttpContent)(this.http, pkgUrl); // istanbul ignore if if (!packageContent) { invalidPackageUrls.add(pkgUrl); continue; } const rootPath = new URL(pkgUrl).pathname; const versions = (0, util_2.extractPageLinks)(packageContent, (href) => { const path = href.replace(rootPath, ''); if (path.startsWith('.')) { return null; } return path; }); for (const version of versions) { allVersions.add(version); } } if (invalidPackageUrls.size > 0) { await packageCache.set('datasource-sbt-package', invalidPackageUrlsKey, [...invalidPackageUrls], 30 * 24 * 60); } if (packageUrls.length > 0) { const packageUrlsKey = `package-urls:${registryUrl}:${packageName}`; await packageCache.set('datasource-sbt-package', packageUrlsKey, packageUrls, 30 * 24 * 60); } const versions = [...allVersions]; if (!versions.length) { return null; } const releases = [...allVersions] .sort(compare_1.compare) .map((version) => ({ version })); const res = { releases, dependencyUrl }; const latestVersion = (0, util_2.getLatestVersion)(versions); const pomInfo = await this.getPomInfo(registryUrl, packageName, latestVersion, packageUrls); if (pomInfo?.homepage) { res.homepage = pomInfo.homepage; } if (pomInfo?.sourceUrl) { res.sourceUrl = pomInfo.sourceUrl; } return res; } async getPomInfo(registryUrl, packageName, version, pkgUrls) { const packageUrlsKey = `package-urls:${registryUrl}:${packageName}`; // istanbul ignore next: will be covered later const packageUrls = pkgUrls ?? (await packageCache.get('datasource-sbt-package', packageUrlsKey)); // istanbul ignore if if (!packageUrls?.length) { return null; } // istanbul ignore if if (!version) { return null; } const invalidPomFilesKey = `invalid-pom-files:${registryUrl}:${packageName}:${version}`; const invalidPomFiles = new Set(await packageCache.get('datasource-sbt-package', invalidPomFilesKey)); const saveCache = async () => { if (invalidPomFiles.size > 0) { await packageCache.set('datasource-sbt-package', invalidPomFilesKey, [...invalidPomFiles], 30 * 24 * 60); } }; for (const packageUrl of packageUrls) { const artifactDir = upath.basename(packageUrl); const [artifact] = artifactDir.split('_'); for (const pomFilePrefix of [artifactDir, artifact]) { const pomFileName = `${pomFilePrefix}-${version}.pom`; const pomUrl = `${packageUrl}${version}/${pomFileName}`; if (invalidPomFiles.has(pomUrl)) { continue; } const res = await (0, util_1.downloadHttpProtocol)(this.http, pomUrl); const { val } = res.unwrap(); if (!val) { invalidPomFiles.add(pomUrl); continue; } const result = {}; const releaseTimestamp = (0, timestamp_1.asTimestamp)(val.lastModified); if (releaseTimestamp) { result.releaseTimestamp = releaseTimestamp; } const pomXml = new xmldoc_1.XmlDocument(val.data); const homepage = pomXml.valueWithPath('url'); if (homepage) { result.homepage = homepage; } const sourceUrl = pomXml.valueWithPath('scm.url'); if (sourceUrl) { result.sourceUrl = sourceUrl .replace((0, regex_1.regEx)(/^scm:/), '') .replace((0, regex_1.regEx)(/^git:/), '') .replace((0, regex_1.regEx)(/^git@github.com:/), 'https://github.com/') .replace((0, regex_1.regEx)(/\.git$/), ''); } await saveCache(); return result; } } await saveCache(); return null; } async getReleases(config) { const { packageName, registryUrl } = config; // istanbul ignore if if (!registryUrl) { return null; } const sbtReleases = await this.getSbtReleases(registryUrl, packageName); if (sbtReleases) { return sbtReleases; } logger_1.logger.debug(`Sbt: no versions discovered for ${packageName} listing organization root package folder, fallback to maven datasource for version discovery`); const mavenReleaseResult = await super.getReleases(config); if (mavenReleaseResult) { return mavenReleaseResult; } logger_1.logger.debug(`Sbt: no versions found for "${packageName}"`); return null; } async postprocessRelease(config, release) { /* v8 ignore next 3 -- should never happen */ if (!config.registryUrl) { return release; } const res = await this.getPomInfo(config.registryUrl, config.packageName, release.version); if (res?.releaseTimestamp) { release.releaseTimestamp = res.releaseTimestamp; } return release; } } exports.SbtPackageDatasource = SbtPackageDatasource; tslib_1.__decorate([ (0, decorator_1.cache)({ namespace: 'datasource-sbt-package', key: ({ registryUrl, packageName }, { version }) => `postprocessRelease:${registryUrl}:${packageName}:${version}`, ttlMinutes: 30 * 24 * 60, }) ], SbtPackageDatasource.prototype, "postprocessRelease", null); //# sourceMappingURL=index.js.map