Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: support config file as typescript #23

Merged
merged 1 commit into from
Dec 31, 2021
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Check out the use case description from eslint-remote-tester's documentation: [P
| :-----------------------------: | :------------------: |
| `v1` | `1.0.1` or above |
| `v2` | `1.0.1` or above |
| `v3` | `2.1.1` or above |

## Configuration:

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.4",
"@actions/github": "^4.0.0",
"eslint-remote-tester": "^1.2.0",
"eslint-remote-tester": "^2.1.1",
"semver": "^7.3.4"
},
"devDependencies": {
Expand All @@ -41,6 +41,7 @@
"prettier": "^2.2.1",
"rimraf": "^3.0.2",
"ts-jest": "24",
"ts-node": "^10.4.0",
"typescript": "^4.1.3"
},
"husky": {
Expand Down
2 changes: 1 addition & 1 deletion src/peer-dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface DependencyInfo {
// Changes to minVersion's require major release
const DEPENDENCY_TO_INFO: Record<PeerDependency, DependencyInfo> = {
'eslint-remote-tester': {
minVersion: '1.0.1',
minVersion: '2.1.1',
exportPath: 'eslint-remote-tester/dist/exports-for-compare-action',
packageJsonPath: 'eslint-remote-tester/package.json',
bin: 'eslint-remote-tester',
Expand Down
66 changes: 44 additions & 22 deletions src/run-tester.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import fs from 'fs';
import path from 'path';
import { exec } from '@actions/exec';
import { Config } from 'eslint-remote-tester/dist/exports-for-compare-action';
import type { Config } from 'eslint-remote-tester';

import {
requirePeerDependency,
ESLINT_REMOTE_TESTER_BIN,
} from './peer-dependencies';

const INTERNAL_CONFIG = './eslint-remote-tester-runner-internal.config.js';
const INTERNAL_CONFIG = './eslint-remote-tester-runner-internal.config';
export const RESULTS_TMP = '/tmp/results.json';

/**
Expand All @@ -19,19 +19,7 @@ const DEFAULT_CONFIG: Partial<Config> = {
CI: true,
};

// prettier-ignore
const CONFIGURATION_TEMPLATE = (
pathToUsersConfiguration: string
) =>
`// Generated by eslint-remote-tester-run-action
const fs = require('fs');

// Load user's eslint-remote-tester.config.js
const usersConfig = require('${pathToUsersConfiguration}');

module.exports = {
...usersConfig,

const CONFIGURATION_TEMPLATE_BASE = `
// Values from eslint-remote-tester-run-action's default configuration
...${JSON.stringify(DEFAULT_CONFIG, null, 4)},

Expand All @@ -43,7 +31,35 @@ module.exports = {
await usersConfig.onComplete(results, comparisonResults, repositoryCount);
}
}
`;

const CONFIGURATION_TEMPLATE_JS = (pathToUsersConfiguration: string) =>
`// Generated by eslint-remote-tester-run-action
const fs = require('fs');

// Load user's eslint-remote-tester.config.js
const usersConfig = require('${pathToUsersConfiguration}');

module.exports = {
...usersConfig,
${CONFIGURATION_TEMPLATE_BASE}
};
`;

const CONFIGURATION_TEMPLATE_TS = (pathToUsersConfiguration: string) =>
`// Generated by eslint-remote-tester-run-action
import fs from 'fs';
import type { Config } from 'eslint-remote-tester';

// Load user's eslint-remote-tester.config.ts
import usersConfig from '${pathToUsersConfiguration.replace(/\.ts$/, '')}';

const config: Config = {
...usersConfig,
${CONFIGURATION_TEMPLATE_BASE}
};

export default config;
`;

/**
Expand All @@ -65,27 +81,33 @@ export default async function runTester(configLocation: string): Promise<void> {
);
}

const extension = usersConfigLocation.split('.').pop();
const configTemplate =
extension === 'ts'
? CONFIGURATION_TEMPLATE_TS
: CONFIGURATION_TEMPLATE_JS;
const createdConfig = `${INTERNAL_CONFIG}.${extension}`;

// Write eslint-remote-tester configuration file
fs.writeFileSync(
INTERNAL_CONFIG,
CONFIGURATION_TEMPLATE(usersConfigLocation)
);
fs.writeFileSync(createdConfig, configTemplate(usersConfigLocation));

const { loadConfig, validateConfig } = requirePeerDependency(
'eslint-remote-tester'
);
let config: Config;

// Useless try-catch required by esbuild
// eslint-disable-next-line no-useless-catch
try {
config = require(path.resolve(INTERNAL_CONFIG));
config = loadConfig(path.resolve(createdConfig));
} catch (e) {
throw e;
}

// Validate configuration before run
const { validateConfig } = requirePeerDependency('eslint-remote-tester');
await validateConfig(config, false);

await exec(`${ESLINT_REMOTE_TESTER_BIN} --config ${INTERNAL_CONFIG}`, [], {
await exec(`${ESLINT_REMOTE_TESTER_BIN} --config ${createdConfig}`, [], {
ignoreReturnCode: true,
env: { ...process.env, NODE_OPTIONS: '--max_old_space_size=5120' },
});
Expand Down
12 changes: 12 additions & 0 deletions test/eslint-remote-tester.typescript.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { Config } from 'eslint-remote-tester';

const config: Config = {
repositories: ['AriPerkkio/eslint-remote-tester-integration-test-target'],
extensions: ['.ts'],
eslintrc: {
root: true,
extends: ['eslint:recommended'],
},
};

export default config;
114 changes: 99 additions & 15 deletions test/run-tester.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@ import { ESLINT_REMOTE_TESTER_BIN } from '../src/peer-dependencies';
import { sanitizeStackTrace } from './utils';
import { Config } from 'eslint-remote-tester/dist/exports-for-compare-action';

const EXPECTED_RUN_CONFIG = './eslint-remote-tester-runner-internal.config.js';
const CONFIG = './test/eslint-remote-tester.config.js';
const EXPECTED_RUN_CONFIG = './eslint-remote-tester-runner-internal.config';
const CONFIG_JS = './test/eslint-remote-tester.config.js';
const CONFIG_TS = './test/eslint-remote-tester.typescript.config.ts';
const INVALID_CONFIG = './test/eslint-remote-tester.invalid.config.js';
const CONFIG_WITH_ON_COMPLETE =
'./test/eslint-remote-tester.config.onComplete.js';

jest.mock('@actions/exec', () => ({ exec: jest.fn() }));

function readRunConfig() {
function readRunConfig(extension: 'js' | 'ts') {
let content: Config;

jest.isolateModules(() => {
content = require(resolve(EXPECTED_RUN_CONFIG));
content = require(resolve(`${EXPECTED_RUN_CONFIG}.${extension}`));
});

return content!;
Expand All @@ -28,20 +29,24 @@ function readRunConfig() {
function cleanup() {
jest.resetModules();

if (fs.existsSync(EXPECTED_RUN_CONFIG)) {
fs.unlinkSync(EXPECTED_RUN_CONFIG);
}
['js', 'ts'].forEach(extension => {
const name = `${EXPECTED_RUN_CONFIG}.${extension}`;

if (fs.existsSync(name)) {
fs.unlinkSync(name);
}
});
}

describe('run-tester', () => {
beforeEach(cleanup);
afterEach(cleanup);

test('runs eslint-remote-tester with provided configuration', async () => {
await runTester(CONFIG);
test('runs eslint-remote-tester with provided Javascript configuration', async () => {
await runTester(CONFIG_JS);

expect(exec).toHaveBeenCalledWith(
`${ESLINT_REMOTE_TESTER_BIN} --config ${EXPECTED_RUN_CONFIG}`,
`${ESLINT_REMOTE_TESTER_BIN} --config ${EXPECTED_RUN_CONFIG}.js`,
[],
{
ignoreReturnCode: true,
Expand All @@ -52,6 +57,85 @@ describe('run-tester', () => {
);
});

test('creates CommonJS module when using Javascript configuration file', async () => {
await runTester(CONFIG_JS);

const configContents = fs.readFileSync(
`${EXPECTED_RUN_CONFIG}.js`,
'utf8'
);

expect(sanitizeStackTrace(configContents)).toMatchInlineSnapshot(`
"// Generated by eslint-remote-tester-run-action
const fs = require('fs');

// Load user's eslint-remote-tester.config.js
const usersConfig = require('<removed>/test/eslint-remote-tester.config.js');

module.exports = {
...usersConfig,

// Values from eslint-remote-tester-run-action's default configuration
...{
\\"cache\\": false,
\\"CI\\": true
},

onComplete: async function onComplete(results, comparisonResults, repositoryCount) {
// Write results to cache
fs.writeFileSync('/tmp/results.json', JSON.stringify({ results, repositoryCount }));

if(usersConfig.onComplete) {
await usersConfig.onComplete(results, comparisonResults, repositoryCount);
}
}

};
"
`);
});

test('creates ES module when using Typescript configuration file', async () => {
await runTester(CONFIG_TS);

const configContents = fs.readFileSync(
`${EXPECTED_RUN_CONFIG}.ts`,
'utf8'
);

expect(sanitizeStackTrace(configContents)).toMatchInlineSnapshot(`
"// Generated by eslint-remote-tester-run-action
import fs from 'fs';
import type { Config } from 'eslint-remote-tester';

// Load user's eslint-remote-tester.config.ts
import usersConfig from '<removed>/test/eslint-remote-tester.typescript.config';

const config: Config = {
...usersConfig,

// Values from eslint-remote-tester-run-action's default configuration
...{
\\"cache\\": false,
\\"CI\\": true
},

onComplete: async function onComplete(results, comparisonResults, repositoryCount) {
// Write results to cache
fs.writeFileSync('/tmp/results.json', JSON.stringify({ results, repositoryCount }));

if(usersConfig.onComplete) {
await usersConfig.onComplete(results, comparisonResults, repositoryCount);
}
}

};

export default config;
"
`);
});

test('throws if given configuration does not exist', () => {
return expect(runTester('./non-existing-config')).rejects.toThrowError(
/(?=.*Unable to find eslint-remote-tester config with path)(?=.*non-existing-config)/
Expand All @@ -61,7 +145,7 @@ describe('run-tester', () => {
test('uses onComplete from users configuration', async () => {
await runTester(CONFIG_WITH_ON_COMPLETE);

expect(sanitizeStackTrace(readRunConfig().onComplete!.toString()))
expect(sanitizeStackTrace(readRunConfig('js').onComplete!.toString()))
.toMatchInlineSnapshot(`
"async function onComplete(results, comparisonResults, repositoryCount) {
// Write results to cache
Expand All @@ -75,15 +159,15 @@ describe('run-tester', () => {
});

test('cache is disabled by default', async () => {
await runTester(CONFIG);
await runTester(CONFIG_JS);

expect(readRunConfig().cache).toBe(false);
expect(readRunConfig('js').cache).toBe(false);
});

test('CI is enabled by default', async () => {
await runTester(CONFIG);
await runTester(CONFIG_JS);

expect(readRunConfig().CI).toBe(true);
expect(readRunConfig('js').CI).toBe(true);
});

test('configuration is validated', () => {
Expand Down
Loading