mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
[tslint] Fix violations in kbn-pm (#19335)
* [tslint/kbn-pm] apply autofixes * [tslint/kbn-pm] whitelist all console.log calls for now * [tslint/kbn-pm] sort object keys alphabetically * [tslint/kbn-pm] use comments to "fill" empty blocks * [tslint/kbn-pm] use I-prefix for interface names * [tslint/kbn-pm] use arrow-functions where possible * [tslint/kbn-pm] use lowerCamelCase for variable names * [tslint/kbn-pm] prevent shadowed variable names * [tslint/kbn-pm] avoid variable name and type clashes * [tslint/kbn-pm] replace console.log statements with bare-bones logger
This commit is contained in:
parent
3d08c5cb31
commit
ce20463f59
30 changed files with 248 additions and 228 deletions
|
@ -1,17 +1,18 @@
|
|||
import getopts from 'getopts';
|
||||
import dedent from 'dedent';
|
||||
import chalk from 'chalk';
|
||||
import dedent from 'dedent';
|
||||
import getopts from 'getopts';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { commands } from './commands';
|
||||
import { runCommand } from './run';
|
||||
import { log } from './utils/log';
|
||||
|
||||
function help() {
|
||||
const availableCommands = Object.keys(commands)
|
||||
.map(commandName => commands[commandName])
|
||||
.map(command => `${command.name} - ${command.description}`);
|
||||
|
||||
console.log(dedent`
|
||||
log.write(dedent`
|
||||
usage: kbn <command> [<args>]
|
||||
|
||||
By default commands are run for Kibana itself, all packages in the 'packages/'
|
||||
|
@ -35,7 +36,7 @@ export async function run(argv: string[]) {
|
|||
// starts forwarding the `--` directly to this script, see
|
||||
// https://github.com/yarnpkg/yarn/blob/b2d3e1a8fe45ef376b716d597cc79b38702a9320/src/cli/index.js#L174-L182
|
||||
if (argv.includes('--')) {
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.red(
|
||||
`Using "--" is not allowed, as it doesn't work with 'yarn kbn'.`
|
||||
)
|
||||
|
@ -45,9 +46,9 @@ export async function run(argv: string[]) {
|
|||
|
||||
const options = getopts(argv, {
|
||||
alias: {
|
||||
e: 'exclude',
|
||||
h: 'help',
|
||||
i: 'include',
|
||||
e: 'exclude',
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -69,7 +70,7 @@ export async function run(argv: string[]) {
|
|||
|
||||
const command = commands[commandName];
|
||||
if (command === undefined) {
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.red(`[${commandName}] is not a valid command, see 'kbn --help'`)
|
||||
);
|
||||
process.exit(1);
|
||||
|
|
|
@ -7,18 +7,18 @@ import {
|
|||
absolutePathSnapshotSerializer,
|
||||
stripAnsiSnapshotSerializer,
|
||||
} from '../test_helpers';
|
||||
import { BootstrapCommand } from './bootstrap';
|
||||
import { PackageJson } from '../utils/package_json';
|
||||
import { linkProjectExecutables } from '../utils/link_project_executables';
|
||||
import { IPackageJson } from '../utils/package_json';
|
||||
import { Project } from '../utils/project';
|
||||
import { buildProjectGraph } from '../utils/projects';
|
||||
import { installInDir, runScriptInPackageStreaming } from '../utils/scripts';
|
||||
import { linkProjectExecutables } from '../utils/link_project_executables';
|
||||
import { BootstrapCommand } from './bootstrap';
|
||||
|
||||
const mockInstallInDir = installInDir as jest.Mock;
|
||||
const mockRunScriptInPackageStreaming = runScriptInPackageStreaming as jest.Mock;
|
||||
const mockLinkProjectExecutables = linkProjectExecutables as jest.Mock;
|
||||
|
||||
const createProject = (packageJson: PackageJson, path = '.') =>
|
||||
const createProject = (packageJson: IPackageJson, path = '.') =>
|
||||
new Project(
|
||||
{
|
||||
name: 'kibana',
|
||||
|
@ -31,7 +31,9 @@ const createProject = (packageJson: PackageJson, path = '.') =>
|
|||
expect.addSnapshotSerializer(absolutePathSnapshotSerializer);
|
||||
expect.addSnapshotSerializer(stripAnsiSnapshotSerializer);
|
||||
|
||||
const noop = () => {};
|
||||
const noop = () => {
|
||||
// noop
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
@ -45,19 +47,19 @@ test('handles dependencies of dependencies', async () => {
|
|||
});
|
||||
const foo = createProject(
|
||||
{
|
||||
name: 'foo',
|
||||
dependencies: {
|
||||
bar: 'link:../bar',
|
||||
},
|
||||
name: 'foo',
|
||||
},
|
||||
'packages/foo'
|
||||
);
|
||||
const bar = createProject(
|
||||
{
|
||||
name: 'bar',
|
||||
dependencies: {
|
||||
baz: 'link:../baz',
|
||||
},
|
||||
name: 'bar',
|
||||
},
|
||||
'packages/bar'
|
||||
);
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import chalk from 'chalk';
|
||||
|
||||
import { topologicallyBatchProjects } from '../utils/projects';
|
||||
import { linkProjectExecutables } from '../utils/link_project_executables';
|
||||
import { log } from '../utils/log';
|
||||
import { parallelizeBatches } from '../utils/parallelize';
|
||||
import { Command } from './';
|
||||
import { topologicallyBatchProjects } from '../utils/projects';
|
||||
import { ICommand } from './';
|
||||
|
||||
export const BootstrapCommand: Command = {
|
||||
name: 'bootstrap',
|
||||
export const BootstrapCommand: ICommand = {
|
||||
description: 'Install dependencies and crosslink projects',
|
||||
name: 'bootstrap',
|
||||
|
||||
async run(projects, projectGraph, { options }) {
|
||||
const batchedProjects = topologicallyBatchProjects(projects, projectGraph);
|
||||
|
@ -15,7 +16,7 @@ export const BootstrapCommand: Command = {
|
|||
const frozenLockfile = options['frozen-lockfile'] === true;
|
||||
const extraArgs = frozenLockfile ? ['--frozen-lockfile'] : [];
|
||||
|
||||
console.log(chalk.bold('\nRunning installs in topological order:'));
|
||||
log.write(chalk.bold('\nRunning installs in topological order:'));
|
||||
|
||||
for (const batch of batchedProjects) {
|
||||
for (const project of batch) {
|
||||
|
@ -25,7 +26,7 @@ export const BootstrapCommand: Command = {
|
|||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.bold('\nInstalls completed, linking package executables:\n')
|
||||
);
|
||||
await linkProjectExecutables(projects, projectGraph);
|
||||
|
@ -36,7 +37,7 @@ export const BootstrapCommand: Command = {
|
|||
* transpiled before they can be used. Ideally we shouldn't do this unless we
|
||||
* have to, as it will slow down the bootstrapping process.
|
||||
*/
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.bold(
|
||||
'\nLinking executables completed, running `kbn:bootstrap` scripts\n'
|
||||
)
|
||||
|
@ -47,6 +48,6 @@ export const BootstrapCommand: Command = {
|
|||
}
|
||||
});
|
||||
|
||||
console.log(chalk.green.bold('\nBootstrapping completed!\n'));
|
||||
log.write(chalk.green.bold('\nBootstrapping completed!\n'));
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import del from 'del';
|
||||
import chalk from 'chalk';
|
||||
import { relative } from 'path';
|
||||
import del from 'del';
|
||||
import ora from 'ora';
|
||||
import { relative } from 'path';
|
||||
|
||||
import { isDirectory } from '../utils/fs';
|
||||
import { Command } from './';
|
||||
import { log } from '../utils/log';
|
||||
import { ICommand } from './';
|
||||
|
||||
export const CleanCommand: Command = {
|
||||
name: 'clean',
|
||||
export const CleanCommand: ICommand = {
|
||||
description:
|
||||
'Remove the node_modules and target directories from all projects.',
|
||||
name: 'clean',
|
||||
|
||||
async run(projects, projectGraph, { rootPath }) {
|
||||
const directoriesToDelete = [];
|
||||
|
@ -24,9 +25,9 @@ export const CleanCommand: Command = {
|
|||
}
|
||||
|
||||
if (directoriesToDelete.length === 0) {
|
||||
console.log(chalk.bold.green('\n\nNo directories to delete'));
|
||||
log.write(chalk.bold.green('\n\nNo directories to delete'));
|
||||
} else {
|
||||
console.log(chalk.bold.red('\n\nDeleting directories:\n'));
|
||||
log.write(chalk.bold.red('\n\nDeleting directories:\n'));
|
||||
|
||||
for (const dir of directoriesToDelete) {
|
||||
const deleting = del(dir, { force: true });
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import { ProjectGraph, ProjectMap } from '../utils/projects';
|
||||
|
||||
export interface CommandConfig {
|
||||
export interface ICommandConfig {
|
||||
extraArgs: string[];
|
||||
options: { [key: string]: any };
|
||||
rootPath: string;
|
||||
}
|
||||
|
||||
export interface Command {
|
||||
export interface ICommand {
|
||||
name: string;
|
||||
description: string;
|
||||
|
||||
run: (
|
||||
projects: ProjectMap,
|
||||
projectGraph: ProjectGraph,
|
||||
config: CommandConfig
|
||||
config: ICommandConfig
|
||||
) => Promise<void>;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ import { CleanCommand } from './clean';
|
|||
import { RunCommand } from './run';
|
||||
import { WatchCommand } from './watch';
|
||||
|
||||
export const commands: { [key: string]: Command } = {
|
||||
export const commands: { [key: string]: ICommand } = {
|
||||
bootstrap: BootstrapCommand,
|
||||
clean: CleanCommand,
|
||||
run: RunCommand,
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
import chalk from 'chalk';
|
||||
|
||||
import { topologicallyBatchProjects } from '../utils/projects';
|
||||
import { log } from '../utils/log';
|
||||
import { parallelizeBatches } from '../utils/parallelize';
|
||||
import { Command } from './';
|
||||
import { topologicallyBatchProjects } from '../utils/projects';
|
||||
import { ICommand } from './';
|
||||
|
||||
export const RunCommand: Command = {
|
||||
name: 'run',
|
||||
export const RunCommand: ICommand = {
|
||||
description:
|
||||
'Run script defined in package.json in each package that contains that script.',
|
||||
name: 'run',
|
||||
|
||||
async run(projects, projectGraph, { extraArgs }) {
|
||||
const batchedProjects = topologicallyBatchProjects(projects, projectGraph);
|
||||
|
||||
if (extraArgs.length === 0) {
|
||||
console.log(chalk.red.bold('\nNo script specified'));
|
||||
log.write(chalk.red.bold('\nNo script specified'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const scriptName = extraArgs[0];
|
||||
const scriptArgs = extraArgs.slice(1);
|
||||
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.bold(
|
||||
`\nRunning script [${chalk.green(
|
||||
scriptName
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import chalk from 'chalk';
|
||||
import { topologicallyBatchProjects, ProjectMap } from '../utils/projects';
|
||||
import { log } from '../utils/log';
|
||||
import { parallelizeBatches } from '../utils/parallelize';
|
||||
import { ProjectMap, topologicallyBatchProjects } from '../utils/projects';
|
||||
import { waitUntilWatchIsReady } from '../utils/watch';
|
||||
import { Command } from './';
|
||||
import { ICommand } from './';
|
||||
|
||||
/**
|
||||
* Name of the script in the package/project package.json file to run during `kbn watch`.
|
||||
|
@ -24,9 +25,9 @@ const kibanaProjectName = 'kibana';
|
|||
* the `kbn:watch` script and eventually for the entire batch. Currently we support completion "markers" for
|
||||
* `webpack` and `tsc` only, for the rest we rely on predefined timeouts.
|
||||
*/
|
||||
export const WatchCommand: Command = {
|
||||
name: 'watch',
|
||||
export const WatchCommand: ICommand = {
|
||||
description: 'Runs `kbn:watch` script for every project.',
|
||||
name: 'watch',
|
||||
|
||||
async run(projects, projectGraph) {
|
||||
const projectsToWatch: ProjectMap = new Map();
|
||||
|
@ -38,7 +39,7 @@ export const WatchCommand: Command = {
|
|||
}
|
||||
|
||||
if (projectsToWatch.size === 0) {
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.red(
|
||||
`\nThere are no projects to watch found. Make sure that projects define 'kbn:watch' script in 'package.json'.\n`
|
||||
)
|
||||
|
@ -47,7 +48,7 @@ export const WatchCommand: Command = {
|
|||
}
|
||||
|
||||
const projectNames = Array.from(projectsToWatch.keys());
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.bold(
|
||||
chalk.green(
|
||||
`Running ${watchScriptName} scripts for [${projectNames.join(', ')}].`
|
||||
|
@ -73,7 +74,7 @@ export const WatchCommand: Command = {
|
|||
pkg.runScriptStreaming(watchScriptName).stdout
|
||||
);
|
||||
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.bold(
|
||||
`[${chalk.green(
|
||||
pkg.name
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
import { resolve } from 'path';
|
||||
|
||||
export type ProjectPathOptions = {
|
||||
export interface IProjectPathOptions {
|
||||
'skip-kibana-extra'?: boolean;
|
||||
'oss'?: boolean;
|
||||
};
|
||||
oss?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the paths where plugins are located
|
||||
*/
|
||||
export function getProjectPaths(rootPath: string, options: ProjectPathOptions) {
|
||||
export function getProjectPaths(
|
||||
rootPath: string,
|
||||
options: IProjectPathOptions
|
||||
) {
|
||||
const skipKibanaExtra = Boolean(options['skip-kibana-extra']);
|
||||
const ossOnly = Boolean(options.oss);
|
||||
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import del from 'del';
|
||||
import { relative, resolve, join } from 'path';
|
||||
import copy from 'cpy';
|
||||
import del from 'del';
|
||||
import { join, relative, resolve } from 'path';
|
||||
|
||||
import { getProjectPaths } from '../config';
|
||||
import {
|
||||
getProjects,
|
||||
buildProjectGraph,
|
||||
topologicallyBatchProjects,
|
||||
ProjectMap,
|
||||
includeTransitiveProjects,
|
||||
} from '../utils/projects';
|
||||
import { isDirectory, isFile } from '../utils/fs';
|
||||
import { log } from '../utils/log';
|
||||
import {
|
||||
createProductionPackageJson,
|
||||
writePackageJson,
|
||||
readPackageJson,
|
||||
writePackageJson,
|
||||
} from '../utils/package_json';
|
||||
import { isDirectory, isFile } from '../utils/fs';
|
||||
import { Project } from '../utils/project';
|
||||
import {
|
||||
buildProjectGraph,
|
||||
getProjects,
|
||||
includeTransitiveProjects,
|
||||
topologicallyBatchProjects,
|
||||
} from '../utils/projects';
|
||||
|
||||
export async function buildProductionProjects({
|
||||
kibanaRoot,
|
||||
|
@ -30,7 +30,7 @@ export async function buildProductionProjects({
|
|||
const batchedProjects = topologicallyBatchProjects(projects, projectGraph);
|
||||
|
||||
const projectNames = [...projects.values()].map(project => project.name);
|
||||
console.log(`Preparing production build for [${projectNames.join(', ')}]`);
|
||||
log.write(`Preparing production build for [${projectNames.join(', ')}]`);
|
||||
|
||||
for (const batch of batchedProjects) {
|
||||
for (const project of batch) {
|
||||
|
@ -99,9 +99,9 @@ async function copyToBuild(
|
|||
|
||||
await copy(['**/*', '!node_modules/**'], buildProjectPath, {
|
||||
cwd: project.getIntermediateBuildDirectory(),
|
||||
parents: true,
|
||||
nodir: true,
|
||||
dot: true,
|
||||
nodir: true,
|
||||
parents: true,
|
||||
});
|
||||
|
||||
// If a project is using an intermediate build directory, we special-case our
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import tempy from 'tempy';
|
||||
import copy from 'cpy';
|
||||
import { resolve, relative, join } from 'path';
|
||||
import globby from 'globby';
|
||||
import { join, resolve } from 'path';
|
||||
import tempy from 'tempy';
|
||||
|
||||
import { buildProductionProjects } from '../build_production_projects';
|
||||
import { getProjects } from '../../utils/projects';
|
||||
import { readPackageJson } from '../../utils/package_json';
|
||||
import { getProjects } from '../../utils/projects';
|
||||
import { buildProductionProjects } from '../build_production_projects';
|
||||
|
||||
describe('kbn-pm production', function() {
|
||||
describe('kbn-pm production', () => {
|
||||
test(
|
||||
'builds and copies projects for production',
|
||||
async function() {
|
||||
async () => {
|
||||
const tmpDir = tempy.directory();
|
||||
const buildRoot = tempy.directory();
|
||||
const fixturesPath = resolve(__dirname, '__fixtures__');
|
||||
|
@ -18,9 +18,9 @@ describe('kbn-pm production', function() {
|
|||
// Copy all the test fixtures into a tmp dir, as we will be mutating them
|
||||
await copy(['**/*'], tmpDir, {
|
||||
cwd: fixturesPath,
|
||||
parents: true,
|
||||
nodir: true,
|
||||
dot: true,
|
||||
nodir: true,
|
||||
parents: true,
|
||||
});
|
||||
|
||||
const projects = await getProjects(tmpDir, ['.', './packages/*']);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { resolve, join } from 'path';
|
||||
import { join, resolve } from 'path';
|
||||
|
||||
import { prepareExternalProjectDependencies } from './prepare_project_dependencies';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Project } from '../utils/project';
|
||||
import { isLinkDependency } from '../utils/package_json';
|
||||
import { Project } from '../utils/project';
|
||||
|
||||
/**
|
||||
* All external projects are located within `../kibana-extra/{plugin}` relative
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { resolve } from 'path';
|
||||
import { ICommand, ICommandConfig } from './commands';
|
||||
import { runCommand } from './run';
|
||||
import { Project } from './utils/project';
|
||||
import { Command, CommandConfig } from './commands';
|
||||
|
||||
const rootPath = resolve(`${__dirname}/utils/__fixtures__/kibana`);
|
||||
|
||||
|
@ -25,12 +25,12 @@ function getExpectedProjectsAndGraph(runMock: any) {
|
|||
return { projects, graph };
|
||||
}
|
||||
|
||||
let command: Command;
|
||||
let config: CommandConfig;
|
||||
let command: ICommand;
|
||||
let config: ICommandConfig;
|
||||
beforeEach(() => {
|
||||
command = {
|
||||
name: 'test name',
|
||||
description: 'test description',
|
||||
name: 'test name',
|
||||
run: jest.fn(),
|
||||
};
|
||||
|
||||
|
@ -41,7 +41,9 @@ beforeEach(() => {
|
|||
};
|
||||
|
||||
// Reduce the noise that comes from the run command.
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {
|
||||
// noop
|
||||
});
|
||||
});
|
||||
|
||||
test('passes all found projects to the command if no filter is specified', async () => {
|
||||
|
@ -102,9 +104,9 @@ test('respects both `include` and `exclude` filters if specified at the same tim
|
|||
});
|
||||
|
||||
test('does not run command if all projects are filtered out', async () => {
|
||||
let mockProcessExit = jest
|
||||
.spyOn(process, 'exit')
|
||||
.mockImplementation(() => {});
|
||||
const mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(() => {
|
||||
// noop
|
||||
});
|
||||
|
||||
await runCommand(command, {
|
||||
...config,
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
import chalk from 'chalk';
|
||||
import wrapAnsi from 'wrap-ansi';
|
||||
import indentString from 'indent-string';
|
||||
import wrapAnsi from 'wrap-ansi';
|
||||
|
||||
import { ICommand, ICommandConfig } from './commands';
|
||||
import { getProjectPaths, IProjectPathOptions } from './config';
|
||||
import { CliError } from './utils/errors';
|
||||
import { getProjects, buildProjectGraph } from './utils/projects';
|
||||
import { log } from './utils/log';
|
||||
import { buildProjectGraph, getProjects } from './utils/projects';
|
||||
import { renderProjectsTree } from './utils/projects_tree';
|
||||
import { getProjectPaths, ProjectPathOptions } from './config';
|
||||
import { Command, CommandConfig } from './commands';
|
||||
|
||||
export async function runCommand(command: Command, config: CommandConfig) {
|
||||
export async function runCommand(command: ICommand, config: ICommandConfig) {
|
||||
try {
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.bold(
|
||||
`Running [${chalk.green(command.name)}] command from [${chalk.yellow(
|
||||
config.rootPath
|
||||
|
@ -20,7 +21,7 @@ export async function runCommand(command: Command, config: CommandConfig) {
|
|||
|
||||
const projectPaths = getProjectPaths(
|
||||
config.rootPath,
|
||||
config.options as ProjectPathOptions
|
||||
config.options as IProjectPathOptions
|
||||
);
|
||||
|
||||
const projects = await getProjects(config.rootPath, projectPaths, {
|
||||
|
@ -29,7 +30,7 @@ export async function runCommand(command: Command, config: CommandConfig) {
|
|||
});
|
||||
|
||||
if (projects.size === 0) {
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.red(
|
||||
`There are no projects found. Double check project name(s) in '-i/--include' and '-e/--exclude' filters.\n`
|
||||
)
|
||||
|
@ -39,18 +40,18 @@ export async function runCommand(command: Command, config: CommandConfig) {
|
|||
|
||||
const projectGraph = buildProjectGraph(projects);
|
||||
|
||||
console.log(
|
||||
log.write(
|
||||
chalk.bold(`Found [${chalk.green(projects.size.toString())}] projects:\n`)
|
||||
);
|
||||
console.log(renderProjectsTree(config.rootPath, projects));
|
||||
log.write(renderProjectsTree(config.rootPath, projects));
|
||||
|
||||
await command.run(projects, projectGraph, config);
|
||||
} catch (e) {
|
||||
console.log(chalk.bold.red(`\n[${command.name}] failed:\n`));
|
||||
log.write(chalk.bold.red(`\n[${command.name}] failed:\n`));
|
||||
|
||||
if (e instanceof CliError) {
|
||||
const msg = chalk.red(`CliError: ${e.message}\n`);
|
||||
console.log(wrapAnsi(msg, 80));
|
||||
log.write(wrapAnsi(msg, 80));
|
||||
|
||||
const keys = Object.keys(e.meta);
|
||||
if (keys.length > 0) {
|
||||
|
@ -59,11 +60,11 @@ export async function runCommand(command: Command, config: CommandConfig) {
|
|||
return `${key}: ${value}`;
|
||||
});
|
||||
|
||||
console.log('Additional debugging info:\n');
|
||||
console.log(indentString(metaOutput.join('\n'), 3));
|
||||
log.write('Additional debugging info:\n');
|
||||
log.write(indentString(metaOutput.join('\n'), 3));
|
||||
}
|
||||
} else {
|
||||
console.log(e.stack);
|
||||
log.write(e.stack);
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { resolve, sep as pathSep } from 'path';
|
||||
import cloneDeepWith from 'lodash.clonedeepwith';
|
||||
import { resolve, sep as pathSep } from 'path';
|
||||
|
||||
const repoRoot = resolve(__dirname, '../../../../');
|
||||
|
||||
|
@ -16,8 +16,8 @@ const normalizePaths = (value: any) => {
|
|||
});
|
||||
|
||||
return {
|
||||
didReplacement,
|
||||
clone,
|
||||
didReplacement,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import execa from 'execa';
|
||||
import chalk from 'chalk';
|
||||
import logTransformer from 'strong-log-transformer';
|
||||
import execa from 'execa';
|
||||
import logSymbols from 'log-symbols';
|
||||
import logTransformer from 'strong-log-transformer';
|
||||
|
||||
function generateColors() {
|
||||
const colorWheel = [
|
||||
|
@ -42,8 +42,8 @@ export function spawnStreaming(
|
|||
const color = nextColor();
|
||||
const prefixedStdout = logTransformer({ tag: `${color.bold(prefix)}:` });
|
||||
const prefixedStderr = logTransformer({
|
||||
tag: `${logSymbols.error} ${color.bold(prefix)}:`,
|
||||
mergeMultiline: true,
|
||||
tag: `${logSymbols.error} ${color.bold(prefix)}:`,
|
||||
});
|
||||
|
||||
spawned.stdout.pipe(prefixedStdout).pipe(process.stdout);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import fs from 'fs';
|
||||
import { relative, dirname } from 'path';
|
||||
import { promisify } from 'util';
|
||||
import cmdShimCb from 'cmd-shim';
|
||||
import fs from 'fs';
|
||||
import mkdirpCb from 'mkdirp';
|
||||
import { dirname, relative } from 'path';
|
||||
import { promisify } from 'util';
|
||||
|
||||
const stat = promisify(fs.stat);
|
||||
const readFile = promisify(fs.readFile);
|
||||
|
|
|
@ -15,10 +15,10 @@ const projectsByName = new Map([
|
|||
'foo',
|
||||
new Project(
|
||||
{
|
||||
name: 'foo',
|
||||
dependencies: {
|
||||
bar: 'link:../bar',
|
||||
},
|
||||
name: 'foo',
|
||||
},
|
||||
resolve(__dirname, 'foo')
|
||||
),
|
||||
|
@ -27,8 +27,8 @@ const projectsByName = new Map([
|
|||
'bar',
|
||||
new Project(
|
||||
{
|
||||
name: 'bar',
|
||||
bin: 'bin/bar.js',
|
||||
name: 'bar',
|
||||
},
|
||||
resolve(__dirname, 'bar')
|
||||
),
|
||||
|
@ -37,10 +37,10 @@ const projectsByName = new Map([
|
|||
'baz',
|
||||
new Project(
|
||||
{
|
||||
name: 'baz',
|
||||
devDependencies: {
|
||||
bar: 'link:../bar',
|
||||
},
|
||||
name: 'baz',
|
||||
},
|
||||
resolve(__dirname, 'baz')
|
||||
),
|
||||
|
@ -82,7 +82,9 @@ describe('bin script points to a file', () => {
|
|||
const fs = require('./fs');
|
||||
fs.isFile.mockReturnValue(true);
|
||||
|
||||
const logMock = jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
const logMock = jest.spyOn(console, 'log').mockImplementation(() => {
|
||||
// noop
|
||||
});
|
||||
await linkProjectExecutables(projectsByName, projectGraph);
|
||||
logMock.mockRestore();
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { resolve, relative, dirname, sep } from 'path';
|
||||
import { dirname, relative, resolve, sep } from 'path';
|
||||
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { createSymlink, isFile, chmod, mkdirp } from './fs';
|
||||
import { chmod, createSymlink, isFile, mkdirp } from './fs';
|
||||
import { log } from './log';
|
||||
import { ProjectGraph, ProjectMap } from './projects';
|
||||
|
||||
/**
|
||||
|
@ -39,7 +40,7 @@ export async function linkProjectExecutables(
|
|||
.split(sep)
|
||||
.join('/');
|
||||
|
||||
console.log(
|
||||
log.write(
|
||||
chalk`{dim [${project.name}]} ${name} -> {dim ${projectRelativePath}}`
|
||||
);
|
||||
|
||||
|
|
11
packages/kbn-pm/src/utils/log.ts
Normal file
11
packages/kbn-pm/src/utils/log.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
export const log = {
|
||||
/**
|
||||
* Log something to the console. Ideally we would use a real logger in
|
||||
* kbn-pm, but that's a pretty big change for now.
|
||||
* @param ...args
|
||||
*/
|
||||
write(...args: any[]) {
|
||||
// tslint:disable no-console
|
||||
console.log(...args);
|
||||
},
|
||||
};
|
|
@ -1,20 +1,25 @@
|
|||
import readPkg from 'read-pkg';
|
||||
import writePkg from 'write-pkg';
|
||||
import path from 'path';
|
||||
|
||||
export type PackageJson = { [key: string]: any };
|
||||
export type PackageDependencies = { [key: string]: string };
|
||||
export type PackageScripts = { [key: string]: string };
|
||||
export interface IPackageJson {
|
||||
[key: string]: any;
|
||||
}
|
||||
export interface IPackageDependencies {
|
||||
[key: string]: string;
|
||||
}
|
||||
export interface IPackageScripts {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export function readPackageJson(dir: string) {
|
||||
return readPkg(dir, { normalize: false });
|
||||
}
|
||||
|
||||
export function writePackageJson(path: string, json: PackageJson) {
|
||||
export function writePackageJson(path: string, json: IPackageJson) {
|
||||
return writePkg(path, json);
|
||||
}
|
||||
|
||||
export const createProductionPackageJson = (pkgJson: PackageJson) => ({
|
||||
export const createProductionPackageJson = (pkgJson: IPackageJson) => ({
|
||||
...pkgJson,
|
||||
dependencies: transformDependencies(pkgJson.dependencies),
|
||||
});
|
||||
|
@ -31,8 +36,8 @@ export const isLinkDependency = (depVersion: string) =>
|
|||
* will then _copy_ the `file:` dependencies into `node_modules` instead of
|
||||
* symlinking like we do in development.
|
||||
*/
|
||||
export function transformDependencies(dependencies: PackageDependencies = {}) {
|
||||
const newDeps: PackageDependencies = {};
|
||||
export function transformDependencies(dependencies: IPackageDependencies = {}) {
|
||||
const newDeps: IPackageDependencies = {};
|
||||
for (const name of Object.keys(dependencies)) {
|
||||
const depVersion = dependencies[name];
|
||||
if (isLinkDependency(depVersion)) {
|
||||
|
|
|
@ -106,9 +106,9 @@ test('rejects if any promise rejects', async () => {
|
|||
function createPromiseWithResolve() {
|
||||
let resolve: (val?: any) => void;
|
||||
let reject: (err?: any) => void;
|
||||
const promise = new Promise((_resolve, _reject) => {
|
||||
resolve = _resolve;
|
||||
reject = _reject;
|
||||
const promise = new Promise((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
return { promise, resolve: resolve!, reject: reject!, called: false };
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { resolve, join } from 'path';
|
||||
import { join, resolve } from 'path';
|
||||
|
||||
import { PackageJson } from './package_json';
|
||||
import { IPackageJson } from './package_json';
|
||||
import { Project } from './project';
|
||||
|
||||
const rootPath = resolve(`${__dirname}/__fixtures__/kibana`);
|
||||
|
||||
const createProjectWith = (packageJson: PackageJson, path = '') =>
|
||||
const createProjectWith = (packageJson: IPackageJson, path = '') =>
|
||||
new Project(
|
||||
{
|
||||
name: 'kibana',
|
||||
|
@ -25,12 +25,12 @@ describe('fromPath', () => {
|
|||
|
||||
test('fields', async () => {
|
||||
const kibana = createProjectWith({
|
||||
scripts: {
|
||||
test: 'jest',
|
||||
},
|
||||
dependencies: {
|
||||
foo: '1.2.3',
|
||||
},
|
||||
scripts: {
|
||||
test: 'jest',
|
||||
},
|
||||
});
|
||||
|
||||
expect(kibana.name).toBe('kibana');
|
||||
|
|
|
@ -1,49 +1,50 @@
|
|||
import path from 'path';
|
||||
import { inspect } from 'util';
|
||||
import chalk from 'chalk';
|
||||
import { relative, resolve as resolvePath } from 'path';
|
||||
import { inspect } from 'util';
|
||||
|
||||
import { CliError } from './errors';
|
||||
import { log } from './log';
|
||||
import {
|
||||
IPackageDependencies,
|
||||
IPackageJson,
|
||||
IPackageScripts,
|
||||
isLinkDependency,
|
||||
readPackageJson,
|
||||
} from './package_json';
|
||||
import {
|
||||
installInDir,
|
||||
runScriptInPackage,
|
||||
runScriptInPackageStreaming,
|
||||
} from './scripts';
|
||||
import {
|
||||
PackageJson,
|
||||
PackageDependencies,
|
||||
PackageScripts,
|
||||
isLinkDependency,
|
||||
readPackageJson,
|
||||
} from './package_json';
|
||||
import { CliError } from './errors';
|
||||
|
||||
interface BuildConfig {
|
||||
interface IBuildConfig {
|
||||
skip?: boolean;
|
||||
intermediateBuildDirectory?: string;
|
||||
}
|
||||
|
||||
export class Project {
|
||||
static async fromPath(path: string) {
|
||||
public static async fromPath(path: string) {
|
||||
const pkgJson = await readPackageJson(path);
|
||||
return new Project(pkgJson, path);
|
||||
}
|
||||
|
||||
public readonly json: PackageJson;
|
||||
public readonly json: IPackageJson;
|
||||
public readonly packageJsonLocation: string;
|
||||
public readonly nodeModulesLocation: string;
|
||||
public readonly targetLocation: string;
|
||||
public readonly path: string;
|
||||
public readonly allDependencies: PackageDependencies;
|
||||
public readonly productionDependencies: PackageDependencies;
|
||||
public readonly devDependencies: PackageDependencies;
|
||||
public readonly scripts: PackageScripts;
|
||||
public readonly allDependencies: IPackageDependencies;
|
||||
public readonly productionDependencies: IPackageDependencies;
|
||||
public readonly devDependencies: IPackageDependencies;
|
||||
public readonly scripts: IPackageScripts;
|
||||
|
||||
constructor(packageJson: PackageJson, projectPath: string) {
|
||||
constructor(packageJson: IPackageJson, projectPath: string) {
|
||||
this.json = Object.freeze(packageJson);
|
||||
this.path = projectPath;
|
||||
|
||||
this.packageJsonLocation = path.resolve(this.path, 'package.json');
|
||||
this.nodeModulesLocation = path.resolve(this.path, 'node_modules');
|
||||
this.targetLocation = path.resolve(this.path, 'target');
|
||||
this.packageJsonLocation = resolvePath(this.path, 'package.json');
|
||||
this.nodeModulesLocation = resolvePath(this.path, 'node_modules');
|
||||
this.targetLocation = resolvePath(this.path, 'target');
|
||||
|
||||
this.productionDependencies = this.json.dependencies || {};
|
||||
this.devDependencies = this.json.devDependencies || {};
|
||||
|
@ -59,9 +60,9 @@ export class Project {
|
|||
return this.json.name;
|
||||
}
|
||||
|
||||
ensureValidProjectDependency(project: Project) {
|
||||
public ensureValidProjectDependency(project: Project) {
|
||||
const relativePathToProject = normalizePath(
|
||||
path.relative(this.path, project.path)
|
||||
relative(this.path, project.path)
|
||||
);
|
||||
|
||||
const versionInPackageJson = this.allDependencies[project.name];
|
||||
|
@ -73,9 +74,9 @@ export class Project {
|
|||
|
||||
const updateMsg = 'Update its package.json to the expected value below.';
|
||||
const meta = {
|
||||
package: `${this.name} (${this.packageJsonLocation})`,
|
||||
expected: `"${project.name}": "${expectedVersionInPackageJson}"`,
|
||||
actual: `"${project.name}": "${versionInPackageJson}"`,
|
||||
expected: `"${project.name}": "${expectedVersionInPackageJson}"`,
|
||||
package: `${this.name} (${this.packageJsonLocation})`,
|
||||
};
|
||||
|
||||
if (isLinkDependency(versionInPackageJson)) {
|
||||
|
@ -95,7 +96,7 @@ export class Project {
|
|||
);
|
||||
}
|
||||
|
||||
getBuildConfig(): BuildConfig {
|
||||
public getBuildConfig(): IBuildConfig {
|
||||
return (this.json.kibana && this.json.kibana.build) || {};
|
||||
}
|
||||
|
||||
|
@ -104,18 +105,18 @@ export class Project {
|
|||
* This config can be specified to only include the project's build artifacts
|
||||
* instead of everything located in the project directory.
|
||||
*/
|
||||
getIntermediateBuildDirectory() {
|
||||
return path.resolve(
|
||||
public getIntermediateBuildDirectory() {
|
||||
return resolvePath(
|
||||
this.path,
|
||||
this.getBuildConfig().intermediateBuildDirectory || '.'
|
||||
);
|
||||
}
|
||||
|
||||
hasScript(name: string) {
|
||||
public hasScript(name: string) {
|
||||
return name in this.scripts;
|
||||
}
|
||||
|
||||
getExecutables(): { [key: string]: string } {
|
||||
public getExecutables(): { [key: string]: string } {
|
||||
const raw = this.json.bin;
|
||||
|
||||
if (!raw) {
|
||||
|
@ -124,14 +125,14 @@ export class Project {
|
|||
|
||||
if (typeof raw === 'string') {
|
||||
return {
|
||||
[this.name]: path.resolve(this.path, raw),
|
||||
[this.name]: resolvePath(this.path, raw),
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof raw === 'object') {
|
||||
const binsConfig: { [k: string]: string } = {};
|
||||
for (const binName of Object.keys(raw)) {
|
||||
binsConfig[binName] = path.resolve(this.path, raw[binName]);
|
||||
binsConfig[binName] = resolvePath(this.path, raw[binName]);
|
||||
}
|
||||
return binsConfig;
|
||||
}
|
||||
|
@ -140,14 +141,14 @@ export class Project {
|
|||
`[${this.name}] has an invalid "bin" field in its package.json, ` +
|
||||
`expected an object or a string`,
|
||||
{
|
||||
package: `${this.name} (${this.packageJsonLocation})`,
|
||||
binConfig: inspect(raw),
|
||||
package: `${this.name} (${this.packageJsonLocation})`,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async runScript(scriptName: string, args: string[] = []) {
|
||||
console.log(
|
||||
public async runScript(scriptName: string, args: string[] = []) {
|
||||
log.write(
|
||||
chalk.bold(
|
||||
`\n\nRunning script [${chalk.green(scriptName)}] in [${chalk.green(
|
||||
this.name
|
||||
|
@ -157,16 +158,16 @@ export class Project {
|
|||
return runScriptInPackage(scriptName, args, this);
|
||||
}
|
||||
|
||||
runScriptStreaming(scriptName: string, args: string[] = []) {
|
||||
public runScriptStreaming(scriptName: string, args: string[] = []) {
|
||||
return runScriptInPackageStreaming(scriptName, args, this);
|
||||
}
|
||||
|
||||
hasDependencies() {
|
||||
public hasDependencies() {
|
||||
return Object.keys(this.allDependencies).length > 0;
|
||||
}
|
||||
|
||||
async installDependencies({ extraArgs }: { extraArgs: string[] }) {
|
||||
console.log(
|
||||
public async installDependencies({ extraArgs }: { extraArgs: string[] }) {
|
||||
log.write(
|
||||
chalk.bold(
|
||||
`\n\nInstalling dependencies in [${chalk.green(this.name)}]:\n`
|
||||
)
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import { resolve } from 'path';
|
||||
|
||||
import {
|
||||
getProjects,
|
||||
buildProjectGraph,
|
||||
topologicallyBatchProjects,
|
||||
includeTransitiveProjects,
|
||||
ProjectMap,
|
||||
ProjectGraph,
|
||||
} from './projects';
|
||||
import { Project } from './project';
|
||||
import { getProjectPaths } from '../config';
|
||||
import { Project } from './project';
|
||||
import {
|
||||
buildProjectGraph,
|
||||
getProjects,
|
||||
includeTransitiveProjects,
|
||||
ProjectGraph,
|
||||
ProjectMap,
|
||||
topologicallyBatchProjects,
|
||||
} from './projects';
|
||||
|
||||
const rootPath = resolve(`${__dirname}/__fixtures__/kibana`);
|
||||
|
||||
|
@ -164,12 +164,12 @@ describe('#getProjects', () => {
|
|||
|
||||
describe('#buildProjectGraph', () => {
|
||||
test('builds full project graph', async () => {
|
||||
const projects = await getProjects(rootPath, [
|
||||
const allProjects = await getProjects(rootPath, [
|
||||
'.',
|
||||
'packages/*',
|
||||
'../plugins/*',
|
||||
]);
|
||||
const graph = buildProjectGraph(projects);
|
||||
const graph = buildProjectGraph(allProjects);
|
||||
|
||||
const expected: { [k: string]: string[] } = {};
|
||||
for (const [projectName, projects] of graph.entries()) {
|
||||
|
|
|
@ -9,12 +9,15 @@ const glob = promisify(globSync);
|
|||
|
||||
export type ProjectMap = Map<string, Project>;
|
||||
export type ProjectGraph = Map<string, Project[]>;
|
||||
export type ProjectsOptions = { include?: string[]; exclude?: string[] };
|
||||
export interface IProjectsOptions {
|
||||
include?: string[];
|
||||
exclude?: string[];
|
||||
}
|
||||
|
||||
export async function getProjects(
|
||||
rootPath: string,
|
||||
projectsPathsPatterns: string[],
|
||||
{ include = [], exclude = [] }: ProjectsOptions = {}
|
||||
{ include = [], exclude = [] }: IProjectsOptions = {}
|
||||
) {
|
||||
const projects: ProjectMap = new Map();
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { resolve } from 'path';
|
||||
|
||||
import { stripAnsiSnapshotSerializer } from '../test_helpers';
|
||||
import { renderProjectsTree } from './projects_tree';
|
||||
import { getProjects } from './projects';
|
||||
import { getProjectPaths } from '../config';
|
||||
import { stripAnsiSnapshotSerializer } from '../test_helpers';
|
||||
import { getProjects } from './projects';
|
||||
import { renderProjectsTree } from './projects_tree';
|
||||
|
||||
const rootPath = resolve(`${__dirname}/__fixtures__/kibana`);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import path from 'path';
|
||||
import chalk from 'chalk';
|
||||
import path from 'path';
|
||||
|
||||
import { Project } from './project';
|
||||
|
||||
|
@ -13,41 +13,44 @@ export function renderProjectsTree(
|
|||
return treeToString(createTreeStructure(projectsTree));
|
||||
}
|
||||
|
||||
type Tree = {
|
||||
interface ITree {
|
||||
name?: string;
|
||||
children?: TreeChildren;
|
||||
};
|
||||
interface TreeChildren extends Array<Tree> {}
|
||||
children?: ITreeChildren;
|
||||
}
|
||||
interface ITreeChildren extends Array<ITree> {}
|
||||
|
||||
type DirOrProjectName = string | typeof projectKey;
|
||||
type ProjectsTree = Map<DirOrProjectName, ProjectsTreeValue | string>;
|
||||
interface ProjectsTreeValue extends ProjectsTree {}
|
||||
|
||||
function treeToString(tree: Tree) {
|
||||
return [tree.name].concat(childrenToString(tree.children, '')).join('\n');
|
||||
interface IProjectsTree extends Map<DirOrProjectName, string | IProjectsTree> {}
|
||||
|
||||
function treeToString(tree: ITree) {
|
||||
return [tree.name].concat(childrenToStrings(tree.children, '')).join('\n');
|
||||
}
|
||||
|
||||
function childrenToString(tree: TreeChildren | undefined, treePrefix: string) {
|
||||
function childrenToStrings(
|
||||
tree: ITreeChildren | undefined,
|
||||
treePrefix: string
|
||||
) {
|
||||
if (tree === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let string: string[] = [];
|
||||
let strings: string[] = [];
|
||||
tree.forEach((node, index) => {
|
||||
const isLastNode = tree.length - 1 === index;
|
||||
const nodePrefix = isLastNode ? '└── ' : '├── ';
|
||||
const childPrefix = isLastNode ? ' ' : '│ ';
|
||||
const childrenPrefix = treePrefix + childPrefix;
|
||||
|
||||
string.push(`${treePrefix}${nodePrefix}${node.name}`);
|
||||
string = string.concat(childrenToString(node.children, childrenPrefix));
|
||||
strings.push(`${treePrefix}${nodePrefix}${node.name}`);
|
||||
strings = strings.concat(childrenToStrings(node.children, childrenPrefix));
|
||||
});
|
||||
return string;
|
||||
return strings;
|
||||
}
|
||||
|
||||
function createTreeStructure(tree: ProjectsTree): Tree {
|
||||
function createTreeStructure(tree: IProjectsTree): ITree {
|
||||
let name: string | undefined;
|
||||
const children: TreeChildren = [];
|
||||
const children: ITreeChildren = [];
|
||||
|
||||
for (const [dir, project] of tree.entries()) {
|
||||
// This is a leaf node (aka a project)
|
||||
|
@ -63,8 +66,8 @@ function createTreeStructure(tree: ProjectsTree): Tree {
|
|||
if (project.size === 1 && project.has(projectKey)) {
|
||||
const projectName = project.get(projectKey)! as string;
|
||||
children.push({
|
||||
name: dirOrProjectName(dir, projectName),
|
||||
children: [],
|
||||
name: dirOrProjectName(dir, projectName),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
@ -77,8 +80,8 @@ function createTreeStructure(tree: ProjectsTree): Tree {
|
|||
const projectName = subtree.name;
|
||||
|
||||
children.push({
|
||||
name: dirOrProjectName(dir, projectName),
|
||||
children: subtree.children,
|
||||
name: dirOrProjectName(dir, projectName),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
@ -91,15 +94,15 @@ function createTreeStructure(tree: ProjectsTree): Tree {
|
|||
const newName = chalk.dim(path.join(dir.toString(), child.name!));
|
||||
|
||||
children.push({
|
||||
name: newName,
|
||||
children: child.children,
|
||||
name: newName,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
children.push({
|
||||
name: chalk.dim(dir.toString()),
|
||||
children: subtree.children,
|
||||
name: chalk.dim(dir.toString()),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -113,7 +116,7 @@ function dirOrProjectName(dir: DirOrProjectName, projectName: string) {
|
|||
}
|
||||
|
||||
function buildProjectsTree(rootPath: string, projects: Map<string, Project>) {
|
||||
const tree: ProjectsTree = new Map();
|
||||
const tree: IProjectsTree = new Map();
|
||||
|
||||
for (const project of projects.values()) {
|
||||
if (rootPath === project.path) {
|
||||
|
@ -128,7 +131,7 @@ function buildProjectsTree(rootPath: string, projects: Map<string, Project>) {
|
|||
}
|
||||
|
||||
function addProjectToTree(
|
||||
tree: ProjectsTree,
|
||||
tree: IProjectsTree,
|
||||
pathParts: string[],
|
||||
project: Project
|
||||
) {
|
||||
|
@ -141,7 +144,7 @@ function addProjectToTree(
|
|||
tree.set(currentDir, new Map());
|
||||
}
|
||||
|
||||
const subtree = tree.get(currentDir) as ProjectsTree;
|
||||
const subtree = tree.get(currentDir) as IProjectsTree;
|
||||
addProjectToTree(subtree, rest, project);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ const defaultHandlerReadinessTimeout = 2000;
|
|||
/**
|
||||
* Describes configurable watch options.
|
||||
*/
|
||||
interface WatchOptions {
|
||||
interface IWatchOptions {
|
||||
/**
|
||||
* Number of milliseconds to wait before we fall back to default watch handler.
|
||||
*/
|
||||
|
@ -33,7 +33,7 @@ function getWatchHandlers(
|
|||
{
|
||||
handlerDelay = defaultHandlerDelay,
|
||||
handlerReadinessTimeout = defaultHandlerReadinessTimeout,
|
||||
}: WatchOptions
|
||||
}: IWatchOptions
|
||||
) {
|
||||
const typescriptHandler = buildOutput$
|
||||
.first(data => data.includes('$ tsc'))
|
||||
|
@ -60,7 +60,7 @@ function getWatchHandlers(
|
|||
|
||||
export function waitUntilWatchIsReady(
|
||||
stream: NodeJS.EventEmitter,
|
||||
opts: WatchOptions = {}
|
||||
opts: IWatchOptions = {}
|
||||
) {
|
||||
const buildOutput$ = new Subject<string>();
|
||||
const onDataListener = (data: Buffer) =>
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
extends: ../../tslint.yaml
|
||||
|
||||
rules:
|
||||
max-classes-per-file: false
|
||||
interface-name: false
|
||||
variable-name: false
|
||||
no-empty: false
|
||||
object-literal-sort-keys: false
|
||||
member-ordering: false
|
||||
no-console: false
|
||||
only-arrow-functions: false
|
||||
no-shadowed-variable: false
|
||||
no-empty-interface: false
|
||||
ordered-imports: false
|
||||
interface-over-type-literal: false
|
||||
prettier: false
|
||||
prefer-const: false
|
||||
member-access: false
|
||||
no-unused-variable: false
|
Loading…
Add table
Add a link
Reference in a new issue