diff --git a/lib/modules/manager/sbt/extract.spec.ts b/lib/modules/manager/sbt/extract.spec.ts index c40d21fb74f01e832c8ede489fd8fcc71949da07..24bce088c6bd82d45a787c2a3decf8a35cb8285e 100644 --- a/lib/modules/manager/sbt/extract.spec.ts +++ b/lib/modules/manager/sbt/extract.spec.ts @@ -1,3 +1,4 @@ +import { codeBlock } from 'common-tags'; import { Fixtures } from '../../../../test/fixtures'; import { extractPackageFile as extract } from '.'; @@ -378,5 +379,63 @@ describe('modules/manager/sbt/extract', () => { packageFileVersion: undefined, }); }); + + it('extract sbt version', () => { + expect( + extract( + codeBlock` + sbt.version=1.6.0 + `, + 'project/build.properties' + ) + ).toMatchObject({ + deps: [ + { + datasource: 'github-releases', + packageName: 'sbt/sbt', + depName: 'sbt/sbt', + currentValue: '1.6.0', + replaceString: 'sbt.version=1.6.0', + versioning: 'semver', + extractVersion: '^v(?<version>\\S+)', + }, + ], + }); + }); + + it('extract sbt version if the file contains other properties', () => { + expect( + extract( + codeBlock` + sbt.version=1.6.0 + another.conf=1.4.0 + `, + 'project/build.properties' + ) + ).toMatchObject({ + deps: [ + { + datasource: 'github-releases', + packageName: 'sbt/sbt', + depName: 'sbt/sbt', + currentValue: '1.6.0', + replaceString: 'sbt.version=1.6.0', + versioning: 'semver', + extractVersion: '^v(?<version>\\S+)', + }, + ], + }); + }); + + it('ignores build.properties file if does not contain sbt version', () => { + expect( + extract( + codeBlock` + another.conf=1.4.0 + `, + 'project/build.properties' + ) + ).toBeNull(); + }); }); }); diff --git a/lib/modules/manager/sbt/extract.ts b/lib/modules/manager/sbt/extract.ts index 7ad6d298bb3b8a5e9e518f60a2a2bba615b3a397..db076c8f5b1e9f7a3eb52b13c024128d337d6b6d 100644 --- a/lib/modules/manager/sbt/extract.ts +++ b/lib/modules/manager/sbt/extract.ts @@ -2,6 +2,7 @@ import { lang, query as q } from 'good-enough-parser'; import { logger } from '../../../logger'; import { regEx } from '../../../util/regex'; import { parseUrl } from '../../../util/url'; +import { GithubReleasesDatasource } from '../../datasource/github-releases'; import { MavenDatasource } from '../../datasource/maven'; import { SbtPackageDatasource } from '../../datasource/sbt-package'; import { @@ -10,6 +11,7 @@ import { } from '../../datasource/sbt-plugin'; import { get } from '../../versioning'; import * as mavenVersioning from '../../versioning/maven'; +import * as semverVersioning from '../../versioning/semver'; import { REGISTRY_URLS } from '../gradle/parser/common'; import type { PackageDependency, PackageFileContent } from '../types'; import { normalizeScalaVersion } from './util'; @@ -36,6 +38,10 @@ interface Ctx { const scala = lang.createLang('scala'); +const sbtVersionRegex = regEx( + 'sbt\\.version *= *(?<version>\\d+\\.\\d+\\.\\d+)' +); + const scalaVersionMatch = q .sym<Ctx>('scalaVersion') .op(':=') @@ -285,8 +291,34 @@ const query = q.tree<Ctx>({ export function extractPackageFile( content: string, - _packageFile: string + packageFile: string ): PackageFileContent | null { + 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: PackageDependency = { + datasource: GithubReleasesDatasource.id, + depName: 'sbt/sbt', + packageName: 'sbt/sbt', + versioning: semverVersioning.id, + currentValue: sbtVersion, + replaceString: matchString, + extractVersion: '^v(?<version>\\S+)', + }; + + return { + deps: [sbtDependency], + }; + } else { + return null; + } + } + let parsedResult: Ctx | null = null; try { @@ -296,7 +328,7 @@ export function extractPackageFile( registryUrls: [REGISTRY_URLS.mavenCentral], }); } catch (err) /* istanbul ignore next */ { - logger.warn({ err }, 'Sbt parsing error'); + logger.warn({ err, packageFile }, 'Sbt parsing error'); } if (!parsedResult) { diff --git a/lib/modules/manager/sbt/index.ts b/lib/modules/manager/sbt/index.ts index 48e0fa094b3b47063392759e99ab3dda067bddd6..111c1e52e5da6b45225d6629bcfce8d7e26e4cc6 100644 --- a/lib/modules/manager/sbt/index.ts +++ b/lib/modules/manager/sbt/index.ts @@ -1,3 +1,4 @@ +import { GithubReleasesDatasource } from '../../datasource/github-releases'; import { MavenDatasource } from '../../datasource/maven'; import { SbtPackageDatasource } from '../../datasource/sbt-package'; import { SbtPluginDatasource } from '../../datasource/sbt-plugin'; @@ -10,9 +11,14 @@ export const supportedDatasources = [ MavenDatasource.id, SbtPackageDatasource.id, SbtPluginDatasource.id, + GithubReleasesDatasource.id, // For sbt itself ]; export const defaultConfig = { - fileMatch: ['\\.sbt$', 'project/[^/]*.scala$'], + fileMatch: [ + '\\.sbt$', + 'project/[^/]*\\.scala$', + 'project/build\\.properties$', + ], versioning: ivyVersioning.id, };