Implement unit tests for the project

This commit is contained in:
Thach Nguyen 2022-08-01 02:31:54 +07:00
parent e069019619
commit bae18b5c51
15 changed files with 358 additions and 83 deletions

View File

@ -10,6 +10,9 @@ max_line_length = 100
insert_final_newline = true insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true
[*.{bat,cmd}]
end_of_line = crlf
[*.{ts,js,yml}] [*.{ts,js,yml}]
quote_type = single quote_type = single
spaces_around_brackets = inside spaces_around_brackets = inside

View File

@ -3,13 +3,67 @@
"es6": true, "es6": true,
"node": true "node": true
}, },
"plugins": ["@typescript-eslint"], "extends": ["eslint:all"],
"extends": [ "parserOptions": {
"eslint:recommended", // all "ecmaVersion": 9,
"plugin:@typescript-eslint/all", "sourceType": "module"
"prettier" },
], "rules": {
"capitalized-comments": [
"warn",
"always",
{
"ignorePattern": "noinspection|pragma",
"ignoreInlineComments": true
}
],
"one-var": ["warn", "never"],
"sort-imports": [
"warn",
{
"allowSeparatedGroups": true,
"ignoreDeclarationSort": true
}
],
"no-undefined": "off",
"require-unicode-regexp": "off",
"no-ternary": "off",
"no-negated-condition": "off",
"prefer-named-capture-group": "off"
},
"overrides": [ "overrides": [
{
"files": ["**/*.ts"],
"plugins": ["@typescript-eslint"],
"extends": ["plugin:@typescript-eslint/all"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.eslint.json"
},
"rules": {
"func-style": [
"error",
"declaration",
{
"allowArrowFunctions": true
}
],
"@typescript-eslint/no-implicit-any-catch": "off",
"@typescript-eslint/no-magic-numbers": [
"warn",
{
"ignore": [0, 1],
"ignoreArrayIndexes": true
}
],
"@typescript-eslint/strict-boolean-expressions": [
"error",
{
"allowNullableString": true
}
]
}
},
{ {
"files": ["**/*.test.ts"], "files": ["**/*.test.ts"],
"env": { "env": {
@ -18,29 +72,14 @@
"plugins": ["jest"], "plugins": ["jest"],
"extends": ["plugin:jest/all"], "extends": ["plugin:jest/all"],
"rules": { "rules": {
"max-lines-per-function": ["warn", 100],
"jest/no-hooks": "off",
"jest/prefer-expect-assertions": "off" "jest/prefer-expect-assertions": "off"
} }
},
{
"files": ["**/*"],
"extends": ["prettier"]
} }
], ]
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module",
"project": "./tsconfig.eslint.json"
},
"rules": {
"@typescript-eslint/no-implicit-any-catch": "off",
"@typescript-eslint/no-magic-numbers": [
"error",
{
"ignoreArrayIndexes": true
}
],
"@typescript-eslint/strict-boolean-expressions": [
"error",
{
"allowNullableString": true
}
]
}
} }

4
.gitattributes vendored
View File

@ -5,3 +5,7 @@
# Excluded from stats, hidden in diffs # Excluded from stats, hidden in diffs
dist/** -diff -merge linguist-generated dist/** -diff -merge linguist-generated
# These are explicitly windows files and should use crlf
*.bat text eol=crlf
*.cmd text eol=crlf

7
__tests__/data/mvn Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
echo 'Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T07:58:13Z)'
echo 'Maven home: /usr/share/maven'
echo 'Java version: 1.8.0_121, vendor: Oracle Corporation'
echo 'Java home: /usr/lib/jvm/java-1.8-openjdk/jre'
echo 'Default locale: en_US, platform encoding: UTF-8'
echo 'OS name: "linux", version: "4.4.0-210-generic", arch: "amd64", family: "unix"'

6
__tests__/data/mvn.bat Normal file
View File

@ -0,0 +1,6 @@
@ECHO OFF
ECHO Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d)
ECHO Maven home: C:\Program Files\Java\maven3
ECHO Java version: 11.0.15.1, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk-11.0
ECHO Default locale: en_US, platform encoding: Cp1252
ECHO OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

View File

@ -1,11 +1,110 @@
/* eslint @typescript-eslint/consistent-type-imports: 0 */
import * as os from 'os';
import * as path from 'path';
import { IncomingMessage } from 'http';
import * as core from '@actions/core';
import { HttpClient, HttpCodes } from '@actions/http-client';
import * as installer from '../src/installer'; import * as installer from '../src/installer';
// Mocking modules
jest.mock('@actions/core');
const CACHE_PATH = path.join(__dirname, 'runner');
function createXmlManifest(...versions: readonly string[]): string {
return versions.map(ver => `<version>${ver}</version>`).join();
}
describe('getAvailableVersions', () => { describe('getAvailableVersions', () => {
it('loads real available versions', async () => { it('loads real available versions', async () => {
const availableVersions = await installer.getAvailableVersions(); const availableVersions = await installer.getAvailableVersions();
expect(core.info).toHaveBeenCalledWith(expect.stringMatching(/Downloading.* versions.* from/i));
expect(core.debug).toHaveBeenCalledWith(
expect.stringMatching(/Available.* versions: \[.*,3.1.1,.*]/i)
);
expect(availableVersions).toStrictEqual( expect(availableVersions).toStrictEqual(
expect.arrayContaining(['3.0', '3.2.5', '3.3.3', '3.8.2']) expect.arrayContaining(['3.0', '3.2.5', '3.3.3', '3.8.2'])
); );
}); });
it('failed to download versions manifest', async () => {
jest.spyOn(HttpClient.prototype, 'get').mockResolvedValue({
message: ({ statusCode: 0 } as unknown) as IncomingMessage,
readBody: jest.fn().mockResolvedValue('')
});
await expect(installer.getAvailableVersions()).rejects.toThrow(
/Unable to get available versions from/i
);
expect(core.info).toHaveBeenCalledTimes(1);
});
describe('returns bad versions for incorrect downloaded manifest', () => {
it.each([
[` bar${createXmlManifest('')} foo`, []],
[` ${createXmlManifest(' 1.x', 'foo')}!`, [' 1.x', 'foo']]
])('%s -> %j', async (xml: string, expected: readonly string[]) => {
jest.spyOn(HttpClient.prototype, 'get').mockResolvedValue({
message: ({ statusCode: HttpCodes.OK } as unknown) as IncomingMessage,
readBody: jest.fn().mockResolvedValue(xml)
});
const availableVersions = await installer.getAvailableVersions();
expect(availableVersions).toStrictEqual(expected);
expect(core.info).toHaveBeenCalledTimes(1);
expect(core.debug).toHaveBeenCalledWith(expect.stringContaining(` [${String(expected)}]`));
});
});
});
describe('findVersionForDownload', () => {
describe('raises error if versionSpec was not matched', () => {
it.each([
[' *', ['']],
['* ', ['foo', ' ', ' 1.0.x ', '3.0']],
[' >=3', [' 2.0.1', '!', ' 3.0.x ', '3.3']]
])('%s %j', async (spec: string, versions: readonly string[]) => {
jest.spyOn(HttpClient.prototype, 'get').mockResolvedValue({
message: ({ statusCode: HttpCodes.OK } as unknown) as IncomingMessage,
readBody: jest.fn().mockResolvedValue(createXmlManifest(...versions))
});
await expect(installer.findVersionForDownload(spec)).rejects.toThrow(
new RegExp(`not find.* version for.* ${spec}`, 'i')
);
});
});
describe('returns the best matched correctly', () => {
it.each([
[' 1.x', ['foo', '1.0.1', ' 1.1.0 ', '0.1.0 '], '1.1.0'],
[' * ', ['!', '1.0.1', ' 3.1.0 ', '2.0.1 ', '3.3.0-alpha-1'], '3.1.0'],
['>=1 ', [' ', '1.1.0-beta-1', ' 1.0.1 ', ' 1.0.1-1'], '1.0.1']
])('%s %j -> %s', async (spec: string, versions: readonly string[], expected: string) => {
jest.spyOn(HttpClient.prototype, 'get').mockResolvedValue({
message: ({ statusCode: HttpCodes.OK } as unknown) as IncomingMessage,
readBody: jest.fn().mockResolvedValue(createXmlManifest(...versions))
});
const resolvedVersion = await installer.findVersionForDownload(spec);
expect(resolvedVersion).toBe(expected);
expect(core.debug).toHaveBeenCalledWith(expect.stringMatching(/Resolved version/i));
});
});
});
process.env.RUNNER_TEMP = os.tmpdir();
process.env.RUNNER_TOOL_CACHE = CACHE_PATH;
describe('downloadMaven', () => {
it.todo('download a real version of Maven');
it.todo('raises error if download failed');
it.todo('raises error when extracting failed');
}); });

View File

@ -1,17 +1,57 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import { getActiveMavenVersion } from '../src/utils';
import { setupMaven } from '../src/installer';
import { run } from '../src/main'; import { run } from '../src/main';
// Mocking modules
jest.mock('@actions/core');
jest.mock('../src/utils');
jest.mock('../src/installer');
const DEFAULT_VERSION = '3';
describe('failed to run with invalid inputs', () => { describe('failed to run with invalid inputs', () => {
it.each([ it.each([
['maven-version', { 'maven-version': ' foo-3!' }] // eslint-disable-line no-inline-comments ['maven-version', { 'maven-version': ' foo-3!' }] // eslint-disable-line
])('%s', async (name: string, inputs: Readonly<Record<string, string>>) => { ])('%s', async (name: string, inputs: Readonly<Record<string, string>>) => {
const spyFailed = jest.spyOn(core, 'setFailed'); (core.getInput as jest.Mock).mockImplementation((key: string) => inputs[key]);
jest.spyOn(core, 'getInput').mockImplementation((key: string) => inputs[key]);
await run(); await run();
expect(spyFailed).toHaveBeenCalledWith( expect(core.setFailed).toHaveBeenCalledWith(
expect.stringMatching(new RegExp(`[Ii]nvalid .*'${inputs[name]}'`)) expect.stringMatching(new RegExp(`[Ii]nvalid .*'${inputs[name]}'`))
); );
}); });
}); });
describe('run with valid inputs', () => {
it('setups default version when no Maven is installed', async () => {
(core.getInput as jest.Mock).mockReturnValue('');
(getActiveMavenVersion as jest.Mock).mockResolvedValue(undefined);
(setupMaven as jest.Mock).mockResolvedValue('foo');
await run();
expect(setupMaven).toHaveBeenCalledWith(DEFAULT_VERSION, undefined);
expect(core.setOutput).toHaveBeenCalledWith('version', 'foo');
});
it('setups when installed Maven is different with version input', async () => {
(core.getInput as jest.Mock).mockReturnValue('3.3');
(getActiveMavenVersion as jest.Mock).mockResolvedValue('3.5.2');
(setupMaven as jest.Mock).mockResolvedValue(DEFAULT_VERSION);
await run();
expect(setupMaven).toHaveBeenCalledWith('3.3', undefined);
expect(core.setOutput).toHaveBeenCalledWith('version', DEFAULT_VERSION);
});
it('setups when installed Maven is correspond with version input', async () => {
(core.getInput as jest.Mock).mockReturnValue('3.x');
(getActiveMavenVersion as jest.Mock).mockResolvedValue('3.3.9');
(setupMaven as jest.Mock).mockResolvedValue('');
await run();
expect(setupMaven).toHaveBeenCalledWith('3.x', '3.3.9');
expect(core.setOutput).toHaveBeenCalledWith('version', '');
});
});

View File

@ -1,6 +1,16 @@
import * as path from 'path'; import * as path from 'path';
import * as child from 'child_process';
import { EventEmitter } from 'events';
import { getVersionFromToolcachePath } from '../src/utils'; import * as core from '@actions/core';
import { getActiveMavenVersion, getVersionFromToolcachePath } from '../src/utils';
// Mocking modules
jest.mock('child_process');
jest.mock('@actions/core');
const MVN_PATH = path.join(__dirname, 'data');
describe('getVersionFromToolcachePath', () => { describe('getVersionFromToolcachePath', () => {
it.each([ it.each([
@ -14,3 +24,64 @@ describe('getVersionFromToolcachePath', () => {
expect(actual).toBe(expected); expect(actual).toBe(expected);
}); });
}); });
describe('getActiveMavenVersion', () => {
const ORIGINAL_PATH = process.env.PATH;
const EMIT_AT = 21;
afterEach(() => {
process.env.PATH = ORIGINAL_PATH;
});
it('gets real version by `mvn` command', async () => {
const expectedVersion = '3.5.2';
process.env.PATH = `${MVN_PATH}${path.delimiter}${ORIGINAL_PATH ?? ''}`;
const cp = jest.requireActual<typeof child>('child_process');
(child.spawn as jest.Mock).mockImplementation(cp.spawn);
const installedVersion = await getActiveMavenVersion();
expect(installedVersion).toBe(expectedVersion);
expect(core.debug).toHaveBeenCalledWith(
expect.stringMatching(new RegExp(`Retrieved.* version: ${expectedVersion}`, 'i'))
);
});
it('returns null if no Maven is installed', async () => {
process.env.PATH = '';
const installedVersion = await getActiveMavenVersion();
expect(installedVersion).toBeUndefined();
expect(core.info).toHaveBeenCalledWith(
expect.stringMatching(/Failed.* version.* Unable.* locate executable file: mvn/i)
);
});
it('returns null if `mvn` command is failed', async () => {
process.env.PATH = MVN_PATH;
const cp = new EventEmitter();
(child.spawn as jest.Mock).mockReturnValue(cp);
setTimeout(() => cp.emit('close', EMIT_AT), EMIT_AT);
const installedVersion = await getActiveMavenVersion();
expect(installedVersion).toBeUndefined();
expect(core.info).toHaveBeenCalledWith(
expect.stringMatching(new RegExp(`Failed.* version.* process.* exit code ${EMIT_AT}`, 'i'))
);
});
it('returns empty if `mvn` command is incorrect', async () => {
process.env.PATH = MVN_PATH;
const cp = Object.create(new EventEmitter()) as EventEmitter & { stdout: EventEmitter };
(child.spawn as jest.Mock).mockReturnValue((cp.stdout = cp));
setTimeout(() => cp.emit('data', 'foo') && cp.emit('close', 0), EMIT_AT);
const installedVersion = await getActiveMavenVersion();
expect(installedVersion).toBe('');
expect(core.debug).toHaveBeenCalledTimes(1);
});
});

27
dist/index.js generated vendored
View File

@ -5045,20 +5045,20 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.setupMaven = exports.findVersionForDownload = exports.downloadMaven = exports.getAvailableVersions = void 0; exports.setupMaven = exports.findVersionForDownload = exports.downloadMaven = exports.getAvailableVersions = void 0;
const path = __importStar(__nccwpck_require__(622)); const path = __importStar(__nccwpck_require__(622));
const core = __importStar(__nccwpck_require__(186)); const core = __importStar(__nccwpck_require__(186));
const httpm = __importStar(__nccwpck_require__(925));
const tc = __importStar(__nccwpck_require__(784)); const tc = __importStar(__nccwpck_require__(784));
const semver = __importStar(__nccwpck_require__(911)); const semver = __importStar(__nccwpck_require__(911));
const http_client_1 = __nccwpck_require__(925);
const utils_1 = __nccwpck_require__(314); const utils_1 = __nccwpck_require__(314);
const DOWNLOAD_BASE_URL = 'https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven'; const DOWNLOAD_BASE_URL = 'https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven';
function getAvailableVersions() { function getAvailableVersions() {
var _a; var _a;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const resourceUrl = `${DOWNLOAD_BASE_URL}/maven-metadata.xml`; const resourceUrl = `${DOWNLOAD_BASE_URL}/maven-metadata.xml`;
const http = new httpm.HttpClient('setup-maven', undefined, { allowRetries: true }); const http = new http_client_1.HttpClient('setup-maven', undefined, { allowRetries: true });
core.info(`Downloading Maven versions manifest from ${resourceUrl} ...`); core.info(`Downloading Maven versions manifest from ${resourceUrl} ...`);
const response = yield http.get(resourceUrl); const response = yield http.get(resourceUrl);
const body = yield response.readBody(); const body = yield response.readBody();
if (response.message.statusCode !== httpm.HttpCodes.OK || !body) { if (response.message.statusCode !== http_client_1.HttpCodes.OK || !body) {
throw new Error(`Unable to get available versions from ${resourceUrl}`); throw new Error(`Unable to get available versions from ${resourceUrl}`);
} }
const availableVersions = (_a = body.match(/(?<=<version>)[^<>]+(?=<\/version>)/g)) !== null && _a !== void 0 ? _a : []; const availableVersions = (_a = body.match(/(?<=<version>)[^<>]+(?=<\/version>)/g)) !== null && _a !== void 0 ? _a : [];
@ -5070,21 +5070,21 @@ exports.getAvailableVersions = getAvailableVersions;
/** /**
* Download and extract a specified Maven version to the tool-cache. * Download and extract a specified Maven version to the tool-cache.
*/ */
function downloadMaven(fullVersion) { function downloadMaven(version) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const toolDirectoryName = `apache-maven-${fullVersion}`; const toolDirectoryName = `apache-maven-${version}`;
const downloadUrl = `${DOWNLOAD_BASE_URL}/${fullVersion}/${toolDirectoryName}-bin.tar.gz`; const downloadUrl = `${DOWNLOAD_BASE_URL}/${version}/${toolDirectoryName}-bin.tar.gz`;
core.info(`Downloading Maven ${fullVersion} from ${downloadUrl} ...`); core.info(`Downloading Maven ${version} from ${downloadUrl} ...`);
const downloadPath = yield tc.downloadTool(downloadUrl); const downloadPath = yield tc.downloadTool(downloadUrl);
const extractedPath = yield tc.extractTar(downloadPath); const extractedPath = yield tc.extractTar(downloadPath);
const toolRoot = path.join(extractedPath, toolDirectoryName); const toolRoot = path.join(extractedPath, toolDirectoryName);
return tc.cacheDir(toolRoot, 'maven', fullVersion); return tc.cacheDir(toolRoot, 'maven', version);
}); });
} }
exports.downloadMaven = downloadMaven; exports.downloadMaven = downloadMaven;
function findVersionForDownload(versionSpec) { function findVersionForDownload(versionSpec) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const availableVersions = yield getAvailableVersions(); const availableVersions = (yield getAvailableVersions()).map(ver => ver.trim());
const resolvedVersion = semver.maxSatisfying(availableVersions, versionSpec); const resolvedVersion = semver.maxSatisfying(availableVersions, versionSpec);
if (!resolvedVersion) { if (!resolvedVersion) {
throw new Error(`Could not find satisfied version for SemVer ${versionSpec}`); throw new Error(`Could not find satisfied version for SemVer ${versionSpec}`);
@ -5156,8 +5156,9 @@ const core = __importStar(__nccwpck_require__(186));
const semver = __importStar(__nccwpck_require__(911)); const semver = __importStar(__nccwpck_require__(911));
const utils_1 = __nccwpck_require__(314); const utils_1 = __nccwpck_require__(314);
const installer_1 = __nccwpck_require__(574); const installer_1 = __nccwpck_require__(574);
const DEFAULT_VERSION = '3';
function resolveVersionInput() { function resolveVersionInput() {
const versionSpec = core.getInput('maven-version') || '3'; const versionSpec = core.getInput('maven-version') || DEFAULT_VERSION;
if (!semver.validRange(versionSpec)) { if (!semver.validRange(versionSpec)) {
throw new Error(`Invalid SemVer notation '${versionSpec}' for a Maven version`); throw new Error(`Invalid SemVer notation '${versionSpec}' for a Maven version`);
} }
@ -5233,13 +5234,13 @@ function getActiveMavenVersion() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
const { stdout } = yield exec.getExecOutput('mvn', ['-v'], { silent: true }); const { stdout } = yield exec.getExecOutput('mvn', ['-v'], { silent: true });
const found = /^[^\d]*(\S+)/.exec(stdout); const found = /^[^\d]*(\d\S*)/.exec(stdout);
const installedVersion = !found ? '' : found[1]; const installedVersion = !found ? '' : found[1];
core.debug(`Retrieved activated Maven version: ${installedVersion}`); core.debug(`Retrieved activated Maven version: ${installedVersion}`);
return installedVersion; return installedVersion;
} }
catch (err) { catch (err) {
core.info(`Failed to get activated Maven version. ${err.message}`); core.info(`Failed to get activated Maven version. ${String(err)}`);
} }
return undefined; return undefined;
}); });
@ -5414,9 +5415,9 @@ var __webpack_exports__ = {};
var exports = __webpack_exports__; var exports = __webpack_exports__;
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
/* eslint @typescript-eslint/no-floating-promises: 0 */
const main_1 = __nccwpck_require__(399); const main_1 = __nccwpck_require__(399);
// noinspection JSIgnoredPromiseFromCall // noinspection JSIgnoredPromiseFromCall
// eslint-disable-next-line @typescript-eslint/no-floating-promises
main_1.run(); main_1.run();
})(); })();

View File

@ -1,5 +1,6 @@
{ {
"clearMocks": true, "clearMocks": true,
"resetMocks": true,
"moduleFileExtensions": ["ts", "js"], "moduleFileExtensions": ["ts", "js"],
"testEnvironment": "node", "testEnvironment": "node",
"testMatch": ["**/*.test.ts"], "testMatch": ["**/*.test.ts"],

View File

@ -1,8 +1,9 @@
import * as path from 'path'; import * as path from 'path';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as httpm from '@actions/http-client';
import * as tc from '@actions/tool-cache'; import * as tc from '@actions/tool-cache';
import * as semver from 'semver'; import * as semver from 'semver';
import { HttpClient, HttpCodes } from '@actions/http-client';
import { getVersionFromToolcachePath } from './utils'; import { getVersionFromToolcachePath } from './utils';
@ -10,13 +11,13 @@ const DOWNLOAD_BASE_URL = 'https://repo.maven.apache.org/maven2/org/apache/maven
export async function getAvailableVersions(): Promise<string[]> { export async function getAvailableVersions(): Promise<string[]> {
const resourceUrl = `${DOWNLOAD_BASE_URL}/maven-metadata.xml`; const resourceUrl = `${DOWNLOAD_BASE_URL}/maven-metadata.xml`;
const http = new httpm.HttpClient('setup-maven', undefined, { allowRetries: true }); const http = new HttpClient('setup-maven', undefined, { allowRetries: true });
core.info(`Downloading Maven versions manifest from ${resourceUrl} ...`); core.info(`Downloading Maven versions manifest from ${resourceUrl} ...`);
const response = await http.get(resourceUrl); const response = await http.get(resourceUrl);
const body = await response.readBody(); const body = await response.readBody();
if (response.message.statusCode !== httpm.HttpCodes.OK || !body) { if (response.message.statusCode !== HttpCodes.OK || !body) {
throw new Error(`Unable to get available versions from ${resourceUrl}`); throw new Error(`Unable to get available versions from ${resourceUrl}`);
} }
@ -29,21 +30,21 @@ export async function getAvailableVersions(): Promise<string[]> {
/** /**
* Download and extract a specified Maven version to the tool-cache. * Download and extract a specified Maven version to the tool-cache.
*/ */
export async function downloadMaven(fullVersion: string): Promise<string> { export async function downloadMaven(version: string): Promise<string> {
const toolDirectoryName = `apache-maven-${fullVersion}`; const toolDirectoryName = `apache-maven-${version}`;
const downloadUrl = `${DOWNLOAD_BASE_URL}/${fullVersion}/${toolDirectoryName}-bin.tar.gz`; const downloadUrl = `${DOWNLOAD_BASE_URL}/${version}/${toolDirectoryName}-bin.tar.gz`;
core.info(`Downloading Maven ${fullVersion} from ${downloadUrl} ...`); core.info(`Downloading Maven ${version} from ${downloadUrl} ...`);
const downloadPath = await tc.downloadTool(downloadUrl); const downloadPath = await tc.downloadTool(downloadUrl);
const extractedPath = await tc.extractTar(downloadPath); const extractedPath = await tc.extractTar(downloadPath);
const toolRoot = path.join(extractedPath, toolDirectoryName); const toolRoot = path.join(extractedPath, toolDirectoryName);
return tc.cacheDir(toolRoot, 'maven', fullVersion); return tc.cacheDir(toolRoot, 'maven', version);
} }
export async function findVersionForDownload(versionSpec: string): Promise<string> { export async function findVersionForDownload(versionSpec: string): Promise<string> {
const availableVersions = await getAvailableVersions(); const availableVersions = (await getAvailableVersions()).map(ver => ver.trim());
const resolvedVersion = semver.maxSatisfying(availableVersions, versionSpec); const resolvedVersion = semver.maxSatisfying(availableVersions, versionSpec);
if (!resolvedVersion) { if (!resolvedVersion) {

View File

@ -4,8 +4,10 @@ import * as semver from 'semver';
import { getActiveMavenVersion } from './utils'; import { getActiveMavenVersion } from './utils';
import { setupMaven } from './installer'; import { setupMaven } from './installer';
const DEFAULT_VERSION = '3';
function resolveVersionInput(): string { function resolveVersionInput(): string {
const versionSpec = core.getInput('maven-version') || '3'; const versionSpec = core.getInput('maven-version') || DEFAULT_VERSION;
if (!semver.validRange(versionSpec)) { if (!semver.validRange(versionSpec)) {
throw new Error(`Invalid SemVer notation '${versionSpec}' for a Maven version`); throw new Error(`Invalid SemVer notation '${versionSpec}' for a Maven version`);

View File

@ -1,5 +1,5 @@
/* eslint @typescript-eslint/no-floating-promises: 0 */
import { run } from './main'; import { run } from './main';
// noinspection JSIgnoredPromiseFromCall // noinspection JSIgnoredPromiseFromCall
// eslint-disable-next-line @typescript-eslint/no-floating-promises
run(); run();

View File

@ -1,4 +1,5 @@
import * as path from 'path'; import * as path from 'path';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
@ -13,13 +14,13 @@ export async function getActiveMavenVersion(): Promise<string | undefined> {
try { try {
const { stdout } = await exec.getExecOutput('mvn', ['-v'], { silent: true }); const { stdout } = await exec.getExecOutput('mvn', ['-v'], { silent: true });
const found = /^[^\d]*(\S+)/.exec(stdout); const found = /^[^\d]*(\d\S*)/.exec(stdout);
const installedVersion = !found ? '' : found[1]; const installedVersion = !found ? '' : found[1];
core.debug(`Retrieved activated Maven version: ${installedVersion}`); core.debug(`Retrieved activated Maven version: ${installedVersion}`);
return installedVersion; return installedVersion;
} catch (err) { } catch (err) {
core.info(`Failed to get activated Maven version. ${(err as Error).message}`); core.info(`Failed to get activated Maven version. ${String(err)}`);
} }
return undefined; return undefined;

View File

@ -962,15 +962,15 @@ browser-process-hrtime@^1.0.0:
integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
browserslist@^4.14.5: browserslist@^4.14.5:
version "4.16.6" version "4.17.6"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.6.tgz#c76be33e7786b497f66cad25a73756c8b938985d"
integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== integrity sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw==
dependencies: dependencies:
caniuse-lite "^1.0.30001219" caniuse-lite "^1.0.30001274"
colorette "^1.2.2" electron-to-chromium "^1.3.886"
electron-to-chromium "^1.3.723"
escalade "^3.1.1" escalade "^3.1.1"
node-releases "^1.1.71" node-releases "^2.0.1"
picocolors "^1.0.0"
bs-logger@0.x: bs-logger@0.x:
version "0.2.6" version "0.2.6"
@ -1006,10 +1006,10 @@ camelcase@^6.2.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
caniuse-lite@^1.0.30001219: caniuse-lite@^1.0.30001274:
version "1.0.30001228" version "1.0.30001312"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f"
integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==
chalk@^2.0.0: chalk@^2.0.0:
version "2.4.2" version "2.4.2"
@ -1081,11 +1081,6 @@ color-name@1.1.3, color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
colorette@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
combined-stream@^1.0.8: combined-stream@^1.0.8:
version "1.0.8" version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@ -1203,10 +1198,10 @@ domexception@^2.0.1:
dependencies: dependencies:
webidl-conversions "^5.0.0" webidl-conversions "^5.0.0"
electron-to-chromium@^1.3.723: electron-to-chromium@^1.3.886:
version "1.3.729" version "1.4.71"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.729.tgz#3dc87b55c4aa3c75370471d9c72accf70d9af263" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz#17056914465da0890ce00351a3b946fd4cd51ff6"
integrity sha512-Ho8K+hCEFOt6FsRZRgh1zUpIJ4Nn9MUSgLBEF+I2Xbzo3E8zvvxZFV/tEmAl2e9dsJDWzTFnGsZTuEVfYEv8eg== integrity sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==
emittery@^0.8.1: emittery@^0.8.1:
version "0.8.1" version "0.8.1"
@ -2398,10 +2393,10 @@ node-modules-regexp@^1.0.0:
resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40"
integrity sha512-JMaRS9L4wSRIR+6PTVEikTrq/lMGEZR43a48ETeilY0Q0iMwVnccMFrUM1k+tNzmYuIU0Vh710bCUqHX+/+ctQ== integrity sha512-JMaRS9L4wSRIR+6PTVEikTrq/lMGEZR43a48ETeilY0Q0iMwVnccMFrUM1k+tNzmYuIU0Vh710bCUqHX+/+ctQ==
node-releases@^1.1.71: node-releases@^2.0.1:
version "1.1.72" version "2.0.2"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01"
integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==
normalize-path@^3.0.0: normalize-path@^3.0.0:
version "3.0.0" version "3.0.0"
@ -2502,6 +2497,11 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
version "2.2.3" version "2.2.3"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d"