Skip to content

Commit

Permalink
feat(cli): add debug command to help with setting up the CLI
Browse files Browse the repository at this point in the history
Closes #136
  • Loading branch information
B4nan committed Sep 20, 2019
1 parent 9b1719b commit 7919071
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ checks:
return-statements:
config:
threshold: 5
method-complexity:
config:
threshold: 6

engines:
duplication:
Expand Down
13 changes: 6 additions & 7 deletions lib/cli/CLIHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Configuration, Utils } from '../utils';
import { ClearCacheCommand } from './ClearCacheCommand';
import { GenerateEntitiesCommand } from './GenerateEntitiesCommand';
import { SchemaCommandFactory } from './SchemaCommandFactory';
import { DebugCommand } from './DebugCommand';

export class CLIHelper {

Expand Down Expand Up @@ -59,14 +60,15 @@ export class CLIHelper {
.command(SchemaCommandFactory.create('create'))
.command(SchemaCommandFactory.create('drop'))
.command(SchemaCommandFactory.create('update'))
.command(new DebugCommand())
.recommendCommands()
.strict();
}

private static async getSettings(): Promise<Settings> {
static async getSettings(): Promise<Settings> {
if (await pathExists(process.cwd() + '/package.json')) {
const config = require(process.cwd() + '/package.json');
return config['mikro-orm'];
return config['mikro-orm'] || {};
}

return {};
Expand All @@ -83,16 +85,13 @@ export class CLIHelper {

static async getConfigPaths(): Promise<string[]> {
const paths: string[] = [];
const settings = await CLIHelper.getSettings();

if (process.env.MIKRO_ORM_CLI) {
paths.push(process.env.MIKRO_ORM_CLI);
}

if (await pathExists(process.cwd() + '/package.json')) {
const config = require(process.cwd() + '/package.json');
const settings = config['mikro-orm'] as Settings;
paths.push(...(settings.configPaths || []));
}
paths.push(...(settings.configPaths || []));

return [...paths, './cli-config'];
}
Expand Down
59 changes: 59 additions & 0 deletions lib/cli/DebugCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Arguments, CommandModule } from 'yargs';
import chalk from 'chalk';
import { CLIHelper } from './CLIHelper';
import { pathExists } from 'fs-extra';
import { Utils } from '../utils';

export class DebugCommand implements CommandModule {

command = 'debug';
describe = 'Debug CLI configuration';

async handler(args: Arguments) {
CLIHelper.dump(`Current ${chalk.cyan('MikroORM')} CLI configuration`);

if (await pathExists(process.cwd() + '/package.json')) {
CLIHelper.dump(' - package.json ' + chalk.green('found'));
} else {
CLIHelper.dump(' - package.json ' + chalk.red('not found'));
}

const settings = await CLIHelper.getSettings();

if (settings.useTsNode) {
CLIHelper.dump(' - ts-node ' + chalk.green('enabled'));
}

const configPaths = await CLIHelper.getConfigPaths();
CLIHelper.dump(' - searched config paths:');
await DebugCommand.checkPaths(configPaths);

try {
const config = await CLIHelper.getConfiguration();
CLIHelper.dump(` - configuration ${chalk.green('found')}`);
const length = config.get('entities', []).length;

if (length > 0) {
CLIHelper.dump(` - will use \`entities\` array (contains ${length} items)`);
} else if (config.get('entitiesDirs', []).length > 0) {
CLIHelper.dump(' - will use `entitiesDirs` paths:');
await DebugCommand.checkPaths(config.get('entitiesDirs'));
}
} catch (e) {
CLIHelper.dump(`- configuration ${chalk.red('not found')} ${chalk.red(`(${e.message})`)}`);
}
}

private static async checkPaths(paths: string[]): Promise<void> {
for (let path of paths) {
path = Utils.normalizePath(path);

if (await pathExists(path)) {
CLIHelper.dump(` - ${path} (${chalk.green('found')})`);
} else {
CLIHelper.dump(` - ${path} (${chalk.red('not found')})`);
}
}
}

}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mikro-orm",
"version": "3.0.0-alpha.7",
"version": "3.0.0-alpha.9",
"description": "Simple typescript ORM for node.js based on data-mapper, unit-of-work and identity-map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JS.",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand Down
22 changes: 20 additions & 2 deletions tests/cli/CLIHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('CLIHelper', () => {
test('configures yargs instance', async () => {
const cli = await CLIHelper.configure() as any;
expect(cli.$0).toBe('mikro-orm');
expect(cli.getCommandInstance().getCommands()).toEqual(['cache:clear', 'generate-entities', 'schema:create', 'schema:drop', 'schema:update']);
expect(cli.getCommandInstance().getCommands()).toEqual(['cache:clear', 'generate-entities', 'schema:create', 'schema:drop', 'schema:update', 'debug']);
});

test('configures yargs instance [ts-node]', async () => {
Expand All @@ -28,7 +28,7 @@ describe('CLIHelper', () => {
const cli = await CLIHelper.configure() as any;
expect(cli.$0).toBe('mikro-orm');
expect(tsNodeMock).toHaveBeenCalled();
expect(cli.getCommandInstance().getCommands()).toEqual(['cache:clear', 'generate-entities', 'schema:create', 'schema:drop', 'schema:update']);
expect(cli.getCommandInstance().getCommands()).toEqual(['cache:clear', 'generate-entities', 'schema:create', 'schema:drop', 'schema:update', 'debug']);
pathExistsMock.mockRestore();
});

Expand Down Expand Up @@ -103,11 +103,29 @@ describe('CLIHelper', () => {
}
});

test('getSettings', async () => {
const pathExistsMock = jest.spyOn(require('fs-extra'), 'pathExists');
pathExistsMock.mockResolvedValue(true);
pkg['mikro-orm'] = undefined;
pathExistsMock.mockResolvedValue(true);
await expect(CLIHelper.getSettings()).resolves.toEqual({});
pathExistsMock.mockRestore();
});

test('getConfigPaths', async () => {
(global as any).process.env.MIKRO_ORM_CLI = './override/orm-config.ts';
await expect(CLIHelper.getConfigPaths()).resolves.toEqual(['./override/orm-config.ts', './cli-config']);
delete (global as any).process.env.MIKRO_ORM_CLI;
await expect(CLIHelper.getConfigPaths()).resolves.toEqual(['./cli-config']);

const pathExistsMock = jest.spyOn(require('fs-extra'), 'pathExists');
pathExistsMock.mockReturnValue(Promise.resolve(true));
pkg['mikro-orm'] = { configPaths: ['orm-config'] };
await expect(CLIHelper.getConfigPaths()).resolves.toEqual(['orm-config', './cli-config']);

pathExistsMock.mockResolvedValue(false);
await expect(CLIHelper.getConfigPaths()).resolves.toEqual(['./cli-config']);
pathExistsMock.mockRestore();
});

});
91 changes: 91 additions & 0 deletions tests/cli/DebugCommand.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
const dump = jest.fn();
const getSettings = jest.fn();
const getConfigPaths = jest.fn();
const getConfiguration = jest.fn();
jest.mock('../../lib/cli/CLIHelper', () => ({ CLIHelper: { dump, getSettings, getConfigPaths, getConfiguration } }));

(global as any).process.env.FORCE_COLOR = 0;
(global as any).console.log = jest.fn();

import { DebugCommand } from '../../lib/cli/DebugCommand';
import { Configuration } from '../../lib/utils';
import { FooBar } from '../entities/FooBar';
import { FooBaz } from '../entities/FooBaz';

describe('DebugCommand', () => {

test('handler', async () => {
const cmd = new DebugCommand();

const pathExistsMock = jest.spyOn(require('fs-extra'), 'pathExists');
pathExistsMock.mockResolvedValue(true);
getSettings.mockResolvedValue({});
getConfiguration.mockResolvedValue(new Configuration({} as any, false));
getConfigPaths.mockReturnValue(['./path/orm-config.ts']);
await expect(cmd.handler({} as any)).resolves.toBeUndefined();
expect(dump.mock.calls).toEqual([
['Current MikroORM CLI configuration'],
[' - package.json found'],
[' - searched config paths:'],
[` - ${process.cwd()}/path/orm-config.ts (found)`],
[' - configuration found'],
]);

getSettings.mockResolvedValue({ useTsNode: true });
pathExistsMock.mockResolvedValue((path: string) => path.endsWith('entities-1'));
getConfiguration.mockResolvedValue(new Configuration({ entitiesDirs: ['./entities-1', './entities-2'] } as any, false));
dump.mock.calls.length = 0;
await expect(cmd.handler({} as any)).resolves.toBeUndefined();
expect(dump.mock.calls).toEqual([
['Current MikroORM CLI configuration'],
[' - package.json found'],
[' - ts-node enabled'],
[' - searched config paths:'],
[` - ${process.cwd()}/path/orm-config.ts (found)`],
[' - configuration found'],
[' - will use `entitiesDirs` paths:'],
[' - /usr/local/var/www/b4nan/mikro-orm/entities-1 (found)'],
[' - /usr/local/var/www/b4nan/mikro-orm/entities-2 (found)'],
]);

getConfiguration.mockResolvedValue(new Configuration({ entities: [FooBar, FooBaz] } as any, false));
dump.mock.calls.length = 0;
await expect(cmd.handler({} as any)).resolves.toBeUndefined();
expect(dump.mock.calls).toEqual([
['Current MikroORM CLI configuration'],
[' - package.json found'],
[' - ts-node enabled'],
[' - searched config paths:'],
[` - ${process.cwd()}/path/orm-config.ts (found)`],
[' - configuration found'],
[' - will use `entities` array (contains 2 items)'],
]);

getConfiguration.mockRejectedValueOnce(new Error('test error message'));
dump.mock.calls.length = 0;
await expect(cmd.handler({} as any)).resolves.toBeUndefined();
expect(dump.mock.calls).toEqual([
['Current MikroORM CLI configuration'],
[' - package.json found'],
[' - ts-node enabled'],
[' - searched config paths:'],
[` - ${process.cwd()}/path/orm-config.ts (found)`],
['- configuration not found (test error message)'],
]);

pathExistsMock.mockResolvedValue(false);
dump.mock.calls.length = 0;
await expect(cmd.handler({} as any)).resolves.toBeUndefined();
expect(dump.mock.calls).toEqual([
['Current MikroORM CLI configuration'],
[' - package.json not found'],
[' - ts-node enabled'],
[' - searched config paths:'],
[` - ${process.cwd()}/path/orm-config.ts (not found)`],
[' - configuration found'],
[' - will use `entities` array (contains 2 items)'],
]);
pathExistsMock.mockRestore();
});

});

0 comments on commit 7919071

Please sign in to comment.