Skip to content

Commit 06264fd

Browse files
authored
feat(sbt-package): Support releaseTimestamp (#31882)
1 parent 969d4ee commit 06264fd

File tree

2 files changed

+93
-13
lines changed

2 files changed

+93
-13
lines changed

lib/modules/datasource/sbt-package/index.spec.ts

+36
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@ import { codeBlock } from 'common-tags';
22
import { getPkgReleases } from '..';
33
import { Fixtures } from '../../../../test/fixtures';
44
import * as httpMock from '../../../../test/http-mock';
5+
import { mocked } from '../../../../test/util';
6+
import * as _packageCache from '../../../util/cache/package';
57
import { regEx } from '../../../util/regex';
68
import * as mavenVersioning from '../../versioning/maven';
79
import { MAVEN_REPO } from '../maven/common';
810
import { extractPageLinks } from './util';
911
import { SbtPackageDatasource } from '.';
1012

13+
jest.mock('../../../util/cache/package');
14+
const packageCache = mocked(_packageCache);
15+
1116
describe('modules/datasource/sbt-package/index', () => {
1217
it('parses Maven index directory', () => {
1318
expect(
@@ -278,4 +283,35 @@ describe('modules/datasource/sbt-package/index', () => {
278283
expect(res).toMatchObject({});
279284
});
280285
});
286+
287+
describe('postprocessRelease', () => {
288+
const datasource = new SbtPackageDatasource();
289+
290+
it('extracts URL from Maven POM file', async () => {
291+
const registryUrl = 'https://repo.maven.apache.org/maven2/';
292+
const packageName = 'org.example:example';
293+
packageCache.get.mockImplementation(((ns: string, k: string) =>
294+
ns === 'datasource-sbt-package' &&
295+
k === `package-urls:${registryUrl}:${packageName}`
296+
? Promise.resolve([`${registryUrl}org/example/`])
297+
: Promise.resolve(undefined)) as never);
298+
299+
httpMock
300+
.scope(registryUrl)
301+
.get('/org/example/1.2.3/example-1.2.3.pom')
302+
.reply(200, codeBlock`<project></project>`, {
303+
'last-modified': 'Wed, 21 Oct 2015 07:28:00 GMT',
304+
});
305+
306+
const res = await datasource.postprocessRelease(
307+
{ packageName, registryUrl },
308+
{ version: '1.2.3' },
309+
);
310+
311+
expect(res).toEqual({
312+
version: '1.2.3',
313+
releaseTimestamp: '2015-10-21T07:28:00.000Z',
314+
});
315+
});
316+
});
281317
});

lib/modules/datasource/sbt-package/index.ts

+57-13
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as upath from 'upath';
22
import { XmlDocument } from 'xmldoc';
33
import { logger } from '../../../logger';
44
import * as packageCache from '../../../util/cache/package';
5+
import { cache } from '../../../util/cache/package/decorator';
56
import { Http } from '../../../util/http';
67
import { regEx } from '../../../util/regex';
78
import { ensureTrailingSlash, trimTrailingSlash } from '../../../util/url';
@@ -10,6 +11,7 @@ import { compare } from '../../versioning/maven/compare';
1011
import { MavenDatasource } from '../maven';
1112
import { MAVEN_REPO } from '../maven/common';
1213
import { downloadHttpProtocol } from '../maven/util';
14+
import { normalizeDate } from '../metadata';
1315
import type {
1416
GetReleasesConfig,
1517
PostprocessReleaseConfig,
@@ -26,6 +28,12 @@ interface ScalaDepCoordinate {
2628
scalaVersion?: string;
2729
}
2830

31+
interface PomInfo {
32+
homepage?: string;
33+
sourceUrl?: string;
34+
releaseTimestamp?: string;
35+
}
36+
2937
export class SbtPackageDatasource extends MavenDatasource {
3038
static override readonly id = 'sbt-package';
3139

@@ -187,6 +195,11 @@ export class SbtPackageDatasource extends MavenDatasource {
187195
return null;
188196
}
189197

198+
const releases: Release[] = [...allVersions]
199+
.sort(compare)
200+
.map((version) => ({ version }));
201+
const res: ReleaseResult = { releases, dependencyUrl };
202+
190203
const latestVersion = getLatestVersion(versions);
191204
const pomInfo = await this.getPomInfo(
192205
registryUrl,
@@ -195,20 +208,23 @@ export class SbtPackageDatasource extends MavenDatasource {
195208
packageUrls,
196209
);
197210

198-
const releases: Release[] = [...allVersions]
199-
.sort(compare)
200-
.map((version) => ({ version }));
201-
return { releases, dependencyUrl, ...pomInfo };
211+
if (pomInfo?.homepage) {
212+
res.homepage = pomInfo.homepage;
213+
}
214+
215+
if (pomInfo?.sourceUrl) {
216+
res.sourceUrl = pomInfo.sourceUrl;
217+
}
218+
219+
return res;
202220
}
203221

204222
async getPomInfo(
205223
registryUrl: string,
206224
packageName: string,
207225
version: string | null,
208226
pkgUrls?: string[],
209-
): Promise<Pick<ReleaseResult, 'homepage' | 'sourceUrl'>> {
210-
const result: Pick<ReleaseResult, 'homepage' | 'sourceUrl'> = {};
211-
227+
): Promise<PomInfo | null> {
212228
const packageUrlsKey = `package-urls:${registryUrl}:${packageName}`;
213229
// istanbul ignore next: will be covered later
214230
const packageUrls =
@@ -220,12 +236,12 @@ export class SbtPackageDatasource extends MavenDatasource {
220236

221237
// istanbul ignore if
222238
if (!packageUrls?.length) {
223-
return result;
239+
return null;
224240
}
225241

226242
// istanbul ignore if
227243
if (!version) {
228-
return result;
244+
return null;
229245
}
230246

231247
const invalidPomFilesKey = `invalid-pom-files:${registryUrl}:${packageName}:${version}`;
@@ -265,6 +281,13 @@ export class SbtPackageDatasource extends MavenDatasource {
265281
continue;
266282
}
267283

284+
const result: PomInfo = {};
285+
286+
const releaseTimestamp = normalizeDate(res.headers['last-modified']);
287+
if (releaseTimestamp) {
288+
result.releaseTimestamp = releaseTimestamp;
289+
}
290+
268291
const pomXml = new XmlDocument(content);
269292

270293
const homepage = pomXml.valueWithPath('url');
@@ -287,7 +310,7 @@ export class SbtPackageDatasource extends MavenDatasource {
287310
}
288311

289312
await saveCache();
290-
return result;
313+
return null;
291314
}
292315

293316
override async getReleases(
@@ -316,12 +339,33 @@ export class SbtPackageDatasource extends MavenDatasource {
316339
return null;
317340
}
318341

319-
// istanbul ignore next: to be rewritten
342+
@cache({
343+
namespace: 'datasource-sbt-package',
344+
key: (
345+
{ registryUrl, packageName }: PostprocessReleaseConfig,
346+
{ version }: Release,
347+
) => `postprocessRelease:${registryUrl}:${packageName}:${version}`,
348+
ttlMinutes: 30 * 24 * 60,
349+
})
320350
override async postprocessRelease(
321351
config: PostprocessReleaseConfig,
322352
release: Release,
323353
): Promise<PostprocessReleaseResult> {
324-
const mavenResult = await super.postprocessRelease(config, release);
325-
return mavenResult === 'reject' ? release : mavenResult;
354+
// istanbul ignore if
355+
if (!config.registryUrl) {
356+
return release;
357+
}
358+
359+
const res = await this.getPomInfo(
360+
config.registryUrl,
361+
config.packageName,
362+
release.version,
363+
);
364+
365+
if (res?.releaseTimestamp) {
366+
release.releaseTimestamp = res.releaseTimestamp;
367+
}
368+
369+
return release;
326370
}
327371
}

0 commit comments

Comments
 (0)