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 4402 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

26
.licenses/npm/semver-7.3.8.dep.yml generated Normal file
View File

@ -0,0 +1,26 @@
---
name: semver
version: 7.3.8
type: npm
summary: The semantic version parser used by npm.
homepage:
license: isc
licenses:
- sources: LICENSE
text: |
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
notices: []

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