mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[TypeScript] add type-check script (#19325)
* [TypeScript] add type-check script * [ci] run scripts/type_check after linting * [ts] improve filterProjectsByFlag readability * fix typo * simplify type signature
This commit is contained in:
parent
78e1c8b147
commit
141a97d93c
11 changed files with 220 additions and 55 deletions
|
@ -238,6 +238,7 @@
|
|||
"@types/bluebird": "^3.1.1",
|
||||
"@types/chance": "^1.0.0",
|
||||
"@types/classnames": "^2.2.3",
|
||||
"@types/dedent": "^0.7.0",
|
||||
"@types/enzyme": "^3.1.12",
|
||||
"@types/eslint": "^4.16.2",
|
||||
"@types/execa": "^0.9.0",
|
||||
|
|
21
scripts/type_check.js
Normal file
21
scripts/type_check.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
require('../src/setup_node_env');
|
||||
require('../src/dev/typescript').runTypeCheckCli();
|
|
@ -17,76 +17,31 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { createToolingLog } from '@kbn/dev-utils';
|
||||
import chalk from 'chalk';
|
||||
import execa from 'execa';
|
||||
import getopts from 'getopts';
|
||||
import Listr from 'listr';
|
||||
|
||||
import { Project, PROJECTS } from '../typescript';
|
||||
|
||||
class LintFailure {
|
||||
constructor(public project: Project, public error: execa.ExecaError) {}
|
||||
}
|
||||
import { execInProjects, filterProjectsByFlag, Project } from '../typescript';
|
||||
|
||||
export function runTslintCliOnTsConfigPaths(tsConfigPaths: string[]) {
|
||||
runTslintCli(tsConfigPaths.map(tsConfigPath => new Project(tsConfigPath)));
|
||||
}
|
||||
|
||||
export function runTslintCli(projects = PROJECTS) {
|
||||
export function runTslintCli(projects?: Project[]) {
|
||||
const log = createToolingLog('info');
|
||||
log.pipe(process.stdout);
|
||||
|
||||
const opts = getopts(process.argv.slice(2));
|
||||
projects = projects || filterProjectsByFlag(opts.project);
|
||||
|
||||
if (!opts.format) {
|
||||
process.argv.push('--format', 'stylish');
|
||||
}
|
||||
|
||||
const list = new Listr(
|
||||
projects
|
||||
.filter(project => {
|
||||
if (!opts.project) {
|
||||
return true;
|
||||
}
|
||||
const getProjectArgs = (project: Project) => [
|
||||
...process.argv.slice(2),
|
||||
'--project',
|
||||
project.tsConfigPath,
|
||||
];
|
||||
|
||||
return resolve(opts.project) === project.tsConfigPath;
|
||||
})
|
||||
.map(project => ({
|
||||
task: () =>
|
||||
execa('tslint', [...process.argv.slice(2), '--project', project.tsConfigPath], {
|
||||
cwd: project.directory,
|
||||
env: chalk.enabled ? { FORCE_COLOR: 'true' } : {},
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
}).catch(error => {
|
||||
throw new LintFailure(project, error);
|
||||
}),
|
||||
title: project.name,
|
||||
})),
|
||||
{
|
||||
concurrent: true,
|
||||
exitOnError: false,
|
||||
}
|
||||
);
|
||||
|
||||
list.run().catch((error: any) => {
|
||||
process.exitCode = 1;
|
||||
|
||||
if (!error.errors) {
|
||||
log.error('Unhandled execption!');
|
||||
log.error(error);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
for (const e of error.errors) {
|
||||
if (e instanceof LintFailure) {
|
||||
log.write('');
|
||||
log.error(`${e.project.name} failed\n${e.error.stdout}`);
|
||||
} else {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
execInProjects(log, projects, 'tslint', getProjectArgs);
|
||||
}
|
||||
|
|
73
src/dev/typescript/exec_in_projects.ts
Normal file
73
src/dev/typescript/exec_in_projects.ts
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { ToolingLog } from '@kbn/dev-utils';
|
||||
import chalk from 'chalk';
|
||||
import execa from 'execa';
|
||||
import Listr from 'listr';
|
||||
|
||||
import { Project } from './project';
|
||||
|
||||
class ProjectFailure {
|
||||
constructor(public project: Project, public error: execa.ExecaError) {}
|
||||
}
|
||||
|
||||
export function execInProjects(
|
||||
log: ToolingLog,
|
||||
projects: Project[],
|
||||
cmd: string,
|
||||
getArgs: (project: Project) => string[]
|
||||
) {
|
||||
const list = new Listr(
|
||||
projects.map(project => ({
|
||||
task: () =>
|
||||
execa(cmd, getArgs(project), {
|
||||
cwd: project.directory,
|
||||
env: chalk.enabled ? { FORCE_COLOR: 'true' } : {},
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
}).catch(error => {
|
||||
throw new ProjectFailure(project, error);
|
||||
}),
|
||||
title: project.name,
|
||||
})),
|
||||
{
|
||||
concurrent: true,
|
||||
exitOnError: false,
|
||||
}
|
||||
);
|
||||
|
||||
list.run().catch((error: any) => {
|
||||
process.exitCode = 1;
|
||||
|
||||
if (!error.errors) {
|
||||
log.error('Unhandled exception!');
|
||||
log.error(error);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
for (const e of error.errors) {
|
||||
if (e instanceof ProjectFailure) {
|
||||
log.write('');
|
||||
log.error(`${e.project.name} failed\n${e.error.stdout}`);
|
||||
} else {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -18,5 +18,7 @@
|
|||
*/
|
||||
|
||||
export { Project } from './project';
|
||||
export { PROJECTS } from './projects';
|
||||
export { filterProjectsByFlag } from './projects';
|
||||
export { getTsProjectForAbsolutePath } from './get_ts_project_for_absolute_path';
|
||||
export { execInProjects } from './exec_in_projects';
|
||||
export { runTypeCheckCli } from './run_type_check_cli';
|
||||
|
|
|
@ -31,3 +31,12 @@ export const PROJECTS = [
|
|||
// both took closer to 1000ms.
|
||||
...glob.sync('packages/*/tsconfig.json', { cwd: REPO_ROOT }),
|
||||
].map(path => new Project(resolve(REPO_ROOT, path)));
|
||||
|
||||
export function filterProjectsByFlag(projectFlag?: string) {
|
||||
if (!projectFlag) {
|
||||
return PROJECTS;
|
||||
}
|
||||
|
||||
const tsConfigPath = resolve(projectFlag);
|
||||
return PROJECTS.filter(project => project.tsConfigPath === tsConfigPath);
|
||||
}
|
||||
|
|
89
src/dev/typescript/run_type_check_cli.ts
Normal file
89
src/dev/typescript/run_type_check_cli.ts
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { createToolingLog } from '@kbn/dev-utils';
|
||||
import chalk from 'chalk';
|
||||
import dedent from 'dedent';
|
||||
import getopts from 'getopts';
|
||||
|
||||
import { execInProjects } from './exec_in_projects';
|
||||
import { filterProjectsByFlag } from './projects';
|
||||
|
||||
export function runTypeCheckCli() {
|
||||
const extraFlags: string[] = [];
|
||||
const opts = getopts(process.argv.slice(2), {
|
||||
boolean: ['skip-lib-check', 'help'],
|
||||
default: {
|
||||
project: undefined,
|
||||
},
|
||||
unknown(name) {
|
||||
extraFlags.push(name);
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
const log = createToolingLog('info');
|
||||
log.pipe(process.stdout);
|
||||
|
||||
if (extraFlags.length) {
|
||||
for (const flag of extraFlags) {
|
||||
log.error(`Unknown flag: ${flag}`);
|
||||
}
|
||||
|
||||
process.exitCode = 1;
|
||||
opts.help = true;
|
||||
}
|
||||
|
||||
if (opts.help) {
|
||||
process.stdout.write(
|
||||
dedent(chalk`
|
||||
{dim usage:} node scripts/type_check [...options]
|
||||
|
||||
Run the TypeScript compiler without emitting files so that it can check
|
||||
types during development.
|
||||
|
||||
Examples:
|
||||
|
||||
{dim # check types in all projects}
|
||||
{dim $} node scripts/type_check
|
||||
|
||||
{dim # check types in a single project}
|
||||
{dim $} node scripts/type_check --project packages/kbn-pm/tsconfig.json
|
||||
|
||||
Options:
|
||||
|
||||
--project [path] {dim Path to a tsconfig.json file determines the project to check}
|
||||
--skip-lib-check {dim Skip type checking of all declaration files (*.d.ts)}
|
||||
--help {dim Show this message}
|
||||
`)
|
||||
);
|
||||
process.stdout.write('\n');
|
||||
process.exit();
|
||||
}
|
||||
|
||||
const tscArgs = ['--noEmit', '--pretty', ...(opts['skip-lib-check'] ? ['--skipLibCheck'] : [])];
|
||||
const projects = filterProjectsByFlag(opts.project);
|
||||
|
||||
if (!projects.length) {
|
||||
log.error(`Unable to find project at ${opts.project}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
execInProjects(log, projects, 'tsc', project => ['--project', project.tsConfigPath, ...tscArgs]);
|
||||
}
|
|
@ -90,6 +90,15 @@ module.exports = function (grunt) {
|
|||
]
|
||||
},
|
||||
|
||||
// used by the test and jenkins:unit tasks
|
||||
// runs the tslint script to check for Typescript linting errors
|
||||
typeCheck: {
|
||||
cmd: process.execPath,
|
||||
args: [
|
||||
require.resolve('../../scripts/type_check')
|
||||
]
|
||||
},
|
||||
|
||||
// used by the test:server task
|
||||
// runs all node.js/server mocha tests
|
||||
mocha: {
|
||||
|
|
|
@ -25,6 +25,7 @@ module.exports = function (grunt) {
|
|||
grunt.registerTask('jenkins:unit', [
|
||||
'run:eslint',
|
||||
'run:tslint',
|
||||
'run:typeCheck',
|
||||
'run:checkFileCasing',
|
||||
'licenses',
|
||||
'verifyDependencyVersions',
|
||||
|
|
|
@ -67,6 +67,7 @@ module.exports = function (grunt) {
|
|||
_.compact([
|
||||
!grunt.option('quick') && 'run:eslint',
|
||||
!grunt.option('quick') && 'run:tslint',
|
||||
!grunt.option('quick') && 'run:typeCheck',
|
||||
'run:checkFileCasing',
|
||||
'licenses',
|
||||
'test:quick',
|
||||
|
|
|
@ -300,6 +300,10 @@
|
|||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.0.tgz#4b7daf2c51696cfc70b942c11690528229d1a1ce"
|
||||
|
||||
"@types/dedent@^0.7.0":
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/dedent/-/dedent-0.7.0.tgz#155f339ca404e6dd90b9ce46a3f78fd69ca9b050"
|
||||
|
||||
"@types/delay@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/delay/-/delay-2.0.1.tgz#61bcf318a74b61e79d1658fbf054f984c90ef901"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue