diff --git a/lib/modules/datasource/sbt-package/index.ts b/lib/modules/datasource/sbt-package/index.ts index b714aae786c7b6..96f68b0fbf289e 100644 --- a/lib/modules/datasource/sbt-package/index.ts +++ b/lib/modules/datasource/sbt-package/index.ts @@ -8,7 +8,11 @@ import { compare } from '../../versioning/maven/compare'; import { MavenDatasource } from '../maven'; import { MAVEN_REPO } from '../maven/common'; import { downloadHttpProtocol } from '../maven/util'; -import type { GetReleasesConfig, ReleaseResult } from '../types'; +import type { + GetReleasesConfig, + RegistryStrategy, + ReleaseResult, +} from '../types'; import { getLatestVersion, normalizeRootRelativeUrls, @@ -22,7 +26,7 @@ export class SbtPackageDatasource extends MavenDatasource { override readonly defaultVersioning = ivyVersioning.id; - override readonly registryStrategy = 'hunt'; + override readonly registryStrategy: RegistryStrategy = 'hunt'; override readonly sourceUrlSupport = 'package'; override readonly sourceUrlNote = diff --git a/lib/modules/datasource/sbt-package/readme.md b/lib/modules/datasource/sbt-package/readme.md new file mode 100644 index 00000000000000..ff2e3d3a152b82 --- /dev/null +++ b/lib/modules/datasource/sbt-package/readme.md @@ -0,0 +1,15 @@ +This datasource finds SBT package updates from Maven repositories. + +By default, Renovate checks `https://repo.maven.apache.org/maven2` for SBT packages. +You can override the default behavior with the `registryUrls` config option. +For example: + +```json +{ + "matchDatasources": ["sbt-package"], + "registryUrls": [ + "https://repo.maven.apache.org/maven2", + "https://oss.sonatype.org/content/repositories/snapshots" + ] +} +``` diff --git a/lib/modules/datasource/sbt-plugin/index.spec.ts b/lib/modules/datasource/sbt-plugin/index.spec.ts index f2b3daaaa81df9..6387ff45e60a0e 100644 --- a/lib/modules/datasource/sbt-plugin/index.spec.ts +++ b/lib/modules/datasource/sbt-plugin/index.spec.ts @@ -1,3 +1,4 @@ +import { codeBlock, html } from 'common-tags'; import { getPkgReleases } from '..'; import { Fixtures } from '../../../../test/fixtures'; import * as httpMock from '../../../../test/http-mock'; @@ -37,10 +38,12 @@ describe('modules/datasource/sbt-plugin/index', () => { .get('/maven2/org/scalatest/') .reply( 200, - 'scalatest_2.12/\n' + - 'scalatest_2.12/\n' + - "scalatest_2.12/" + - "scalatest_2.12/", + html` + scalatest/ + scalatest_2.12/ + scalatest_sjs2.12/ + scalatest_native2.12/ + `, ); httpMock .scope('https://repo.maven.apache.org') @@ -52,53 +55,46 @@ describe('modules/datasource/sbt-plugin/index', () => { .reply(200, "4.5.6/"); httpMock - .scope('https://repo.scala-sbt.org') - .get('/scalasbt/sbt-plugin-releases/com.github.gseitz/') - .reply(200, ''); - httpMock - .scope('https://repo.scala-sbt.org') - .get('/scalasbt/sbt-plugin-releases/org.foundweekends/sbt-bintray/') + .scope('https://repo.maven.apache.org') + .get('/maven2/org/foundweekends/sbt-bintray/') .reply( 200, - '\n' + - '\n' + - '\n' + - '\n' + - '
scala_2.12/
\n' + - '\n' + - '', + html` + + + +
scala_2.12/
+ + + `, ); httpMock - .scope('https://repo.scala-sbt.org') - .get( - '/scalasbt/sbt-plugin-releases/org.foundweekends/sbt-bintray/scala_2.12/', - ) + .scope('https://repo.maven.apache.org') + .get('/maven2/org/foundweekends/sbt-bintray/scala_2.12/') .reply( 200, - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '
sbt_1.0/
\n' + - '\n' + - '\n', + html` + + + +
sbt_1.0/
+ + + `, ); httpMock - .scope('https://repo.scala-sbt.org') - .get( - '/scalasbt/sbt-plugin-releases/org.foundweekends/sbt-bintray/scala_2.12/sbt_1.0/', - ) + .scope('https://repo.maven.apache.org') + .get('/maven2/org/foundweekends/sbt-bintray/scala_2.12/sbt_1.0/') .reply( 200, - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '
0.5.5/
\n' + - '\n' + - '\n', + html` + + + +
0.5.5/
+ + + `, ); httpMock @@ -106,20 +102,28 @@ describe('modules/datasource/sbt-plugin/index', () => { .get('/maven2/io/get-coursier/') .reply( 200, - 'sbt-coursier_2.10_0.13/\n' + - 'sbt-coursier_2.12_1.0/\n' + - 'sbt-coursier_2.12_1.0.0-M5/\n' + - 'sbt-coursier_2.12_1.0.0-M6/\n', + html` + sbt-coursier_2.10_0.13/ + sbt-coursier_2.12_1.0/ + sbt-coursier_2.12_1.0.0-M5/ + sbt-coursier_2.12_1.0.0-M6/ + `, ); httpMock .scope('https://repo.maven.apache.org') .get('/maven2/io/get-coursier/sbt-coursier_2.12_1.0/') .reply( 200, - '2.0.0-RC2/\n' + - '2.0.0-RC6-1/\n' + - '2.0.0-RC6-2/\n' + - '2.0.0-RC6-6/\n', + html` + 2.0.0-RC2/ + 2.0.0-RC6-1/ + 2.0.0-RC6-2/ + 2.0.0-RC6-6/ + `, ); httpMock .scope('https://repo.maven.apache.org') @@ -128,12 +132,14 @@ describe('modules/datasource/sbt-plugin/index', () => { ) .reply( 200, - '\n' + - 'https://get-coursier.io/\n' + - '\n' + - 'https://github.com/coursier/sbt-coursier\n' + - '\n' + - '\n', + codeBlock` + + https://get-coursier.io/ + + https://github.com/coursier/sbt-coursier + + + `, ); }); @@ -169,8 +175,8 @@ describe('modules/datasource/sbt-plugin/index', () => { }), ).toEqual({ dependencyUrl: - 'https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/org.foundweekends/sbt-bintray', - registryUrl: 'https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases', + 'https://repo.maven.apache.org/maven2/org/foundweekends/sbt-bintray', + registryUrl: 'https://repo.maven.apache.org/maven2', releases: [{ version: '0.5.5' }], }); }); @@ -185,8 +191,8 @@ describe('modules/datasource/sbt-plugin/index', () => { }), ).toEqual({ dependencyUrl: - 'https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/org.foundweekends/sbt-bintray', - registryUrl: 'https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases', + 'https://repo.maven.apache.org/maven2/org/foundweekends/sbt-bintray', + registryUrl: 'https://repo.maven.apache.org/maven2', releases: [{ version: '0.5.5' }], }); }); diff --git a/lib/modules/datasource/sbt-plugin/index.ts b/lib/modules/datasource/sbt-plugin/index.ts index 1d4c18a6ab039a..de9ca82afe2ae6 100644 --- a/lib/modules/datasource/sbt-plugin/index.ts +++ b/lib/modules/datasource/sbt-plugin/index.ts @@ -4,22 +4,27 @@ import { regEx } from '../../../util/regex'; import { ensureTrailingSlash } from '../../../util/url'; import * as ivyVersioning from '../../versioning/ivy'; import { compare } from '../../versioning/maven/compare'; +import { MAVEN_REPO } from '../maven/common'; import { downloadHttpProtocol } from '../maven/util'; import { SbtPackageDatasource } from '../sbt-package'; import { getLatestVersion, parseIndexDir } from '../sbt-package/util'; -import type { GetReleasesConfig, ReleaseResult } from '../types'; +import type { + GetReleasesConfig, + RegistryStrategy, + ReleaseResult, +} from '../types'; export const SBT_PLUGINS_REPO = 'https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases'; -export const defaultRegistryUrls = [SBT_PLUGINS_REPO]; +export const defaultRegistryUrls = [SBT_PLUGINS_REPO, MAVEN_REPO]; export class SbtPluginDatasource extends SbtPackageDatasource { static override readonly id = 'sbt-plugin'; override readonly defaultRegistryUrls = defaultRegistryUrls; - override readonly registryStrategy = 'hunt'; + override readonly registryStrategy: RegistryStrategy = 'merge'; override readonly defaultVersioning = ivyVersioning.id; @@ -98,7 +103,9 @@ export class SbtPluginDatasource extends SbtPackageDatasource { const repoRoot = ensureTrailingSlash(registryUrl); const searchRoots: string[] = []; // Optimize lookup order - searchRoots.push(`${repoRoot}${groupIdSplit.join('.')}`); + if (!registryUrl.startsWith(MAVEN_REPO)) { + searchRoots.push(`${repoRoot}${groupIdSplit.join('.')}`); + } searchRoots.push(`${repoRoot}${groupIdSplit.join('/')}`); for (let idx = 0; idx < searchRoots.length; idx += 1) { diff --git a/lib/modules/datasource/sbt-plugin/readme.md b/lib/modules/datasource/sbt-plugin/readme.md new file mode 100644 index 00000000000000..01f5302616dcae --- /dev/null +++ b/lib/modules/datasource/sbt-plugin/readme.md @@ -0,0 +1,20 @@ +This datasource finds SBT plugin updates from Maven repositories. + +By default, Renovate: + +1. Checks `https://repo1.maven.org/maven2/` for SBT plugins +1. If the above URL returns no results, then Renovate tries the _legacy_ URL: `https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases` + +You can override the default behavior with the `registryUrls` config option. +For example: + +```json +{ + "matchDatasources": ["sbt-plugin"], + "registryUrls": [ + "https://repo1.maven.org/maven2/", + "https://oss.sonatype.org/content/repositories/snapshots", + "https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases" + ] +} +``` diff --git a/lib/modules/datasource/types.ts b/lib/modules/datasource/types.ts index 98f6279ebb2101..ae8eaac067b28a 100644 --- a/lib/modules/datasource/types.ts +++ b/lib/modules/datasource/types.ts @@ -102,9 +102,9 @@ export interface DatasourceApi extends ModuleApi { /** * Strategy to use when multiple registryUrls are available to the datasource. - * first: only the first registryUrl will be tried and others ignored - * hunt: registryUrls will be tried in order until one returns a result - * merge: all registryUrls will be tried and the results merged if more than one returns a result + * - `first`: only the first registryUrl will be tried and others ignored + * - `hunt`: registryUrls will be tried in order until one returns a result + * - `merge`: all registryUrls will be tried and the results merged if more than one returns a result */ registryStrategy?: RegistryStrategy | undefined; diff --git a/lib/modules/manager/sbt/extract.spec.ts b/lib/modules/manager/sbt/extract.spec.ts index 29b09a5eae1600..7410b282ae382c 100644 --- a/lib/modules/manager/sbt/extract.spec.ts +++ b/lib/modules/manager/sbt/extract.spec.ts @@ -490,7 +490,7 @@ describe('modules/manager/sbt/extract', () => { registryUrls: [ 'http://example.org/repo', 'https://example.org/ivy-repo/', - 'https://repo1.maven.org/maven2', + 'https://repo.maven.apache.org/maven2', ], }, { @@ -499,7 +499,7 @@ describe('modules/manager/sbt/extract', () => { registryUrls: [ 'http://example.org/repo', 'https://example.org/ivy-repo/', - 'https://repo1.maven.org/maven2', + 'https://repo.maven.apache.org/maven2', ], }, { @@ -508,7 +508,7 @@ describe('modules/manager/sbt/extract', () => { registryUrls: [ 'http://example.org/repo', 'https://example.org/ivy-repo/', - 'https://repo1.maven.org/maven2', + 'https://repo.maven.apache.org/maven2', ], }, { @@ -517,7 +517,7 @@ describe('modules/manager/sbt/extract', () => { registryUrls: [ 'http://example.org/repo', 'https://example.org/ivy-repo/', - 'https://repo1.maven.org/maven2', + 'https://repo.maven.apache.org/maven2', ], }, { @@ -526,7 +526,7 @@ describe('modules/manager/sbt/extract', () => { registryUrls: [ 'http://example.org/repo', 'https://example.org/ivy-repo/', - 'https://repo1.maven.org/maven2', + 'https://repo.maven.apache.org/maven2', ], }, { @@ -535,7 +535,7 @@ describe('modules/manager/sbt/extract', () => { registryUrls: [ 'http://example.org/repo', 'https://example.org/ivy-repo/', - 'https://repo1.maven.org/maven2', + 'https://repo.maven.apache.org/maven2', ], }, ], @@ -551,7 +551,7 @@ describe('modules/manager/sbt/extract', () => { for (const dep of pkg.deps.filter((d) => d.depType === 'plugin')) { expect(dep.registryUrls).toStrictEqual([ 'https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases', - 'https://repo1.maven.org/maven2', + 'https://repo.maven.apache.org/maven2', 'https://example.com/repos/1/', 'https://example.com/repos/2/', 'https://example.com/repos/3/', @@ -563,7 +563,7 @@ describe('modules/manager/sbt/extract', () => { for (const pkg of packages) { for (const dep of pkg.deps.filter((d) => d.depType !== 'plugin')) { expect(dep.registryUrls).toStrictEqual([ - 'https://repo1.maven.org/maven2', + 'https://repo.maven.apache.org/maven2', 'https://example.com/repos/1/', 'https://example.com/repos/2/', 'https://example.com/repos/3/', diff --git a/lib/modules/manager/sbt/extract.ts b/lib/modules/manager/sbt/extract.ts index 747245f1ae14ee..fd5a9173769dd0 100644 --- a/lib/modules/manager/sbt/extract.ts +++ b/lib/modules/manager/sbt/extract.ts @@ -5,6 +5,7 @@ import { newlineRegex, regEx } from '../../../util/regex'; import { parseUrl } from '../../../util/url'; import { GithubReleasesDatasource } from '../../datasource/github-releases'; import { MavenDatasource } from '../../datasource/maven'; +import { MAVEN_REPO } from '../../datasource/maven/common'; import { SbtPackageDatasource } from '../../datasource/sbt-package'; import { SBT_PLUGINS_REPO, @@ -41,8 +42,6 @@ interface Ctx { variableName?: string; } -const SBT_MVN_REPO = 'https://repo1.maven.org/maven2'; - const scala = lang.createLang('scala'); const sbtVersionRegex = regEx( @@ -308,7 +307,7 @@ export function extractProxyUrls( if (extraction?.groups?.proxy) { extractedProxyUrls.push(extraction.groups.proxy); } else if (line.trim() === 'maven-central') { - extractedProxyUrls.push(SBT_MVN_REPO); + extractedProxyUrls.push(MAVEN_REPO); } } return extractedProxyUrls; @@ -418,9 +417,9 @@ export async function extractAllPackageFiles( if (proxyUrls.length > 0) { dep.registryUrls!.unshift(...proxyUrls); } else if (dep.depType === 'plugin') { - dep.registryUrls!.unshift(SBT_PLUGINS_REPO, SBT_MVN_REPO); + dep.registryUrls!.unshift(SBT_PLUGINS_REPO, MAVEN_REPO); } else { - dep.registryUrls!.unshift(SBT_MVN_REPO); + dep.registryUrls!.unshift(MAVEN_REPO); } } }