mirror of
https://github.com/actions/setup-java.git
synced 2026-07-28 15:14:30 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
333d9ce35a | ||
|
|
cb48866ec3 | ||
|
|
2c4a2dda70 | ||
|
|
a7c4828ceb | ||
|
|
d9cbbc45bb |
@@ -146,6 +146,7 @@ Currently, the following distributions are supported:
|
||||
| `corretto` | [Amazon Corretto Build of OpenJDK](https://aws.amazon.com/corretto/) | [`corretto` license](https://aws.amazon.com/corretto/faqs/)
|
||||
| `semeru` | [IBM Semeru Runtime Open Edition](https://developer.ibm.com/languages/java/semeru-runtimes/downloads/) | [`semeru` license](https://openjdk.java.net/legal/gplv2+ce.html) |
|
||||
| `oracle` | [Oracle JDK](https://www.oracle.com/java/technologies/downloads/) | [`oracle` license](https://java.com/freeuselicense)
|
||||
| `openjdk` | [OpenJDK](https://jdk.java.net/) | [`openjdk` license](https://openjdk.org/legal/gplv2+ce.html)
|
||||
| `dragonwell` | [Alibaba Dragonwell JDK](https://dragonwell-jdk.io/) | [`dragonwell` license](https://www.aliyun.com/product/dragonwell/)
|
||||
| `sapmachine` | [SAP SapMachine JDK/JRE](https://sapmachine.io/) | [`sapmachine` license](https://github.com/SAP/SapMachine/blob/sapmachine/LICENSE)
|
||||
| `graalvm` | [Oracle GraalVM](https://www.graalvm.org/) | [`graalvm` license](https://www.oracle.com/downloads/licenses/graal-free-license.html)
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
import {afterEach, beforeEach, describe, expect, it, jest} from '@jest/globals';
|
||||
import {HttpClient} from '@actions/http-client';
|
||||
|
||||
jest.unstable_mockModule('@actions/core', () => ({
|
||||
info: jest.fn(),
|
||||
warning: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
error: jest.fn(),
|
||||
notice: jest.fn(),
|
||||
setFailed: jest.fn(),
|
||||
setOutput: jest.fn(),
|
||||
getInput: jest.fn(),
|
||||
getBooleanInput: jest.fn(),
|
||||
getMultilineInput: jest.fn(),
|
||||
addPath: jest.fn(),
|
||||
exportVariable: jest.fn(),
|
||||
saveState: jest.fn(),
|
||||
getState: jest.fn(),
|
||||
setSecret: jest.fn(),
|
||||
isDebug: jest.fn(() => false),
|
||||
startGroup: jest.fn(),
|
||||
endGroup: jest.fn(),
|
||||
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
|
||||
toPlatformPath: jest.fn((value: string) => value),
|
||||
toWin32Path: jest.fn((value: string) => value),
|
||||
toPosixPath: jest.fn((value: string) => value)
|
||||
}));
|
||||
|
||||
const {OpenJdkDistribution} =
|
||||
await import('../../src/distributions/openjdk/installer.js');
|
||||
const {getJavaDistribution} =
|
||||
await import('../../src/distributions/distribution-factory.js');
|
||||
|
||||
const homePage = `
|
||||
<a href="/26/">JDK 26</a>
|
||||
<a href="/27/">JDK
|
||||
27</a>
|
||||
`;
|
||||
const currentPage = `
|
||||
<a href="https://download.java.net/java/GA/jdk26.0.2/hash/10/GPL/openjdk-26.0.2_linux-x64_bin.tar.gz">tar.gz</a>
|
||||
<a href="https://download.java.net/java/GA/jdk26.0.2/hash/10/GPL/openjdk-26.0.2_linux-aarch64_bin.tar.gz">tar.gz</a>
|
||||
`;
|
||||
const earlyAccessPage = `
|
||||
<a href="https://download.java.net/java/early_access/jdk27/32/GPL/openjdk-27-ea+32_linux-x64_bin.tar.gz">tar.gz</a>
|
||||
`;
|
||||
const archivePage = `
|
||||
<a href="https://download.java.net/java/GA/jdk26.0.1/hash/8/GPL/openjdk-26.0.1_linux-x64_bin.tar.gz">tar.gz</a>
|
||||
<a href="https://download.java.net/java/GA/jdk25/hash/36/GPL/openjdk-25_linux-x64_bin.tar.gz">tar.gz</a>
|
||||
<a href="https://download.java.net/java/GA/jdk18.0.1.1/hash/2/GPL/openjdk-18.0.1.1_linux-x64_bin.tar.gz">tar.gz</a>
|
||||
<th>9.0.4 (build 9.0.4+11)</th>
|
||||
<a href="https://download.java.net/java/GA/jdk9/9.0.4/binaries/openjdk-9.0.4_linux-x64_bin.tar.gz">tar.gz</a>
|
||||
`;
|
||||
|
||||
function createDistribution(
|
||||
version = '26',
|
||||
architecture = 'x64',
|
||||
packageType = 'jdk'
|
||||
) {
|
||||
return new OpenJdkDistribution({
|
||||
version,
|
||||
architecture,
|
||||
packageType,
|
||||
checkLatest: false
|
||||
});
|
||||
}
|
||||
|
||||
describe('OpenJdkDistribution', () => {
|
||||
let getSpy: jest.SpiedFunction<HttpClient['get']>;
|
||||
|
||||
beforeEach(() => {
|
||||
getSpy = jest
|
||||
.spyOn(HttpClient.prototype, 'get')
|
||||
.mockImplementation(async url => {
|
||||
const pages: Record<string, string> = {
|
||||
'https://jdk.java.net/': homePage,
|
||||
'https://jdk.java.net/26/': currentPage,
|
||||
'https://jdk.java.net/27/': earlyAccessPage,
|
||||
'https://jdk.java.net/archive/': archivePage
|
||||
};
|
||||
return {
|
||||
readBody: async () => pages[url] ?? ''
|
||||
} as Awaited<ReturnType<HttpClient['get']>>;
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('resolves the newest matching GA release', async () => {
|
||||
const result = await createDistribution()['findPackageForDownload']('26');
|
||||
|
||||
expect(result).toEqual({
|
||||
version: '26.0.2+10',
|
||||
url: 'https://download.java.net/java/GA/jdk26.0.2/hash/10/GPL/openjdk-26.0.2_linux-x64_bin.tar.gz'
|
||||
});
|
||||
});
|
||||
|
||||
it('resolves an archived GA release', async () => {
|
||||
const result =
|
||||
await createDistribution('26.0.1')['findPackageForDownload']('26.0.1');
|
||||
|
||||
expect(result.version).toBe('26.0.1+8');
|
||||
expect(result.url).toContain('/openjdk-26.0.1_linux-x64_bin.tar.gz');
|
||||
});
|
||||
|
||||
it('resolves an exact GA build', async () => {
|
||||
const result =
|
||||
await createDistribution('26.0.2+10')['findPackageForDownload'](
|
||||
'26.0.2+10'
|
||||
);
|
||||
|
||||
expect(result.version).toBe('26.0.2+10');
|
||||
});
|
||||
|
||||
it('resolves an exact build from a legacy archive heading', async () => {
|
||||
const result =
|
||||
await createDistribution('9.0.4+11')['findPackageForDownload'](
|
||||
'9.0.4+11'
|
||||
);
|
||||
|
||||
expect(result.version).toBe('9.0.4+11');
|
||||
expect(result.url).toContain('/binaries/openjdk-9.0.4_linux-x64_bin');
|
||||
});
|
||||
|
||||
it('resolves a four-field Java version', async () => {
|
||||
const result =
|
||||
await createDistribution('18.0.1.1')['findPackageForDownload'](
|
||||
'18.0.1+1'
|
||||
);
|
||||
|
||||
expect(result.version).toBe('18.0.1+1');
|
||||
expect(result.url).toContain('/openjdk-18.0.1.1_linux-x64_bin.tar.gz');
|
||||
});
|
||||
|
||||
it('resolves an early-access release without requesting the archive', async () => {
|
||||
const result =
|
||||
await createDistribution('27-ea')['findPackageForDownload']('27');
|
||||
|
||||
expect(result).toEqual({
|
||||
version: '27.0.0+32',
|
||||
url: 'https://download.java.net/java/early_access/jdk27/32/GPL/openjdk-27-ea+32_linux-x64_bin.tar.gz'
|
||||
});
|
||||
expect(getSpy).not.toHaveBeenCalledWith('https://jdk.java.net/archive/');
|
||||
});
|
||||
|
||||
it('reports available versions when no release matches', async () => {
|
||||
await expect(
|
||||
createDistribution()['findPackageForDownload']('24')
|
||||
).rejects.toThrow(
|
||||
"No matching version found for SemVer '24'.\nDistribution: OpenJDK"
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['jre', 'OpenJDK provides only the `jdk` package type'],
|
||||
['jdk+fx', 'OpenJDK provides only the `jdk` package type']
|
||||
])('rejects the %s package type', async (packageType, message) => {
|
||||
await expect(
|
||||
createDistribution('26', 'x64', packageType)['findPackageForDownload'](
|
||||
'26'
|
||||
)
|
||||
).rejects.toThrow(message);
|
||||
});
|
||||
|
||||
it('rejects unsupported architectures', async () => {
|
||||
await expect(
|
||||
createDistribution('26', 'x86')['findPackageForDownload']('26')
|
||||
).rejects.toThrow('Unsupported architecture: x86');
|
||||
});
|
||||
|
||||
it('maps supported platforms', () => {
|
||||
const distribution = createDistribution();
|
||||
|
||||
expect(distribution['getPlatform']('linux')).toBe('linux');
|
||||
expect(distribution['getPlatform']('darwin')).toBe('macos');
|
||||
expect(distribution['getPlatform']('win32')).toBe('windows');
|
||||
expect(() => distribution['getPlatform']('freebsd')).toThrow(
|
||||
"Platform 'freebsd' is not supported"
|
||||
);
|
||||
});
|
||||
|
||||
it('parses legacy platform names and archive formats', () => {
|
||||
const distribution = createDistribution();
|
||||
const macRelease = distribution['parseReleases'](
|
||||
'<a href="https://download.java.net/java/GA/jdk16/hash/7/GPL/openjdk-16_osx-x64_bin.tar.gz">tar.gz</a>',
|
||||
'macos',
|
||||
'x64'
|
||||
);
|
||||
const windowsRelease = distribution['parseReleases'](
|
||||
'<a href="https://download.java.net/java/GA/jdk10/hash/13/openjdk-10.0.2_windows-x64_bin.tar.gz">tar.gz</a>',
|
||||
'windows',
|
||||
'x64'
|
||||
);
|
||||
|
||||
expect(macRelease[0].version).toBe('16.0.0+7');
|
||||
expect(windowsRelease[0].version).toBe('10.0.2+13');
|
||||
expect(windowsRelease[0].url.endsWith('.tar.gz')).toBe(true);
|
||||
});
|
||||
|
||||
it('is registered in the distribution factory', () => {
|
||||
const distribution = getJavaDistribution('openjdk', {
|
||||
version: '26',
|
||||
architecture: 'x64',
|
||||
packageType: 'jdk',
|
||||
checkLatest: false
|
||||
});
|
||||
|
||||
expect(distribution).toBeInstanceOf(OpenJdkDistribution);
|
||||
});
|
||||
});
|
||||
Vendored
+107
@@ -131874,6 +131874,109 @@ class KonaDistribution extends JavaBase {
|
||||
}
|
||||
}
|
||||
|
||||
;// CONCATENATED MODULE: ./src/distributions/openjdk/installer.ts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const OPENJDK_BASE_URL = 'https://jdk.java.net';
|
||||
class OpenJdkDistribution extends JavaBase {
|
||||
constructor(installerOptions) {
|
||||
super('OpenJDK', installerOptions);
|
||||
}
|
||||
async findPackageForDownload(range) {
|
||||
if (this.packageType !== 'jdk') {
|
||||
throw new Error('OpenJDK provides only the `jdk` package type');
|
||||
}
|
||||
const arch = this.distributionArchitecture();
|
||||
if (!['x64', 'aarch64'].includes(arch)) {
|
||||
throw new Error(`Unsupported architecture: ${this.architecture}`);
|
||||
}
|
||||
const platform = this.getPlatform();
|
||||
const releases = await this.getAvailableVersions(platform, arch);
|
||||
const matchingReleases = releases
|
||||
.filter(release => isVersionSatisfies(range, release.version))
|
||||
.sort((left, right) => -semver_default().compareBuild(left.version, right.version));
|
||||
if (!matchingReleases.length) {
|
||||
throw this.createVersionNotFoundError(range, releases.map(release => release.version), `Platform: ${platform}`);
|
||||
}
|
||||
return matchingReleases[0];
|
||||
}
|
||||
async downloadTool(javaRelease) {
|
||||
info(`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`);
|
||||
let javaArchivePath = await downloadTool(javaRelease.url);
|
||||
info(`Extracting Java archive...`);
|
||||
const extension = javaRelease.url.endsWith('.zip') ? 'zip' : 'tar.gz';
|
||||
if (extension === 'zip') {
|
||||
javaArchivePath = renameWinArchive(javaArchivePath);
|
||||
}
|
||||
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
|
||||
const archiveName = external_fs_default().readdirSync(extractedJavaPath)[0];
|
||||
const archivePath = external_path_default().join(extractedJavaPath, archiveName);
|
||||
const javaPath = await cacheDir(archivePath, this.toolcacheFolderName, this.getToolcacheVersionName(javaRelease.version), this.architecture);
|
||||
return { version: javaRelease.version, path: javaPath };
|
||||
}
|
||||
async getAvailableVersions(platform, arch) {
|
||||
const homePage = await this.fetchPage(`${OPENJDK_BASE_URL}/`);
|
||||
const releasePageUrls = Array.from(homePage.matchAll(/href="\/(\d+)\/">JDK\s+\d+/g), match => `${OPENJDK_BASE_URL}/${match[1]}/`);
|
||||
const pages = await Promise.all(releasePageUrls.map(url => this.fetchPage(url)));
|
||||
if (this.stable) {
|
||||
pages.push(await this.fetchPage(`${OPENJDK_BASE_URL}/archive/`));
|
||||
}
|
||||
const releases = pages.flatMap(page => this.parseReleases(page, platform, arch));
|
||||
return releases.filter(release => release.url.includes('/early_access/') !== this.stable);
|
||||
}
|
||||
async fetchPage(url) {
|
||||
const response = await this.http.get(url);
|
||||
return response.readBody();
|
||||
}
|
||||
parseReleases(html, platform, arch) {
|
||||
const platformPattern = platform === 'macos' ? '(?:macos|osx)' : platform;
|
||||
const extensionPattern = platform === 'windows' ? '(?:zip|tar\\.gz)' : 'tar\\.gz';
|
||||
const pattern = new RegExp(`href="(https://download\\.java\\.net/[^"]+/openjdk-([^"_]+)_${platformPattern}-${arch}_bin\\.${extensionPattern})"`, 'g');
|
||||
return Array.from(html.matchAll(pattern), match => {
|
||||
const url = match[1];
|
||||
const build = url.match(/\/(\d+)\/(?:GPL\/)?openjdk-/)?.[1] ??
|
||||
this.findBuildInArchiveHeading(html, match.index, match[2]);
|
||||
return {
|
||||
version: this.toSemver(match[2], build),
|
||||
url
|
||||
};
|
||||
});
|
||||
}
|
||||
findBuildInArchiveHeading(html, assetIndex, version) {
|
||||
const headings = Array.from(html.slice(0, assetIndex).matchAll(/\(build\s+([^)]+)\)/g));
|
||||
const headingVersion = headings.at(-1)?.[1];
|
||||
if (!headingVersion) {
|
||||
return undefined;
|
||||
}
|
||||
const [javaVersion, build] = headingVersion.split('+');
|
||||
return javaVersion === version ? build : undefined;
|
||||
}
|
||||
toSemver(version, urlBuild) {
|
||||
const [javaVersion, filenameBuild] = version.replace('-ea', '').split('+');
|
||||
const versionParts = javaVersion.split('.');
|
||||
const normalizedVersion = convertVersionToSemver(versionParts.length === 1 ? `${javaVersion}.0.0` : javaVersion);
|
||||
const build = filenameBuild ?? (versionParts.length <= 3 ? urlBuild : undefined);
|
||||
return build ? `${normalizedVersion}+${build}` : normalizedVersion;
|
||||
}
|
||||
getPlatform(platform = process.platform) {
|
||||
switch (platform) {
|
||||
case 'darwin':
|
||||
return 'macos';
|
||||
case 'linux':
|
||||
return 'linux';
|
||||
case 'win32':
|
||||
return 'windows';
|
||||
default:
|
||||
throw new Error(`Platform '${platform}' is not supported. Supported platforms: 'linux', 'macos', 'windows'`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
;// CONCATENATED MODULE: ./src/distributions/distribution-factory.ts
|
||||
|
||||
|
||||
@@ -131890,6 +131993,7 @@ class KonaDistribution extends JavaBase {
|
||||
|
||||
|
||||
|
||||
|
||||
var JavaDistribution;
|
||||
(function (JavaDistribution) {
|
||||
JavaDistribution["Adopt"] = "adopt";
|
||||
@@ -131910,6 +132014,7 @@ var JavaDistribution;
|
||||
JavaDistribution["GraalVMCommunity"] = "graalvm-community";
|
||||
JavaDistribution["JetBrains"] = "jetbrains";
|
||||
JavaDistribution["Kona"] = "kona";
|
||||
JavaDistribution["OpenJdk"] = "openjdk";
|
||||
})(JavaDistribution || (JavaDistribution = {}));
|
||||
function getJavaDistribution(distributionName, installerOptions, jdkFile) {
|
||||
switch (distributionName) {
|
||||
@@ -131948,6 +132053,8 @@ function getJavaDistribution(distributionName, installerOptions, jdkFile) {
|
||||
return new JetBrainsDistribution(installerOptions);
|
||||
case JavaDistribution.Kona:
|
||||
return new KonaDistribution(installerOptions);
|
||||
case JavaDistribution.OpenJdk:
|
||||
return new OpenJdkDistribution(installerOptions);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
} from './graalvm/installer.js';
|
||||
import {JetBrainsDistribution} from './jetbrains/installer.js';
|
||||
import {KonaDistribution} from './kona/installer.js';
|
||||
import {OpenJdkDistribution} from './openjdk/installer.js';
|
||||
|
||||
enum JavaDistribution {
|
||||
Adopt = 'adopt',
|
||||
@@ -40,7 +41,8 @@ enum JavaDistribution {
|
||||
GraalVM = 'graalvm',
|
||||
GraalVMCommunity = 'graalvm-community',
|
||||
JetBrains = 'jetbrains',
|
||||
Kona = 'kona'
|
||||
Kona = 'kona',
|
||||
OpenJdk = 'openjdk'
|
||||
}
|
||||
|
||||
export function getJavaDistribution(
|
||||
@@ -93,6 +95,8 @@ export function getJavaDistribution(
|
||||
return new JetBrainsDistribution(installerOptions);
|
||||
case JavaDistribution.Kona:
|
||||
return new KonaDistribution(installerOptions);
|
||||
case JavaDistribution.OpenJdk:
|
||||
return new OpenJdkDistribution(installerOptions);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as tc from '@actions/tool-cache';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import semver from 'semver';
|
||||
|
||||
import {JavaBase} from '../base-installer.js';
|
||||
import {
|
||||
JavaDownloadRelease,
|
||||
JavaInstallerOptions,
|
||||
JavaInstallerResults
|
||||
} from '../base-models.js';
|
||||
import {
|
||||
convertVersionToSemver,
|
||||
extractJdkFile,
|
||||
isVersionSatisfies,
|
||||
renameWinArchive
|
||||
} from '../../util.js';
|
||||
|
||||
const OPENJDK_BASE_URL = 'https://jdk.java.net';
|
||||
|
||||
export class OpenJdkDistribution extends JavaBase {
|
||||
constructor(installerOptions: JavaInstallerOptions) {
|
||||
super('OpenJDK', installerOptions);
|
||||
}
|
||||
|
||||
protected async findPackageForDownload(
|
||||
range: string
|
||||
): Promise<JavaDownloadRelease> {
|
||||
if (this.packageType !== 'jdk') {
|
||||
throw new Error('OpenJDK provides only the `jdk` package type');
|
||||
}
|
||||
|
||||
const arch = this.distributionArchitecture();
|
||||
if (!['x64', 'aarch64'].includes(arch)) {
|
||||
throw new Error(`Unsupported architecture: ${this.architecture}`);
|
||||
}
|
||||
|
||||
const platform = this.getPlatform();
|
||||
const releases = await this.getAvailableVersions(platform, arch);
|
||||
const matchingReleases = releases
|
||||
.filter(release => isVersionSatisfies(range, release.version))
|
||||
.sort((left, right) => -semver.compareBuild(left.version, right.version));
|
||||
|
||||
if (!matchingReleases.length) {
|
||||
throw this.createVersionNotFoundError(
|
||||
range,
|
||||
releases.map(release => release.version),
|
||||
`Platform: ${platform}`
|
||||
);
|
||||
}
|
||||
|
||||
return matchingReleases[0];
|
||||
}
|
||||
|
||||
protected async downloadTool(
|
||||
javaRelease: JavaDownloadRelease
|
||||
): Promise<JavaInstallerResults> {
|
||||
core.info(
|
||||
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
|
||||
);
|
||||
let javaArchivePath = await tc.downloadTool(javaRelease.url);
|
||||
|
||||
core.info(`Extracting Java archive...`);
|
||||
const extension = javaRelease.url.endsWith('.zip') ? 'zip' : 'tar.gz';
|
||||
if (extension === 'zip') {
|
||||
javaArchivePath = renameWinArchive(javaArchivePath);
|
||||
}
|
||||
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
|
||||
|
||||
const archiveName = fs.readdirSync(extractedJavaPath)[0];
|
||||
const archivePath = path.join(extractedJavaPath, archiveName);
|
||||
const javaPath = await tc.cacheDir(
|
||||
archivePath,
|
||||
this.toolcacheFolderName,
|
||||
this.getToolcacheVersionName(javaRelease.version),
|
||||
this.architecture
|
||||
);
|
||||
|
||||
return {version: javaRelease.version, path: javaPath};
|
||||
}
|
||||
|
||||
private async getAvailableVersions(
|
||||
platform: string,
|
||||
arch: string
|
||||
): Promise<JavaDownloadRelease[]> {
|
||||
const homePage = await this.fetchPage(`${OPENJDK_BASE_URL}/`);
|
||||
const releasePageUrls = Array.from(
|
||||
homePage.matchAll(/href="\/(\d+)\/">JDK\s+\d+/g),
|
||||
match => `${OPENJDK_BASE_URL}/${match[1]}/`
|
||||
);
|
||||
|
||||
const pages = await Promise.all(
|
||||
releasePageUrls.map(url => this.fetchPage(url))
|
||||
);
|
||||
if (this.stable) {
|
||||
pages.push(await this.fetchPage(`${OPENJDK_BASE_URL}/archive/`));
|
||||
}
|
||||
|
||||
const releases = pages.flatMap(page =>
|
||||
this.parseReleases(page, platform, arch)
|
||||
);
|
||||
|
||||
return releases.filter(
|
||||
release => release.url.includes('/early_access/') !== this.stable
|
||||
);
|
||||
}
|
||||
|
||||
private async fetchPage(url: string): Promise<string> {
|
||||
const response = await this.http.get(url);
|
||||
return response.readBody();
|
||||
}
|
||||
|
||||
private parseReleases(
|
||||
html: string,
|
||||
platform: string,
|
||||
arch: string
|
||||
): JavaDownloadRelease[] {
|
||||
const platformPattern = platform === 'macos' ? '(?:macos|osx)' : platform;
|
||||
const extensionPattern =
|
||||
platform === 'windows' ? '(?:zip|tar\\.gz)' : 'tar\\.gz';
|
||||
const pattern = new RegExp(
|
||||
`href="(https://download\\.java\\.net/[^"]+/openjdk-([^"_]+)_${platformPattern}-${arch}_bin\\.${extensionPattern})"`,
|
||||
'g'
|
||||
);
|
||||
|
||||
return Array.from(html.matchAll(pattern), match => {
|
||||
const url = match[1];
|
||||
const build =
|
||||
url.match(/\/(\d+)\/(?:GPL\/)?openjdk-/)?.[1] ??
|
||||
this.findBuildInArchiveHeading(html, match.index, match[2]);
|
||||
return {
|
||||
version: this.toSemver(match[2], build),
|
||||
url
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private findBuildInArchiveHeading(
|
||||
html: string,
|
||||
assetIndex: number,
|
||||
version: string
|
||||
): string | undefined {
|
||||
const headings = Array.from(
|
||||
html.slice(0, assetIndex).matchAll(/\(build\s+([^)]+)\)/g)
|
||||
);
|
||||
const headingVersion = headings.at(-1)?.[1];
|
||||
if (!headingVersion) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const [javaVersion, build] = headingVersion.split('+');
|
||||
return javaVersion === version ? build : undefined;
|
||||
}
|
||||
|
||||
private toSemver(version: string, urlBuild?: string): string {
|
||||
const [javaVersion, filenameBuild] = version.replace('-ea', '').split('+');
|
||||
const versionParts = javaVersion.split('.');
|
||||
const normalizedVersion = convertVersionToSemver(
|
||||
versionParts.length === 1 ? `${javaVersion}.0.0` : javaVersion
|
||||
);
|
||||
const build =
|
||||
filenameBuild ?? (versionParts.length <= 3 ? urlBuild : undefined);
|
||||
return build ? `${normalizedVersion}+${build}` : normalizedVersion;
|
||||
}
|
||||
|
||||
private getPlatform(platform: NodeJS.Platform = process.platform): string {
|
||||
switch (platform) {
|
||||
case 'darwin':
|
||||
return 'macos';
|
||||
case 'linux':
|
||||
return 'linux';
|
||||
case 'win32':
|
||||
return 'windows';
|
||||
default:
|
||||
throw new Error(
|
||||
`Platform '${platform}' is not supported. Supported platforms: 'linux', 'macos', 'windows'`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user