Skip to content

Commit

Permalink
Merge pull request #203 from codemod-js/ci-refactor
Browse files Browse the repository at this point in the history
test(ci): refactor test/lint infrastructure
  • Loading branch information
eventualbuddha authored Jan 25, 2019
2 parents 9b1e4b9 + b891d9b commit a42235a
Show file tree
Hide file tree
Showing 30 changed files with 258 additions and 156 deletions.
21 changes: 4 additions & 17 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,13 @@ aliases:
- *install_dependencies_step
- *save_cache_step
- run:
name: '@codemod/cli tests'
name: script/ci
command: |
cd packages/cli
yarn tsc
yarn mocha "test/**/*Test.js" --reporter mocha-junit-reporter
environment:
MOCHA_FILE: "reports/junit/js-test-results.xml"
- run:
name: '@codemod/cli tslint'
command: |
cd packages/cli
yarn tslint --project . --format junit -o reports/junit/tslint-results.xml
- run:
name: eslint
command: |
yarn eslint . --ext .ts --format junit -o reports/junit/eslint-results.xml
script/ci
- store_test_results:
path: packages/cli/reports/junit
path: reports/junit
- store_artifacts:
path: packages/cli/reports/junit
path: reports/junit

version: 2
jobs:
Expand Down
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"typescript/explicit-member-accessibility": "off",
"typescript/no-use-before-define": "off",
"typescript/no-parameter-properties": "off",
"typescript/no-object-literal-type-assertion": "off"
"typescript/no-object-literal-type-assertion": "off",
"typescript/no-unused-vars": "error"
}
}
12 changes: 6 additions & 6 deletions packages/cli/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,22 @@ $ yarn prepublish

### Running linting/testing

Because this project is written in TypeScript, we use [TSLint](https://palantir.github.io/tslint/) rather than [ESLint](http://eslint.org/). It provides similar functionality but with rules explicitly catering to TypeScript. To run TSLint on the project, run:
We use [ESLint](https://eslint.org/). To run ESLint on the project, run:

```
$ yarn lint
$ script/ci lint
```

To automatically fix some of the issues TSLint finds:
To automatically fix some of the issues ESLint finds:

```
$ yarn lint-fix
$ script/ci lint --fix
```

The tests in this project are written using the [Mocha](https://mochajs.org/) test framework and, like the non-test code, are also written in TypeScript. To run the tests:
The tests in this project are written using [Mocha](https://mochajs.org/) and [Jest](https://jestjs.io/) and, like the non-test code, are also written in TypeScript. To run the tests:

```
$ yarn test
$ script/ci test
```

## Submitting Changes
Expand Down
8 changes: 1 addition & 7 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@
"description": "codemod rewrites JavaScript and TypeScript",
"main": "src/index.js",
"scripts": {
"build": "tsc",
"prepare": "yarn test",
"lint": "tslint --project .",
"lint-fix": "tslint --project . --fix",
"pretest": "yarn lint && tsc --project .",
"test": "mocha \"test/**/*Test.js\""
"test": "script/ci"
},
"lint-staged": {
"*.ts": [
Expand Down Expand Up @@ -60,8 +56,6 @@
"mocha-junit-reporter": "^1.18.0",
"rimraf": "2.6.2",
"semver": "^5.6.0",
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.16.0",
"typescript": "^3.1.6",
"yarnhook": "^0.3.0"
},
Expand Down
102 changes: 102 additions & 0 deletions packages/cli/script/_commands/ci.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { join } from 'path';
import runNodePackageBinary from '../../../../script/_utils/runNodePackageBinary';

export default async function main(
args: Array<string>,
stdin: NodeJS.ReadStream,
stdout: NodeJS.WriteStream,
stderr: NodeJS.WriteStream
): Promise<number> {
const rest = args.slice(1);

switch (args[0]) {
case undefined:
return (
(await build(rest, stdin, stdout, stderr)) ||
(await lint(rest, stdin, stdout, stderr)) ||
(await runTests(rest, stdin, stdout, stderr))
);

case 'test':
return (
(await build(rest, stdin, stdout, stderr)) ||
(await runTests(rest, stdin, stdout, stderr))
);

case 'lint':
return await lint(rest, stdin, stdout, stderr);

default:
throw new Error(`unexpected command: ${args[0]}`);
}
}

async function build(
args: Array<string>,
stdin: NodeJS.ReadStream,
stdout: NodeJS.WriteStream,
stderr: NodeJS.WriteStream
): Promise<number> {
return await runNodePackageBinary(
'tsc',
[],
join(__dirname, '../..'),
stdin,
stdout,
stderr
);
}

async function runTests(
args: Array<string>,
stdin: NodeJS.ReadStream,
stdout: NodeJS.WriteStream,
stderr: NodeJS.WriteStream
): Promise<number> {
return await runNodePackageBinary(
'mocha',
[
'test/**/*Test.js',
...(isCI()
? [
'--reporter',
'mocha-junit-reporter',
'--reporter-options',
'mochaFile=reports/junit/js-test-results.xml'
]
: [])
],
join(__dirname, '../..'),
stdin,
stdout,
stderr
);
}

async function lint(
args: Array<string>,
stdin: NodeJS.ReadStream,
stdout: NodeJS.WriteStream,
stderr: NodeJS.WriteStream
): Promise<number> {
return await runNodePackageBinary(
'eslint',
[
'packages/cli',
'--ext',
'.ts',
...(isCI()
? ['--format', 'junit', '-o', 'reports/junit/eslint-results.xml']
: []),
...args
],
join(__dirname, '../../../..'),
stdin,
stdout,
stderr
);
}

function isCI(): boolean {
return process.env.CI === 'true';
}
5 changes: 5 additions & 0 deletions packages/cli/script/ci
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env node

require('../../../script/_utils/runCommand')(
require.resolve('./_commands/ci.ts')
);
2 changes: 1 addition & 1 deletion packages/cli/src/AllSyntaxPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function pluginsForFilename(
export default function buildPlugin(
sourceType: Babel.ParserOptions['sourceType']
): BabelPlugin {
return function(babel: typeof Babel): PluginObj {
return function(): PluginObj {
return {
manipulateOptions(
opts: Babel.TransformOptions,
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/BabelPrinterPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as Babel from '@babel/core';
import { PluginObj } from './BabelPluginTypes';

export default function(babel: typeof Babel) {
export default function(): PluginObj {
// We don't need to override anything; babel will do what babel does.
return {};
}
14 changes: 4 additions & 10 deletions packages/cli/src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import AstExplorerResolver from './resolvers/AstExplorerResolver';
import FileSystemResolver from './resolvers/FileSystemResolver';
import NetworkResolver from './resolvers/NetworkResolver';
import PackageResolver from './resolvers/PackageResolver';
import { EntryType } from './System';
import { disable, enable } from './transpile-requires';

export class Plugin {
Expand All @@ -34,12 +33,7 @@ export class Plugin {
}
}

function defaultIgnorePredicate(
path: string,
basename: string,
root: string,
type: EntryType
): boolean {
function defaultIgnorePredicate(path: string, basename: string): boolean {
return (
// ignore paths starting with a dot
basename.startsWith('.') ||
Expand Down Expand Up @@ -115,20 +109,20 @@ export default class Config {
return this._pluginCache;
}

loadRequires() {
loadRequires(): void {
for (let modulePath of this.requires) {
require(modulePath);
}
}

loadBabelTranspile() {
loadBabelTranspile(): void {
if (this.transpilePlugins) {
enable(this.findBabelConfig);
install();
}
}

unloadBabelTranspile() {
unloadBabelTranspile(): void {
if (this.transpilePlugins) {
disable();
}
Expand Down
10 changes: 4 additions & 6 deletions packages/cli/src/PrettierPrinterPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as Babel from '@babel/core';
import { GeneratorOptions } from '@babel/generator';
import { File } from '@babel/types';
import * as Prettier from 'prettier';
import { sync as resolveSync } from 'resolve';
import { generate, parse } from './RecastPlugin';
import { PluginObj } from './BabelPluginTypes';

function loadPrettier(): typeof Prettier {
try {
Expand All @@ -13,7 +13,7 @@ function loadPrettier(): typeof Prettier {
}
}

export default function(babel: typeof Babel) {
export default function(): PluginObj {
let prettier = loadPrettier();

function resolvePrettierConfig(filepath: string): Prettier.Options {
Expand All @@ -27,13 +27,11 @@ export default function(babel: typeof Babel) {
parserOverride: parse,
generatorOverride(
ast: File,
options: GeneratorOptions,
code: string,
_generate: (ast: File, options: GeneratorOptions) => string
options: GeneratorOptions
): { code: string; map?: object } {
return {
code: prettier.format(
generate(ast, options, code, _generate).code,
generate(ast).code,
resolvePrettierConfig(options.filename as string)
)
};
Expand Down
13 changes: 6 additions & 7 deletions packages/cli/src/ProcessSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@ interface MapDiff<K, V> {
deleted: Map<K, V>;
}

// tslint:disable no-any
type CacheSnapshot = Map<string, Module>;
type ExtensionSnapshot = Map<string, typeof require.extensions['.js']>;
type EventsSnapshot = Map<
string | symbol,
Array<(...args: Array<any>) => void>
Array<(...args: Array<unknown>) => void>
>;
// tslint:enable no-any

/**
* Snapshots various global values and allows rolling back to the snapshot.
Expand Down Expand Up @@ -152,7 +150,8 @@ export default class ProcessSnapshot {
for (let originalEntry of original) {
if (!updated.includes(originalEntry)) {
this.log(`restoring removed '${event.toString()}' event listener`);
process.addListener(event as any, originalEntry); // tslint:disable-line no-any
// eslint-disable-next-line typescript/no-explicit-any
process.addListener(event as any, originalEntry);
}
}

Expand All @@ -167,7 +166,8 @@ export default class ProcessSnapshot {
for (let [event, callbacks] of deleted) {
for (let callback of callbacks) {
this.log(`restoring removed '${event.toString()}' event listener`);
process.addListener(event as any, callback); // tslint:disable-line no-any
// eslint-disable-next-line typescript/no-explicit-any
process.addListener(event as any, callback);
}
}
}
Expand Down Expand Up @@ -212,9 +212,8 @@ export default class ProcessSnapshot {
let events = this.processImpl.eventNames();

for (let name of events) {
// tslint:disable no-any
// eslint-disable-next-line typescript/no-explicit-any
result.set(name, this.processImpl.listeners(name as any));
// tslint:enable no-any
}

return result;
Expand Down
9 changes: 2 additions & 7 deletions packages/cli/src/RecastPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,11 @@ export function parse(
});
}

export function generate(
ast: File,
options: Babel.GeneratorOptions,
code: string,
generate: (ast: File, options: Babel.GeneratorOptions) => string
): { code: string; map?: object } {
export function generate(ast: File): { code: string; map?: object } {
return recast.print(ast);
}

export default function(babel: typeof Babel): PluginObj {
export default function(): PluginObj {
return {
parserOverride: parse,
generatorOverride: generate
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/extensions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function union<T>(...sets: Array<Set<T>>) {
function union<T>(...sets: Array<Set<T>>): Set<T> {
return new Set(sets.reduce((result, set) => [...result, ...set], []));
}

Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function optionAnnotation(
}
}

function printHelp(argv: Array<string>, out: NodeJS.WritableStream) {
function printHelp(argv: Array<string>, out: NodeJS.WritableStream): void {
let $0 = basename(argv[1]);
let defaults = new Config();

Expand Down Expand Up @@ -115,7 +115,7 @@ EXAMPLES
out.write('\n');
}

function printVersion(argv: Array<string>, out: NodeJS.WritableStream) {
function printVersion(argv: Array<string>, out: NodeJS.WritableStream): void {
out.write(require('../package.json').version);
out.write('\n');
}
Expand Down
Loading

0 comments on commit a42235a

Please sign in to comment.