Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions __tests__/entrypoints.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {afterAll, beforeAll, describe, expect, it} from '@jest/globals';
import {spawnSync} from 'child_process';
import fs from 'fs';
import os from 'os';
import path from 'path';
import {fileURLToPath, pathToFileURL} from 'url';

const dist = fileURLToPath(new URL('../dist/', import.meta.url));
let tempDir: string;
let linkedDist: string;

beforeAll(() => {
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-java-entrypoints-'));
linkedDist = path.join(tempDir, 'linked # dist');
fs.symlinkSync(dist, linkedDist, 'junction');
});

afterAll(() => {
fs.rmSync(tempDir, {recursive: true, force: true});
});

function execute(args: string[], input?: string) {
return spawnSync(process.execPath, args, {
encoding: 'utf8',
input,
timeout: 10000,
env: {
PATH: process.env.PATH,
SystemRoot: process.env.SystemRoot
}
});
}

describe.each([
['setup', 1, 'java-version or java-version-file input expected'],
['cleanup', 0, '']
] as const)('%s entrypoint', (name, exitCode, output) => {
it.each(['direct', 'symlink', 'preserved symlink'])(
'executes through a %s path',
mode => {
const entry = path.join(
mode === 'direct' ? dist : linkedDist,
name,
'index.js'
);
const args =
mode === 'preserved symlink'
? ['--preserve-symlinks-main', entry]
: [entry];
const result = execute(args);

expect(result.error).toBeUndefined();
expect(result.status).toBe(exitCode);
expect(result.stderr).toBe('');
expect(result.stdout).not.toContain('skipping the execution');
if (output) {
expect(result.stdout).toContain(output);
} else {
expect(result.stdout).toBe('');
}
}
);

it.each(['eval', 'stdin', 'file'])(
'does not execute when imported from %s',
mode => {
const moduleUrl = pathToFileURL(path.join(dist, name, 'index.js')).href;
const source = `const {run} = await import(${JSON.stringify(moduleUrl)}); console.log(typeof run);`;
const importer = path.join(tempDir, `${name}-importer.mjs`);
fs.writeFileSync(importer, source);
const args =
mode === 'file'
? [importer]
: mode === 'eval'
? ['--input-type=module', '-e', source]
: ['--input-type=module', '-'];
const result = execute(args, mode === 'stdin' ? source : undefined);

expect(result.error).toBeUndefined();
expect(result.status).toBe(0);
expect(result.stderr).toBe('');
expect(result.stdout).toContain('skipping the execution');
expect(result.stdout).toContain('function');
expect(result.stdout).not.toContain('::error::');
}
);
});
52 changes: 52 additions & 0 deletions __tests__/is-main-module.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {afterEach, beforeEach, describe, expect, it, jest} from '@jest/globals';
import fs from 'fs';
import {isMainModule} from '../src/is-main-module.js';

describe('main module detection', () => {
const originalArgv = process.argv;

beforeEach(() => {
process.argv = [process.execPath, 'entrypoint.js'];
});

afterEach(() => {
process.argv = originalArgv;
jest.restoreAllMocks();
});

it.each([undefined, '-'])(
'skips filesystem access when argv[1] is %s',
entrypoint => {
process.argv =
entrypoint === undefined
? [process.execPath]
: [process.execPath, entrypoint];
const realpath = jest.spyOn(fs, 'realpathSync');

expect(isMainModule(import.meta.url)).toBe(false);
expect(realpath).not.toHaveBeenCalled();
}
);

it.each(['ENOENT', 'ENOTDIR'])(
'treats a non-file entrypoint returning %s as an import',
code => {
jest.spyOn(fs, 'realpathSync').mockImplementation(() => {
throw Object.assign(new Error('No file-based entrypoint'), {code});
});

expect(isMainModule(import.meta.url)).toBe(false);
}
);

it('propagates unexpected filesystem errors', () => {
const error = Object.assign(new Error('Permission denied'), {
code: 'EACCES'
});
jest.spyOn(fs, 'realpathSync').mockImplementation(() => {
throw error;
});

expect(() => isMainModule(import.meta.url)).toThrow(error);
});
});
1 change: 1 addition & 0 deletions __tests__/setup-java.module-loading.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jest.unstable_mockModule('@actions/core', () => ({

jest.unstable_mockModule('fs', () => ({
default: {
...jest.requireActual<typeof import('fs')>('fs'),
readFileSync: jest.fn()
}
}));
Expand Down
1 change: 1 addition & 0 deletions __tests__/setup-java.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jest.unstable_mockModule('@actions/core', () => ({

jest.unstable_mockModule('fs', () => ({
default: {
...jest.requireActual<typeof import('fs')>('fs'),
readFileSync: jest.fn()
}
}));
Expand Down
27 changes: 26 additions & 1 deletion dist/cleanup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35747,6 +35747,7 @@ __nccwpck_require__.d(__webpack_exports__, {
var cleanup_java_core = __nccwpck_require__(3838);
// EXTERNAL MODULE: external "fs"
var external_fs_ = __nccwpck_require__(9896);
var external_fs_default = /*#__PURE__*/__nccwpck_require__.n(external_fs_);
// EXTERNAL MODULE: external "path"
var external_path_ = __nccwpck_require__(6928);
// EXTERNAL MODULE: external "crypto"
Expand Down Expand Up @@ -35890,6 +35891,30 @@ async function verifyPackageSignature(archivePath, signatureUrl, publicKeyConten
var constants = __nccwpck_require__(7242);
// EXTERNAL MODULE: external "url"
var external_url_ = __nccwpck_require__(7016);
;// CONCATENATED MODULE: ./src/is-main-module.ts


function isMainModule(moduleUrl) {
const entrypoint = process.argv[1];
if (!entrypoint || entrypoint === '-') {
return false;
}
let entrypointPath;
try {
entrypointPath = external_fs_default().realpathSync(entrypoint);
}
catch (error) {
if (error instanceof Error &&
'code' in error &&
(error.code === 'ENOENT' || error.code === 'ENOTDIR')) {
return false;
}
throw error;
}
// Resolve both paths for runtimes using --preserve-symlinks-main.
return entrypointPath === external_fs_default().realpathSync((0,external_url_.fileURLToPath)(moduleUrl));
}

;// CONCATENATED MODULE: ./src/cleanup-java.ts


Expand Down Expand Up @@ -35957,7 +35982,7 @@ async function run() {
await cleanup_java_removeGpgHome();
await ignoreError(saveCaches());
}
if (process.argv[1] === (0,external_url_.fileURLToPath)(import.meta.url)) {
if (isMainModule(import.meta.url)) {
run();
}
else {
Expand Down
27 changes: 26 additions & 1 deletion dist/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36354,6 +36354,30 @@ function configureProblemMatcher(matcherPath) {

// EXTERNAL MODULE: ./src/toolchain-ids.ts
var toolchain_ids = __nccwpck_require__(7083);
;// CONCATENATED MODULE: ./src/is-main-module.ts


function isMainModule(moduleUrl) {
const entrypoint = process.argv[1];
if (!entrypoint || entrypoint === '-') {
return false;
}
let entrypointPath;
try {
entrypointPath = external_fs_default().realpathSync(entrypoint);
}
catch (error) {
if (error instanceof Error &&
'code' in error &&
(error.code === 'ENOENT' || error.code === 'ENOTDIR')) {
return false;
}
throw error;
}
// Resolve both paths for runtimes using --preserve-symlinks-main.
return entrypointPath === external_fs_default().realpathSync((0,external_url_.fileURLToPath)(moduleUrl));
}

;// CONCATENATED MODULE: ./src/setup-java.ts


Expand All @@ -36364,6 +36388,7 @@ var toolchain_ids = __nccwpck_require__(7083);




async function run() {
const versions = setup_java_core/* getMultilineInput */.q3(constants/* INPUT_JAVA_VERSION */.QM);
let distributionName = setup_java_core/* getInput */.V4(constants/* INPUT_DISTRIBUTION */.g_);
Expand Down Expand Up @@ -36480,7 +36505,7 @@ async function validateCacheInput(cache) {
function settle(promise) {
return promise.then(value => ({ status: 'fulfilled', value }), reason => ({ status: 'rejected', reason }));
}
if (process.argv[1] === (0,external_url_.fileURLToPath)(import.meta.url)) {
if (isMainModule(import.meta.url)) {
run();
}
else {
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/cleanup-java.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
isJdkCacheEnabled,
isJobStatusSuccess
} from './util.js';
import {fileURLToPath} from 'url';
import {isMainModule} from './is-main-module.js';

async function removeGpgHome() {
const gpgHome = core.getState(constants.STATE_GPG_HOME);
Expand Down Expand Up @@ -77,7 +77,7 @@ export async function run() {
await ignoreError(saveCaches());
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
if (isMainModule(import.meta.url)) {
run();
} else {
// https://nodejs.org/api/modules.html#modules_accessing_the_main_module
Expand Down
26 changes: 26 additions & 0 deletions src/is-main-module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import fs from 'fs';
import {fileURLToPath} from 'url';

export function isMainModule(moduleUrl: string): boolean {
const entrypoint = process.argv[1];
if (!entrypoint || entrypoint === '-') {
return false;
}

let entrypointPath: string;
try {
entrypointPath = fs.realpathSync(entrypoint);
} catch (error) {
if (
error instanceof Error &&
'code' in error &&
(error.code === 'ENOENT' || error.code === 'ENOTDIR')
) {
return false;
}
throw error;
}

// Resolve both paths for runtimes using --preserve-symlinks-main.
return entrypointPath === fs.realpathSync(fileURLToPath(moduleUrl));
}
3 changes: 2 additions & 1 deletion src/setup-java.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {getJavaDistribution} from './distributions/distribution-factory.js';
import {JavaInstallerOptions} from './distributions/base-models.js';
import {configureProblemMatcher} from './problem-matcher.js';
import {validateToolchainIds} from './toolchain-ids.js';
import {isMainModule} from './is-main-module.js';

export async function run() {
const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION);
Expand Down Expand Up @@ -172,7 +173,7 @@ function settle<T>(promise: Promise<T>): Promise<PromiseSettledResult<T>> {
);
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
if (isMainModule(import.meta.url)) {
run();
} else {
// https://nodejs.org/api/modules.html#modules_accessing_the_main_module
Expand Down
Loading