Add and configure ESLint and update configuration for Prettier (#458)

* Add ESLint config and update Prettier

* Update test files

* Rebuild action

* Update docs

* Update licenses

* Update tsconfig

* Rebuild action

* Update tsconfig.json

* Fix console.time calls

* Rebuild action

* Rebuild action on Linux
This commit is contained in:
Ivan 2023-03-09 14:49:35 +02:00 committed by GitHub
parent ea15b3b99c
commit 0de5c66fc0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 4376 additions and 1317 deletions

6
.eslintignore Normal file
View file

@ -0,0 +1,6 @@
# Ignore list
/*
# Do not ignore these folders:
!__tests__/
!src/

49
.eslintrc.js Normal file
View file

@ -0,0 +1,49 @@
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:eslint-plugin-jest/recommended',
'eslint-config-prettier'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'eslint-plugin-jest'],
rules: {
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/ban-ts-comment': [
'error',
{
'ts-ignore': 'allow-with-description'
}
],
'no-console': 'error',
'yoda': 'error',
'prefer-const': [
'error',
{
destructuring: 'all'
}
],
'no-control-regex': 'off',
'no-constant-condition': ['error', {checkLoops: false}]
},
overrides: [
{
files: ['**/*{test,spec}.ts'],
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'jest/no-standalone-expect': 'off',
'jest/no-conditional-expect': 'off',
'no-console': 'off',
}
}
],
env: {
node: true,
es6: true,
'jest/globals': true
}
};

1
.gitattributes vendored
View file

@ -1,3 +1,4 @@
* text=auto eol=lf
dist/index.js -diff -merge dist/index.js -diff -merge
dist/index.js linguist-generated=true dist/index.js linguist-generated=true
.licenses/** -diff linguist-generated=true .licenses/** -diff linguist-generated=true

View file

@ -2,9 +2,9 @@ name: CodeQL analysis
on: on:
push: push:
branches: [ main ] branches: [main]
pull_request: pull_request:
branches: [ main ] branches: [main]
schedule: schedule:
- cron: '0 3 * * 0' - cron: '0 3 * * 0'

View file

@ -151,7 +151,6 @@ jobs:
exit 1 exit 1
fi fi
- name: Check files to cache on ubuntu-latest - name: Check files to cache on ubuntu-latest
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
run: | run: |

View file

@ -21,7 +21,15 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [macos-latest, windows-latest, ubuntu-latest] os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['temurin', 'adopt', 'adopt-openj9', 'zulu', 'liberica', 'microsoft', 'corretto' ] # internally 'adopt-hotspot' is the same as 'adopt' distribution: [
'temurin',
'adopt',
'adopt-openj9',
'zulu',
'liberica',
'microsoft',
'corretto'
] # internally 'adopt-hotspot' is the same as 'adopt'
version: ['8', '11', '16'] version: ['8', '11', '16']
exclude: exclude:
- distribution: microsoft - distribution: microsoft
@ -262,7 +270,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [macos-latest, windows-latest, ubuntu-latest] os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['temurin', 'microsoft', 'corretto' ] distribution: ['temurin', 'microsoft', 'corretto']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -287,7 +295,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [macos-latest, windows-latest, ubuntu-latest] os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['temurin', 'zulu', 'liberica', 'microsoft', 'corretto' ] distribution: ['temurin', 'zulu', 'liberica', 'microsoft', 'corretto']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -311,7 +319,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [macos-latest, windows-latest, ubuntu-latest] os: [macos-latest, windows-latest, ubuntu-latest]
distribution: [ 'adopt', 'adopt-openj9', 'zulu' ] distribution: ['adopt', 'adopt-openj9', 'zulu']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -335,7 +343,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [macos-latest, windows-latest, ubuntu-latest] os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['adopt', 'zulu', 'liberica' ] distribution: ['adopt', 'zulu', 'liberica']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3

BIN
.licenses/npm/semver-7.3.8.dep.yml generated Normal file

Binary file not shown.

7
.prettierignore Normal file
View file

@ -0,0 +1,7 @@
# Ignore list
/*
# Do not ignore these folders:
!__tests__/
!.github/
!src/

10
.prettierrc.js Normal file
View file

@ -0,0 +1,10 @@
module.exports = {
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: true,
singleQuote: true,
trailingComma: 'none',
bracketSpacing: false,
arrowParens: 'avoid'
};

View file

@ -1,11 +0,0 @@
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": true,
"arrowParens": "avoid",
"parser": "typescript"
}

View file

@ -1,11 +1,11 @@
import io = require('@actions/io'); import * as io from '@actions/io';
import fs = require('fs');
import path = require('path');
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as fs from 'fs';
import * as path from 'path';
import os from 'os'; import os from 'os';
import * as auth from '../src/auth'; import * as auth from '../src/auth';
import { M2_DIR, MVN_SETTINGS_FILE } from '../src/constants'; import {M2_DIR, MVN_SETTINGS_FILE} from '../src/constants';
const m2Dir = path.join(__dirname, M2_DIR); const m2Dir = path.join(__dirname, M2_DIR);
const settingsFile = path.join(m2Dir, MVN_SETTINGS_FILE); const settingsFile = path.join(m2Dir, MVN_SETTINGS_FILE);
@ -42,7 +42,13 @@ describe('auth tests', () => {
const altSettingsFile = path.join(altHome, MVN_SETTINGS_FILE); const altSettingsFile = path.join(altHome, MVN_SETTINGS_FILE);
await io.rmRF(altHome); // ensure it doesn't already exist await io.rmRF(altHome); // ensure it doesn't already exist
await auth.createAuthenticationSettings(id, username, password, altHome, true); await auth.createAuthenticationSettings(
id,
username,
password,
altHome,
true
);
expect(fs.existsSync(m2Dir)).toBe(false); expect(fs.existsSync(m2Dir)).toBe(false);
expect(fs.existsSync(settingsFile)).toBe(false); expect(fs.existsSync(settingsFile)).toBe(false);
@ -61,11 +67,19 @@ describe('auth tests', () => {
const username = 'UNAME'; const username = 'UNAME';
const password = 'TOKEN'; const password = 'TOKEN';
await auth.createAuthenticationSettings(id, username, password, m2Dir, true); await auth.createAuthenticationSettings(
id,
username,
password,
m2Dir,
true
);
expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(auth.generate(id, username, password)); expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
auth.generate(id, username, password)
);
}, 100000); }, 100000);
it('creates settings.xml with additional configuration', async () => { it('creates settings.xml with additional configuration', async () => {
@ -74,7 +88,14 @@ describe('auth tests', () => {
const password = 'TOKEN'; const password = 'TOKEN';
const gpgPassphrase = 'GPG'; const gpgPassphrase = 'GPG';
await auth.createAuthenticationSettings(id, username, password, m2Dir, true, gpgPassphrase); await auth.createAuthenticationSettings(
id,
username,
password,
m2Dir,
true,
gpgPassphrase
);
expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true);
@ -88,16 +109,24 @@ describe('auth tests', () => {
const username = 'USERNAME'; const username = 'USERNAME';
const password = 'PASSWORD'; const password = 'PASSWORD';
fs.mkdirSync(m2Dir, { recursive: true }); fs.mkdirSync(m2Dir, {recursive: true});
fs.writeFileSync(settingsFile, 'FAKE FILE'); fs.writeFileSync(settingsFile, 'FAKE FILE');
expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true);
await auth.createAuthenticationSettings(id, username, password, m2Dir, true); await auth.createAuthenticationSettings(
id,
username,
password,
m2Dir,
true
);
expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(auth.generate(id, username, password)); expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
auth.generate(id, username, password)
);
}, 100000); }, 100000);
it('does not overwrite existing settings.xml files', async () => { it('does not overwrite existing settings.xml files', async () => {
@ -105,12 +134,18 @@ describe('auth tests', () => {
const username = 'USERNAME'; const username = 'USERNAME';
const password = 'PASSWORD'; const password = 'PASSWORD';
fs.mkdirSync(m2Dir, { recursive: true }); fs.mkdirSync(m2Dir, {recursive: true});
fs.writeFileSync(settingsFile, 'FAKE FILE'); fs.writeFileSync(settingsFile, 'FAKE FILE');
expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true);
await auth.createAuthenticationSettings(id, username, password, m2Dir, false); await auth.createAuthenticationSettings(
id,
username,
password,
m2Dir,
false
);
expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true);
@ -159,6 +194,8 @@ describe('auth tests', () => {
</servers> </servers>
</settings>`; </settings>`;
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(expectedSettings); expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(
expectedSettings
);
}); });
}); });

View file

@ -1,7 +1,7 @@
import { mkdtempSync } from 'fs'; import {mkdtempSync} from 'fs';
import { tmpdir } from 'os'; import {tmpdir} from 'os';
import { join } from 'path'; import {join} from 'path';
import { restore, save } from '../src/cache'; import {restore, save} from '../src/cache';
import * as fs from 'fs'; import * as fs from 'fs';
import * as os from 'os'; import * as os from 'os';
import * as core from '@actions/core'; import * as core from '@actions/core';
@ -68,17 +68,21 @@ describe('dependency cache', () => {
beforeEach(() => { beforeEach(() => {
spyCacheRestore = jest spyCacheRestore = jest
.spyOn(cache, 'restoreCache') .spyOn(cache, 'restoreCache')
.mockImplementation((paths: string[], primaryKey: string) => Promise.resolve(undefined)); .mockImplementation((paths: string[], primaryKey: string) =>
Promise.resolve(undefined)
);
spyWarning.mockImplementation(() => null); spyWarning.mockImplementation(() => null);
}); });
it('throws error if unsupported package manager specified', () => { it('throws error if unsupported package manager specified', () => {
return expect(restore('ant')).rejects.toThrowError('unknown package manager specified: ant'); return expect(restore('ant')).rejects.toThrow(
'unknown package manager specified: ant'
);
}); });
describe('for maven', () => { describe('for maven', () => {
it('throws error if no pom.xml found', async () => { it('throws error if no pom.xml found', async () => {
await expect(restore('maven')).rejects.toThrowError( await expect(restore('maven')).rejects.toThrow(
`No file in ${projectRoot( `No file in ${projectRoot(
workspace workspace
)} matched to [**/pom.xml], make sure you have checked out the target repository` )} matched to [**/pom.xml], make sure you have checked out the target repository`
@ -88,14 +92,14 @@ describe('dependency cache', () => {
createFile(join(workspace, 'pom.xml')); createFile(join(workspace, 'pom.xml'));
await restore('maven'); await restore('maven');
expect(spyCacheRestore).toBeCalled(); expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith('maven cache is not found'); expect(spyInfo).toHaveBeenCalledWith('maven cache is not found');
}); });
}); });
describe('for gradle', () => { describe('for gradle', () => {
it('throws error if no build.gradle found', async () => { it('throws error if no build.gradle found', async () => {
await expect(restore('gradle')).rejects.toThrowError( await expect(restore('gradle')).rejects.toThrow(
`No file in ${projectRoot( `No file in ${projectRoot(
workspace workspace
)} matched to [**/*.gradle*,**/gradle-wrapper.properties,buildSrc/**/Versions.kt,buildSrc/**/Dependencies.kt,gradle/*.versions.toml], make sure you have checked out the target repository` )} matched to [**/*.gradle*,**/gradle-wrapper.properties,buildSrc/**/Versions.kt,buildSrc/**/Dependencies.kt,gradle/*.versions.toml], make sure you have checked out the target repository`
@ -105,26 +109,26 @@ describe('dependency cache', () => {
createFile(join(workspace, 'build.gradle')); createFile(join(workspace, 'build.gradle'));
await restore('gradle'); await restore('gradle');
expect(spyCacheRestore).toBeCalled(); expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith('gradle cache is not found'); expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found');
}); });
it('downloads cache based on build.gradle.kts', async () => { it('downloads cache based on build.gradle.kts', async () => {
createFile(join(workspace, 'build.gradle.kts')); createFile(join(workspace, 'build.gradle.kts'));
await restore('gradle'); await restore('gradle');
expect(spyCacheRestore).toBeCalled(); expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith('gradle cache is not found'); expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found');
}); });
it('downloads cache based on libs.versions.toml', async () => { it('downloads cache based on libs.versions.toml', async () => {
createDirectory(join(workspace, 'gradle')); createDirectory(join(workspace, 'gradle'));
createFile(join(workspace, 'gradle', 'libs.versions.toml')); createFile(join(workspace, 'gradle', 'libs.versions.toml'));
await restore('gradle'); await restore('gradle');
expect(spyCacheRestore).toBeCalled(); expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith('gradle cache is not found'); expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found');
}); });
}); });
it('downloads cache based on buildSrc/Versions.kt', async () => { it('downloads cache based on buildSrc/Versions.kt', async () => {
@ -132,13 +136,13 @@ describe('dependency cache', () => {
createFile(join(workspace, 'buildSrc', 'Versions.kt')); createFile(join(workspace, 'buildSrc', 'Versions.kt'));
await restore('gradle'); await restore('gradle');
expect(spyCacheRestore).toBeCalled(); expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith('gradle cache is not found'); expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found');
}); });
describe('for sbt', () => { describe('for sbt', () => {
it('throws error if no build.sbt found', async () => { it('throws error if no build.sbt found', async () => {
await expect(restore('sbt')).rejects.toThrowError( await expect(restore('sbt')).rejects.toThrow(
`No file in ${projectRoot( `No file in ${projectRoot(
workspace workspace
)} matched to [**/*.sbt,**/project/build.properties,**/project/**.{scala,sbt}], make sure you have checked out the target repository` )} matched to [**/*.sbt,**/project/build.properties,**/project/**.{scala,sbt}], make sure you have checked out the target repository`
@ -148,9 +152,9 @@ describe('dependency cache', () => {
createFile(join(workspace, 'build.sbt')); createFile(join(workspace, 'build.sbt'));
await restore('sbt'); await restore('sbt');
expect(spyCacheRestore).toBeCalled(); expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith('sbt cache is not found'); expect(spyInfo).toHaveBeenCalledWith('sbt cache is not found');
}); });
}); });
}); });
@ -163,12 +167,16 @@ describe('dependency cache', () => {
beforeEach(() => { beforeEach(() => {
spyCacheSave = jest spyCacheSave = jest
.spyOn(cache, 'saveCache') .spyOn(cache, 'saveCache')
.mockImplementation((paths: string[], key: string) => Promise.resolve(0)); .mockImplementation((paths: string[], key: string) =>
Promise.resolve(0)
);
spyWarning.mockImplementation(() => null); spyWarning.mockImplementation(() => null);
}); });
it('throws error if unsupported package manager specified', () => { it('throws error if unsupported package manager specified', () => {
return expect(save('ant')).rejects.toThrowError('unknown package manager specified: ant'); return expect(save('ant')).rejects.toThrow(
'unknown package manager specified: ant'
);
}); });
it('save with -1 cacheId , should not fail workflow', async () => { it('save with -1 cacheId , should not fail workflow', async () => {
@ -176,10 +184,12 @@ describe('dependency cache', () => {
createStateForMissingBuildFile(); createStateForMissingBuildFile();
await save('maven'); await save('maven');
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalled(); expect(spyInfo).toHaveBeenCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
}); });
it('saves with error from toolkit, should fail workflow', async () => { it('saves with error from toolkit, should fail workflow', async () => {
@ -189,31 +199,37 @@ describe('dependency cache', () => {
createStateForMissingBuildFile(); createStateForMissingBuildFile();
expect.assertions(1); expect.assertions(1);
await expect(save('maven')).rejects.toEqual(new cache.ValidationError('Validation failed')); await expect(save('maven')).rejects.toEqual(
new cache.ValidationError('Validation failed')
);
}); });
describe('for maven', () => { describe('for maven', () => {
it('uploads cache even if no pom.xml found', async () => { it('uploads cache even if no pom.xml found', async () => {
createStateForMissingBuildFile(); createStateForMissingBuildFile();
await save('maven'); await save('maven');
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
}); });
it('does not upload cache if no restore run before', async () => { it('does not upload cache if no restore run before', async () => {
createFile(join(workspace, 'pom.xml')); createFile(join(workspace, 'pom.xml'));
await save('maven'); await save('maven');
expect(spyCacheSave).not.toBeCalled(); expect(spyCacheSave).not.toHaveBeenCalled();
expect(spyWarning).toBeCalledWith('Error retrieving key from state.'); expect(spyWarning).toHaveBeenCalledWith(
'Error retrieving key from state.'
);
}); });
it('uploads cache', async () => { it('uploads cache', async () => {
createFile(join(workspace, 'pom.xml')); createFile(join(workspace, 'pom.xml'));
createStateForSuccessfulRestore(); createStateForSuccessfulRestore();
await save('maven'); await save('maven');
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
}); });
}); });
describe('for gradle', () => { describe('for gradle', () => {
@ -221,33 +237,39 @@ describe('dependency cache', () => {
createStateForMissingBuildFile(); createStateForMissingBuildFile();
await save('gradle'); await save('gradle');
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
}); });
it('does not upload cache if no restore run before', async () => { it('does not upload cache if no restore run before', async () => {
createFile(join(workspace, 'build.gradle')); createFile(join(workspace, 'build.gradle'));
await save('gradle'); await save('gradle');
expect(spyCacheSave).not.toBeCalled(); expect(spyCacheSave).not.toHaveBeenCalled();
expect(spyWarning).toBeCalledWith('Error retrieving key from state.'); expect(spyWarning).toHaveBeenCalledWith(
'Error retrieving key from state.'
);
}); });
it('uploads cache based on build.gradle', async () => { it('uploads cache based on build.gradle', async () => {
createFile(join(workspace, 'build.gradle')); createFile(join(workspace, 'build.gradle'));
createStateForSuccessfulRestore(); createStateForSuccessfulRestore();
await save('gradle'); await save('gradle');
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
}); });
it('uploads cache based on build.gradle.kts', async () => { it('uploads cache based on build.gradle.kts', async () => {
createFile(join(workspace, 'build.gradle.kts')); createFile(join(workspace, 'build.gradle.kts'));
createStateForSuccessfulRestore(); createStateForSuccessfulRestore();
await save('gradle'); await save('gradle');
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
}); });
it('uploads cache based on buildSrc/Versions.kt', async () => { it('uploads cache based on buildSrc/Versions.kt', async () => {
createDirectory(join(workspace, 'buildSrc')); createDirectory(join(workspace, 'buildSrc'));
@ -255,33 +277,39 @@ describe('dependency cache', () => {
createStateForSuccessfulRestore(); createStateForSuccessfulRestore();
await save('gradle'); await save('gradle');
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
}); });
}); });
describe('for sbt', () => { describe('for sbt', () => {
it('uploads cache even if no build.sbt found', async () => { it('uploads cache even if no build.sbt found', async () => {
createStateForMissingBuildFile(); createStateForMissingBuildFile();
await save('sbt'); await save('sbt');
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
}); });
it('does not upload cache if no restore run before', async () => { it('does not upload cache if no restore run before', async () => {
createFile(join(workspace, 'build.sbt')); createFile(join(workspace, 'build.sbt'));
await save('sbt'); await save('sbt');
expect(spyCacheSave).not.toBeCalled(); expect(spyCacheSave).not.toHaveBeenCalled();
expect(spyWarning).toBeCalledWith('Error retrieving key from state.'); expect(spyWarning).toHaveBeenCalledWith(
'Error retrieving key from state.'
);
}); });
it('uploads cache', async () => { it('uploads cache', async () => {
createFile(join(workspace, 'build.sbt')); createFile(join(workspace, 'build.sbt'));
createStateForSuccessfulRestore(); createStateForSuccessfulRestore();
await save('sbt'); await save('sbt');
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
}); });
}); });
}); });

View file

@ -1,4 +1,4 @@
import { run as cleanup } from '../src/cleanup-java'; import {run as cleanup} from '../src/cleanup-java';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as cache from '@actions/cache'; import * as cache from '@actions/cache';
import * as util from '../src/util'; import * as util from '../src/util';
@ -38,8 +38,8 @@ describe('cleanup', () => {
return name === 'cache' ? 'gradle' : ''; return name === 'cache' ? 'gradle' : '';
}); });
await cleanup(); await cleanup();
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toBeCalled(); expect(spyWarning).not.toHaveBeenCalled();
}); });
it('does not fail even though the save process throws error', async () => { it('does not fail even though the save process throws error', async () => {
@ -50,7 +50,7 @@ describe('cleanup', () => {
return name === 'cache' ? 'gradle' : ''; return name === 'cache' ? 'gradle' : '';
}); });
await cleanup(); await cleanup();
expect(spyCacheSave).toBeCalled(); expect(spyCacheSave).toHaveBeenCalled();
}); });
}); });

View file

@ -1,11 +1,14 @@
import { HttpClient } from '@actions/http-client'; import {HttpClient} from '@actions/http-client';
import {IAdoptAvailableVersions} from '../../src/distributions/adopt/models';
import { AdoptDistribution, AdoptImplementation } from '../../src/distributions/adopt/installer'; import {
import { JavaInstallerOptions } from '../../src/distributions/base-models'; AdoptDistribution,
AdoptImplementation
} from '../../src/distributions/adopt/installer';
import {JavaInstallerOptions} from '../../src/distributions/base-models';
import os from 'os'; import os from 'os';
let manifestData = require('../data/adopt.json') as []; import manifestData from '../data/adopt.json';
describe('getAvailableVersions', () => { describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance; let spyHttpClient: jest.SpyInstance;
@ -27,42 +30,82 @@ describe('getAvailableVersions', () => {
it.each([ it.each([
[ [
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot, AdoptImplementation.Hotspot,
'os=mac&architecture=x64&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0' 'os=mac&architecture=x64&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
], ],
[ [
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot, AdoptImplementation.Hotspot,
'os=mac&architecture=x86&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0' 'os=mac&architecture=x86&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
], ],
[ [
{ version: '11', architecture: 'x64', packageType: 'jre', checkLatest: false }, {
version: '11',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
AdoptImplementation.Hotspot, AdoptImplementation.Hotspot,
'os=mac&architecture=x64&image_type=jre&release_type=ga&jvm_impl=hotspot&page_size=20&page=0' 'os=mac&architecture=x64&image_type=jre&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
], ],
[ [
{ version: '11-ea', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11-ea',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot, AdoptImplementation.Hotspot,
'os=mac&architecture=x64&image_type=jdk&release_type=ea&jvm_impl=hotspot&page_size=20&page=0' 'os=mac&architecture=x64&image_type=jdk&release_type=ea&jvm_impl=hotspot&page_size=20&page=0'
], ],
[ [
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.OpenJ9, AdoptImplementation.OpenJ9,
'os=mac&architecture=x64&image_type=jdk&release_type=ga&jvm_impl=openj9&page_size=20&page=0' 'os=mac&architecture=x64&image_type=jdk&release_type=ga&jvm_impl=openj9&page_size=20&page=0'
], ],
[ [
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.OpenJ9, AdoptImplementation.OpenJ9,
'os=mac&architecture=x86&image_type=jdk&release_type=ga&jvm_impl=openj9&page_size=20&page=0' 'os=mac&architecture=x86&image_type=jdk&release_type=ga&jvm_impl=openj9&page_size=20&page=0'
], ],
[ [
{ version: '11', architecture: 'x64', packageType: 'jre', checkLatest: false }, {
version: '11',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
AdoptImplementation.OpenJ9, AdoptImplementation.OpenJ9,
'os=mac&architecture=x64&image_type=jre&release_type=ga&jvm_impl=openj9&page_size=20&page=0' 'os=mac&architecture=x64&image_type=jre&release_type=ga&jvm_impl=openj9&page_size=20&page=0'
], ],
[ [
{ version: '11-ea', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11-ea',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.OpenJ9, AdoptImplementation.OpenJ9,
'os=mac&architecture=x64&image_type=jdk&release_type=ea&jvm_impl=openj9&page_size=20&page=0' 'os=mac&architecture=x64&image_type=jdk&release_type=ea&jvm_impl=openj9&page_size=20&page=0'
] ]
@ -74,7 +117,8 @@ describe('getAvailableVersions', () => {
expectedParameters expectedParameters
) => { ) => {
const distribution = new AdoptDistribution(installerOptions, impl); const distribution = new AdoptDistribution(installerOptions, impl);
const baseUrl = 'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D'; const baseUrl =
'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D';
const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptopenjdk&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`; const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptopenjdk&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`;
distribution['getPlatformOption'] = () => 'mac'; distribution['getPlatformOption'] = () => 'mac';
@ -91,12 +135,12 @@ describe('getAvailableVersions', () => {
.mockReturnValueOnce({ .mockReturnValueOnce({
statusCode: 200, statusCode: 200,
headers: {}, headers: {},
result: manifestData result: manifestData as any
}) })
.mockReturnValueOnce({ .mockReturnValueOnce({
statusCode: 200, statusCode: 200,
headers: {}, headers: {},
result: manifestData result: manifestData as any
}) })
.mockReturnValueOnce({ .mockReturnValueOnce({
statusCode: 200, statusCode: 200,
@ -105,7 +149,12 @@ describe('getAvailableVersions', () => {
}); });
const distribution = new AdoptDistribution( const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot AdoptImplementation.Hotspot
); );
const availableVersions = await distribution['getAvailableVersions'](); const availableVersions = await distribution['getAvailableVersions']();
@ -122,7 +171,12 @@ describe('getAvailableVersions', () => {
'find right toolchain folder', 'find right toolchain folder',
(impl: AdoptImplementation, packageType: string, expected: string) => { (impl: AdoptImplementation, packageType: string, expected: string) => {
const distribution = new AdoptDistribution( const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: packageType, checkLatest: false }, {
version: '11',
architecture: 'x64',
packageType: packageType,
checkLatest: false
},
impl impl
); );
@ -148,8 +202,12 @@ describe('getAvailableVersions', () => {
const expectedParameters = `os=mac&architecture=${distroArch}&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0`; const expectedParameters = `os=mac&architecture=${distroArch}&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0`;
const distribution = new AdoptDistribution(installerOptions, AdoptImplementation.Hotspot); const distribution = new AdoptDistribution(
const baseUrl = 'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D'; installerOptions,
AdoptImplementation.Hotspot
);
const baseUrl =
'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D';
const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptopenjdk&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`; const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptopenjdk&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`;
distribution['getPlatformOption'] = () => 'mac'; distribution['getPlatformOption'] = () => 'mac';
@ -176,43 +234,63 @@ describe('findPackageForDownload', () => {
['15.0.1+9.1', '15.0.1+9.1'] ['15.0.1+9.1', '15.0.1+9.1']
])('version is resolved correctly %s -> %s', async (input, expected) => { ])('version is resolved correctly %s -> %s', async (input, expected) => {
const distribution = new AdoptDistribution( const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot AdoptImplementation.Hotspot
); );
distribution['getAvailableVersions'] = async () => manifestData; distribution['getAvailableVersions'] = async () => manifestData as any;
const resolvedVersion = await distribution['findPackageForDownload'](input); const resolvedVersion = await distribution['findPackageForDownload'](input);
expect(resolvedVersion.version).toBe(expected); expect(resolvedVersion.version).toBe(expected);
}); });
it('version is found but binaries list is empty', async () => { it('version is found but binaries list is empty', async () => {
const distribution = new AdoptDistribution( const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot AdoptImplementation.Hotspot
); );
distribution['getAvailableVersions'] = async () => manifestData; distribution['getAvailableVersions'] = async () => manifestData as any;
await expect(distribution['findPackageForDownload']('9.0.8')).rejects.toThrowError( await expect(
/Could not find satisfied version for SemVer */ distribution['findPackageForDownload']('9.0.8')
); ).rejects.toThrow(/Could not find satisfied version for SemVer */);
}); });
it('version is not found', async () => { it('version is not found', async () => {
const distribution = new AdoptDistribution( const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot AdoptImplementation.Hotspot
); );
distribution['getAvailableVersions'] = async () => manifestData; distribution['getAvailableVersions'] = async () => manifestData as any;
await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrowError( await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrow(
/Could not find satisfied version for SemVer */ /Could not find satisfied version for SemVer */
); );
}); });
it('version list is empty', async () => { it('version list is empty', async () => {
const distribution = new AdoptDistribution( const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot AdoptImplementation.Hotspot
); );
distribution['getAvailableVersions'] = async () => []; distribution['getAvailableVersions'] = async () => [];
await expect(distribution['findPackageForDownload']('11')).rejects.toThrowError( await expect(distribution['findPackageForDownload']('11')).rejects.toThrow(
/Could not find satisfied version for SemVer */ /Could not find satisfied version for SemVer */
); );
}); });

View file

@ -5,7 +5,7 @@ import * as util from '../../src/util';
import path from 'path'; import path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
import { JavaBase } from '../../src/distributions/base-installer'; import {JavaBase} from '../../src/distributions/base-installer';
import { import {
JavaDownloadRelease, JavaDownloadRelease,
JavaInstallerOptions, JavaInstallerOptions,
@ -19,14 +19,23 @@ class EmptyJavaBase extends JavaBase {
super('Empty', installerOptions); super('Empty', installerOptions);
} }
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> { protected async downloadTool(
javaRelease: JavaDownloadRelease
): Promise<JavaInstallerResults> {
return { return {
version: '11.0.9', version: '11.0.9',
path: path.join('toolcache', this.toolcacheFolderName, '11.0.9', this.architecture) path: path.join(
'toolcache',
this.toolcacheFolderName,
'11.0.9',
this.architecture
)
}; };
} }
protected async findPackageForDownload(range: string): Promise<JavaDownloadRelease> { protected async findPackageForDownload(
range: string
): Promise<JavaDownloadRelease> {
const availableVersion = '11.0.9'; const availableVersion = '11.0.9';
if (!semver.satisfies(availableVersion, range)) { if (!semver.satisfies(availableVersion, range)) {
throw new Error('Available version not found'); throw new Error('Available version not found');
@ -60,44 +69,111 @@ describe('findInToolcache', () => {
it.each([ it.each([
[ [
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
{ version: actualJavaVersion, path: javaPath } version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
{version: actualJavaVersion, path: javaPath}
], ],
[ [
{ version: '11.0', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
{ version: actualJavaVersion, path: javaPath } version: '11.0',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
{version: actualJavaVersion, path: javaPath}
], ],
[ [
{ version: '11.0.8', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
{ version: actualJavaVersion, path: javaPath } version: '11.0.8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
{version: actualJavaVersion, path: javaPath}
], ],
[ [
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: true }, {
{ version: actualJavaVersion, path: javaPath } version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: true
},
{version: actualJavaVersion, path: javaPath}
], ],
[ [
{ version: '11.0', architecture: 'x64', packageType: 'jdk', checkLatest: true }, {
{ version: actualJavaVersion, path: javaPath } version: '11.0',
architecture: 'x64',
packageType: 'jdk',
checkLatest: true
},
{version: actualJavaVersion, path: javaPath}
], ],
[ [
{ version: '11.0.8', architecture: 'x64', packageType: 'jdk', checkLatest: true }, {
{ version: actualJavaVersion, path: javaPath } version: '11.0.8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: true
},
{version: actualJavaVersion, path: javaPath}
], ],
[{ version: '11', architecture: 'x64', packageType: 'jre', checkLatest: false }, null], [
[{ version: '8', architecture: 'x64', packageType: 'jdk', checkLatest: false }, null], {
[{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false }, null], version: '11',
[{ version: '11', architecture: 'x86', packageType: 'jre', checkLatest: false }, null] architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
null
],
[
{
version: '8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
null
],
[
{
version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
null
],
[
{
version: '11',
architecture: 'x86',
packageType: 'jre',
checkLatest: false
},
null
]
])(`should find java for path %s -> %s`, (input, expected) => { ])(`should find java for path %s -> %s`, (input, expected) => {
spyTcFindAllVersions.mockReturnValue([actualJavaVersion]); spyTcFindAllVersions.mockReturnValue([actualJavaVersion]);
spyGetToolcachePath.mockImplementation( spyGetToolcachePath.mockImplementation(
(toolname: string, javaVersion: string, architecture: string) => { (toolname: string, javaVersion: string, architecture: string) => {
const semverVersion = new semver.Range(javaVersion); const semverVersion = new semver.Range(javaVersion);
if (path.basename(javaPath) !== architecture || !javaPath.includes(toolname)) { if (
path.basename(javaPath) !== architecture ||
!javaPath.includes(toolname)
) {
return ''; return '';
} }
return semver.satisfies(actualJavaVersion, semverVersion) ? javaPath : ''; return semver.satisfies(actualJavaVersion, semverVersion)
? javaPath
: '';
} }
); );
mockJavaBase = new EmptyJavaBase(input); mockJavaBase = new EmptyJavaBase(input);
@ -105,17 +181,22 @@ describe('findInToolcache', () => {
}); });
it.each([ it.each([
['11', { version: '11.0.3+2', versionInPath: '11.0.3-2' }], ['11', {version: '11.0.3+2', versionInPath: '11.0.3-2'}],
['11.0', { version: '11.0.3+2', versionInPath: '11.0.3-2' }], ['11.0', {version: '11.0.3+2', versionInPath: '11.0.3-2'}],
['11.0.1', { version: '11.0.1', versionInPath: '11.0.1' }], ['11.0.1', {version: '11.0.1', versionInPath: '11.0.1'}],
['11.0.3', { version: '11.0.3+2', versionInPath: '11.0.3-2' }], ['11.0.3', {version: '11.0.3+2', versionInPath: '11.0.3-2'}],
['15', { version: '15.0.2+4', versionInPath: '15.0.2-4' }], ['15', {version: '15.0.2+4', versionInPath: '15.0.2-4'}],
['x', { version: '15.0.2+4', versionInPath: '15.0.2-4' }], ['x', {version: '15.0.2+4', versionInPath: '15.0.2-4'}],
['x-ea', { version: '17.4.4', versionInPath: '17.4.4-ea' }], ['x-ea', {version: '17.4.4', versionInPath: '17.4.4-ea'}],
['11-ea', { version: '11.3.3+5.2.1231421', versionInPath: '11.3.3-ea.5.2.1231421' }], [
['11.2-ea', { version: '11.2.1', versionInPath: '11.2.1-ea' }], '11-ea',
['11.2.1-ea', { version: '11.2.1', versionInPath: '11.2.1-ea' }] {version: '11.3.3+5.2.1231421', versionInPath: '11.3.3-ea.5.2.1231421'}
])('should choose correct java from tool-cache for input %s', (input, expected) => { ],
['11.2-ea', {version: '11.2.1', versionInPath: '11.2.1-ea'}],
['11.2.1-ea', {version: '11.2.1', versionInPath: '11.2.1-ea'}]
])(
'should choose correct java from tool-cache for input %s',
(input, expected) => {
spyTcFindAllVersions.mockReturnValue([ spyTcFindAllVersions.mockReturnValue([
'17.4.4-ea', '17.4.4-ea',
'11.0.2', '11.0.2',
@ -143,14 +224,20 @@ describe('findInToolcache', () => {
version: expected.version, version: expected.version,
path: `/hostedtoolcache/Java_Empty_jdk/${expected.versionInPath}/x64` path: `/hostedtoolcache/Java_Empty_jdk/${expected.versionInPath}/x64`
}); });
}); }
);
}); });
describe('setupJava', () => { describe('setupJava', () => {
const actualJavaVersion = '11.0.9'; const actualJavaVersion = '11.0.9';
const installedJavaVersion = '11.0.8'; const installedJavaVersion = '11.0.8';
const javaPath = path.join('Java_Empty_jdk', installedJavaVersion, 'x86'); const javaPath = path.join('Java_Empty_jdk', installedJavaVersion, 'x86');
const javaPathInstalled = path.join('toolcache', 'Java_Empty_jdk', actualJavaVersion, 'x86'); const javaPathInstalled = path.join(
'toolcache',
'Java_Empty_jdk',
actualJavaVersion,
'x86'
);
let mockJavaBase: EmptyJavaBase; let mockJavaBase: EmptyJavaBase;
@ -168,11 +255,16 @@ describe('setupJava', () => {
(toolname: string, javaVersion: string, architecture: string) => { (toolname: string, javaVersion: string, architecture: string) => {
const semverVersion = new semver.Range(javaVersion); const semverVersion = new semver.Range(javaVersion);
if (path.basename(javaPath) !== architecture || !javaPath.includes(toolname)) { if (
path.basename(javaPath) !== architecture ||
!javaPath.includes(toolname)
) {
return ''; return '';
} }
return semver.satisfies(installedJavaVersion, semverVersion) ? javaPath : ''; return semver.satisfies(installedJavaVersion, semverVersion)
? javaPath
: '';
} }
); );
@ -206,27 +298,46 @@ describe('setupJava', () => {
it.each([ it.each([
[ [
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false }, {
{ version: installedJavaVersion, path: javaPath } version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
{version: installedJavaVersion, path: javaPath}
], ],
[ [
{ version: '11.0', architecture: 'x86', packageType: 'jdk', checkLatest: false }, {
{ version: installedJavaVersion, path: javaPath } version: '11.0',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
{version: installedJavaVersion, path: javaPath}
], ],
[ [
{ version: '11.0.8', architecture: 'x86', packageType: 'jdk', checkLatest: false }, {
{ version: installedJavaVersion, path: javaPath } version: '11.0.8',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
{version: installedJavaVersion, path: javaPath}
], ],
[ [
{ version: '11', architecture: '', packageType: 'jdk', checkLatest: false }, {version: '11', architecture: '', packageType: 'jdk', checkLatest: false},
{ version: installedJavaVersion, path: javaPath } {version: installedJavaVersion, path: javaPath}
] ]
])('should find java locally for %s', (input, expected) => { ])('should find java locally for %s', async (input, expected) => {
mockJavaBase = new EmptyJavaBase(input); mockJavaBase = new EmptyJavaBase(input);
expect(mockJavaBase.setupJava()).resolves.toEqual(expected); await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyGetToolcachePath).toHaveBeenCalled(); expect(spyGetToolcachePath).toHaveBeenCalled();
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved Java ${expected.version} from tool-cache`); expect(spyCoreInfo).toHaveBeenCalledWith(
expect(spyCoreInfo).toHaveBeenCalledWith(`Setting Java ${expected.version} as the default`); `Resolved Java ${expected.version} from tool-cache`
);
expect(spyCoreInfo).toHaveBeenCalledWith(
`Setting Java ${expected.version} as the default`
);
expect(spyCoreInfo).not.toHaveBeenCalledWith( expect(spyCoreInfo).not.toHaveBeenCalledWith(
'Trying to resolve the latest version from remote' 'Trying to resolve the latest version from remote'
); );
@ -235,20 +346,47 @@ describe('setupJava', () => {
it.each([ it.each([
[ [
{ version: '11', architecture: 'x86', packageType: 'jre', checkLatest: false }, {
{ path: path.join('toolcache', 'Java_Empty_jre', '11.0.9', 'x86'), version: '11.0.9' } version: '11',
architecture: 'x86',
packageType: 'jre',
checkLatest: false
},
{
path: path.join('toolcache', 'Java_Empty_jre', '11.0.9', 'x86'),
version: '11.0.9'
}
], ],
[ [
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
{ path: path.join('toolcache', 'Java_Empty_jdk', '11.0.9', 'x64'), version: '11.0.9' } version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
{
path: path.join('toolcache', 'Java_Empty_jdk', '11.0.9', 'x64'),
version: '11.0.9'
}
], ],
[ [
{ version: '11', architecture: 'x64', packageType: 'jre', checkLatest: false }, {
{ path: path.join('toolcache', 'Java_Empty_jre', '11.0.9', 'x64'), version: '11.0.9' } version: '11',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
{
path: path.join('toolcache', 'Java_Empty_jre', '11.0.9', 'x64'),
version: '11.0.9'
}
], ],
[ [
{ version: '11', architecture: '', packageType: 'jre', checkLatest: false }, {version: '11', architecture: '', packageType: 'jre', checkLatest: false},
{ path: path.join('toolcache', 'Java_Empty_jre', '11.0.9', 'x86'), version: '11.0.9' } {
path: path.join('toolcache', 'Java_Empty_jre', '11.0.9', 'x86'),
version: '11.0.9'
}
] ]
])('download java with configuration %s', async (input, expected) => { ])('download java with configuration %s', async (input, expected) => {
mockJavaBase = new EmptyJavaBase(input); mockJavaBase = new EmptyJavaBase(input);
@ -257,93 +395,176 @@ describe('setupJava', () => {
expect(spyCoreAddPath).toHaveBeenCalled(); expect(spyCoreAddPath).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalled(); expect(spyCoreExportVariable).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalledWith( expect(spyCoreExportVariable).toHaveBeenCalledWith(
`JAVA_HOME_${input.version}_${(input.architecture || 'x86').toLocaleUpperCase()}`, `JAVA_HOME_${input.version}_${(
input.architecture || 'x86'
).toLocaleUpperCase()}`,
expected.path expected.path
); );
expect(spyCoreSetOutput).toHaveBeenCalled(); expect(spyCoreSetOutput).toHaveBeenCalled();
expect(spyCoreInfo).toHaveBeenCalledWith('Trying to resolve the latest version from remote'); expect(spyCoreInfo).toHaveBeenCalledWith(
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved latest version as ${expected.version}`); 'Trying to resolve the latest version from remote'
);
expect(spyCoreInfo).toHaveBeenCalledWith(
`Resolved latest version as ${expected.version}`
);
expect(spyCoreInfo).toHaveBeenCalledWith('Trying to download...'); expect(spyCoreInfo).toHaveBeenCalledWith('Trying to download...');
expect(spyCoreInfo).toHaveBeenCalledWith(`Java ${expected.version} was downloaded`); expect(spyCoreInfo).toHaveBeenCalledWith(
expect(spyCoreInfo).toHaveBeenCalledWith(`Setting Java ${expected.version} as the default`); `Java ${expected.version} was downloaded`
);
expect(spyCoreInfo).toHaveBeenCalledWith(
`Setting Java ${expected.version} as the default`
);
}); });
it.each([ it.each([
[ [
{ version: '11.0.9', architecture: 'x86', packageType: 'jdk', checkLatest: true }, {
{ version: '11.0.9', path: javaPathInstalled } version: '11.0.9',
architecture: 'x86',
packageType: 'jdk',
checkLatest: true
},
{version: '11.0.9', path: javaPathInstalled}
], ],
[ [
{ version: '11.0.9', architecture: '', packageType: 'jdk', checkLatest: true }, {
{ version: '11.0.9', path: javaPathInstalled } version: '11.0.9',
architecture: '',
packageType: 'jdk',
checkLatest: true
},
{version: '11.0.9', path: javaPathInstalled}
] ]
])('should check the latest java version for %s and resolve locally', async (input, expected) => { ])(
'should check the latest java version for %s and resolve locally',
async (input, expected) => {
mockJavaBase = new EmptyJavaBase(input); mockJavaBase = new EmptyJavaBase(input);
mockJavaBase['findInToolcache'] = () => ({ version: '11.0.9', path: expected.path }); mockJavaBase['findInToolcache'] = () => ({
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected); version: '11.0.9',
expect(spyCoreInfo).toHaveBeenCalledWith('Trying to resolve the latest version from remote'); path: expected.path
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved latest version as ${expected.version}`);
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved Java ${expected.version} from tool-cache`);
expect(spyCoreInfo).toHaveBeenCalledWith(`Setting Java ${expected.version} as the default`);
}); });
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyCoreInfo).toHaveBeenCalledWith(
'Trying to resolve the latest version from remote'
);
expect(spyCoreInfo).toHaveBeenCalledWith(
`Resolved latest version as ${expected.version}`
);
expect(spyCoreInfo).toHaveBeenCalledWith(
`Resolved Java ${expected.version} from tool-cache`
);
expect(spyCoreInfo).toHaveBeenCalledWith(
`Setting Java ${expected.version} as the default`
);
}
);
it.each([ it.each([
[ [
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: true }, {
{ version: actualJavaVersion, path: javaPathInstalled } version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: true
},
{version: actualJavaVersion, path: javaPathInstalled}
], ],
[ [
{ version: '11.0', architecture: 'x86', packageType: 'jdk', checkLatest: true }, {
{ version: actualJavaVersion, path: javaPathInstalled } version: '11.0',
architecture: 'x86',
packageType: 'jdk',
checkLatest: true
},
{version: actualJavaVersion, path: javaPathInstalled}
], ],
[ [
{ version: '11.0.x', architecture: 'x86', packageType: 'jdk', checkLatest: true }, {
{ version: actualJavaVersion, path: javaPathInstalled } version: '11.0.x',
architecture: 'x86',
packageType: 'jdk',
checkLatest: true
},
{version: actualJavaVersion, path: javaPathInstalled}
], ],
[ [
{ version: '11', architecture: '', packageType: 'jdk', checkLatest: true }, {version: '11', architecture: '', packageType: 'jdk', checkLatest: true},
{ version: actualJavaVersion, path: javaPathInstalled } {version: actualJavaVersion, path: javaPathInstalled}
] ]
])('should check the latest java version for %s and download', async (input, expected) => { ])(
'should check the latest java version for %s and download',
async (input, expected) => {
mockJavaBase = new EmptyJavaBase(input); mockJavaBase = new EmptyJavaBase(input);
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected); await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyGetToolcachePath).toHaveBeenCalled(); expect(spyGetToolcachePath).toHaveBeenCalled();
expect(spyCoreInfo).toHaveBeenCalledWith('Trying to resolve the latest version from remote'); expect(spyCoreInfo).toHaveBeenCalledWith(
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved latest version as ${actualJavaVersion}`); 'Trying to resolve the latest version from remote'
);
expect(spyCoreInfo).toHaveBeenCalledWith(
`Resolved latest version as ${actualJavaVersion}`
);
expect(spyCoreInfo).toHaveBeenCalledWith('Trying to download...'); expect(spyCoreInfo).toHaveBeenCalledWith('Trying to download...');
expect(spyCoreInfo).toHaveBeenCalledWith(`Java ${actualJavaVersion} was downloaded`); expect(spyCoreInfo).toHaveBeenCalledWith(
expect(spyCoreInfo).toHaveBeenCalledWith(`Setting Java ${expected.version} as the default`); `Java ${actualJavaVersion} was downloaded`
}); );
expect(spyCoreInfo).toHaveBeenCalledWith(
`Setting Java ${expected.version} as the default`
);
}
);
it.each([ it.each([
[{ version: '15', architecture: 'x86', packageType: 'jre', checkLatest: false }], [
[{ version: '11.0.7', architecture: 'x64', packageType: 'jre', checkLatest: false }] {
])('should throw an error for Available version not found for %s', async input => { version: '15',
architecture: 'x86',
packageType: 'jre',
checkLatest: false
}
],
[
{
version: '11.0.7',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
}
]
])(
'should throw an error for Available version not found for %s',
async input => {
mockJavaBase = new EmptyJavaBase(input); mockJavaBase = new EmptyJavaBase(input);
await expect(mockJavaBase.setupJava()).rejects.toThrowError('Available version not found'); await expect(mockJavaBase.setupJava()).rejects.toThrow(
'Available version not found'
);
expect(spyTcFindAllVersions).toHaveBeenCalled(); expect(spyTcFindAllVersions).toHaveBeenCalled();
expect(spyCoreAddPath).not.toHaveBeenCalled(); expect(spyCoreAddPath).not.toHaveBeenCalled();
expect(spyCoreExportVariable).not.toHaveBeenCalled(); expect(spyCoreExportVariable).not.toHaveBeenCalled();
expect(spyCoreSetOutput).not.toHaveBeenCalled(); expect(spyCoreSetOutput).not.toHaveBeenCalled();
}); }
);
}); });
describe('normalizeVersion', () => { describe('normalizeVersion', () => {
const DummyJavaBase = JavaBase as any; const DummyJavaBase = JavaBase as any;
it.each([ it.each([
['11', { version: '11', stable: true }], ['11', {version: '11', stable: true}],
['11.0', { version: '11.0', stable: true }], ['11.0', {version: '11.0', stable: true}],
['11.0.10', { version: '11.0.10', stable: true }], ['11.0.10', {version: '11.0.10', stable: true}],
['11-ea', { version: '11', stable: false }], ['11-ea', {version: '11', stable: false}],
['11.0.2-ea', { version: '11.0.2', stable: false }] ['11.0.2-ea', {version: '11.0.2', stable: false}]
])('normalizeVersion from %s to %s', (input, expected) => { ])('normalizeVersion from %s to %s', (input, expected) => {
expect(DummyJavaBase.prototype.normalizeVersion.call(null, input)).toEqual(expected); expect(DummyJavaBase.prototype.normalizeVersion.call(null, input)).toEqual(
expected
);
}); });
it('normalizeVersion should throw an error for non semver', () => { it('normalizeVersion should throw an error for non semver', () => {
const version = '11g'; const version = '11g';
expect(DummyJavaBase.prototype.normalizeVersion.bind(null, version)).toThrowError( expect(
DummyJavaBase.prototype.normalizeVersion.bind(null, version)
).toThrow(
`The string '${version}' is not valid SemVer notation for a Java version. Please check README file for code snippets and more detailed information` `The string '${version}' is not valid SemVer notation for a Java version. Please check README file for code snippets and more detailed information`
); );
}); });
@ -353,14 +574,14 @@ describe('getToolcacheVersionName', () => {
const DummyJavaBase = JavaBase as any; const DummyJavaBase = JavaBase as any;
it.each([ it.each([
[{ version: '11', stable: true }, '11'], [{version: '11', stable: true}, '11'],
[{ version: '11.0.2', stable: true }, '11.0.2'], [{version: '11.0.2', stable: true}, '11.0.2'],
[{ version: '11.0.2+4', stable: true }, '11.0.2-4'], [{version: '11.0.2+4', stable: true}, '11.0.2-4'],
[{ version: '11.0.2+4.1.2563234', stable: true }, '11.0.2-4.1.2563234'], [{version: '11.0.2+4.1.2563234', stable: true}, '11.0.2-4.1.2563234'],
[{ version: '11.0', stable: false }, '11.0-ea'], [{version: '11.0', stable: false}, '11.0-ea'],
[{ version: '11.0.3', stable: false }, '11.0.3-ea'], [{version: '11.0.3', stable: false}, '11.0.3-ea'],
[{ version: '11.0.3+4', stable: false }, '11.0.3-ea.4'], [{version: '11.0.3+4', stable: false}, '11.0.3-ea.4'],
[{ version: '11.0.3+4.2.256', stable: false }, '11.0.3-ea.4.2.256'] [{version: '11.0.3+4.2.256', stable: false}, '11.0.3-ea.4.2.256']
])('returns correct version name for %s', (input, expected) => { ])('returns correct version name for %s', (input, expected) => {
const inputVersion = input.stable ? '11' : '11-ea'; const inputVersion = input.stable ? '11' : '11-ea';
const mockJavaBase = new EmptyJavaBase({ const mockJavaBase = new EmptyJavaBase({

View file

@ -1,12 +1,12 @@
import { HttpClient } from '@actions/http-client'; import {HttpClient} from '@actions/http-client';
import { JavaInstallerOptions } from '../../src/distributions/base-models'; import {JavaInstallerOptions} from '../../src/distributions/base-models';
import { CorrettoDistribution } from '../../src/distributions/corretto/installer'; import {CorrettoDistribution} from '../../src/distributions/corretto/installer';
import * as util from '../../src/util'; import * as util from '../../src/util';
import os from 'os'; import os from 'os';
import { isGeneratorFunction } from 'util/types'; import {isGeneratorFunction} from 'util/types';
const manifestData = require('../data/corretto.json') as []; import manifestData from '../data/corretto.json';
describe('getAvailableVersions', () => { describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance; let spyHttpClient: jest.SpyInstance;
@ -19,7 +19,10 @@ describe('getAvailableVersions', () => {
headers: {}, headers: {},
result: manifestData result: manifestData
}); });
spyGetDownloadArchiveExtension = jest.spyOn(util, 'getDownloadArchiveExtension'); spyGetDownloadArchiveExtension = jest.spyOn(
util,
'getDownloadArchiveExtension'
);
}); });
afterEach(() => { afterEach(() => {
@ -44,16 +47,66 @@ describe('getAvailableVersions', () => {
}); });
it.each([ it.each([
[{ version: '16', architecture: 'x64', packageType: 'jdk', checkLatest: false }, 'macos', 6],
[{ version: '16', architecture: 'x86', packageType: 'jdk', checkLatest: false }, 'macos', 0],
[{ version: '16', architecture: 'x64', packageType: 'jre', checkLatest: false }, 'macos', 0],
[{ version: '16', architecture: 'x64', packageType: 'jdk', checkLatest: false }, 'linux', 6],
[ [
{ version: '18', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '16',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
'macos',
6
],
[
{
version: '16',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
'macos',
0
],
[
{
version: '16',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
'macos',
0
],
[
{
version: '16',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
'linux',
6
],
[
{
version: '18',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
'windows', 'windows',
6 6
], ],
[{ version: '18', architecture: 'x64', packageType: 'jre', checkLatest: false }, 'windows', 1] [
{
version: '18',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
'windows',
1
]
])( ])(
'fetch expected amount of available versions for %s', 'fetch expected amount of available versions for %s',
async ( async (
@ -66,7 +119,9 @@ describe('getAvailableVersions', () => {
const availableVersions = await distribution['getAvailableVersions'](); const availableVersions = await distribution['getAvailableVersions']();
expect(availableVersions).not.toBeNull(); expect(availableVersions).not.toBeNull();
expect(availableVersions.length).toBe(expectedAmountOfAvailableVersions); expect(availableVersions.length).toBe(
expectedAmountOfAvailableVersions
);
} }
); );
}); });
@ -95,7 +150,9 @@ describe('getAvailableVersions', () => {
}); });
mockPlatform(distribution, platform); mockPlatform(distribution, platform);
const availableVersion = await distribution['findPackageForDownload'](version); const availableVersion = await distribution['findPackageForDownload'](
version
);
expect(availableVersion).not.toBeNull(); expect(availableVersion).not.toBeNull();
expect(availableVersion.url).toBe(expectedLink); expect(availableVersion.url).toBe(expectedLink);
}); });
@ -110,9 +167,9 @@ describe('getAvailableVersions', () => {
}); });
mockPlatform(distribution, 'linux'); mockPlatform(distribution, 'linux');
await expect(distribution['findPackageForDownload'](version)).rejects.toThrowError( await expect(
'Early access versions are not supported' distribution['findPackageForDownload'](version)
); ).rejects.toThrow('Early access versions are not supported');
}); });
it('with non major version expect to throw not supported error', async () => { it('with non major version expect to throw not supported error', async () => {
@ -125,9 +182,9 @@ describe('getAvailableVersions', () => {
}); });
mockPlatform(distribution, 'linux'); mockPlatform(distribution, 'linux');
await expect(distribution['findPackageForDownload'](version)).rejects.toThrowError( await expect(
'Only major versions are supported' distribution['findPackageForDownload'](version)
); ).rejects.toThrow('Only major versions are supported');
}); });
it('with unfound version throw could not find error', async () => { it('with unfound version throw could not find error', async () => {
@ -140,9 +197,9 @@ describe('getAvailableVersions', () => {
}); });
mockPlatform(distribution, 'linux'); mockPlatform(distribution, 'linux');
await expect(distribution['findPackageForDownload'](version)).rejects.toThrowError( await expect(
"Could not find satisfied version for SemVer '4'" distribution['findPackageForDownload'](version)
); ).rejects.toThrow("Could not find satisfied version for SemVer '4'");
}); });
it.each([ it.each([
@ -166,14 +223,19 @@ describe('getAvailableVersions', () => {
const expectedLink = `https://corretto.aws/downloads/resources/17.0.2.8.1/amazon-corretto-17.0.2.8.1-macosx-${distroArch}.tar.gz`; const expectedLink = `https://corretto.aws/downloads/resources/17.0.2.8.1/amazon-corretto-17.0.2.8.1-macosx-${distroArch}.tar.gz`;
const availableVersion = await distribution['findPackageForDownload'](version); const availableVersion = await distribution['findPackageForDownload'](
version
);
expect(availableVersion).not.toBeNull(); expect(availableVersion).not.toBeNull();
expect(availableVersion.url).toBe(expectedLink); expect(availableVersion.url).toBe(expectedLink);
} }
); );
}); });
const mockPlatform = (distribution: CorrettoDistribution, platform: string) => { const mockPlatform = (
distribution: CorrettoDistribution,
platform: string
) => {
distribution['getPlatformOption'] = () => platform; distribution['getPlatformOption'] = () => platform;
const mockedExtension = platform === 'windows' ? 'zip' : 'tar.gz'; const mockedExtension = platform === 'windows' ? 'zip' : 'tar.gz';
spyGetDownloadArchiveExtension.mockReturnValue(mockedExtension); spyGetDownloadArchiveExtension.mockReturnValue(mockedExtension);

View file

@ -1,9 +1,12 @@
import { LibericaDistributions } from '../../src/distributions/liberica/installer'; import {LibericaDistributions} from '../../src/distributions/liberica/installer';
import { ArchitectureOptions, LibericaVersion } from '../../src/distributions/liberica/models'; import {
import { HttpClient } from '@actions/http-client'; ArchitectureOptions,
LibericaVersion
} from '../../src/distributions/liberica/models';
import {HttpClient} from '@actions/http-client';
import os from 'os'; import os from 'os';
const manifestData = require('../data/liberica.json') as LibericaVersion[]; import manifestData from '../data/liberica.json';
describe('getAvailableVersions', () => { describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance; let spyHttpClient: jest.SpyInstance;
@ -13,7 +16,7 @@ describe('getAvailableVersions', () => {
spyHttpClient.mockReturnValue({ spyHttpClient.mockReturnValue({
statusCode: 200, statusCode: 200,
headers: {}, headers: {},
result: manifestData result: manifestData as LibericaVersion[]
}); });
}); });
@ -25,27 +28,57 @@ describe('getAvailableVersions', () => {
it.each([ it.each([
[ [
{ version: '11.x', architecture: 'x86', packageType: 'jdk', checkLatest: false }, {
version: '11.x',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
'bundle-type=jdk&bitness=32&arch=x86&build-type=all' 'bundle-type=jdk&bitness=32&arch=x86&build-type=all'
], ],
[ [
{ version: '11-ea', architecture: 'x86', packageType: 'jdk', checkLatest: false }, {
version: '11-ea',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
'bundle-type=jdk&bitness=32&arch=x86&build-type=ea' 'bundle-type=jdk&bitness=32&arch=x86&build-type=ea'
], ],
[ [
{ version: '16.0.2', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '16.0.2',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
'bundle-type=jdk&bitness=64&arch=x86&build-type=all' 'bundle-type=jdk&bitness=64&arch=x86&build-type=all'
], ],
[ [
{ version: '16.0.2', architecture: 'x64', packageType: 'jre', checkLatest: false }, {
version: '16.0.2',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
'bundle-type=jre&bitness=64&arch=x86&build-type=all' 'bundle-type=jre&bitness=64&arch=x86&build-type=all'
], ],
[ [
{ version: '8', architecture: 'armv7', packageType: 'jdk+fx', checkLatest: false }, {
version: '8',
architecture: 'armv7',
packageType: 'jdk+fx',
checkLatest: false
},
'bundle-type=jdk-full&bitness=32&arch=arm&build-type=all' 'bundle-type=jdk-full&bitness=32&arch=arm&build-type=all'
], ],
[ [
{ version: '8', architecture: 'aarch64', packageType: 'jre+fx', checkLatest: false }, {
version: '8',
architecture: 'aarch64',
packageType: 'jre+fx',
checkLatest: false
},
'bundle-type=jre-full&bitness=64&arch=arm&build-type=all' 'bundle-type=jre-full&bitness=64&arch=arm&build-type=all'
] ]
])('build correct url for %s -> %s', async (input, urlParams) => { ])('build correct url for %s -> %s', async (input, urlParams) => {
@ -67,8 +100,8 @@ describe('getAvailableVersions', () => {
arch: string; arch: string;
}; };
it.each([ it.each([
['amd64', { bitness: '64', arch: 'x86' }], ['amd64', {bitness: '64', arch: 'x86'}],
['arm64', { bitness: '64', arch: 'arm' }] ['arm64', {bitness: '64', arch: 'arm'}]
])( ])(
'defaults to os.arch(): %s mapped to distro arch: %s', 'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: DistroArch) => { async (osArch: string, distroArch: DistroArch) => {
@ -109,12 +142,14 @@ describe('getAvailableVersions', () => {
describe('getArchitectureOptions', () => { describe('getArchitectureOptions', () => {
it.each([ it.each([
['x86', { bitness: '32', arch: 'x86' }], ['x86', {bitness: '32', arch: 'x86'}],
['x64', { bitness: '64', arch: 'x86' }], ['x64', {bitness: '64', arch: 'x86'}],
['armv7', { bitness: '32', arch: 'arm' }], ['armv7', {bitness: '32', arch: 'arm'}],
['aarch64', { bitness: '64', arch: 'arm' }], ['aarch64', {bitness: '64', arch: 'arm'}],
['ppc64le', { bitness: '64', arch: 'ppc' }] ['ppc64le', {bitness: '64', arch: 'ppc'}]
] as [string, ArchitectureOptions][])('parse architecture %s -> %s', (input, expected) => { ] as [string, ArchitectureOptions][])(
'parse architecture %s -> %s',
(input, expected) => {
const distributions = new LibericaDistributions({ const distributions = new LibericaDistributions({
architecture: input, architecture: input,
checkLatest: false, checkLatest: false,
@ -123,7 +158,8 @@ describe('getArchitectureOptions', () => {
}); });
expect(distributions['getArchitectureOptions']()).toEqual(expected); expect(distributions['getArchitectureOptions']()).toEqual(expected);
}); }
);
it.each(['armv6', 's390x'])('not support architecture %s', input => { it.each(['armv6', 's390x'])('not support architecture %s', input => {
const distributions = new LibericaDistributions({ const distributions = new LibericaDistributions({
@ -199,9 +235,9 @@ describe('getPlatformOption', () => {
it.each(['aix', 'android', 'freebsd', 'openbsd', 'netbsd'])( it.each(['aix', 'android', 'freebsd', 'openbsd', 'netbsd'])(
'not support os version %s', 'not support os version %s',
input => { input => {
expect(() => distributions['getPlatformOption'](input as NodeJS.Platform)).toThrow( expect(() =>
/Platform '\w+' is not supported\. Supported platforms: .+/ distributions['getPlatformOption'](input as NodeJS.Platform)
); ).toThrow(/Platform '\w+' is not supported\. Supported platforms: .+/);
} }
); );
}); });
@ -215,9 +251,33 @@ describe('convertVersionToSemver', () => {
}); });
it.each([ it.each([
[{ featureVersion: 11, interimVersion: 0, updateVersion: 12, buildVersion: 7 }, '11.0.12+7'], [
[{ featureVersion: 11, interimVersion: 0, updateVersion: 12, buildVersion: 0 }, '11.0.12'], {
[{ featureVersion: 11, interimVersion: 0, updateVersion: 0, buildVersion: 13 }, '11.0.0+13'] featureVersion: 11,
interimVersion: 0,
updateVersion: 12,
buildVersion: 7
},
'11.0.12+7'
],
[
{
featureVersion: 11,
interimVersion: 0,
updateVersion: 12,
buildVersion: 0
},
'11.0.12'
],
[
{
featureVersion: 11,
interimVersion: 0,
updateVersion: 0,
buildVersion: 13
},
'11.0.0+13'
]
])('%s -> %s', (input, expected) => { ])('%s -> %s', (input, expected) => {
const actual = distributions['convertVersionToSemver']({ const actual = distributions['convertVersionToSemver']({
downloadUrl: '', downloadUrl: '',

View file

@ -7,7 +7,7 @@ import path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
import * as util from '../../src/util'; import * as util from '../../src/util';
import { LocalDistribution } from '../../src/distributions/local/installer'; import {LocalDistribution} from '../../src/distributions/local/installer';
describe('setupJava', () => { describe('setupJava', () => {
const actualJavaVersion = '11.1.10'; const actualJavaVersion = '11.1.10';
@ -27,7 +27,7 @@ describe('setupJava', () => {
let spyFsReadDir: jest.SpyInstance; let spyFsReadDir: jest.SpyInstance;
let spyUtilsExtractJdkFile: jest.SpyInstance; let spyUtilsExtractJdkFile: jest.SpyInstance;
let spyPathResolve: jest.SpyInstance; let spyPathResolve: jest.SpyInstance;
let expectedJdkFile = 'JavaLocalJdkFile'; const expectedJdkFile = 'JavaLocalJdkFile';
beforeEach(() => { beforeEach(() => {
spyGetToolcachePath = jest.spyOn(util, 'getToolcachePath'); spyGetToolcachePath = jest.spyOn(util, 'getToolcachePath');
@ -35,18 +35,27 @@ describe('setupJava', () => {
(toolname: string, javaVersion: string, architecture: string) => { (toolname: string, javaVersion: string, architecture: string) => {
const semverVersion = new semver.Range(javaVersion); const semverVersion = new semver.Range(javaVersion);
if (path.basename(javaPath) !== architecture || !javaPath.includes(toolname)) { if (
path.basename(javaPath) !== architecture ||
!javaPath.includes(toolname)
) {
return ''; return '';
} }
return semver.satisfies(actualJavaVersion, semverVersion) ? javaPath : ''; return semver.satisfies(actualJavaVersion, semverVersion)
? javaPath
: '';
} }
); );
spyTcCacheDir = jest.spyOn(tc, 'cacheDir'); spyTcCacheDir = jest.spyOn(tc, 'cacheDir');
spyTcCacheDir.mockImplementation( spyTcCacheDir.mockImplementation(
(archivePath: string, toolcacheFolderName: string, version: string, architecture: string) => (
path.join(toolcacheFolderName, version, architecture) archivePath: string,
toolcacheFolderName: string,
version: string,
architecture: string
) => path.join(toolcacheFolderName, version, architecture)
); );
spyTcFindAllVersions = jest.spyOn(tc, 'findAllVersions'); spyTcFindAllVersions = jest.spyOn(tc, 'findAllVersions');
@ -74,7 +83,7 @@ describe('setupJava', () => {
spyFsStat = jest.spyOn(fs, 'statSync'); spyFsStat = jest.spyOn(fs, 'statSync');
spyFsStat.mockImplementation((file: string) => { spyFsStat.mockImplementation((file: string) => {
return { isFile: () => file === expectedJdkFile }; return {isFile: () => file === expectedJdkFile};
}); });
// Spy on util methods // Spy on util methods
@ -108,7 +117,9 @@ describe('setupJava', () => {
mockJavaBase = new LocalDistribution(inputs, jdkFile); mockJavaBase = new LocalDistribution(inputs, jdkFile);
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected); await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyGetToolcachePath).toHaveBeenCalled(); expect(spyGetToolcachePath).toHaveBeenCalled();
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved Java ${actualJavaVersion} from tool-cache`); expect(spyCoreInfo).toHaveBeenCalledWith(
`Resolved Java ${actualJavaVersion} from tool-cache`
);
expect(spyCoreInfo).not.toHaveBeenCalledWith( expect(spyCoreInfo).not.toHaveBeenCalledWith(
`Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...` `Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...`
); );
@ -130,7 +141,9 @@ describe('setupJava', () => {
mockJavaBase = new LocalDistribution(inputs, jdkFile); mockJavaBase = new LocalDistribution(inputs, jdkFile);
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected); await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyGetToolcachePath).toHaveBeenCalled(); expect(spyGetToolcachePath).toHaveBeenCalled();
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved Java ${actualJavaVersion} from tool-cache`); expect(spyCoreInfo).toHaveBeenCalledWith(
`Resolved Java ${actualJavaVersion} from tool-cache`
);
expect(spyCoreInfo).not.toHaveBeenCalledWith( expect(spyCoreInfo).not.toHaveBeenCalledWith(
`Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...` `Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...`
); );
@ -155,7 +168,9 @@ describe('setupJava', () => {
expect(spyCoreInfo).not.toHaveBeenCalledWith( expect(spyCoreInfo).not.toHaveBeenCalledWith(
`Resolved Java ${actualJavaVersion} from tool-cache` `Resolved Java ${actualJavaVersion} from tool-cache`
); );
expect(spyCoreInfo).toHaveBeenCalledWith(`Extracting Java from '${jdkFile}'`); expect(spyCoreInfo).toHaveBeenCalledWith(
`Extracting Java from '${jdkFile}'`
);
expect(spyCoreInfo).toHaveBeenCalledWith( expect(spyCoreInfo).toHaveBeenCalledWith(
`Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...` `Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...`
); );
@ -171,19 +186,29 @@ describe('setupJava', () => {
const jdkFile = 'not_existing_one'; const jdkFile = 'not_existing_one';
const expected = { const expected = {
javaVersion: '11.0.289', javaVersion: '11.0.289',
javaPath: path.join('Java_jdkfile_jdk', inputs.version, inputs.architecture) javaPath: path.join(
'Java_jdkfile_jdk',
inputs.version,
inputs.architecture
)
}; };
mockJavaBase = new LocalDistribution(inputs, jdkFile); mockJavaBase = new LocalDistribution(inputs, jdkFile);
expected.javaPath = path.join('Java_jdkfile_jdk', inputs.version, inputs.architecture); expected.javaPath = path.join(
await expect(mockJavaBase.setupJava()).rejects.toThrowError( 'Java_jdkfile_jdk',
inputs.version,
inputs.architecture
);
await expect(mockJavaBase.setupJava()).rejects.toThrow(
"JDK file was not found in path 'not_existing_one'" "JDK file was not found in path 'not_existing_one'"
); );
expect(spyTcFindAllVersions).toHaveBeenCalled(); expect(spyTcFindAllVersions).toHaveBeenCalled();
expect(spyCoreInfo).not.toHaveBeenCalledWith( expect(spyCoreInfo).not.toHaveBeenCalledWith(
`Resolved Java ${actualJavaVersion} from tool-cache` `Resolved Java ${actualJavaVersion} from tool-cache`
); );
expect(spyCoreInfo).not.toHaveBeenCalledWith(`Extracting Java from '${jdkFile}'`); expect(spyCoreInfo).not.toHaveBeenCalledWith(
`Extracting Java from '${jdkFile}'`
);
expect(spyCoreInfo).toHaveBeenCalledWith( expect(spyCoreInfo).toHaveBeenCalledWith(
`Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...` `Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...`
); );
@ -191,26 +216,46 @@ describe('setupJava', () => {
it.each([ it.each([
[ [
{ version: '8.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '8.0.289',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
'otherJdkFile' 'otherJdkFile'
], ],
[ [
{ version: '11.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11.0.289',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
'otherJdkFile' 'otherJdkFile'
], ],
[ [
{ version: '12.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '12.0.289',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
'otherJdkFile' 'otherJdkFile'
], ],
[ [
{ version: '11.1.11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11.1.11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
'not_existing_one' 'not_existing_one'
] ]
])( ])(
`Throw an error if jdkfile has wrong path, inputs %s, jdkfile %s, real name ${expectedJdkFile}`, `Throw an error if jdkfile has wrong path, inputs %s, jdkfile %s, real name ${expectedJdkFile}`,
async (inputs, jdkFile) => { async (inputs, jdkFile) => {
mockJavaBase = new LocalDistribution(inputs, jdkFile); mockJavaBase = new LocalDistribution(inputs, jdkFile);
await expect(mockJavaBase.setupJava()).rejects.toThrowError( await expect(mockJavaBase.setupJava()).rejects.toThrow(
/JDK file was not found in path */ /JDK file was not found in path */
); );
expect(spyTcFindAllVersions).toHaveBeenCalled(); expect(spyTcFindAllVersions).toHaveBeenCalled();
@ -218,18 +263,41 @@ describe('setupJava', () => {
); );
it.each([ it.each([
[{ version: '8.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, ''],
[ [
{ version: '7.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '8.0.289',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
''
],
[
{
version: '7.0.289',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
undefined undefined
], ],
[ [
{ version: '11.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '11.0.289',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
undefined undefined
] ]
])('Throw an error if jdkfile is not specified, inputs %s', async (inputs, jdkFile) => { ])(
'Throw an error if jdkfile is not specified, inputs %s',
async (inputs, jdkFile) => {
mockJavaBase = new LocalDistribution(inputs, jdkFile); mockJavaBase = new LocalDistribution(inputs, jdkFile);
await expect(mockJavaBase.setupJava()).rejects.toThrowError("'jdkFile' is not specified"); await expect(mockJavaBase.setupJava()).rejects.toThrow(
"'jdkFile' is not specified"
);
expect(spyTcFindAllVersions).toHaveBeenCalled(); expect(spyTcFindAllVersions).toHaveBeenCalled();
}); }
);
}); });

View file

@ -1,4 +1,4 @@
import { MicrosoftDistributions } from '../../src/distributions/microsoft/installer'; import {MicrosoftDistributions} from '../../src/distributions/microsoft/installer';
import os from 'os'; import os from 'os';
import data from '../../src/distributions/microsoft/microsoft-openjdk-versions.json'; import data from '../../src/distributions/microsoft/microsoft-openjdk-versions.json';
import * as httpm from '@actions/http-client'; import * as httpm from '@actions/http-client';
@ -73,7 +73,9 @@ describe('findPackageForDownload', () => {
archive = 'tar.gz'; archive = 'tar.gz';
break; break;
} }
const url = expectedUrl.replace('{{OS_TYPE}}', os).replace('{{ARCHIVE_TYPE}}', archive); const url = expectedUrl
.replace('{{OS_TYPE}}', os)
.replace('{{ARCHIVE_TYPE}}', archive);
expect(result.url).toBe(url); expect(result.url).toBe(url);
}); });

View file

@ -1,7 +1,7 @@
import { OracleDistribution } from '../../src/distributions/oracle/installer'; import {OracleDistribution} from '../../src/distributions/oracle/installer';
import os from 'os'; import os from 'os';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { getDownloadArchiveExtension } from '../../src/util'; import {getDownloadArchiveExtension} from '../../src/util';
describe('findPackageForDownload', () => { describe('findPackageForDownload', () => {
let distribution: OracleDistribution; let distribution: OracleDistribution;
@ -50,7 +50,9 @@ describe('findPackageForDownload', () => {
expect(result.version).toBe(expectedVersion); expect(result.version).toBe(expectedVersion);
const osType = distribution.getPlatform(); const osType = distribution.getPlatform();
const archiveType = getDownloadArchiveExtension(); const archiveType = getDownloadArchiveExtension();
const url = expectedUrl.replace('{{OS_TYPE}}', osType).replace('{{ARCHIVE_TYPE}}', archiveType); const url = expectedUrl
.replace('{{OS_TYPE}}', osType)
.replace('{{ARCHIVE_TYPE}}', archiveType);
expect(result.url).toBe(url); expect(result.url).toBe(url);
}); });

View file

@ -1,12 +1,12 @@
import { HttpClient } from '@actions/http-client'; import {HttpClient} from '@actions/http-client';
import os from 'os'; import os from 'os';
import { import {
TemurinDistribution, TemurinDistribution,
TemurinImplementation TemurinImplementation
} from '../../src/distributions/temurin/installer'; } from '../../src/distributions/temurin/installer';
import { JavaInstallerOptions } from '../../src/distributions/base-models'; import {JavaInstallerOptions} from '../../src/distributions/base-models';
let manifestData = require('../data/temurin.json') as []; import manifestData from '../data/temurin.json';
describe('getAvailableVersions', () => { describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance; let spyHttpClient: jest.SpyInstance;
@ -28,22 +28,42 @@ describe('getAvailableVersions', () => {
it.each([ it.each([
[ [
{ version: '16', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '16',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
TemurinImplementation.Hotspot, TemurinImplementation.Hotspot,
'os=mac&architecture=x64&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0' 'os=mac&architecture=x64&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
], ],
[ [
{ version: '16', architecture: 'x86', packageType: 'jdk', checkLatest: false }, {
version: '16',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
TemurinImplementation.Hotspot, TemurinImplementation.Hotspot,
'os=mac&architecture=x86&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0' 'os=mac&architecture=x86&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
], ],
[ [
{ version: '16', architecture: 'x64', packageType: 'jre', checkLatest: false }, {
version: '16',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
TemurinImplementation.Hotspot, TemurinImplementation.Hotspot,
'os=mac&architecture=x64&image_type=jre&release_type=ga&jvm_impl=hotspot&page_size=20&page=0' 'os=mac&architecture=x64&image_type=jre&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
], ],
[ [
{ version: '16-ea', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '16-ea',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
TemurinImplementation.Hotspot, TemurinImplementation.Hotspot,
'os=mac&architecture=x64&image_type=jdk&release_type=ea&jvm_impl=hotspot&page_size=20&page=0' 'os=mac&architecture=x64&image_type=jdk&release_type=ea&jvm_impl=hotspot&page_size=20&page=0'
] ]
@ -55,7 +75,8 @@ describe('getAvailableVersions', () => {
expectedParameters expectedParameters
) => { ) => {
const distribution = new TemurinDistribution(installerOptions, impl); const distribution = new TemurinDistribution(installerOptions, impl);
const baseUrl = 'https://api.adoptium.net/v3/assets/version/%5B1.0,100.0%5D'; const baseUrl =
'https://api.adoptium.net/v3/assets/version/%5B1.0,100.0%5D';
const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptium&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`; const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptium&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`;
distribution['getPlatformOption'] = () => 'mac'; distribution['getPlatformOption'] = () => 'mac';
@ -72,12 +93,12 @@ describe('getAvailableVersions', () => {
.mockReturnValueOnce({ .mockReturnValueOnce({
statusCode: 200, statusCode: 200,
headers: {}, headers: {},
result: manifestData result: manifestData as any
}) })
.mockReturnValueOnce({ .mockReturnValueOnce({
statusCode: 200, statusCode: 200,
headers: {}, headers: {},
result: manifestData result: manifestData as any
}) })
.mockReturnValueOnce({ .mockReturnValueOnce({
statusCode: 200, statusCode: 200,
@ -86,7 +107,12 @@ describe('getAvailableVersions', () => {
}); });
const distribution = new TemurinDistribution( const distribution = new TemurinDistribution(
{ version: '8', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
TemurinImplementation.Hotspot TemurinImplementation.Hotspot
); );
const availableVersions = await distribution['getAvailableVersions'](); const availableVersions = await distribution['getAvailableVersions']();
@ -101,7 +127,12 @@ describe('getAvailableVersions', () => {
'find right toolchain folder', 'find right toolchain folder',
(impl: TemurinImplementation, packageType: string, expected: string) => { (impl: TemurinImplementation, packageType: string, expected: string) => {
const distribution = new TemurinDistribution( const distribution = new TemurinDistribution(
{ version: '8', architecture: 'x64', packageType: packageType, checkLatest: false }, {
version: '8',
architecture: 'x64',
packageType: packageType,
checkLatest: false
},
impl impl
); );
@ -127,8 +158,12 @@ describe('getAvailableVersions', () => {
const expectedParameters = `os=mac&architecture=${distroArch}&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0`; const expectedParameters = `os=mac&architecture=${distroArch}&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0`;
const distribution = new TemurinDistribution(installerOptions, TemurinImplementation.Hotspot); const distribution = new TemurinDistribution(
const baseUrl = 'https://api.adoptium.net/v3/assets/version/%5B1.0,100.0%5D'; installerOptions,
TemurinImplementation.Hotspot
);
const baseUrl =
'https://api.adoptium.net/v3/assets/version/%5B1.0,100.0%5D';
const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptium&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`; const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptium&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`;
distribution['getPlatformOption'] = () => 'mac'; distribution['getPlatformOption'] = () => 'mac';
@ -150,43 +185,63 @@ describe('findPackageForDownload', () => {
['x', '16.0.2+7'] ['x', '16.0.2+7']
])('version is resolved correctly %s -> %s', async (input, expected) => { ])('version is resolved correctly %s -> %s', async (input, expected) => {
const distribution = new TemurinDistribution( const distribution = new TemurinDistribution(
{ version: '8', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
TemurinImplementation.Hotspot TemurinImplementation.Hotspot
); );
distribution['getAvailableVersions'] = async () => manifestData; distribution['getAvailableVersions'] = async () => manifestData as any;
const resolvedVersion = await distribution['findPackageForDownload'](input); const resolvedVersion = await distribution['findPackageForDownload'](input);
expect(resolvedVersion.version).toBe(expected); expect(resolvedVersion.version).toBe(expected);
}); });
it('version is found but binaries list is empty', async () => { it('version is found but binaries list is empty', async () => {
const distribution = new TemurinDistribution( const distribution = new TemurinDistribution(
{ version: '9.0.8', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '9.0.8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
TemurinImplementation.Hotspot TemurinImplementation.Hotspot
); );
distribution['getAvailableVersions'] = async () => manifestData; distribution['getAvailableVersions'] = async () => manifestData as any;
await expect(distribution['findPackageForDownload']('9.0.8')).rejects.toThrowError( await expect(
/Could not find satisfied version for SemVer */ distribution['findPackageForDownload']('9.0.8')
); ).rejects.toThrow(/Could not find satisfied version for SemVer */);
}); });
it('version is not found', async () => { it('version is not found', async () => {
const distribution = new TemurinDistribution( const distribution = new TemurinDistribution(
{ version: '7.x', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '7.x',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
TemurinImplementation.Hotspot TemurinImplementation.Hotspot
); );
distribution['getAvailableVersions'] = async () => manifestData; distribution['getAvailableVersions'] = async () => manifestData as any;
await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrowError( await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrow(
/Could not find satisfied version for SemVer */ /Could not find satisfied version for SemVer */
); );
}); });
it('version list is empty', async () => { it('version list is empty', async () => {
const distribution = new TemurinDistribution( const distribution = new TemurinDistribution(
{ version: '8', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
TemurinImplementation.Hotspot TemurinImplementation.Hotspot
); );
distribution['getAvailableVersions'] = async () => []; distribution['getAvailableVersions'] = async () => [];
await expect(distribution['findPackageForDownload']('8')).rejects.toThrowError( await expect(distribution['findPackageForDownload']('8')).rejects.toThrow(
/Could not find satisfied version for SemVer */ /Could not find satisfied version for SemVer */
); );
}); });

View file

@ -1,11 +1,11 @@
import { HttpClient } from '@actions/http-client'; import {HttpClient} from '@actions/http-client';
import * as semver from 'semver'; import * as semver from 'semver';
import { ZuluDistribution } from '../../src/distributions/zulu/installer'; import {ZuluDistribution} from '../../src/distributions/zulu/installer';
import { IZuluVersions } from '../../src/distributions/zulu/models'; import {IZuluVersions} from '../../src/distributions/zulu/models';
import * as utils from '../../src/util'; import * as utils from '../../src/util';
import os from 'os'; import os from 'os';
const manifestData = require('../data/zulu-releases-default.json') as []; import manifestData from '../data/zulu-releases-default.json';
describe('getAvailableVersions', () => { describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance; let spyHttpClient: jest.SpyInstance;
@ -19,7 +19,10 @@ describe('getAvailableVersions', () => {
result: manifestData as IZuluVersions[] result: manifestData as IZuluVersions[]
}); });
spyUtilGetDownloadArchiveExtension = jest.spyOn(utils, 'getDownloadArchiveExtension'); spyUtilGetDownloadArchiveExtension = jest.spyOn(
utils,
'getDownloadArchiveExtension'
);
spyUtilGetDownloadArchiveExtension.mockReturnValue('tar.gz'); spyUtilGetDownloadArchiveExtension.mockReturnValue('tar.gz');
}); });
@ -31,35 +34,75 @@ describe('getAvailableVersions', () => {
it.each([ it.each([
[ [
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
'?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=x86&hw_bitness=32&release_status=ga' '?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=x86&hw_bitness=32&release_status=ga'
], ],
[ [
{ version: '11-ea', architecture: 'x86', packageType: 'jdk', checkLatest: false }, {
version: '11-ea',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
'?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=x86&hw_bitness=32&release_status=ea' '?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=x86&hw_bitness=32&release_status=ea'
], ],
[ [
{ version: '8', architecture: 'x64', packageType: 'jdk', checkLatest: false }, {
version: '8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
'?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=x86&hw_bitness=64&release_status=ga' '?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=x86&hw_bitness=64&release_status=ga'
], ],
[ [
{ version: '8', architecture: 'x64', packageType: 'jre', checkLatest: false }, {
version: '8',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
'?os=macos&ext=tar.gz&bundle_type=jre&javafx=false&arch=x86&hw_bitness=64&release_status=ga' '?os=macos&ext=tar.gz&bundle_type=jre&javafx=false&arch=x86&hw_bitness=64&release_status=ga'
], ],
[ [
{ version: '8', architecture: 'x64', packageType: 'jdk+fx', checkLatest: false }, {
version: '8',
architecture: 'x64',
packageType: 'jdk+fx',
checkLatest: false
},
'?os=macos&ext=tar.gz&bundle_type=jdk&javafx=true&arch=x86&hw_bitness=64&release_status=ga&features=fx' '?os=macos&ext=tar.gz&bundle_type=jdk&javafx=true&arch=x86&hw_bitness=64&release_status=ga&features=fx'
], ],
[ [
{ version: '8', architecture: 'x64', packageType: 'jre+fx', checkLatest: false }, {
version: '8',
architecture: 'x64',
packageType: 'jre+fx',
checkLatest: false
},
'?os=macos&ext=tar.gz&bundle_type=jre&javafx=true&arch=x86&hw_bitness=64&release_status=ga&features=fx' '?os=macos&ext=tar.gz&bundle_type=jre&javafx=true&arch=x86&hw_bitness=64&release_status=ga&features=fx'
], ],
[ [
{ version: '11', architecture: 'arm64', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'arm64',
packageType: 'jdk',
checkLatest: false
},
'?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=arm&hw_bitness=64&release_status=ga' '?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=arm&hw_bitness=64&release_status=ga'
], ],
[ [
{ version: '11', architecture: 'arm', packageType: 'jdk', checkLatest: false }, {
version: '11',
architecture: 'arm',
packageType: 'jdk',
checkLatest: false
},
'?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=arm&hw_bitness=&release_status=ga' '?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=arm&hw_bitness=&release_status=ga'
] ]
])('build correct url for %s -> %s', async (input, parsedUrl) => { ])('build correct url for %s -> %s', async (input, parsedUrl) => {
@ -78,8 +121,8 @@ describe('getAvailableVersions', () => {
arch: string; arch: string;
}; };
it.each([ it.each([
['amd64', { bitness: '64', arch: 'x86' }], ['amd64', {bitness: '64', arch: 'x86'}],
['arm64', { bitness: '64', arch: 'arm' }] ['arm64', {bitness: '64', arch: 'arm'}]
])( ])(
'defaults to os.arch(): %s mapped to distro arch: %s', 'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: DistroArch) => { async (osArch: string, distroArch: DistroArch) => {
@ -115,10 +158,10 @@ describe('getAvailableVersions', () => {
describe('getArchitectureOptions', () => { describe('getArchitectureOptions', () => {
it.each([ it.each([
[{ architecture: 'x64' }, { arch: 'x86', hw_bitness: '64', abi: '' }], [{architecture: 'x64'}, {arch: 'x86', hw_bitness: '64', abi: ''}],
[{ architecture: 'x86' }, { arch: 'x86', hw_bitness: '32', abi: '' }], [{architecture: 'x86'}, {arch: 'x86', hw_bitness: '32', abi: ''}],
[{ architecture: 'x32' }, { arch: 'x32', hw_bitness: '', abi: '' }], [{architecture: 'x32'}, {arch: 'x32', hw_bitness: '', abi: ''}],
[{ architecture: 'arm' }, { arch: 'arm', hw_bitness: '', abi: '' }] [{architecture: 'arm'}, {arch: 'arm', hw_bitness: '', abi: ''}]
])('%s -> %s', (input, expected) => { ])('%s -> %s', (input, expected) => {
const distribution = new ZuluDistribution({ const distribution = new ZuluDistribution({
version: '11', version: '11',
@ -151,7 +194,9 @@ describe('findPackageForDownload', () => {
checkLatest: false checkLatest: false
}); });
distribution['getAvailableVersions'] = async () => manifestData; distribution['getAvailableVersions'] = async () => manifestData;
const result = await distribution['findPackageForDownload'](distribution['version']); const result = await distribution['findPackageForDownload'](
distribution['version']
);
expect(result.version).toBe(expected); expect(result.version).toBe(expected);
}); });
@ -179,7 +224,7 @@ describe('findPackageForDownload', () => {
distribution['getAvailableVersions'] = async () => manifestData; distribution['getAvailableVersions'] = async () => manifestData;
await expect( await expect(
distribution['findPackageForDownload'](distribution['version']) distribution['findPackageForDownload'](distribution['version'])
).rejects.toThrowError(/Could not find satisfied version for semver */); ).rejects.toThrow(/Could not find satisfied version for semver */);
}); });
}); });

View file

@ -1,6 +1,7 @@
import path = require('path'); import * as path from 'path';
import io = require('@actions/io'); import * as io from '@actions/io';
import exec = require('@actions/exec'); import * as exec from '@actions/exec';
import * as gpg from '../src/gpg';
jest.mock('@actions/exec', () => { jest.mock('@actions/exec', () => {
return { return {
@ -11,8 +12,6 @@ jest.mock('@actions/exec', () => {
const tempDir = path.join(__dirname, 'runner', 'temp'); const tempDir = path.join(__dirname, 'runner', 'temp');
process.env['RUNNER_TEMP'] = tempDir; process.env['RUNNER_TEMP'] = tempDir;
import gpg = require('../src/gpg');
describe('gpg tests', () => { describe('gpg tests', () => {
beforeEach(async () => { beforeEach(async () => {
await io.mkdirP(tempDir); await io.mkdirP(tempDir);
@ -33,7 +32,11 @@ describe('gpg tests', () => {
expect(keyId).toBeNull(); expect(keyId).toBeNull();
expect(exec.exec).toHaveBeenCalledWith('gpg', expect.anything(), expect.anything()); expect(exec.exec).toHaveBeenCalledWith(
'gpg',
expect.anything(),
expect.anything()
);
}); });
}); });
@ -42,7 +45,11 @@ describe('gpg tests', () => {
const keyId = 'asdfhjkl'; const keyId = 'asdfhjkl';
await gpg.deleteKey(keyId); await gpg.deleteKey(keyId);
expect(exec.exec).toHaveBeenCalledWith('gpg', expect.anything(), expect.anything()); expect(exec.exec).toHaveBeenCalledWith(
'gpg',
expect.anything(),
expect.anything()
);
}); });
}); });
}); });

View file

@ -4,7 +4,7 @@ import * as path from 'path';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as io from '@actions/io'; import * as io from '@actions/io';
import * as toolchains from '../src/toolchains'; import * as toolchains from '../src/toolchains';
import { M2_DIR, MVN_TOOLCHAINS_FILE } from '../src/constants'; import {M2_DIR, MVN_TOOLCHAINS_FILE} from '../src/constants';
const m2Dir = path.join(__dirname, M2_DIR); const m2Dir = path.join(__dirname, M2_DIR);
const toolchainsFile = path.join(m2Dir, MVN_TOOLCHAINS_FILE); const toolchainsFile = path.join(m2Dir, MVN_TOOLCHAINS_FILE);
@ -168,7 +168,7 @@ describe('toolchains tests', () => {
</toolchain> </toolchain>
</toolchains>`; </toolchains>`;
fs.mkdirSync(m2Dir, { recursive: true }); fs.mkdirSync(m2Dir, {recursive: true});
fs.writeFileSync(toolchainsFile, originalFile); fs.writeFileSync(toolchainsFile, originalFile);
expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(toolchainsFile)).toBe(true); expect(fs.existsSync(toolchainsFile)).toBe(true);
@ -223,7 +223,7 @@ describe('toolchains tests', () => {
</toolchain> </toolchain>
</toolchains>`; </toolchains>`;
fs.mkdirSync(m2Dir, { recursive: true }); fs.mkdirSync(m2Dir, {recursive: true});
fs.writeFileSync(toolchainsFile, originalFile); fs.writeFileSync(toolchainsFile, originalFile);
expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(toolchainsFile)).toBe(true); expect(fs.existsSync(toolchainsFile)).toBe(true);
@ -279,14 +279,26 @@ describe('toolchains tests', () => {
const version = '17'; const version = '17';
const distributionName = 'temurin'; const distributionName = 'temurin';
const id = 'temurin_17'; const id = 'temurin_17';
const jdkHome = '/opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/17.0.1-12/x64'; const jdkHome =
'/opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/17.0.1-12/x64';
await toolchains.configureToolchains(version, distributionName, jdkHome, undefined); await toolchains.configureToolchains(
version,
distributionName,
jdkHome,
undefined
);
expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(toolchainsFile)).toBe(true); expect(fs.existsSync(toolchainsFile)).toBe(true);
expect(fs.readFileSync(toolchainsFile, 'utf-8')).toEqual( expect(fs.readFileSync(toolchainsFile, 'utf-8')).toEqual(
toolchains.generateToolchainDefinition('', version, distributionName, id, jdkHome) toolchains.generateToolchainDefinition(
'',
version,
distributionName,
id,
jdkHome
)
); );
}, 100000); }, 100000);
}); });

View file

@ -1,6 +1,6 @@
import * as cache from '@actions/cache'; import * as cache from '@actions/cache';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { isVersionSatisfies, isCacheFeatureAvailable } from '../src/util'; import {isVersionSatisfies, isCacheFeatureAvailable} from '../src/util';
jest.mock('@actions/cache'); jest.mock('@actions/cache');
jest.mock('@actions/core'); jest.mock('@actions/core');
@ -20,10 +20,13 @@ describe('isVersionSatisfies', () => {
['2.5.1+3', '2.5.1+2', false], ['2.5.1+3', '2.5.1+2', false],
['15.0.0+14', '15.0.0+14.1.202003190635', false], ['15.0.0+14', '15.0.0+14.1.202003190635', false],
['15.0.0+14.1.202003190635', '15.0.0+14.1.202003190635', true] ['15.0.0+14.1.202003190635', '15.0.0+14.1.202003190635', true]
])('%s, %s -> %s', (inputRange: string, inputVersion: string, expected: boolean) => { ])(
'%s, %s -> %s',
(inputRange: string, inputVersion: string, expected: boolean) => {
const actual = isVersionSatisfies(inputRange, inputVersion); const actual = isVersionSatisfies(inputRange, inputVersion);
expect(actual).toBe(expected); expect(actual).toBe(expected);
}); }
);
}); });
describe('isCacheFeatureAvailable', () => { describe('isCacheFeatureAvailable', () => {
@ -44,7 +47,8 @@ describe('isCacheFeatureAvailable', () => {
it('isCacheFeatureAvailable disabled on dotcom', () => { it('isCacheFeatureAvailable disabled on dotcom', () => {
jest.spyOn(cache, 'isFeatureAvailable').mockImplementation(() => false); jest.spyOn(cache, 'isFeatureAvailable').mockImplementation(() => false);
const infoMock = jest.spyOn(core, 'warning'); const infoMock = jest.spyOn(core, 'warning');
const message = 'The runner was not able to contact the cache service. Caching will be skipped'; const message =
'The runner was not able to contact the cache service. Caching will be skipped';
try { try {
process.env['GITHUB_SERVER_URL'] = 'http://github.com'; process.env['GITHUB_SERVER_URL'] = 'http://github.com';
expect(isCacheFeatureAvailable()).toBe(false); expect(isCacheFeatureAvailable()).toBe(false);

437
dist/cleanup/index.js vendored
View file

@ -60004,6 +60004,7 @@ class Comparator {
static get ANY () { static get ANY () {
return ANY return ANY
} }
constructor (comp, options) { constructor (comp, options) {
options = parseOptions(options) options = parseOptions(options)
@ -60080,7 +60081,7 @@ class Comparator {
if (!options || typeof options !== 'object') { if (!options || typeof options !== 'object') {
options = { options = {
loose: !!options, loose: !!options,
includePrerelease: false includePrerelease: false,
} }
} }
@ -60128,7 +60129,7 @@ class Comparator {
module.exports = Comparator module.exports = Comparator
const parseOptions = __nccwpck_require__(785) const parseOptions = __nccwpck_require__(785)
const {re, t} = __nccwpck_require__(9523) const { re, t } = __nccwpck_require__(9523)
const cmp = __nccwpck_require__(5098) const cmp = __nccwpck_require__(5098)
const debug = __nccwpck_require__(106) const debug = __nccwpck_require__(106)
const SemVer = __nccwpck_require__(8088) const SemVer = __nccwpck_require__(8088)
@ -60171,9 +60172,9 @@ class Range {
// First, split based on boolean or || // First, split based on boolean or ||
this.raw = range this.raw = range
this.set = range this.set = range
.split(/\s*\|\|\s*/) .split('||')
// map the range to a 2d array of comparators // map the range to a 2d array of comparators
.map(range => this.parseRange(range.trim())) .map(r => this.parseRange(r.trim()))
// throw out any comparator lists that are empty // throw out any comparator lists that are empty
// this generally means that it was not a valid range, which is allowed // this generally means that it was not a valid range, which is allowed
// in loose mode, but will still throw if the WHOLE range is invalid. // in loose mode, but will still throw if the WHOLE range is invalid.
@ -60188,9 +60189,9 @@ class Range {
// keep the first one, in case they're all null sets // keep the first one, in case they're all null sets
const first = this.set[0] const first = this.set[0]
this.set = this.set.filter(c => !isNullSet(c[0])) this.set = this.set.filter(c => !isNullSet(c[0]))
if (this.set.length === 0) if (this.set.length === 0) {
this.set = [first] this.set = [first]
else if (this.set.length > 1) { } else if (this.set.length > 1) {
// if we have any that are *, then the range is just * // if we have any that are *, then the range is just *
for (const c of this.set) { for (const c of this.set) {
if (c.length === 1 && isAny(c[0])) { if (c.length === 1 && isAny(c[0])) {
@ -60226,8 +60227,9 @@ class Range {
const memoOpts = Object.keys(this.options).join(',') const memoOpts = Object.keys(this.options).join(',')
const memoKey = `parseRange:${memoOpts}:${range}` const memoKey = `parseRange:${memoOpts}:${range}`
const cached = cache.get(memoKey) const cached = cache.get(memoKey)
if (cached) if (cached) {
return cached return cached
}
const loose = this.options.loose const loose = this.options.loose
// `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
@ -60236,7 +60238,7 @@ class Range {
debug('hyphen replace', range) debug('hyphen replace', range)
// `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace)
debug('comparator trim', range, re[t.COMPARATORTRIM]) debug('comparator trim', range)
// `~ 1.2.3` => `~1.2.3` // `~ 1.2.3` => `~1.2.3`
range = range.replace(re[t.TILDETRIM], tildeTrimReplace) range = range.replace(re[t.TILDETRIM], tildeTrimReplace)
@ -60250,30 +60252,37 @@ class Range {
// At this point, the range is completely trimmed and // At this point, the range is completely trimmed and
// ready to be split into comparators. // ready to be split into comparators.
const compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] let rangeList = range
const rangeList = range
.split(' ') .split(' ')
.map(comp => parseComparator(comp, this.options)) .map(comp => parseComparator(comp, this.options))
.join(' ') .join(' ')
.split(/\s+/) .split(/\s+/)
// >=0.0.0 is equivalent to * // >=0.0.0 is equivalent to *
.map(comp => replaceGTE0(comp, this.options)) .map(comp => replaceGTE0(comp, this.options))
if (loose) {
// in loose mode, throw out any that are not valid comparators // in loose mode, throw out any that are not valid comparators
.filter(this.options.loose ? comp => !!comp.match(compRe) : () => true) rangeList = rangeList.filter(comp => {
.map(comp => new Comparator(comp, this.options)) debug('loose invalid filter', comp, this.options)
return !!comp.match(re[t.COMPARATORLOOSE])
})
}
debug('range list', rangeList)
// if any comparators are the null set, then replace with JUST null set // if any comparators are the null set, then replace with JUST null set
// if more than one comparator, remove any * comparators // if more than one comparator, remove any * comparators
// also, don't include the same comparator more than once // also, don't include the same comparator more than once
const l = rangeList.length
const rangeMap = new Map() const rangeMap = new Map()
for (const comp of rangeList) { const comparators = rangeList.map(comp => new Comparator(comp, this.options))
if (isNullSet(comp)) for (const comp of comparators) {
if (isNullSet(comp)) {
return [comp] return [comp]
}
rangeMap.set(comp.value, comp) rangeMap.set(comp.value, comp)
} }
if (rangeMap.size > 1 && rangeMap.has('')) if (rangeMap.size > 1 && rangeMap.has('')) {
rangeMap.delete('') rangeMap.delete('')
}
const result = [...rangeMap.values()] const result = [...rangeMap.values()]
cache.set(memoKey, result) cache.set(memoKey, result)
@ -60338,7 +60347,7 @@ const {
t, t,
comparatorTrimReplace, comparatorTrimReplace,
tildeTrimReplace, tildeTrimReplace,
caretTrimReplace caretTrimReplace,
} = __nccwpck_require__(9523) } = __nccwpck_require__(9523)
const isNullSet = c => c.value === '<0.0.0-0' const isNullSet = c => c.value === '<0.0.0-0'
@ -60386,9 +60395,10 @@ const isX = id => !id || id.toLowerCase() === 'x' || id === '*'
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0 // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0
// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0
// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0
// ~0.0.1 --> >=0.0.1 <0.1.0-0
const replaceTildes = (comp, options) => const replaceTildes = (comp, options) =>
comp.trim().split(/\s+/).map((comp) => { comp.trim().split(/\s+/).map((c) => {
return replaceTilde(comp, options) return replaceTilde(c, options)
}).join(' ') }).join(' ')
const replaceTilde = (comp, options) => { const replaceTilde = (comp, options) => {
@ -60425,9 +60435,11 @@ const replaceTilde = (comp, options) => {
// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0 // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0
// ^1.2.3 --> >=1.2.3 <2.0.0-0 // ^1.2.3 --> >=1.2.3 <2.0.0-0
// ^1.2.0 --> >=1.2.0 <2.0.0-0 // ^1.2.0 --> >=1.2.0 <2.0.0-0
// ^0.0.1 --> >=0.0.1 <0.0.2-0
// ^0.1.0 --> >=0.1.0 <0.2.0-0
const replaceCarets = (comp, options) => const replaceCarets = (comp, options) =>
comp.trim().split(/\s+/).map((comp) => { comp.trim().split(/\s+/).map((c) => {
return replaceCaret(comp, options) return replaceCaret(c, options)
}).join(' ') }).join(' ')
const replaceCaret = (comp, options) => { const replaceCaret = (comp, options) => {
@ -60485,8 +60497,8 @@ const replaceCaret = (comp, options) => {
const replaceXRanges = (comp, options) => { const replaceXRanges = (comp, options) => {
debug('replaceXRanges', comp, options) debug('replaceXRanges', comp, options)
return comp.split(/\s+/).map((comp) => { return comp.split(/\s+/).map((c) => {
return replaceXRange(comp, options) return replaceXRange(c, options)
}).join(' ') }).join(' ')
} }
@ -60547,8 +60559,9 @@ const replaceXRange = (comp, options) => {
} }
} }
if (gtlt === '<') if (gtlt === '<') {
pr = '-0' pr = '-0'
}
ret = `${gtlt + M}.${m}.${p}${pr}` ret = `${gtlt + M}.${m}.${p}${pr}`
} else if (xm) { } else if (xm) {
@ -60924,7 +60937,7 @@ class SemVer {
if (identifier) { if (identifier) {
// 1.2.0-beta.1 bumps to 1.2.0-beta.2, // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
if (this.prerelease[0] === identifier) { if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
if (isNaN(this.prerelease[1])) { if (isNaN(this.prerelease[1])) {
this.prerelease = [identifier, 0] this.prerelease = [identifier, 0]
} }
@ -60974,17 +60987,21 @@ const lte = __nccwpck_require__(7520)
const cmp = (a, op, b, loose) => { const cmp = (a, op, b, loose) => {
switch (op) { switch (op) {
case '===': case '===':
if (typeof a === 'object') if (typeof a === 'object') {
a = a.version a = a.version
if (typeof b === 'object') }
if (typeof b === 'object') {
b = b.version b = b.version
}
return a === b return a === b
case '!==': case '!==':
if (typeof a === 'object') if (typeof a === 'object') {
a = a.version a = a.version
if (typeof b === 'object') }
if (typeof b === 'object') {
b = b.version b = b.version
}
return a !== b return a !== b
case '': case '':
@ -61021,7 +61038,7 @@ module.exports = cmp
const SemVer = __nccwpck_require__(8088) const SemVer = __nccwpck_require__(8088)
const parse = __nccwpck_require__(5925) const parse = __nccwpck_require__(5925)
const {re, t} = __nccwpck_require__(9523) const { re, t } = __nccwpck_require__(9523)
const coerce = (version, options) => { const coerce = (version, options) => {
if (version instanceof SemVer) { if (version instanceof SemVer) {
@ -61064,8 +61081,9 @@ const coerce = (version, options) => {
re[t.COERCERTL].lastIndex = -1 re[t.COERCERTL].lastIndex = -1
} }
if (match === null) if (match === null) {
return null return null
}
return parse(`${match[2]}.${match[3] || '0'}.${match[4] || '0'}`, options) return parse(`${match[2]}.${match[3] || '0'}.${match[4] || '0'}`, options)
} }
@ -61182,7 +61200,10 @@ const inc = (version, release, options, identifier) => {
} }
try { try {
return new SemVer(version, options).inc(release, identifier).version return new SemVer(
version instanceof SemVer ? version.version : version,
options
).inc(release, identifier).version
} catch (er) { } catch (er) {
return null return null
} }
@ -61245,7 +61266,7 @@ module.exports = neq
/***/ 5925: /***/ 5925:
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
const {MAX_LENGTH} = __nccwpck_require__(2293) const { MAX_LENGTH } = __nccwpck_require__(2293)
const { re, t } = __nccwpck_require__(9523) const { re, t } = __nccwpck_require__(9523)
const SemVer = __nccwpck_require__(8088) const SemVer = __nccwpck_require__(8088)
@ -61370,51 +61391,91 @@ module.exports = valid
// just pre-load all the stuff that index.js lazily exports // just pre-load all the stuff that index.js lazily exports
const internalRe = __nccwpck_require__(9523) const internalRe = __nccwpck_require__(9523)
const constants = __nccwpck_require__(2293)
const SemVer = __nccwpck_require__(8088)
const identifiers = __nccwpck_require__(2463)
const parse = __nccwpck_require__(5925)
const valid = __nccwpck_require__(9601)
const clean = __nccwpck_require__(8848)
const inc = __nccwpck_require__(900)
const diff = __nccwpck_require__(4297)
const major = __nccwpck_require__(6688)
const minor = __nccwpck_require__(8447)
const patch = __nccwpck_require__(2866)
const prerelease = __nccwpck_require__(4016)
const compare = __nccwpck_require__(4309)
const rcompare = __nccwpck_require__(6417)
const compareLoose = __nccwpck_require__(2804)
const compareBuild = __nccwpck_require__(2156)
const sort = __nccwpck_require__(1426)
const rsort = __nccwpck_require__(8701)
const gt = __nccwpck_require__(4123)
const lt = __nccwpck_require__(194)
const eq = __nccwpck_require__(1898)
const neq = __nccwpck_require__(6017)
const gte = __nccwpck_require__(5522)
const lte = __nccwpck_require__(7520)
const cmp = __nccwpck_require__(5098)
const coerce = __nccwpck_require__(3466)
const Comparator = __nccwpck_require__(1532)
const Range = __nccwpck_require__(9828)
const satisfies = __nccwpck_require__(6055)
const toComparators = __nccwpck_require__(2706)
const maxSatisfying = __nccwpck_require__(579)
const minSatisfying = __nccwpck_require__(832)
const minVersion = __nccwpck_require__(4179)
const validRange = __nccwpck_require__(2098)
const outside = __nccwpck_require__(420)
const gtr = __nccwpck_require__(9380)
const ltr = __nccwpck_require__(3323)
const intersects = __nccwpck_require__(7008)
const simplifyRange = __nccwpck_require__(5297)
const subset = __nccwpck_require__(7863)
module.exports = { module.exports = {
parse,
valid,
clean,
inc,
diff,
major,
minor,
patch,
prerelease,
compare,
rcompare,
compareLoose,
compareBuild,
sort,
rsort,
gt,
lt,
eq,
neq,
gte,
lte,
cmp,
coerce,
Comparator,
Range,
satisfies,
toComparators,
maxSatisfying,
minSatisfying,
minVersion,
validRange,
outside,
gtr,
ltr,
intersects,
simplifyRange,
subset,
SemVer,
re: internalRe.re, re: internalRe.re,
src: internalRe.src, src: internalRe.src,
tokens: internalRe.t, tokens: internalRe.t,
SEMVER_SPEC_VERSION: (__nccwpck_require__(2293).SEMVER_SPEC_VERSION), SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION,
SemVer: __nccwpck_require__(8088), compareIdentifiers: identifiers.compareIdentifiers,
compareIdentifiers: (__nccwpck_require__(2463).compareIdentifiers), rcompareIdentifiers: identifiers.rcompareIdentifiers,
rcompareIdentifiers: (__nccwpck_require__(2463).rcompareIdentifiers),
parse: __nccwpck_require__(5925),
valid: __nccwpck_require__(9601),
clean: __nccwpck_require__(8848),
inc: __nccwpck_require__(900),
diff: __nccwpck_require__(4297),
major: __nccwpck_require__(6688),
minor: __nccwpck_require__(8447),
patch: __nccwpck_require__(2866),
prerelease: __nccwpck_require__(4016),
compare: __nccwpck_require__(4309),
rcompare: __nccwpck_require__(6417),
compareLoose: __nccwpck_require__(2804),
compareBuild: __nccwpck_require__(2156),
sort: __nccwpck_require__(1426),
rsort: __nccwpck_require__(8701),
gt: __nccwpck_require__(4123),
lt: __nccwpck_require__(194),
eq: __nccwpck_require__(1898),
neq: __nccwpck_require__(6017),
gte: __nccwpck_require__(5522),
lte: __nccwpck_require__(7520),
cmp: __nccwpck_require__(5098),
coerce: __nccwpck_require__(3466),
Comparator: __nccwpck_require__(1532),
Range: __nccwpck_require__(9828),
satisfies: __nccwpck_require__(6055),
toComparators: __nccwpck_require__(2706),
maxSatisfying: __nccwpck_require__(579),
minSatisfying: __nccwpck_require__(832),
minVersion: __nccwpck_require__(4179),
validRange: __nccwpck_require__(2098),
outside: __nccwpck_require__(420),
gtr: __nccwpck_require__(9380),
ltr: __nccwpck_require__(3323),
intersects: __nccwpck_require__(7008),
simplifyRange: __nccwpck_require__(5297),
subset: __nccwpck_require__(7863),
} }
@ -61429,7 +61490,7 @@ const SEMVER_SPEC_VERSION = '2.0.0'
const MAX_LENGTH = 256 const MAX_LENGTH = 256
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
/* istanbul ignore next */ 9007199254740991 /* istanbul ignore next */ 9007199254740991
// Max safe segment length for coercion. // Max safe segment length for coercion.
const MAX_SAFE_COMPONENT_LENGTH = 16 const MAX_SAFE_COMPONENT_LENGTH = 16
@ -61438,7 +61499,7 @@ module.exports = {
SEMVER_SPEC_VERSION, SEMVER_SPEC_VERSION,
MAX_LENGTH, MAX_LENGTH,
MAX_SAFE_INTEGER, MAX_SAFE_INTEGER,
MAX_SAFE_COMPONENT_LENGTH MAX_SAFE_COMPONENT_LENGTH,
} }
@ -61484,7 +61545,7 @@ const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a)
module.exports = { module.exports = {
compareIdentifiers, compareIdentifiers,
rcompareIdentifiers rcompareIdentifiers,
} }
@ -61499,9 +61560,9 @@ const opts = ['includePrerelease', 'loose', 'rtl']
const parseOptions = options => const parseOptions = options =>
!options ? {} !options ? {}
: typeof options !== 'object' ? { loose: true } : typeof options !== 'object' ? { loose: true }
: opts.filter(k => options[k]).reduce((options, k) => { : opts.filter(k => options[k]).reduce((o, k) => {
options[k] = true o[k] = true
return options return o
}, {}) }, {})
module.exports = parseOptions module.exports = parseOptions
@ -61523,7 +61584,7 @@ let R = 0
const createToken = (name, value, isGlobal) => { const createToken = (name, value, isGlobal) => {
const index = R++ const index = R++
debug(index, value) debug(name, index, value)
t[name] = index t[name] = index
src[index] = value src[index] = value
re[index] = new RegExp(value, isGlobal ? 'g' : undefined) re[index] = new RegExp(value, isGlobal ? 'g' : undefined)
@ -61691,8 +61752,8 @@ createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
// Star ranges basically just allow anything at all. // Star ranges basically just allow anything at all.
createToken('STAR', '(<|>)?=?\\s*\\*') createToken('STAR', '(<|>)?=?\\s*\\*')
// >=0.0.0 is like a star // >=0.0.0 is like a star
createToken('GTE0', '^\\s*>=\\s*0\.0\.0\\s*$') createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$')
createToken('GTE0PRE', '^\\s*>=\\s*0\.0\.0-0\\s*$') createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$')
/***/ }), /***/ }),
@ -61848,9 +61909,10 @@ const minVersion = (range, loose) => {
throw new Error(`Unexpected operation: ${comparator.operator}`) throw new Error(`Unexpected operation: ${comparator.operator}`)
} }
}) })
if (setMin && (!minver || gt(minver, setMin))) if (setMin && (!minver || gt(minver, setMin))) {
minver = setMin minver = setMin
} }
}
if (minver && range.test(minver)) { if (minver && range.test(minver)) {
return minver return minver
@ -61868,7 +61930,7 @@ module.exports = minVersion
const SemVer = __nccwpck_require__(8088) const SemVer = __nccwpck_require__(8088)
const Comparator = __nccwpck_require__(1532) const Comparator = __nccwpck_require__(1532)
const {ANY} = Comparator const { ANY } = Comparator
const Range = __nccwpck_require__(9828) const Range = __nccwpck_require__(9828)
const satisfies = __nccwpck_require__(6055) const satisfies = __nccwpck_require__(6055)
const gt = __nccwpck_require__(4123) const gt = __nccwpck_require__(4123)
@ -61960,39 +62022,42 @@ const satisfies = __nccwpck_require__(6055)
const compare = __nccwpck_require__(4309) const compare = __nccwpck_require__(4309)
module.exports = (versions, range, options) => { module.exports = (versions, range, options) => {
const set = [] const set = []
let min = null let first = null
let prev = null let prev = null
const v = versions.sort((a, b) => compare(a, b, options)) const v = versions.sort((a, b) => compare(a, b, options))
for (const version of v) { for (const version of v) {
const included = satisfies(version, range, options) const included = satisfies(version, range, options)
if (included) { if (included) {
prev = version prev = version
if (!min) if (!first) {
min = version first = version
}
} else { } else {
if (prev) { if (prev) {
set.push([min, prev]) set.push([first, prev])
} }
prev = null prev = null
min = null first = null
} }
} }
if (min) if (first) {
set.push([min, null]) set.push([first, null])
}
const ranges = [] const ranges = []
for (const [min, max] of set) { for (const [min, max] of set) {
if (min === max) if (min === max) {
ranges.push(min) ranges.push(min)
else if (!max && min === v[0]) } else if (!max && min === v[0]) {
ranges.push('*') ranges.push('*')
else if (!max) } else if (!max) {
ranges.push(`>=${min}`) ranges.push(`>=${min}`)
else if (min === v[0]) } else if (min === v[0]) {
ranges.push(`<=${max}`) ranges.push(`<=${max}`)
else } else {
ranges.push(`${min} - ${max}`) ranges.push(`${min} - ${max}`)
} }
}
const simplified = ranges.join(' || ') const simplified = ranges.join(' || ')
const original = typeof range.raw === 'string' ? range.raw : String(range) const original = typeof range.raw === 'string' ? range.raw : String(range)
return simplified.length < original.length ? simplified : range return simplified.length < original.length ? simplified : range
@ -62005,22 +62070,30 @@ module.exports = (versions, range, options) => {
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
const Range = __nccwpck_require__(9828) const Range = __nccwpck_require__(9828)
const { ANY } = __nccwpck_require__(1532) const Comparator = __nccwpck_require__(1532)
const { ANY } = Comparator
const satisfies = __nccwpck_require__(6055) const satisfies = __nccwpck_require__(6055)
const compare = __nccwpck_require__(4309) const compare = __nccwpck_require__(4309)
// Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff: // Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff:
// - Every simple range `r1, r2, ...` is a subset of some `R1, R2, ...` // - Every simple range `r1, r2, ...` is a null set, OR
// - Every simple range `r1, r2, ...` which is not a null set is a subset of
// some `R1, R2, ...`
// //
// Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff: // Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff:
// - If c is only the ANY comparator // - If c is only the ANY comparator
// - If C is only the ANY comparator, return true // - If C is only the ANY comparator, return true
// - Else return false // - Else if in prerelease mode, return false
// - else replace c with `[>=0.0.0]`
// - If C is only the ANY comparator
// - if in prerelease mode, return true
// - else replace C with `[>=0.0.0]`
// - Let EQ be the set of = comparators in c // - Let EQ be the set of = comparators in c
// - If EQ is more than one, return true (null set) // - If EQ is more than one, return true (null set)
// - Let GT be the highest > or >= comparator in c // - Let GT be the highest > or >= comparator in c
// - Let LT be the lowest < or <= comparator in c // - Let LT be the lowest < or <= comparator in c
// - If GT and LT, and GT.semver > LT.semver, return true (null set) // - If GT and LT, and GT.semver > LT.semver, return true (null set)
// - If any C is a = range, and GT or LT are set, return false
// - If EQ // - If EQ
// - If GT, and EQ does not satisfy GT, return true (null set) // - If GT, and EQ does not satisfy GT, return true (null set)
// - If LT, and EQ does not satisfy LT, return true (null set) // - If LT, and EQ does not satisfy LT, return true (null set)
@ -62029,15 +62102,19 @@ const compare = __nccwpck_require__(4309)
// - If GT // - If GT
// - If GT.semver is lower than any > or >= comp in C, return false // - If GT.semver is lower than any > or >= comp in C, return false
// - If GT is >=, and GT.semver does not satisfy every C, return false // - If GT is >=, and GT.semver does not satisfy every C, return false
// - If GT.semver has a prerelease, and not in prerelease mode
// - If no C has a prerelease and the GT.semver tuple, return false
// - If LT // - If LT
// - If LT.semver is greater than any < or <= comp in C, return false // - If LT.semver is greater than any < or <= comp in C, return false
// - If LT is <=, and LT.semver does not satisfy every C, return false // - If LT is <=, and LT.semver does not satisfy every C, return false
// - If any C is a = range, and GT or LT are set, return false // - If GT.semver has a prerelease, and not in prerelease mode
// - If no C has a prerelease and the LT.semver tuple, return false
// - Else return true // - Else return true
const subset = (sub, dom, options) => { const subset = (sub, dom, options = {}) => {
if (sub === dom) if (sub === dom) {
return true return true
}
sub = new Range(sub, options) sub = new Range(sub, options)
dom = new Range(dom, options) dom = new Range(dom, options)
@ -62047,106 +62124,175 @@ const subset = (sub, dom, options) => {
for (const simpleDom of dom.set) { for (const simpleDom of dom.set) {
const isSub = simpleSubset(simpleSub, simpleDom, options) const isSub = simpleSubset(simpleSub, simpleDom, options)
sawNonNull = sawNonNull || isSub !== null sawNonNull = sawNonNull || isSub !== null
if (isSub) if (isSub) {
continue OUTER continue OUTER
} }
}
// the null set is a subset of everything, but null simple ranges in // the null set is a subset of everything, but null simple ranges in
// a complex range should be ignored. so if we saw a non-null range, // a complex range should be ignored. so if we saw a non-null range,
// then we know this isn't a subset, but if EVERY simple range was null, // then we know this isn't a subset, but if EVERY simple range was null,
// then it is a subset. // then it is a subset.
if (sawNonNull) if (sawNonNull) {
return false return false
} }
}
return true return true
} }
const simpleSubset = (sub, dom, options) => { const simpleSubset = (sub, dom, options) => {
if (sub === dom) if (sub === dom) {
return true return true
}
if (sub.length === 1 && sub[0].semver === ANY) if (sub.length === 1 && sub[0].semver === ANY) {
return dom.length === 1 && dom[0].semver === ANY if (dom.length === 1 && dom[0].semver === ANY) {
return true
} else if (options.includePrerelease) {
sub = [new Comparator('>=0.0.0-0')]
} else {
sub = [new Comparator('>=0.0.0')]
}
}
if (dom.length === 1 && dom[0].semver === ANY) {
if (options.includePrerelease) {
return true
} else {
dom = [new Comparator('>=0.0.0')]
}
}
const eqSet = new Set() const eqSet = new Set()
let gt, lt let gt, lt
for (const c of sub) { for (const c of sub) {
if (c.operator === '>' || c.operator === '>=') if (c.operator === '>' || c.operator === '>=') {
gt = higherGT(gt, c, options) gt = higherGT(gt, c, options)
else if (c.operator === '<' || c.operator === '<=') } else if (c.operator === '<' || c.operator === '<=') {
lt = lowerLT(lt, c, options) lt = lowerLT(lt, c, options)
else } else {
eqSet.add(c.semver) eqSet.add(c.semver)
} }
}
if (eqSet.size > 1) if (eqSet.size > 1) {
return null return null
}
let gtltComp let gtltComp
if (gt && lt) { if (gt && lt) {
gtltComp = compare(gt.semver, lt.semver, options) gtltComp = compare(gt.semver, lt.semver, options)
if (gtltComp > 0) if (gtltComp > 0) {
return null return null
else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) } else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) {
return null return null
} }
}
// will iterate one or zero times // will iterate one or zero times
for (const eq of eqSet) { for (const eq of eqSet) {
if (gt && !satisfies(eq, String(gt), options)) if (gt && !satisfies(eq, String(gt), options)) {
return null return null
}
if (lt && !satisfies(eq, String(lt), options)) if (lt && !satisfies(eq, String(lt), options)) {
return null return null
}
for (const c of dom) { for (const c of dom) {
if (!satisfies(eq, String(c), options)) if (!satisfies(eq, String(c), options)) {
return false return false
} }
}
return true return true
} }
let higher, lower let higher, lower
let hasDomLT, hasDomGT let hasDomLT, hasDomGT
// if the subset has a prerelease, we need a comparator in the superset
// with the same tuple and a prerelease, or it's not a subset
let needDomLTPre = lt &&
!options.includePrerelease &&
lt.semver.prerelease.length ? lt.semver : false
let needDomGTPre = gt &&
!options.includePrerelease &&
gt.semver.prerelease.length ? gt.semver : false
// exception: <1.2.3-0 is the same as <1.2.3
if (needDomLTPre && needDomLTPre.prerelease.length === 1 &&
lt.operator === '<' && needDomLTPre.prerelease[0] === 0) {
needDomLTPre = false
}
for (const c of dom) { for (const c of dom) {
hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>=' hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>='
hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<=' hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<='
if (gt) { if (gt) {
if (needDomGTPre) {
if (c.semver.prerelease && c.semver.prerelease.length &&
c.semver.major === needDomGTPre.major &&
c.semver.minor === needDomGTPre.minor &&
c.semver.patch === needDomGTPre.patch) {
needDomGTPre = false
}
}
if (c.operator === '>' || c.operator === '>=') { if (c.operator === '>' || c.operator === '>=') {
higher = higherGT(gt, c, options) higher = higherGT(gt, c, options)
if (higher === c && higher !== gt) if (higher === c && higher !== gt) {
return false return false
} else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) }
} else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) {
return false return false
} }
}
if (lt) { if (lt) {
if (needDomLTPre) {
if (c.semver.prerelease && c.semver.prerelease.length &&
c.semver.major === needDomLTPre.major &&
c.semver.minor === needDomLTPre.minor &&
c.semver.patch === needDomLTPre.patch) {
needDomLTPre = false
}
}
if (c.operator === '<' || c.operator === '<=') { if (c.operator === '<' || c.operator === '<=') {
lower = lowerLT(lt, c, options) lower = lowerLT(lt, c, options)
if (lower === c && lower !== lt) if (lower === c && lower !== lt) {
return false
} else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options))
return false return false
} }
if (!c.operator && (lt || gt) && gtltComp !== 0) } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) {
return false return false
} }
}
if (!c.operator && (lt || gt) && gtltComp !== 0) {
return false
}
}
// if there was a < or >, and nothing in the dom, then must be false // if there was a < or >, and nothing in the dom, then must be false
// UNLESS it was limited by another range in the other direction. // UNLESS it was limited by another range in the other direction.
// Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0 // Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0
if (gt && hasDomLT && !lt && gtltComp !== 0) if (gt && hasDomLT && !lt && gtltComp !== 0) {
return false return false
}
if (lt && hasDomGT && !gt && gtltComp !== 0) if (lt && hasDomGT && !gt && gtltComp !== 0) {
return false return false
}
// we needed a prerelease range in a specific tuple, but didn't get one
// then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0,
// because it includes prereleases in the 1.2.3 tuple
if (needDomGTPre || needDomLTPre) {
return false
}
return true return true
} }
// >=1.2.3 is lower than >1.2.3 // >=1.2.3 is lower than >1.2.3
const higherGT = (a, b, options) => { const higherGT = (a, b, options) => {
if (!a) if (!a) {
return b return b
}
const comp = compare(a.semver, b.semver, options) const comp = compare(a.semver, b.semver, options)
return comp > 0 ? a return comp > 0 ? a
: comp < 0 ? b : comp < 0 ? b
@ -62156,8 +62302,9 @@ const higherGT = (a, b, options) => {
// <=1.2.3 is higher than <1.2.3 // <=1.2.3 is higher than <1.2.3
const lowerLT = (a, b, options) => { const lowerLT = (a, b, options) => {
if (!a) if (!a) {
return b return b
}
const comp = compare(a.semver, b.semver, options) const comp = compare(a.semver, b.semver, options)
return comp < 0 ? a return comp < 0 ? a
: comp > 0 ? b : comp > 0 ? b
@ -68242,7 +68389,10 @@ const supportedPackageManager = [
}, },
{ {
id: 'gradle', id: 'gradle',
path: [path_1.join(os_1.default.homedir(), '.gradle', 'caches'), path_1.join(os_1.default.homedir(), '.gradle', 'wrapper')], path: [
path_1.join(os_1.default.homedir(), '.gradle', 'caches'),
path_1.join(os_1.default.homedir(), '.gradle', 'wrapper')
],
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle // https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
pattern: [ pattern: [
'**/*.gradle*', '**/*.gradle*',
@ -68263,7 +68413,11 @@ const supportedPackageManager = [
'!' + path_1.join(os_1.default.homedir(), '.sbt', '*.lock'), '!' + path_1.join(os_1.default.homedir(), '.sbt', '*.lock'),
'!' + path_1.join(os_1.default.homedir(), '**', 'ivydata-*.properties') '!' + path_1.join(os_1.default.homedir(), '**', 'ivydata-*.properties')
], ],
pattern: ['**/*.sbt', '**/project/build.properties', '**/project/**.{scala,sbt}'] pattern: [
'**/*.sbt',
'**/project/build.properties',
'**/project/**.{scala,sbt}'
]
} }
]; ];
function getCoursierCachePath() { function getCoursierCachePath() {
@ -68363,7 +68517,8 @@ exports.save = save;
* @see {@link https://github.com/actions/cache/issues/454#issuecomment-840493935|why --no-daemon is necessary} * @see {@link https://github.com/actions/cache/issues/454#issuecomment-840493935|why --no-daemon is necessary}
*/ */
function isProbablyGradleDaemonProblem(packageManager, error) { function isProbablyGradleDaemonProblem(packageManager, error) {
if (packageManager.id !== 'gradle' || process.env['RUNNER_OS'] !== 'Windows') { if (packageManager.id !== 'gradle' ||
process.env['RUNNER_OS'] !== 'Windows') {
return false; return false;
} }
const message = error.message || ''; const message = error.message || '';
@ -68568,7 +68723,13 @@ function importKey(privateKey) {
} }
} }
}; };
yield exec.exec('gpg', ['--batch', '--import-options', 'import-show', '--import', exports.PRIVATE_KEY_FILE], options); yield exec.exec('gpg', [
'--batch',
'--import-options',
'import-show',
'--import',
exports.PRIVATE_KEY_FILE
], options);
yield io.rmRF(exports.PRIVATE_KEY_FILE); yield io.rmRF(exports.PRIVATE_KEY_FILE);
const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX); const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX);
return match && match[0]; return match && match[0];
@ -68634,12 +68795,12 @@ const core = __importStar(__nccwpck_require__(2186));
const tc = __importStar(__nccwpck_require__(7784)); const tc = __importStar(__nccwpck_require__(7784));
const constants_1 = __nccwpck_require__(9042); const constants_1 = __nccwpck_require__(9042);
function getTempDir() { function getTempDir() {
let tempDirectory = process.env['RUNNER_TEMP'] || os_1.default.tmpdir(); const tempDirectory = process.env['RUNNER_TEMP'] || os_1.default.tmpdir();
return tempDirectory; return tempDirectory;
} }
exports.getTempDir = getTempDir; exports.getTempDir = getTempDir;
function getBooleanInput(inputName, defaultValue = false) { function getBooleanInput(inputName, defaultValue = false) {
return (core.getInput(inputName) || String(defaultValue)).toUpperCase() === 'TRUE'; return ((core.getInput(inputName) || String(defaultValue)).toUpperCase() === 'TRUE');
} }
exports.getBooleanInput = getBooleanInput; exports.getBooleanInput = getBooleanInput;
function getVersionFromToolcachePath(toolPath) { function getVersionFromToolcachePath(toolPath) {
@ -68652,7 +68813,9 @@ exports.getVersionFromToolcachePath = getVersionFromToolcachePath;
function extractJdkFile(toolPath, extension) { function extractJdkFile(toolPath, extension) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
if (!extension) { if (!extension) {
extension = toolPath.endsWith('.tar.gz') ? 'tar.gz' : path_1.default.extname(toolPath); extension = toolPath.endsWith('.tar.gz')
? 'tar.gz'
: path_1.default.extname(toolPath);
if (extension.startsWith('.')) { if (extension.startsWith('.')) {
extension = extension.substring(1); extension = extension.substring(1);
} }
@ -68721,7 +68884,7 @@ function isCacheFeatureAvailable() {
exports.isCacheFeatureAvailable = isCacheFeatureAvailable; exports.isCacheFeatureAvailable = isCacheFeatureAvailable;
function getVersionFromFileContent(content, distributionName) { function getVersionFromFileContent(content, distributionName) {
var _a, _b, _c, _d, _e; var _a, _b, _c, _d, _e;
const javaVersionRegExp = /(?<version>(?<=(^|\s|\-))(\d+\S*))(\s|$)/; const javaVersionRegExp = /(?<version>(?<=(^|\s|-))(\d+\S*))(\s|$)/;
const fileContent = ((_b = (_a = content.match(javaVersionRegExp)) === null || _a === void 0 ? void 0 : _a.groups) === null || _b === void 0 ? void 0 : _b.version) const fileContent = ((_b = (_a = content.match(javaVersionRegExp)) === null || _a === void 0 ? void 0 : _a.groups) === null || _b === void 0 ? void 0 : _b.version)
? (_d = (_c = content.match(javaVersionRegExp)) === null || _c === void 0 ? void 0 : _c.groups) === null || _d === void 0 ? void 0 : _d.version ? (_d = (_c = content.match(javaVersionRegExp)) === null || _c === void 0 ? void 0 : _c.groups) === null || _d === void 0 ? void 0 : _d.version
: ''; : '';
@ -68731,7 +68894,9 @@ function getVersionFromFileContent(content, distributionName) {
core.debug(`Version from file '${fileContent}'`); core.debug(`Version from file '${fileContent}'`);
const tentativeVersion = avoidOldNotation(fileContent); const tentativeVersion = avoidOldNotation(fileContent);
const rawVersion = tentativeVersion.split('-')[0]; const rawVersion = tentativeVersion.split('-')[0];
let version = semver.validRange(rawVersion) ? tentativeVersion : semver.coerce(tentativeVersion); let version = semver.validRange(rawVersion)
? tentativeVersion
: semver.coerce(tentativeVersion);
core.debug(`Range version from file is '${version}'`); core.debug(`Range version from file is '${version}'`);
if (!version) { if (!version) {
return null; return null;

583
dist/setup/index.js vendored

File diff suppressed because it is too large Load diff

View file

@ -60,6 +60,7 @@ Pull requests are the easiest way to contribute changes to git repos at GitHub.
- To implement new features or fix bugs, you need to make changes to the `.ts` files, which are located in the `src` folder - To implement new features or fix bugs, you need to make changes to the `.ts` files, which are located in the `src` folder
- To comply with the code style, **you need to run the `format` script** - To comply with the code style, **you need to run the `format` script**
- To lint the code, **you need to run the `lint:fix` script**
- To transpile source code to `javascript` we use [NCC](https://github.com/vercel/ncc). **It is very important to run the `build` script after making changes**, otherwise your changes will not get into the final `javascript` build - To transpile source code to `javascript` we use [NCC](https://github.com/vercel/ncc). **It is very important to run the `build` script after making changes**, otherwise your changes will not get into the final `javascript` build
**Learn more about how to implement tests:** **Learn more about how to implement tests:**

2234
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -6,9 +6,10 @@
"main": "dist/setup/index.js", "main": "dist/setup/index.js",
"scripts": { "scripts": {
"build": "ncc build -o dist/setup src/setup-java.ts && ncc build -o dist/cleanup src/cleanup-java.ts", "build": "ncc build -o dist/setup src/setup-java.ts && ncc build -o dist/cleanup src/cleanup-java.ts",
"format": "prettier --write \"{,!(node_modules)/**/}*.ts\"", "format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write **/*.{ts,yml,yaml}",
"format-check": "prettier --check \"{,!(node_modules)/**/}*.ts\"", "format-check": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --check **/*.{ts,yml,yaml}",
"lint": "echo \"Fake command that does nothing. It is used in reusable workflows\"", "lint": "eslint --config ./.eslintrc.js **/*.ts",
"lint:fix": "eslint --config ./.eslintrc.js **/*.ts --fix",
"prerelease": "npm run-script build", "prerelease": "npm run-script build",
"release": "git add -f dist/setup/index.js dist/cleanup/index.js", "release": "git add -f dist/setup/index.js dist/cleanup/index.js",
"test": "jest" "test": "jest"
@ -39,10 +40,15 @@
"@types/jest": "^27.0.2", "@types/jest": "^27.0.2",
"@types/node": "^16.11.25", "@types/node": "^16.11.25",
"@types/semver": "^7.3.4", "@types/semver": "^7.3.4",
"@typescript-eslint/eslint-plugin": "^5.54.0",
"@typescript-eslint/parser": "^5.54.0",
"@vercel/ncc": "^0.33.4", "@vercel/ncc": "^0.33.4",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-jest": "^27.2.1",
"jest": "^27.2.5", "jest": "^27.2.5",
"jest-circus": "^27.2.5", "jest-circus": "^27.2.5",
"prettier": "^1.19.1", "prettier": "^2.8.4",
"ts-jest": "^27.0.5", "ts-jest": "^27.0.5",
"typescript": "^4.2.3" "typescript": "^4.2.3"
} }

View file

@ -5,20 +5,25 @@ import * as io from '@actions/io';
import * as fs from 'fs'; import * as fs from 'fs';
import * as os from 'os'; import * as os from 'os';
import { create as xmlCreate } from 'xmlbuilder2'; import {create as xmlCreate} from 'xmlbuilder2';
import * as constants from './constants'; import * as constants from './constants';
import * as gpg from './gpg'; import * as gpg from './gpg';
import { getBooleanInput } from './util'; import {getBooleanInput} from './util';
export async function configureAuthentication() { export async function configureAuthentication() {
const id = core.getInput(constants.INPUT_SERVER_ID); const id = core.getInput(constants.INPUT_SERVER_ID);
const username = core.getInput(constants.INPUT_SERVER_USERNAME); const username = core.getInput(constants.INPUT_SERVER_USERNAME);
const password = core.getInput(constants.INPUT_SERVER_PASSWORD); const password = core.getInput(constants.INPUT_SERVER_PASSWORD);
const settingsDirectory = const settingsDirectory =
core.getInput(constants.INPUT_SETTINGS_PATH) || path.join(os.homedir(), constants.M2_DIR); core.getInput(constants.INPUT_SETTINGS_PATH) ||
const overwriteSettings = getBooleanInput(constants.INPUT_OVERWRITE_SETTINGS, true); path.join(os.homedir(), constants.M2_DIR);
const overwriteSettings = getBooleanInput(
constants.INPUT_OVERWRITE_SETTINGS,
true
);
const gpgPrivateKey = const gpgPrivateKey =
core.getInput(constants.INPUT_GPG_PRIVATE_KEY) || constants.INPUT_DEFAULT_GPG_PRIVATE_KEY; core.getInput(constants.INPUT_GPG_PRIVATE_KEY) ||
constants.INPUT_DEFAULT_GPG_PRIVATE_KEY;
const gpgPassphrase = const gpgPassphrase =
core.getInput(constants.INPUT_GPG_PASSPHRASE) || core.getInput(constants.INPUT_GPG_PASSPHRASE) ||
(gpgPrivateKey ? constants.INPUT_DEFAULT_GPG_PASSPHRASE : undefined); (gpgPrivateKey ? constants.INPUT_DEFAULT_GPG_PASSPHRASE : undefined);
@ -69,7 +74,7 @@ export function generate(
password: string, password: string,
gpgPassphrase?: string | undefined gpgPassphrase?: string | undefined
) { ) {
const xmlObj: { [key: string]: any } = { const xmlObj: {[key: string]: any} = {
settings: { settings: {
'@xmlns': 'http://maven.apache.org/SETTINGS/1.0.0', '@xmlns': 'http://maven.apache.org/SETTINGS/1.0.0',
'@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', '@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
@ -102,7 +107,11 @@ export function generate(
}); });
} }
async function write(directory: string, settings: string, overwriteSettings: boolean) { async function write(
directory: string,
settings: string,
overwriteSettings: boolean
) {
const location = path.join(directory, constants.MVN_SETTINGS_FILE); const location = path.join(directory, constants.MVN_SETTINGS_FILE);
const settingsExists = fs.existsSync(location); const settingsExists = fs.existsSync(location);
if (settingsExists && overwriteSettings) { if (settingsExists && overwriteSettings) {

View file

@ -2,7 +2,7 @@
* @fileoverview this file provides methods handling dependency cache * @fileoverview this file provides methods handling dependency cache
*/ */
import { join } from 'path'; import {join} from 'path';
import os from 'os'; import os from 'os';
import * as cache from '@actions/cache'; import * as cache from '@actions/cache';
import * as core from '@actions/core'; import * as core from '@actions/core';
@ -29,7 +29,10 @@ const supportedPackageManager: PackageManager[] = [
}, },
{ {
id: 'gradle', id: 'gradle',
path: [join(os.homedir(), '.gradle', 'caches'), join(os.homedir(), '.gradle', 'wrapper')], path: [
join(os.homedir(), '.gradle', 'caches'),
join(os.homedir(), '.gradle', 'wrapper')
],
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle // https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
pattern: [ pattern: [
'**/*.gradle*', '**/*.gradle*',
@ -50,18 +53,25 @@ const supportedPackageManager: PackageManager[] = [
'!' + join(os.homedir(), '.sbt', '*.lock'), '!' + join(os.homedir(), '.sbt', '*.lock'),
'!' + join(os.homedir(), '**', 'ivydata-*.properties') '!' + join(os.homedir(), '**', 'ivydata-*.properties')
], ],
pattern: ['**/*.sbt', '**/project/build.properties', '**/project/**.{scala,sbt}'] pattern: [
'**/*.sbt',
'**/project/build.properties',
'**/project/**.{scala,sbt}'
]
} }
]; ];
function getCoursierCachePath(): string { function getCoursierCachePath(): string {
if (os.type() === 'Linux') return join(os.homedir(), '.cache', 'coursier'); if (os.type() === 'Linux') return join(os.homedir(), '.cache', 'coursier');
if (os.type() === 'Darwin') return join(os.homedir(), 'Library', 'Caches', 'Coursier'); if (os.type() === 'Darwin')
return join(os.homedir(), 'Library', 'Caches', 'Coursier');
return join(os.homedir(), 'AppData', 'Local', 'Coursier', 'Cache'); return join(os.homedir(), 'AppData', 'Local', 'Coursier', 'Cache');
} }
function findPackageManager(id: string): PackageManager { function findPackageManager(id: string): PackageManager {
const packageManager = supportedPackageManager.find(packageManager => packageManager.id === id); const packageManager = supportedPackageManager.find(
packageManager => packageManager.id === id
);
if (packageManager === undefined) { if (packageManager === undefined) {
throw new Error(`unknown package manager specified: ${id}`); throw new Error(`unknown package manager specified: ${id}`);
} }
@ -125,7 +135,9 @@ export async function save(id: string) {
return; return;
} else if (matchedKey === primaryKey) { } else if (matchedKey === primaryKey) {
// no change in target directories // no change in target directories
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`); core.info(
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
);
return; return;
} }
try { try {
@ -151,8 +163,14 @@ export async function save(id: string) {
* @returns true if the given error seems related to the {@link https://github.com/actions/cache/issues/454|running Gradle Daemon issue}. * @returns true if the given error seems related to the {@link https://github.com/actions/cache/issues/454|running Gradle Daemon issue}.
* @see {@link https://github.com/actions/cache/issues/454#issuecomment-840493935|why --no-daemon is necessary} * @see {@link https://github.com/actions/cache/issues/454#issuecomment-840493935|why --no-daemon is necessary}
*/ */
function isProbablyGradleDaemonProblem(packageManager: PackageManager, error: Error) { function isProbablyGradleDaemonProblem(
if (packageManager.id !== 'gradle' || process.env['RUNNER_OS'] !== 'Windows') { packageManager: PackageManager,
error: Error
) {
if (
packageManager.id !== 'gradle' ||
process.env['RUNNER_OS'] !== 'Windows'
) {
return false; return false;
} }
const message = error.message || ''; const message = error.message || '';

View file

@ -1,14 +1,16 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as gpg from './gpg'; import * as gpg from './gpg';
import * as constants from './constants'; import * as constants from './constants';
import { isJobStatusSuccess } from './util'; import {isJobStatusSuccess} from './util';
import { save } from './cache'; import {save} from './cache';
async function removePrivateKeyFromKeychain() { async function removePrivateKeyFromKeychain() {
if (core.getInput(constants.INPUT_GPG_PRIVATE_KEY, { required: false })) { if (core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false})) {
core.info('Removing private key from keychain'); core.info('Removing private key from keychain');
try { try {
const keyFingerprint = core.getState(constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT); const keyFingerprint = core.getState(
constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT
);
await gpg.deleteKey(keyFingerprint); await gpg.deleteKey(keyFingerprint);
} catch (error) { } catch (error) {
core.setFailed(`Failed to remove private key due to: ${error.message}`); core.setFailed(`Failed to remove private key due to: ${error.message}`);

View file

@ -5,10 +5,18 @@ import fs from 'fs';
import path from 'path'; import path from 'path';
import semver from 'semver'; import semver from 'semver';
import { JavaBase } from '../base-installer'; import {JavaBase} from '../base-installer';
import { IAdoptAvailableVersions } from './models'; import {IAdoptAvailableVersions} from './models';
import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from '../base-models'; import {
import { extractJdkFile, getDownloadArchiveExtension, isVersionSatisfies } from '../../util'; JavaDownloadRelease,
JavaInstallerOptions,
JavaInstallerResults
} from '../base-models';
import {
extractJdkFile,
getDownloadArchiveExtension,
isVersionSatisfies
} from '../../util';
export enum AdoptImplementation { export enum AdoptImplementation {
Hotspot = 'Hotspot', Hotspot = 'Hotspot',
@ -23,7 +31,9 @@ export class AdoptDistribution extends JavaBase {
super(`Adopt-${jvmImpl}`, installerOptions); super(`Adopt-${jvmImpl}`, installerOptions);
} }
protected async findPackageForDownload(version: string): Promise<JavaDownloadRelease> { protected async findPackageForDownload(
version: string
): Promise<JavaDownloadRelease> {
const availableVersionsRaw = await this.getAvailableVersions(); const availableVersionsRaw = await this.getAvailableVersions();
const availableVersionsWithBinaries = availableVersionsRaw const availableVersionsWithBinaries = availableVersionsRaw
.filter(item => item.binaries.length > 0) .filter(item => item.binaries.length > 0)
@ -40,9 +50,12 @@ export class AdoptDistribution extends JavaBase {
return -semver.compareBuild(a.version, b.version); return -semver.compareBuild(a.version, b.version);
}); });
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null; const resolvedFullVersion =
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) { if (!resolvedFullVersion) {
const availableOptions = availableVersionsWithBinaries.map(item => item.version).join(', '); const availableOptions = availableVersionsWithBinaries
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}` ? `\nAvailable versions: ${availableOptions}`
: ''; : '';
@ -54,27 +67,31 @@ export class AdoptDistribution extends JavaBase {
return resolvedFullVersion; return resolvedFullVersion;
} }
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> { protected async downloadTool(
let javaPath: string; javaRelease: JavaDownloadRelease
let extractedJavaPath: string; ): Promise<JavaInstallerResults> {
core.info( core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...` `Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
); );
const javaArchivePath = await tc.downloadTool(javaRelease.url); const javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`); core.info(`Extracting Java archive...`);
let extension = getDownloadArchiveExtension(); const extension = getDownloadArchiveExtension();
extractedJavaPath = await extractJdkFile(javaArchivePath, extension); const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0]; const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName); const archivePath = path.join(extractedJavaPath, archiveName);
const version = this.getToolcacheVersionName(javaRelease.version); const version = this.getToolcacheVersionName(javaRelease.version);
javaPath = await tc.cacheDir(archivePath, this.toolcacheFolderName, version, this.architecture); const javaPath = await tc.cacheDir(
archivePath,
this.toolcacheFolderName,
version,
this.architecture
);
return { version: javaRelease.version, path: javaPath }; return {version: javaRelease.version, path: javaPath};
} }
protected get toolcacheFolderName(): string { protected get toolcacheFolderName(): string {
@ -94,7 +111,7 @@ export class AdoptDistribution extends JavaBase {
const releaseType = this.stable ? 'ga' : 'ea'; const releaseType = this.stable ? 'ga' : 'ea';
if (core.isDebug()) { if (core.isDebug()) {
console.time('adopt-retrieve-available-versions'); console.time('Retrieving available versions for Adopt took'); // eslint-disable-line no-console
} }
const baseRequestArguments = [ const baseRequestArguments = [
@ -119,7 +136,9 @@ export class AdoptDistribution extends JavaBase {
const availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`;
if (core.isDebug() && page_index === 0) { if (core.isDebug() && page_index === 0) {
// url is identical except page_index so print it once for debug // url is identical except page_index so print it once for debug
core.debug(`Gathering available versions from '${availableVersionsUrl}'`); core.debug(
`Gathering available versions from '${availableVersionsUrl}'`
);
} }
const paginationPage = ( const paginationPage = (
@ -136,9 +155,11 @@ export class AdoptDistribution extends JavaBase {
if (core.isDebug()) { if (core.isDebug()) {
core.startGroup('Print information about available versions'); core.startGroup('Print information about available versions');
console.timeEnd('adopt-retrieve-available-versions'); console.timeEnd('Retrieving available versions for Adopt took'); // eslint-disable-line no-console
console.log(`Available versions: [${availableVersions.length}]`); core.debug(`Available versions: [${availableVersions.length}]`);
console.log(availableVersions.map(item => item.version_data.semver).join(', ')); core.debug(
availableVersions.map(item => item.version_data.semver).join(', ')
);
core.endGroup(); core.endGroup();
} }

View file

@ -4,9 +4,13 @@ import * as fs from 'fs';
import semver from 'semver'; import semver from 'semver';
import path from 'path'; import path from 'path';
import * as httpm from '@actions/http-client'; import * as httpm from '@actions/http-client';
import { getToolcachePath, isVersionSatisfies } from '../util'; import {getToolcachePath, isVersionSatisfies} from '../util';
import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from './base-models'; import {
import { MACOS_JAVA_CONTENT_POSTFIX } from '../constants'; JavaDownloadRelease,
JavaInstallerOptions,
JavaInstallerResults
} from './base-models';
import {MACOS_JAVA_CONTENT_POSTFIX} from '../constants';
import os from 'os'; import os from 'os';
export abstract class JavaBase { export abstract class JavaBase {
@ -17,13 +21,16 @@ export abstract class JavaBase {
protected stable: boolean; protected stable: boolean;
protected checkLatest: boolean; protected checkLatest: boolean;
constructor(protected distribution: string, installerOptions: JavaInstallerOptions) { constructor(
protected distribution: string,
installerOptions: JavaInstallerOptions
) {
this.http = new httpm.HttpClient('actions/setup-java', undefined, { this.http = new httpm.HttpClient('actions/setup-java', undefined, {
allowRetries: true, allowRetries: true,
maxRetries: 3 maxRetries: 3
}); });
({ version: this.version, stable: this.stable } = this.normalizeVersion( ({version: this.version, stable: this.stable} = this.normalizeVersion(
installerOptions.version installerOptions.version
)); ));
this.architecture = installerOptions.architecture || os.arch(); this.architecture = installerOptions.architecture || os.arch();
@ -31,8 +38,12 @@ export abstract class JavaBase {
this.checkLatest = installerOptions.checkLatest; this.checkLatest = installerOptions.checkLatest;
} }
protected abstract downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults>; protected abstract downloadTool(
protected abstract findPackageForDownload(range: string): Promise<JavaDownloadRelease>; javaRelease: JavaDownloadRelease
): Promise<JavaInstallerResults>;
protected abstract findPackageForDownload(
range: string
): Promise<JavaDownloadRelease>;
public async setupJava(): Promise<JavaInstallerResults> { public async setupJava(): Promise<JavaInstallerResults> {
let foundJava = this.findInToolcache(); let foundJava = this.findInToolcache();
@ -52,7 +63,10 @@ export abstract class JavaBase {
} }
// JDK folder may contain postfix "Contents/Home" on macOS // JDK folder may contain postfix "Contents/Home" on macOS
const macOSPostfixPath = path.join(foundJava.path, MACOS_JAVA_CONTENT_POSTFIX); const macOSPostfixPath = path.join(
foundJava.path,
MACOS_JAVA_CONTENT_POSTFIX
);
if (process.platform === 'darwin' && fs.existsSync(macOSPostfixPath)) { if (process.platform === 'darwin' && fs.existsSync(macOSPostfixPath)) {
foundJava.path = macOSPostfixPath; foundJava.path = macOSPostfixPath;
} }
@ -96,7 +110,12 @@ export abstract class JavaBase {
// so replace "/hostedtoolcache/Java/11.0.3-4/x64" to "/hostedtoolcache/Java/11.0.3+4/x64" when retrieves to cache // so replace "/hostedtoolcache/Java/11.0.3-4/x64" to "/hostedtoolcache/Java/11.0.3+4/x64" when retrieves to cache
// related issue: https://github.com/actions/virtual-environments/issues/3014 // related issue: https://github.com/actions/virtual-environments/issues/3014
.replace('-', '+'), .replace('-', '+'),
path: getToolcachePath(this.toolcacheFolderName, item, this.architecture) || '', path:
getToolcachePath(
this.toolcacheFolderName,
item,
this.architecture
) || '',
stable: !item.includes('-ea') stable: !item.includes('-ea')
}; };
}) })
@ -149,7 +168,10 @@ export abstract class JavaBase {
core.setOutput('distribution', this.distribution); core.setOutput('distribution', this.distribution);
core.setOutput('path', toolPath); core.setOutput('path', toolPath);
core.setOutput('version', version); core.setOutput('version', version);
core.exportVariable(`JAVA_HOME_${majorVersion}_${this.architecture.toUpperCase()}`, toolPath); core.exportVariable(
`JAVA_HOME_${majorVersion}_${this.architecture.toUpperCase()}`,
toolPath
);
} }
protected distributionArchitecture(): string { protected distributionArchitecture(): string {

View file

@ -2,17 +2,26 @@ import * as core from '@actions/core';
import * as tc from '@actions/tool-cache'; import * as tc from '@actions/tool-cache';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { extractJdkFile, getDownloadArchiveExtension } from '../../util'; import {extractJdkFile, getDownloadArchiveExtension} from '../../util';
import { JavaBase } from '../base-installer'; import {JavaBase} from '../base-installer';
import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from '../base-models'; import {
import { ICorrettoAllAvailableVersions, ICorrettoAvailableVersions } from './models'; JavaDownloadRelease,
JavaInstallerOptions,
JavaInstallerResults
} from '../base-models';
import {
ICorrettoAllAvailableVersions,
ICorrettoAvailableVersions
} from './models';
export class CorrettoDistribution extends JavaBase { export class CorrettoDistribution extends JavaBase {
constructor(installerOptions: JavaInstallerOptions) { constructor(installerOptions: JavaInstallerOptions) {
super('Corretto', installerOptions); super('Corretto', installerOptions);
} }
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> { protected async downloadTool(
javaRelease: JavaDownloadRelease
): Promise<JavaInstallerResults> {
core.info( core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...` `Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
); );
@ -20,7 +29,10 @@ export class CorrettoDistribution extends JavaBase {
core.info(`Extracting Java archive...`); core.info(`Extracting Java archive...`);
const extractedJavaPath = await extractJdkFile(javaArchivePath, getDownloadArchiveExtension()); const extractedJavaPath = await extractJdkFile(
javaArchivePath,
getDownloadArchiveExtension()
);
const archiveName = fs.readdirSync(extractedJavaPath)[0]; const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName); const archivePath = path.join(extractedJavaPath, archiveName);
@ -33,10 +45,12 @@ export class CorrettoDistribution extends JavaBase {
this.architecture this.architecture
); );
return { version: javaRelease.version, path: javaPath }; return {version: javaRelease.version, path: javaPath};
} }
protected async findPackageForDownload(version: string): Promise<JavaDownloadRelease> { protected async findPackageForDownload(
version: string
): Promise<JavaDownloadRelease> {
if (!this.stable) { if (!this.stable) {
throw new Error('Early access versions are not supported'); throw new Error('Early access versions are not supported');
} }
@ -53,9 +67,12 @@ export class CorrettoDistribution extends JavaBase {
} as JavaDownloadRelease; } as JavaDownloadRelease;
}); });
const resolvedVersion = matchingVersions.length > 0 ? matchingVersions[0] : null; const resolvedVersion =
matchingVersions.length > 0 ? matchingVersions[0] : null;
if (!resolvedVersion) { if (!resolvedVersion) {
const availableOptions = availableVersions.map(item => item.version).join(', '); const availableOptions = availableVersions
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}` ? `\nAvailable versions: ${availableOptions}`
: ''; : '';
@ -72,43 +89,61 @@ export class CorrettoDistribution extends JavaBase {
const imageType = this.packageType; const imageType = this.packageType;
if (core.isDebug()) { if (core.isDebug()) {
console.time('corretto-retrieve-available-versions'); console.time('Retrieving available versions for Coretto took'); // eslint-disable-line no-console
} }
const availableVersionsUrl = const availableVersionsUrl =
'https://corretto.github.io/corretto-downloads/latest_links/indexmap_with_checksum.json'; 'https://corretto.github.io/corretto-downloads/latest_links/indexmap_with_checksum.json';
const fetchCurrentVersions = await this.http.getJson<ICorrettoAllAvailableVersions>( const fetchCurrentVersions =
await this.http.getJson<ICorrettoAllAvailableVersions>(
availableVersionsUrl availableVersionsUrl
); );
const fetchedCurrentVersions = fetchCurrentVersions.result; const fetchedCurrentVersions = fetchCurrentVersions.result;
if (!fetchedCurrentVersions) { if (!fetchedCurrentVersions) {
throw Error(`Could not fetch latest corretto versions from ${availableVersionsUrl}`); throw Error(
`Could not fetch latest corretto versions from ${availableVersionsUrl}`
);
} }
const eligibleVersions = fetchedCurrentVersions?.[platform]?.[arch]?.[imageType]; const eligibleVersions =
const availableVersions = this.getAvailableVersionsForPlatform(eligibleVersions); fetchedCurrentVersions?.[platform]?.[arch]?.[imageType];
const availableVersions =
this.getAvailableVersionsForPlatform(eligibleVersions);
if (core.isDebug()) { if (core.isDebug()) {
this.printAvailableVersions(availableVersions); core.startGroup('Print information about available versions');
console.timeEnd('Retrieving available versions for Coretto took'); // eslint-disable-line no-console
core.debug(`Available versions: [${availableVersions.length}]`);
core.debug(
availableVersions
.map(item => `${item.version}: ${item.correttoVersion}`)
.join(', ')
);
core.endGroup();
} }
return availableVersions; return availableVersions;
} }
private getAvailableVersionsForPlatform( private getAvailableVersionsForPlatform(
eligibleVersions: ICorrettoAllAvailableVersions['os']['arch']['imageType'] | undefined eligibleVersions:
| ICorrettoAllAvailableVersions['os']['arch']['imageType']
| undefined
): ICorrettoAvailableVersions[] { ): ICorrettoAvailableVersions[] {
const availableVersions: ICorrettoAvailableVersions[] = []; const availableVersions: ICorrettoAvailableVersions[] = [];
for (const version in eligibleVersions) { for (const version in eligibleVersions) {
const availableVersion = eligibleVersions[version]; const availableVersion = eligibleVersions[version];
for (const fileType in availableVersion) { for (const fileType in availableVersion) {
const skipNonExtractableBinaries = fileType != getDownloadArchiveExtension(); const skipNonExtractableBinaries =
fileType != getDownloadArchiveExtension();
if (skipNonExtractableBinaries) { if (skipNonExtractableBinaries) {
continue; continue;
} }
const availableVersionDetails = availableVersion[fileType]; const availableVersionDetails = availableVersion[fileType];
const correttoVersion = this.getCorrettoVersion(availableVersionDetails.resource); const correttoVersion = this.getCorrettoVersion(
availableVersionDetails.resource
);
availableVersions.push({ availableVersions.push({
checksum: availableVersionDetails.checksum, checksum: availableVersionDetails.checksum,
@ -124,16 +159,6 @@ export class CorrettoDistribution extends JavaBase {
return availableVersions; return availableVersions;
} }
private printAvailableVersions(availableVersions: ICorrettoAvailableVersions[]) {
core.startGroup('Print information about available versions');
console.timeEnd('corretto-retrieve-available-versions');
console.log(`Available versions: [${availableVersions.length}]`);
console.log(
availableVersions.map(item => `${item.version}: ${item.correttoVersion}`).join(', ')
);
core.endGroup();
}
private getPlatformOption(): string { private getPlatformOption(): string {
// Corretto has its own platform names so we need to map them // Corretto has its own platform names so we need to map them
switch (process.platform) { switch (process.platform) {

View file

@ -1,13 +1,13 @@
import { JavaBase } from './base-installer'; import {JavaBase} from './base-installer';
import { JavaInstallerOptions } from './base-models'; import {JavaInstallerOptions} from './base-models';
import { LocalDistribution } from './local/installer'; import {LocalDistribution} from './local/installer';
import { ZuluDistribution } from './zulu/installer'; import {ZuluDistribution} from './zulu/installer';
import { AdoptDistribution, AdoptImplementation } from './adopt/installer'; import {AdoptDistribution, AdoptImplementation} from './adopt/installer';
import { TemurinDistribution, TemurinImplementation } from './temurin/installer'; import {TemurinDistribution, TemurinImplementation} from './temurin/installer';
import { LibericaDistributions } from './liberica/installer'; import {LibericaDistributions} from './liberica/installer';
import { MicrosoftDistributions } from './microsoft/installer'; import {MicrosoftDistributions} from './microsoft/installer';
import { CorrettoDistribution } from './corretto/installer'; import {CorrettoDistribution} from './corretto/installer';
import { OracleDistribution } from './oracle/installer'; import {OracleDistribution} from './oracle/installer';
enum JavaDistribution { enum JavaDistribution {
Adopt = 'adopt', Adopt = 'adopt',
@ -32,11 +32,20 @@ export function getJavaDistribution(
return new LocalDistribution(installerOptions, jdkFile); return new LocalDistribution(installerOptions, jdkFile);
case JavaDistribution.Adopt: case JavaDistribution.Adopt:
case JavaDistribution.AdoptHotspot: case JavaDistribution.AdoptHotspot:
return new AdoptDistribution(installerOptions, AdoptImplementation.Hotspot); return new AdoptDistribution(
installerOptions,
AdoptImplementation.Hotspot
);
case JavaDistribution.AdoptOpenJ9: case JavaDistribution.AdoptOpenJ9:
return new AdoptDistribution(installerOptions, AdoptImplementation.OpenJ9); return new AdoptDistribution(
installerOptions,
AdoptImplementation.OpenJ9
);
case JavaDistribution.Temurin: case JavaDistribution.Temurin:
return new TemurinDistribution(installerOptions, TemurinImplementation.Hotspot); return new TemurinDistribution(
installerOptions,
TemurinImplementation.Hotspot
);
case JavaDistribution.Zulu: case JavaDistribution.Zulu:
return new ZuluDistribution(installerOptions); return new ZuluDistribution(installerOptions);
case JavaDistribution.Liberica: case JavaDistribution.Liberica:

View file

@ -1,9 +1,17 @@
import { JavaBase } from '../base-installer'; import {JavaBase} from '../base-installer';
import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from '../base-models'; import {
JavaDownloadRelease,
JavaInstallerOptions,
JavaInstallerResults
} from '../base-models';
import semver from 'semver'; import semver from 'semver';
import { extractJdkFile, getDownloadArchiveExtension, isVersionSatisfies } from '../../util'; import {
extractJdkFile,
getDownloadArchiveExtension,
isVersionSatisfies
} from '../../util';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { ArchitectureOptions, LibericaVersion, OsVersions } from './models'; import {ArchitectureOptions, LibericaVersion, OsVersions} from './models';
import * as tc from '@actions/tool-cache'; import * as tc from '@actions/tool-cache';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
@ -17,7 +25,9 @@ export class LibericaDistributions extends JavaBase {
super('Liberica', installerOptions); super('Liberica', installerOptions);
} }
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> { protected async downloadTool(
javaRelease: JavaDownloadRelease
): Promise<JavaInstallerResults> {
core.info( core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...` `Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
); );
@ -37,10 +47,12 @@ export class LibericaDistributions extends JavaBase {
this.architecture this.architecture
); );
return { version: javaRelease.version, path: javaPath }; return {version: javaRelease.version, path: javaPath};
} }
protected async findPackageForDownload(range: string): Promise<JavaDownloadRelease> { protected async findPackageForDownload(
range: string
): Promise<JavaDownloadRelease> {
const availableVersionsRaw = await this.getAvailableVersions(); const availableVersionsRaw = await this.getAvailableVersions();
const availableVersions = availableVersionsRaw.map(item => ({ const availableVersions = availableVersionsRaw.map(item => ({
@ -53,7 +65,9 @@ export class LibericaDistributions extends JavaBase {
.sort((a, b) => -semver.compareBuild(a.version, b.version))[0]; .sort((a, b) => -semver.compareBuild(a.version, b.version))[0];
if (!satisfiedVersion) { if (!satisfiedVersion) {
const availableOptions = availableVersions.map(item => item.version).join(', '); const availableOptions = availableVersions
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}` ? `\nAvailable versions: ${availableOptions}`
: ''; : '';
@ -67,21 +81,20 @@ export class LibericaDistributions extends JavaBase {
private async getAvailableVersions(): Promise<LibericaVersion[]> { private async getAvailableVersions(): Promise<LibericaVersion[]> {
if (core.isDebug()) { if (core.isDebug()) {
console.time('liberica-retrieve-available-versions'); console.time('Retrieving available versions for Liberica took'); // eslint-disable-line no-console
} }
const url = this.prepareAvailableVersionsUrl(); const url = this.prepareAvailableVersionsUrl();
if (core.isDebug()) {
core.debug(`Gathering available versions from '${url}'`); core.debug(`Gathering available versions from '${url}'`);
}
const availableVersions = (await this.http.getJson<LibericaVersion[]>(url)).result ?? []; const availableVersions =
(await this.http.getJson<LibericaVersion[]>(url)).result ?? [];
if (core.isDebug()) { if (core.isDebug()) {
core.startGroup('Print information about available versions'); core.startGroup('Print information about available versions');
console.timeEnd('liberica-retrieve-available-versions'); console.timeEnd('Retrieving available versions for Liberica took'); // eslint-disable-line no-console
console.log(`Available versions: [${availableVersions.length}]`); core.debug(`Available versions: [${availableVersions.length}]`);
console.log(availableVersions.map(item => item.version)); core.debug(availableVersions.map(item => item.version).join(', '));
core.endGroup(); core.endGroup();
} }
@ -95,7 +108,8 @@ export class LibericaDistributions extends JavaBase {
...this.getArchitectureOptions(), ...this.getArchitectureOptions(),
'build-type': this.stable ? 'all' : 'ea', 'build-type': this.stable ? 'all' : 'ea',
'installation-type': 'archive', 'installation-type': 'archive',
fields: 'downloadUrl,version,featureVersion,interimVersion,updateVersion,buildVersion' fields:
'downloadUrl,version,featureVersion,interimVersion,updateVersion,buildVersion'
}; };
const searchParams = new URLSearchParams(urlOptions).toString(); const searchParams = new URLSearchParams(urlOptions).toString();
@ -115,15 +129,15 @@ export class LibericaDistributions extends JavaBase {
const arch = this.distributionArchitecture(); const arch = this.distributionArchitecture();
switch (arch) { switch (arch) {
case 'x86': case 'x86':
return { bitness: '32', arch: 'x86' }; return {bitness: '32', arch: 'x86'};
case 'x64': case 'x64':
return { bitness: '64', arch: 'x86' }; return {bitness: '64', arch: 'x86'};
case 'armv7': case 'armv7':
return { bitness: '32', arch: 'arm' }; return {bitness: '32', arch: 'arm'};
case 'aarch64': case 'aarch64':
return { bitness: '64', arch: 'arm' }; return {bitness: '64', arch: 'arm'};
case 'ppc64le': case 'ppc64le':
return { bitness: '64', arch: 'ppc' }; return {bitness: '64', arch: 'ppc'};
default: default:
throw new Error( throw new Error(
`Architecture '${this.architecture}' is not supported. Supported architectures: ${supportedArchitectures}` `Architecture '${this.architecture}' is not supported. Supported architectures: ${supportedArchitectures}`
@ -131,7 +145,9 @@ export class LibericaDistributions extends JavaBase {
} }
} }
private getPlatformOption(platform: NodeJS.Platform = process.platform): OsVersions { private getPlatformOption(
platform: NodeJS.Platform = process.platform
): OsVersions {
switch (platform) { switch (platform) {
case 'darwin': case 'darwin':
return 'macos'; return 'macos';
@ -150,8 +166,11 @@ export class LibericaDistributions extends JavaBase {
} }
private convertVersionToSemver(version: LibericaVersion): string { private convertVersionToSemver(version: LibericaVersion): string {
let { buildVersion, featureVersion, interimVersion, updateVersion } = version; const {buildVersion, featureVersion, interimVersion, updateVersion} =
const mainVersion = [featureVersion, interimVersion, updateVersion].join('.'); version;
const mainVersion = [featureVersion, interimVersion, updateVersion].join(
'.'
);
if (buildVersion != 0) { if (buildVersion != 0) {
return `${mainVersion}+${buildVersion}`; return `${mainVersion}+${buildVersion}`;
} }
@ -159,7 +178,7 @@ export class LibericaDistributions extends JavaBase {
} }
protected distributionArchitecture(): string { protected distributionArchitecture(): string {
let arch = super.distributionArchitecture(); const arch = super.distributionArchitecture();
switch (arch) { switch (arch) {
case 'arm': case 'arm':
return 'armv7'; return 'armv7';

View file

@ -3,7 +3,12 @@
export type Bitness = '32' | '64'; export type Bitness = '32' | '64';
export type ArchType = 'arm' | 'ppc' | 'sparc' | 'x86'; export type ArchType = 'arm' | 'ppc' | 'sparc' | 'x86';
export type OsVersions = 'linux' | 'linux-musl' | 'macos' | 'solaris' | 'windows'; export type OsVersions =
| 'linux'
| 'linux-musl'
| 'macos'
| 'solaris'
| 'windows';
export interface ArchitectureOptions { export interface ArchitectureOptions {
bitness: Bitness; bitness: Bitness;

View file

@ -3,15 +3,21 @@ import * as core from '@actions/core';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import semver from 'semver';
import { JavaBase } from '../base-installer'; import {JavaBase} from '../base-installer';
import { JavaInstallerOptions, JavaDownloadRelease, JavaInstallerResults } from '../base-models'; import {
import { extractJdkFile } from '../../util'; JavaInstallerOptions,
import { MACOS_JAVA_CONTENT_POSTFIX } from '../../constants'; JavaDownloadRelease,
JavaInstallerResults
} from '../base-models';
import {extractJdkFile} from '../../util';
import {MACOS_JAVA_CONTENT_POSTFIX} from '../../constants';
export class LocalDistribution extends JavaBase { export class LocalDistribution extends JavaBase {
constructor(installerOptions: JavaInstallerOptions, private jdkFile?: string) { constructor(
installerOptions: JavaInstallerOptions,
private jdkFile?: string
) {
super('jdkfile', installerOptions); super('jdkfile', installerOptions);
} }
@ -21,7 +27,9 @@ export class LocalDistribution extends JavaBase {
if (foundJava) { if (foundJava) {
core.info(`Resolved Java ${foundJava.version} from tool-cache`); core.info(`Resolved Java ${foundJava.version} from tool-cache`);
} else { } else {
core.info(`Java ${this.version} was not found in tool-cache. Trying to unpack JDK file...`); core.info(
`Java ${this.version} was not found in tool-cache. Trying to unpack JDK file...`
);
if (!this.jdkFile) { if (!this.jdkFile) {
throw new Error("'jdkFile' is not specified"); throw new Error("'jdkFile' is not specified");
} }
@ -66,11 +74,19 @@ export class LocalDistribution extends JavaBase {
return foundJava; return foundJava;
} }
protected async findPackageForDownload(version: string): Promise<JavaDownloadRelease> { protected async findPackageForDownload(
throw new Error('This method should not be implemented in local file provider'); version: string // eslint-disable-line @typescript-eslint/no-unused-vars
): Promise<JavaDownloadRelease> {
throw new Error(
'This method should not be implemented in local file provider'
);
} }
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> { protected async downloadTool(
throw new Error('This method should not be implemented in local file provider'); javaRelease: JavaDownloadRelease // eslint-disable-line @typescript-eslint/no-unused-vars
): Promise<JavaInstallerResults> {
throw new Error(
'This method should not be implemented in local file provider'
);
} }
} }

View file

@ -1,19 +1,25 @@
import { JavaBase } from '../base-installer'; import {JavaBase} from '../base-installer';
import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from '../base-models'; import {
import { extractJdkFile, getDownloadArchiveExtension } from '../../util'; JavaDownloadRelease,
JavaInstallerOptions,
JavaInstallerResults
} from '../base-models';
import {extractJdkFile, getDownloadArchiveExtension} from '../../util';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as tc from '@actions/tool-cache'; import * as tc from '@actions/tool-cache';
import { OutgoingHttpHeaders } from 'http'; import {OutgoingHttpHeaders} from 'http';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { ITypedResponse } from '@actions/http-client/interfaces'; import {ITypedResponse} from '@actions/http-client/interfaces';
export class MicrosoftDistributions extends JavaBase { export class MicrosoftDistributions extends JavaBase {
constructor(installerOptions: JavaInstallerOptions) { constructor(installerOptions: JavaInstallerOptions) {
super('Microsoft', installerOptions); super('Microsoft', installerOptions);
} }
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> { protected async downloadTool(
javaRelease: JavaDownloadRelease
): Promise<JavaInstallerResults> {
core.info( core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...` `Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
); );
@ -33,10 +39,12 @@ export class MicrosoftDistributions extends JavaBase {
this.architecture this.architecture
); );
return { version: javaRelease.version, path: javaPath }; return {version: javaRelease.version, path: javaPath};
} }
protected async findPackageForDownload(range: string): Promise<JavaDownloadRelease> { protected async findPackageForDownload(
range: string
): Promise<JavaDownloadRelease> {
const arch = this.distributionArchitecture(); const arch = this.distributionArchitecture();
if (arch !== 'x64' && arch !== 'aarch64') { if (arch !== 'x64' && arch !== 'aarch64') {
throw new Error(`Unsupported architecture: ${this.architecture}`); throw new Error(`Unsupported architecture: ${this.architecture}`);
@ -47,7 +55,9 @@ export class MicrosoftDistributions extends JavaBase {
} }
if (this.packageType !== 'jdk') { if (this.packageType !== 'jdk') {
throw new Error('Microsoft Build of OpenJDK provides only the `jdk` package type'); throw new Error(
'Microsoft Build of OpenJDK provides only the `jdk` package type'
);
} }
const manifest = await this.getAvailableVersions(); const manifest = await this.getAvailableVersions();
@ -66,7 +76,10 @@ export class MicrosoftDistributions extends JavaBase {
); );
} }
return { url: foundRelease.files[0].download_url, version: foundRelease.version }; return {
url: foundRelease.files[0].download_url,
version: foundRelease.version
};
} }
private async getAvailableVersions(): Promise<tc.IToolRelease[] | null> { private async getAvailableVersions(): Promise<tc.IToolRelease[] | null> {
@ -77,7 +90,8 @@ export class MicrosoftDistributions extends JavaBase {
const owner = 'actions'; const owner = 'actions';
const repository = 'setup-java'; const repository = 'setup-java';
const branch = 'main'; const branch = 'main';
const filePath = 'src/distributions/microsoft/microsoft-openjdk-versions.json'; const filePath =
'src/distributions/microsoft/microsoft-openjdk-versions.json';
let releases: tc.IToolRelease[] | null = null; let releases: tc.IToolRelease[] | null = null;
const fileUrl = `https://api.github.com/repos/${owner}/${repository}/contents/${filePath}?ref=${branch}`; const fileUrl = `https://api.github.com/repos/${owner}/${repository}/contents/${filePath}?ref=${branch}`;
@ -89,6 +103,10 @@ export class MicrosoftDistributions extends JavaBase {
let response: ITypedResponse<tc.IToolRelease[]> | null = null; let response: ITypedResponse<tc.IToolRelease[]> | null = null;
if (core.isDebug()) {
console.time('Retrieving available versions for Microsoft took'); // eslint-disable-line no-console
}
try { try {
response = await this.http.getJson<tc.IToolRelease[]>(fileUrl, headers); response = await this.http.getJson<tc.IToolRelease[]>(fileUrl, headers);
if (!response.result) { if (!response.result) {
@ -105,6 +123,14 @@ export class MicrosoftDistributions extends JavaBase {
releases = response.result; releases = response.result;
} }
if (core.isDebug() && releases) {
core.startGroup('Print information about available versions');
console.timeEnd('Retrieving available versions for Microsoft took'); // eslint-disable-line no-console
core.debug(`Available versions: [${releases.length}]`);
core.debug(releases.map(item => item.version).join(', '));
core.endGroup();
}
return releases; return releases;
} }
} }

View file

@ -1,2 +1,3 @@
/* eslint @typescript-eslint/no-unused-vars: "off" -- There is a bug with this rule, it's not working properly with types */
type OsVersions = 'linux' | 'macos' | 'windows'; type OsVersions = 'linux' | 'macos' | 'windows';
type ArchiveType = 'tar.gz' | 'zip'; type ArchiveType = 'tar.gz' | 'zip';

View file

@ -4,10 +4,14 @@ import * as tc from '@actions/tool-cache';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { JavaBase } from '../base-installer'; import {JavaBase} from '../base-installer';
import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from '../base-models'; import {
import { extractJdkFile, getDownloadArchiveExtension } from '../../util'; JavaDownloadRelease,
import { HttpCodes } from '@actions/http-client'; JavaInstallerOptions,
JavaInstallerResults
} from '../base-models';
import {extractJdkFile, getDownloadArchiveExtension} from '../../util';
import {HttpCodes} from '@actions/http-client';
const ORACLE_DL_BASE = 'https://download.oracle.com/java'; const ORACLE_DL_BASE = 'https://download.oracle.com/java';
@ -16,32 +20,36 @@ export class OracleDistribution extends JavaBase {
super('Oracle', installerOptions); super('Oracle', installerOptions);
} }
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> { protected async downloadTool(
javaRelease: JavaDownloadRelease
): Promise<JavaInstallerResults> {
core.info( core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...` `Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
); );
const javaArchivePath = await tc.downloadTool(javaRelease.url); const javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`); core.info(`Extracting Java archive...`);
let extension = getDownloadArchiveExtension(); const extension = getDownloadArchiveExtension();
let extractedJavaPath = await extractJdkFile(javaArchivePath, extension); const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0]; const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName); const archivePath = path.join(extractedJavaPath, archiveName);
const version = this.getToolcacheVersionName(javaRelease.version); const version = this.getToolcacheVersionName(javaRelease.version);
let javaPath = await tc.cacheDir( const javaPath = await tc.cacheDir(
archivePath, archivePath,
this.toolcacheFolderName, this.toolcacheFolderName,
version, version,
this.architecture this.architecture
); );
return { version: javaRelease.version, path: javaPath }; return {version: javaRelease.version, path: javaPath};
} }
protected async findPackageForDownload(range: string): Promise<JavaDownloadRelease> { protected async findPackageForDownload(
range: string
): Promise<JavaDownloadRelease> {
const arch = this.distributionArchitecture(); const arch = this.distributionArchitecture();
if (arch !== 'x64' && arch !== 'aarch64') { if (arch !== 'x64' && arch !== 'aarch64') {
throw new Error(`Unsupported architecture: ${this.architecture}`); throw new Error(`Unsupported architecture: ${this.architecture}`);
@ -83,7 +91,7 @@ export class OracleDistribution extends JavaBase {
); );
} }
return { url: fileUrl, version: range }; return {url: fileUrl, version: range};
} }
public getPlatform(platform: NodeJS.Platform = process.platform): OsVersions { public getPlatform(platform: NodeJS.Platform = process.platform): OsVersions {

View file

@ -5,10 +5,18 @@ import fs from 'fs';
import path from 'path'; import path from 'path';
import semver from 'semver'; import semver from 'semver';
import { JavaBase } from '../base-installer'; import {JavaBase} from '../base-installer';
import { ITemurinAvailableVersions } from './models'; import {ITemurinAvailableVersions} from './models';
import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from '../base-models'; import {
import { extractJdkFile, getDownloadArchiveExtension, isVersionSatisfies } from '../../util'; JavaDownloadRelease,
JavaInstallerOptions,
JavaInstallerResults
} from '../base-models';
import {
extractJdkFile,
getDownloadArchiveExtension,
isVersionSatisfies
} from '../../util';
export enum TemurinImplementation { export enum TemurinImplementation {
Hotspot = 'Hotspot' Hotspot = 'Hotspot'
@ -22,7 +30,9 @@ export class TemurinDistribution extends JavaBase {
super(`Temurin-${jvmImpl}`, installerOptions); super(`Temurin-${jvmImpl}`, installerOptions);
} }
protected async findPackageForDownload(version: string): Promise<JavaDownloadRelease> { protected async findPackageForDownload(
version: string
): Promise<JavaDownloadRelease> {
const availableVersionsRaw = await this.getAvailableVersions(); const availableVersionsRaw = await this.getAvailableVersions();
const availableVersionsWithBinaries = availableVersionsRaw const availableVersionsWithBinaries = availableVersionsRaw
.filter(item => item.binaries.length > 0) .filter(item => item.binaries.length > 0)
@ -43,9 +53,12 @@ export class TemurinDistribution extends JavaBase {
return -semver.compareBuild(a.version, b.version); return -semver.compareBuild(a.version, b.version);
}); });
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null; const resolvedFullVersion =
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) { if (!resolvedFullVersion) {
const availableOptions = availableVersionsWithBinaries.map(item => item.version).join(', '); const availableOptions = availableVersionsWithBinaries
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}` ? `\nAvailable versions: ${availableOptions}`
: ''; : '';
@ -57,27 +70,31 @@ export class TemurinDistribution extends JavaBase {
return resolvedFullVersion; return resolvedFullVersion;
} }
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> { protected async downloadTool(
let javaPath: string; javaRelease: JavaDownloadRelease
let extractedJavaPath: string; ): Promise<JavaInstallerResults> {
core.info( core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...` `Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
); );
const javaArchivePath = await tc.downloadTool(javaRelease.url); const javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`); core.info(`Extracting Java archive...`);
let extension = getDownloadArchiveExtension(); const extension = getDownloadArchiveExtension();
extractedJavaPath = await extractJdkFile(javaArchivePath, extension); const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0]; const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName); const archivePath = path.join(extractedJavaPath, archiveName);
const version = this.getToolcacheVersionName(javaRelease.version); const version = this.getToolcacheVersionName(javaRelease.version);
javaPath = await tc.cacheDir(archivePath, this.toolcacheFolderName, version, this.architecture); const javaPath = await tc.cacheDir(
archivePath,
this.toolcacheFolderName,
version,
this.architecture
);
return { version: javaRelease.version, path: javaPath }; return {version: javaRelease.version, path: javaPath};
} }
protected get toolcacheFolderName(): string { protected get toolcacheFolderName(): string {
@ -92,7 +109,7 @@ export class TemurinDistribution extends JavaBase {
const releaseType = this.stable ? 'ga' : 'ea'; const releaseType = this.stable ? 'ga' : 'ea';
if (core.isDebug()) { if (core.isDebug()) {
console.time('temurin-retrieve-available-versions'); console.time('Retrieving available versions for Temurin took'); // eslint-disable-line no-console
} }
const baseRequestArguments = [ const baseRequestArguments = [
@ -117,11 +134,15 @@ export class TemurinDistribution extends JavaBase {
const availableVersionsUrl = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersionsUrl = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`;
if (core.isDebug() && page_index === 0) { if (core.isDebug() && page_index === 0) {
// url is identical except page_index so print it once for debug // url is identical except page_index so print it once for debug
core.debug(`Gathering available versions from '${availableVersionsUrl}'`); core.debug(
`Gathering available versions from '${availableVersionsUrl}'`
);
} }
const paginationPage = ( const paginationPage = (
await this.http.getJson<ITemurinAvailableVersions[]>(availableVersionsUrl) await this.http.getJson<ITemurinAvailableVersions[]>(
availableVersionsUrl
)
).result; ).result;
if (paginationPage === null || paginationPage.length === 0) { if (paginationPage === null || paginationPage.length === 0) {
// break infinity loop because we have reached end of pagination // break infinity loop because we have reached end of pagination
@ -134,9 +155,11 @@ export class TemurinDistribution extends JavaBase {
if (core.isDebug()) { if (core.isDebug()) {
core.startGroup('Print information about available versions'); core.startGroup('Print information about available versions');
console.timeEnd('temurin-retrieve-available-versions'); console.timeEnd('Retrieving available versions for Temurin took'); // eslint-disable-line no-console
console.log(`Available versions: [${availableVersions.length}]`); core.debug(`Available versions: [${availableVersions.length}]`);
console.log(availableVersions.map(item => item.version_data.semver).join(', ')); core.debug(
availableVersions.map(item => item.version_data.semver).join(', ')
);
core.endGroup(); core.endGroup();
} }

View file

@ -5,17 +5,27 @@ import path from 'path';
import fs from 'fs'; import fs from 'fs';
import semver from 'semver'; import semver from 'semver';
import { JavaBase } from '../base-installer'; import {JavaBase} from '../base-installer';
import { IZuluVersions } from './models'; import {IZuluVersions} from './models';
import { extractJdkFile, getDownloadArchiveExtension, isVersionSatisfies } from '../../util'; import {
import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from '../base-models'; extractJdkFile,
getDownloadArchiveExtension,
isVersionSatisfies
} from '../../util';
import {
JavaDownloadRelease,
JavaInstallerOptions,
JavaInstallerResults
} from '../base-models';
export class ZuluDistribution extends JavaBase { export class ZuluDistribution extends JavaBase {
constructor(installerOptions: JavaInstallerOptions) { constructor(installerOptions: JavaInstallerOptions) {
super('Zulu', installerOptions); super('Zulu', installerOptions);
} }
protected async findPackageForDownload(version: string): Promise<JavaDownloadRelease> { protected async findPackageForDownload(
version: string
): Promise<JavaDownloadRelease> {
const availableVersionsRaw = await this.getAvailableVersions(); const availableVersionsRaw = await this.getAvailableVersions();
const availableVersions = availableVersionsRaw.map(item => { const availableVersions = availableVersionsRaw.map(item => {
return { return {
@ -42,9 +52,12 @@ export class ZuluDistribution extends JavaBase {
} as JavaDownloadRelease; } as JavaDownloadRelease;
}); });
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null; const resolvedFullVersion =
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) { if (!resolvedFullVersion) {
const availableOptions = availableVersions.map(item => item.version).join(', '); const availableOptions = availableVersions
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}` ? `\nAvailable versions: ${availableOptions}`
: ''; : '';
@ -56,18 +69,18 @@ export class ZuluDistribution extends JavaBase {
return resolvedFullVersion; return resolvedFullVersion;
} }
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> { protected async downloadTool(
let extractedJavaPath: string; javaRelease: JavaDownloadRelease
): Promise<JavaInstallerResults> {
core.info( core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...` `Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
); );
const javaArchivePath = await tc.downloadTool(javaRelease.url); const javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`); core.info(`Extracting Java archive...`);
let extension = getDownloadArchiveExtension(); const extension = getDownloadArchiveExtension();
extractedJavaPath = await extractJdkFile(javaArchivePath, extension); const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0]; const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName); const archivePath = path.join(extractedJavaPath, archiveName);
@ -79,11 +92,11 @@ export class ZuluDistribution extends JavaBase {
this.architecture this.architecture
); );
return { version: javaRelease.version, path: javaPath }; return {version: javaRelease.version, path: javaPath};
} }
private async getAvailableVersions(): Promise<IZuluVersions[]> { private async getAvailableVersions(): Promise<IZuluVersions[]> {
const { arch, hw_bitness, abi } = this.getArchitectureOptions(); const {arch, hw_bitness, abi} = this.getArchitectureOptions();
const [bundleType, features] = this.packageType.split('+'); const [bundleType, features] = this.packageType.split('+');
const platform = this.getPlatformOption(); const platform = this.getPlatformOption();
const extension = getDownloadArchiveExtension(); const extension = getDownloadArchiveExtension();
@ -91,8 +104,9 @@ export class ZuluDistribution extends JavaBase {
const releaseStatus = this.stable ? 'ga' : 'ea'; const releaseStatus = this.stable ? 'ga' : 'ea';
if (core.isDebug()) { if (core.isDebug()) {
console.time('azul-retrieve-available-versions'); console.time('Retrieving available versions for Zulu took'); // eslint-disable-line no-console
} }
const requestArguments = [ const requestArguments = [
`os=${platform}`, `os=${platform}`,
`ext=${extension}`, `ext=${extension}`,
@ -108,18 +122,20 @@ export class ZuluDistribution extends JavaBase {
.join('&'); .join('&');
const availableVersionsUrl = `https://api.azul.com/zulu/download/community/v1.0/bundles/?${requestArguments}`; const availableVersionsUrl = `https://api.azul.com/zulu/download/community/v1.0/bundles/?${requestArguments}`;
if (core.isDebug()) {
core.debug(`Gathering available versions from '${availableVersionsUrl}'`); core.debug(`Gathering available versions from '${availableVersionsUrl}'`);
}
const availableVersions = const availableVersions =
(await this.http.getJson<Array<IZuluVersions>>(availableVersionsUrl)).result ?? []; (await this.http.getJson<Array<IZuluVersions>>(availableVersionsUrl))
.result ?? [];
if (core.isDebug()) { if (core.isDebug()) {
core.startGroup('Print information about available versions'); core.startGroup('Print information about available versions');
console.timeEnd('azul-retrieve-available-versions'); console.timeEnd('Retrieving available versions for Zulu took'); // eslint-disable-line no-console
console.log(`Available versions: [${availableVersions.length}]`); core.debug(`Available versions: [${availableVersions.length}]`);
console.log(availableVersions.map(item => item.jdk_version.join('.')).join(', ')); core.debug(
availableVersions.map(item => item.jdk_version.join('.')).join(', ')
);
core.endGroup(); core.endGroup();
} }
@ -134,14 +150,14 @@ export class ZuluDistribution extends JavaBase {
const arch = this.distributionArchitecture(); const arch = this.distributionArchitecture();
switch (arch) { switch (arch) {
case 'x64': case 'x64':
return { arch: 'x86', hw_bitness: '64', abi: '' }; return {arch: 'x86', hw_bitness: '64', abi: ''};
case 'x86': case 'x86':
return { arch: 'x86', hw_bitness: '32', abi: '' }; return {arch: 'x86', hw_bitness: '32', abi: ''};
case 'aarch64': case 'aarch64':
case 'arm64': case 'arm64':
return { arch: 'arm', hw_bitness: '64', abi: '' }; return {arch: 'arm', hw_bitness: '64', abi: ''};
default: default:
return { arch: arch, hw_bitness: '', abi: '' }; return {arch: arch, hw_bitness: '', abi: ''};
} }
} }

View file

@ -3,7 +3,7 @@ import * as path from 'path';
import * as io from '@actions/io'; import * as io from '@actions/io';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
import * as util from './util'; import * as util from './util';
import { ExecOptions } from '@actions/exec/lib/interfaces'; import {ExecOptions} from '@actions/exec/lib/interfaces';
export const PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc'); export const PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc');
@ -28,7 +28,13 @@ export async function importKey(privateKey: string) {
await exec.exec( await exec.exec(
'gpg', 'gpg',
['--batch', '--import-options', 'import-show', '--import', PRIVATE_KEY_FILE], [
'--batch',
'--import-options',
'import-show',
'--import',
PRIVATE_KEY_FILE
],
options options
); );
@ -39,7 +45,11 @@ export async function importKey(privateKey: string) {
} }
export async function deleteKey(keyFingerprint: string) { export async function deleteKey(keyFingerprint: string) {
await exec.exec('gpg', ['--batch', '--yes', '--delete-secret-and-public-key', keyFingerprint], { await exec.exec(
'gpg',
['--batch', '--yes', '--delete-secret-and-public-key', keyFingerprint],
{
silent: true silent: true
}); }
);
} }

View file

@ -1,18 +1,24 @@
import fs from 'fs'; import fs from 'fs';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as auth from './auth'; import * as auth from './auth';
import { getBooleanInput, isCacheFeatureAvailable, getVersionFromFileContent } from './util'; import {
getBooleanInput,
isCacheFeatureAvailable,
getVersionFromFileContent
} from './util';
import * as toolchains from './toolchains'; import * as toolchains from './toolchains';
import * as constants from './constants'; import * as constants from './constants';
import { restore } from './cache'; import {restore} from './cache';
import * as path from 'path'; import * as path from 'path';
import { getJavaDistribution } from './distributions/distribution-factory'; import {getJavaDistribution} from './distributions/distribution-factory';
import { JavaInstallerOptions } from './distributions/base-models'; import {JavaInstallerOptions} from './distributions/base-models';
async function run() { async function run() {
try { try {
const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION); const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION);
const distributionName = core.getInput(constants.INPUT_DISTRIBUTION, { required: true }); const distributionName = core.getInput(constants.INPUT_DISTRIBUTION, {
required: true
});
const versionFile = core.getInput(constants.INPUT_JAVA_VERSION_FILE); const versionFile = core.getInput(constants.INPUT_JAVA_VERSION_FILE);
const architecture = core.getInput(constants.INPUT_ARCHITECTURE); const architecture = core.getInput(constants.INPUT_ARCHITECTURE);
const packageType = core.getInput(constants.INPUT_JAVA_PACKAGE); const packageType = core.getInput(constants.INPUT_JAVA_PACKAGE);
@ -41,17 +47,18 @@ async function run() {
}; };
if (!versions.length) { if (!versions.length) {
core.debug('java-version input is empty, looking for java-version-file input'); core.debug(
const content = fs 'java-version input is empty, looking for java-version-file input'
.readFileSync(versionFile) );
.toString() const content = fs.readFileSync(versionFile).toString().trim();
.trim();
const version = getVersionFromFileContent(content, distributionName); const version = getVersionFromFileContent(content, distributionName);
core.debug(`Parsed version from file '${version}'`); core.debug(`Parsed version from file '${version}'`);
if (!version) { if (!version) {
throw new Error(`No supported version was found in file ${versionFile}`); throw new Error(
`No supported version was found in file ${versionFile}`
);
} }
await installVersion(version, installerInputsOptions); await installVersion(version, installerInputsOptions);
@ -75,7 +82,11 @@ async function run() {
run(); run();
async function installVersion(version: string, options: installerInputsOptions, toolchainId = 0) { async function installVersion(
version: string,
options: installerInputsOptions,
toolchainId = 0
) {
const { const {
distributionName, distributionName,
jdkFile, jdkFile,
@ -92,9 +103,15 @@ async function installVersion(version: string, options: installerInputsOptions,
version version
}; };
const distribution = getJavaDistribution(distributionName, installerOptions, jdkFile); const distribution = getJavaDistribution(
distributionName,
installerOptions,
jdkFile
);
if (!distribution) { if (!distribution) {
throw new Error(`No supported distribution was found for input ${distributionName}`); throw new Error(
`No supported distribution was found for input ${distributionName}`
);
} }
const result = await distribution.setupJava(); const result = await distribution.setupJava();

View file

@ -5,8 +5,8 @@ import * as core from '@actions/core';
import * as io from '@actions/io'; import * as io from '@actions/io';
import * as constants from './constants'; import * as constants from './constants';
import { getBooleanInput } from './util'; import {getBooleanInput} from './util';
import { create as xmlCreate } from 'xmlbuilder2'; import {create as xmlCreate} from 'xmlbuilder2';
interface JdkInfo { interface JdkInfo {
version: string; version: string;
@ -21,11 +21,16 @@ export async function configureToolchains(
jdkHome: string, jdkHome: string,
toolchainId?: string toolchainId?: string
) { ) {
const vendor = core.getInput(constants.INPUT_MVN_TOOLCHAIN_VENDOR) || distributionName; const vendor =
core.getInput(constants.INPUT_MVN_TOOLCHAIN_VENDOR) || distributionName;
const id = toolchainId || `${vendor}_${version}`; const id = toolchainId || `${vendor}_${version}`;
const settingsDirectory = const settingsDirectory =
core.getInput(constants.INPUT_SETTINGS_PATH) || path.join(os.homedir(), constants.M2_DIR); core.getInput(constants.INPUT_SETTINGS_PATH) ||
const overwriteSettings = getBooleanInput(constants.INPUT_OVERWRITE_SETTINGS, true); path.join(os.homedir(), constants.M2_DIR);
const overwriteSettings = getBooleanInput(
constants.INPUT_OVERWRITE_SETTINGS,
true
);
await createToolchainsSettings({ await createToolchainsSettings({
jdkInfo: { jdkInfo: {
@ -54,7 +59,9 @@ export async function createToolchainsSettings({
// when an alternate m2 location is specified use only that location (no .m2 directory) // when an alternate m2 location is specified use only that location (no .m2 directory)
// otherwise use the home/.m2/ path // otherwise use the home/.m2/ path
await io.mkdirP(settingsDirectory); await io.mkdirP(settingsDirectory);
const originalToolchains = await readExistingToolchainsFile(settingsDirectory); const originalToolchains = await readExistingToolchainsFile(
settingsDirectory
);
const updatedToolchains = generateToolchainDefinition( const updatedToolchains = generateToolchainDefinition(
originalToolchains, originalToolchains,
jdkInfo.version, jdkInfo.version,
@ -62,7 +69,11 @@ export async function createToolchainsSettings({
jdkInfo.id, jdkInfo.id,
jdkInfo.jdkHome jdkInfo.jdkHome
); );
await writeToolchainsFileToDisk(settingsDirectory, updatedToolchains, overwriteSettings); await writeToolchainsFileToDisk(
settingsDirectory,
updatedToolchains,
overwriteSettings
);
} }
// only exported for testing purposes // only exported for testing purposes

View file

@ -6,16 +6,18 @@ import * as cache from '@actions/cache';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as tc from '@actions/tool-cache'; import * as tc from '@actions/tool-cache';
import { INPUT_JOB_STATUS, DISTRIBUTIONS_ONLY_MAJOR_VERSION } from './constants'; import {INPUT_JOB_STATUS, DISTRIBUTIONS_ONLY_MAJOR_VERSION} from './constants';
export function getTempDir() { export function getTempDir() {
let tempDirectory = process.env['RUNNER_TEMP'] || os.tmpdir(); const tempDirectory = process.env['RUNNER_TEMP'] || os.tmpdir();
return tempDirectory; return tempDirectory;
} }
export function getBooleanInput(inputName: string, defaultValue: boolean = false) { export function getBooleanInput(inputName: string, defaultValue = false) {
return (core.getInput(inputName) || String(defaultValue)).toUpperCase() === 'TRUE'; return (
(core.getInput(inputName) || String(defaultValue)).toUpperCase() === 'TRUE'
);
} }
export function getVersionFromToolcachePath(toolPath: string) { export function getVersionFromToolcachePath(toolPath: string) {
@ -28,7 +30,9 @@ export function getVersionFromToolcachePath(toolPath: string) {
export async function extractJdkFile(toolPath: string, extension?: string) { export async function extractJdkFile(toolPath: string, extension?: string) {
if (!extension) { if (!extension) {
extension = toolPath.endsWith('.tar.gz') ? 'tar.gz' : path.extname(toolPath); extension = toolPath.endsWith('.tar.gz')
? 'tar.gz'
: path.extname(toolPath);
if (extension.startsWith('.')) { if (extension.startsWith('.')) {
extension = extension.substring(1); extension = extension.substring(1);
} }
@ -63,7 +67,11 @@ export function isVersionSatisfies(range: string, version: string): boolean {
return semver.satisfies(version, range); return semver.satisfies(version, range);
} }
export function getToolcachePath(toolName: string, version: string, architecture: string) { export function getToolcachePath(
toolName: string,
version: string,
architecture: string
) {
const toolcacheRoot = process.env['RUNNER_TOOL_CACHE'] ?? ''; const toolcacheRoot = process.env['RUNNER_TOOL_CACHE'] ?? '';
const fullPath = path.join(toolcacheRoot, toolName, version, architecture); const fullPath = path.join(toolcacheRoot, toolName, version, architecture);
if (fs.existsSync(fullPath)) { if (fs.existsSync(fullPath)) {
@ -80,7 +88,9 @@ export function isJobStatusSuccess() {
} }
export function isGhes(): boolean { export function isGhes(): boolean {
const ghUrl = new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com'); const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
);
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM'; return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
} }
@ -96,7 +106,9 @@ export function isCacheFeatureAvailable(): boolean {
return false; return false;
} }
core.warning('The runner was not able to contact the cache service. Caching will be skipped'); core.warning(
'The runner was not able to contact the cache service. Caching will be skipped'
);
return false; return false;
} }
@ -104,7 +116,7 @@ export function getVersionFromFileContent(
content: string, content: string,
distributionName: string distributionName: string
): string | null { ): string | null {
const javaVersionRegExp = /(?<version>(?<=(^|\s|\-))(\d+\S*))(\s|$)/; const javaVersionRegExp = /(?<version>(?<=(^|\s|-))(\d+\S*))(\s|$)/;
const fileContent = content.match(javaVersionRegExp)?.groups?.version const fileContent = content.match(javaVersionRegExp)?.groups?.version
? (content.match(javaVersionRegExp)?.groups?.version as string) ? (content.match(javaVersionRegExp)?.groups?.version as string)
: ''; : '';
@ -117,7 +129,9 @@ export function getVersionFromFileContent(
const tentativeVersion = avoidOldNotation(fileContent); const tentativeVersion = avoidOldNotation(fileContent);
const rawVersion = tentativeVersion.split('-')[0]; const rawVersion = tentativeVersion.split('-')[0];
let version = semver.validRange(rawVersion) ? tentativeVersion : semver.coerce(tentativeVersion); let version = semver.validRange(rawVersion)
? tentativeVersion
: semver.coerce(tentativeVersion);
core.debug(`Range version from file is '${version}'`); core.debug(`Range version from file is '${version}'`);

View file

@ -21,6 +21,7 @@
// "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
"newLine": "lf", /* Specify the end of line sequence to be used when emitting files: CRLF (dos) or LF (unix). */
/* Strict Type-Checking Options */ /* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */ "strict": true, /* Enable all strict type-checking options. */

View file

@ -1,7 +0,0 @@
extends: default
rules:
# 100 chars should be enough, but don't fail if a line is longer
line-length:
max: 100
level: warning