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

Ability to provide custom configuration with --config flag #120

Merged
merged 5 commits into from
Mar 27, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@leapfrogtechnology/sync-db",
"description": "Command line utility to synchronize and version control relational database objects across databases",
"version": "1.0.0-beta.11",
"version": "1.0.0-beta.12",
samirsilwal marked this conversation as resolved.
Show resolved Hide resolved
"license": "MIT",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
14 changes: 11 additions & 3 deletions src/commands/make-publish.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
import { grey, cyan } from 'chalk';
import { Command } from '@oclif/command';
import { Command, flags } from '@oclif/command';

import { loadConfig } from '../config';
import { CONFIG_FILENAME } from '../constants';
import { printInfo, printLine } from '../util/io';
import * as fileMakerService from '../service/fileMaker';

class MakePublish extends Command {
static description = 'Publish migration templates files.';

static flags = {
config: flags.string({
char: 'c',
default: CONFIG_FILENAME,
samirsilwal marked this conversation as resolved.
Show resolved Hide resolved
description: 'Custom configuration file.'
})
};
/**
samirsilwal marked this conversation as resolved.
Show resolved Hide resolved
* CLI command execution handler.
*
* @returns {Promise<void>}
*/
async run(): Promise<void> {
const config = await loadConfig();
const { flags: parsedFlags } = this.parse(MakePublish);
const config = await loadConfig(parsedFlags.config);

await printLine();

Expand Down
8 changes: 7 additions & 1 deletion src/commands/make.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { loadConfig } from '../config';
import { printLine } from '../util/io';
import { CONFIG_FILENAME } from '../constants';
import { Command, flags } from '@oclif/command';
import MakeOptions from '../domain/MakeOptions';
import Configuration from '../domain/Configuration';
Expand All @@ -17,6 +18,11 @@ class Make extends Command {
default: false,
description: 'Generate create table stub.'
}),
config: flags.string({
char: 'c',
default: CONFIG_FILENAME,
description: 'Custom configuration file.'
}),
type: flags.string({
char: 't',
helpValue: 'TYPE',
Expand All @@ -33,7 +39,7 @@ class Make extends Command {
*/
async run(): Promise<void> {
const { args, flags: parsedFlags } = this.parse(Make);
const config = await loadConfig();
const config = await loadConfig(parsedFlags.config);
const list = await this.makeFiles(config, args.name, parsedFlags.type, {
create: parsedFlags.create,
objectName: parsedFlags['object-name']
Expand Down
8 changes: 7 additions & 1 deletion src/commands/migrate-latest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { bold, red, cyan, magenta } from 'chalk';

import { migrateLatest } from '../api';
import { dbLogger } from '../util/logger';
import { CONFIG_FILENAME } from '../constants';
import { loadConfig, resolveConnections } from '..';
import { printLine, printError, printInfo } from '../util/io';
import OperationResult from '../domain/operation/OperationResult';
Expand All @@ -19,6 +20,11 @@ class MigrateLatest extends Command {
'connection-resolver': flags.string({
helpValue: 'PATH',
description: 'Path to the connection resolver.'
}),
config: flags.string({
char: 'c',
default: CONFIG_FILENAME,
description: 'Custom configuration file.'
})
};

Expand Down Expand Up @@ -72,7 +78,7 @@ class MigrateLatest extends Command {
async run(): Promise<void> {
const { flags: parsedFlags } = this.parse(MigrateLatest);
const isDryRun = parsedFlags['dry-run'];
const config = await loadConfig();
const config = await loadConfig(parsedFlags.config);
const connections = await resolveConnections(config, parsedFlags['connection-resolver']);

if (isDryRun) await printLine(magenta('\n• DRY RUN STARTED\n'));
Expand Down
8 changes: 7 additions & 1 deletion src/commands/migrate-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Command, flags } from '@oclif/command';
import { bold, grey, red, cyan, yellow } from 'chalk';

import { migrateList } from '../api';
import { CONFIG_FILENAME } from '../constants';
import { printLine, printError } from '../util/io';
import { loadConfig, resolveConnections } from '..';
import OperationResult from '../domain/operation/OperationResult';
Expand All @@ -17,6 +18,11 @@ class MigrateList extends Command {
'connection-resolver': flags.string({
helpValue: 'PATH',
description: 'Path to the connection resolver.'
}),
config: flags.string({
char: 'c',
default: CONFIG_FILENAME,
description: 'Custom configuration file.'
})
};

Expand Down Expand Up @@ -67,7 +73,7 @@ class MigrateList extends Command {
*/
async run(): Promise<void> {
const { flags: parsedFlags } = this.parse(MigrateList);
const config = await loadConfig();
const config = await loadConfig(parsedFlags.config);
const connections = await resolveConnections(config, parsedFlags['connection-resolver']);

const results = await migrateList(config, connections, {
Expand Down
8 changes: 7 additions & 1 deletion src/commands/migrate-rollback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { bold, red, cyan, magenta } from 'chalk';

import { migrateRollback } from '../api';
import { dbLogger } from '../util/logger';
import { CONFIG_FILENAME } from '../constants';
import { loadConfig, resolveConnections } from '..';
import { printLine, printError, printInfo } from '../util/io';
import OperationResult from '../domain/operation/OperationResult';
Expand All @@ -19,6 +20,11 @@ class MigrateRollback extends Command {
'connection-resolver': flags.string({
helpValue: 'PATH',
description: 'Path to the connection resolver.'
}),
config: flags.string({
char: 'c',
default: CONFIG_FILENAME,
description: 'Custom configuration file.'
})
};

Expand Down Expand Up @@ -71,7 +77,7 @@ class MigrateRollback extends Command {
async run(): Promise<void> {
const { flags: parsedFlags } = this.parse(MigrateRollback);
const isDryRun = parsedFlags['dry-run'];
const config = await loadConfig();
const config = await loadConfig(parsedFlags.config);
const connections = await resolveConnections(config, parsedFlags['connection-resolver']);

if (isDryRun) await printLine(magenta('\n• DRY RUN STARTED\n'));
Expand Down
8 changes: 7 additions & 1 deletion src/commands/prune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { bold, magenta, red } from 'chalk';
import { Command, flags } from '@oclif/command';

import { prune } from '../api';
import { CONFIG_FILENAME } from '../constants';
import { loadConfig, resolveConnections } from '..';
import { printLine, printError, printInfo } from '../util/io';
import OperationResult from '../domain/operation/OperationResult';
Expand All @@ -18,6 +19,11 @@ class Prune extends Command {
'connection-resolver': flags.string({
helpValue: 'PATH',
description: 'Path to the connection resolver.'
}),
config: flags.string({
char: 'c',
default: CONFIG_FILENAME,
description: 'Custom configuration file.'
})
};

Expand Down Expand Up @@ -51,7 +57,7 @@ class Prune extends Command {
async run(): Promise<void> {
const { flags: parsedFlags } = this.parse(Prune);
const isDryRun = parsedFlags['dry-run'];
const config = await loadConfig();
const config = await loadConfig(parsedFlags.config);
const connections = await resolveConnections(config, parsedFlags['connection-resolver']);

if (isDryRun) await printLine(magenta('\n• DRY RUN STARTED\n'));
Expand Down
8 changes: 7 additions & 1 deletion src/commands/synchronize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { bold, cyan, red, green, magenta } from 'chalk';

import { synchronize } from '../api';
import { getElapsedTime } from '../util/ts';
import { CONFIG_FILENAME } from '../constants';
import { log, dbLogger } from '../util/logger';
import { loadConfig, resolveConnections } from '../config';
import { printError, printLine, printInfo } from '../util/io';
Expand All @@ -25,6 +26,11 @@ class Synchronize extends Command {
'connection-resolver': flags.string({
helpValue: 'PATH',
description: 'Path to the connection resolver.'
}),
config: flags.string({
char: 'c',
default: CONFIG_FILENAME,
description: 'Custom configuration file.'
})
};

Expand Down Expand Up @@ -131,7 +137,7 @@ class Synchronize extends Command {
const isDryRun = parsedFlags['dry-run'];

try {
const config = await loadConfig();
const config = await loadConfig(parsedFlags.config);
const connections = await resolveConnections(config, parsedFlags['connection-resolver']);
const timeStart = process.hrtime();

Expand Down
4 changes: 2 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ export function getSqlBasePath(config: Configuration): string {
*
* @returns {Promise<Configuration>}
*/
export async function loadConfig(): Promise<Configuration> {
export async function loadConfig(configFilename: string = CONFIG_FILENAME): Promise<Configuration> {
log('Resolving config file.');

const filename = path.resolve(process.cwd(), CONFIG_FILENAME);
const filename = path.resolve(process.cwd(), configFilename);
samirsilwal marked this conversation as resolved.
Show resolved Hide resolved
const loadedConfig = (await yaml.load(filename)) as Configuration;

log('Resolved config file.');
Expand Down
59 changes: 59 additions & 0 deletions test/cli/commands/make-publish.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,63 @@ describe('CLI: make-publish', () => {
expect(createUp).to.equal('CREATE TABLE {{table}} (id INT PRIMARY KEY)');
expect(createDown).to.equal('DROP TABLE {{table}}');
});

it('should create respective stub files based on configuration from --config flag.', async () => {
samirsilwal marked this conversation as resolved.
Show resolved Hide resolved
// Write sync-db.yml file.
const cwd = await mkdtemp();
const stubPath = path.join(cwd, 'src/stub');
await mkdir(stubPath, { recursive: true });

const migrationPath1 = path.join(cwd, 'src/migration1');
await mkdir(migrationPath1, { recursive: true });

await write(
path.join(cwd, 'sync-db.yml'),
yaml.stringify({
migration: {
directory: 'migration',
sourceType: 'typescript'
}
} as Configuration)
);

await write(
path.join(cwd, 'sync-db-test.yml'),
yaml.stringify({
migration: {
directory: 'migration1',
sourceType: 'javascript'
}
} as Configuration)
);

const { stdout } = await runCli(['make-publish'], { cwd });

// Check the output.
expect(stdout).to.match(/src\/stub\/create_ts\.stub/);
expect(stdout).to.match(/src\/stub\/update_ts\.stub/);

// Check files are created.
const files = await glob(stubPath);
const createFileExists = await exists(path.join(stubPath, queryByPattern(files, /create_ts\.stub/)));
const updateFileExists = await exists(path.join(stubPath, queryByPattern(files, /update_ts\.stub/)));

expect(files.length).to.equal(2);
expect(createFileExists).to.equal(true);
expect(updateFileExists).to.equal(true);

const { stdout: stdout1 } = await runCli(['make-publish', '--config=sync-db-test.yml'], { cwd });

// Check the output.
expect(stdout1).to.match(/src\/stub\/create_js\.stub/);
expect(stdout1).to.match(/src\/stub\/update_js\.stub/);

// Check files are created.
const files1 = await glob(stubPath);
const createFileExists1 = await exists(path.join(stubPath, queryByPattern(files1, /create_ts\.stub/)));
const updateFileExists1 = await exists(path.join(stubPath, queryByPattern(files1, /update_ts\.stub/)));

expect(createFileExists1).to.equal(true);
expect(updateFileExists1).to.equal(true);
});
});
84 changes: 51 additions & 33 deletions test/cli/commands/make.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,39 +198,6 @@ describe('CLI: make', () => {
expect(migrationFile).to.equal(interpolate(fileOutput, { table: 'demo_users' }));
});

it('should create a migration file with template when name matches filename convention for typescript.', async () => {
// Write sync-db.yml file.
const cwd = await mkdtemp();
const migrationPath = path.join(cwd, 'src/migration');
await mkdir(migrationPath, { recursive: true });
await write(
path.join(cwd, 'sync-db.yml'),
yaml.stringify({
migration: {
directory: 'migration',
sourceType: 'typescript'
}
} as Configuration)
);

const { stdout } = await runCli(['make', 'create_demo_users_table'], { cwd });

// Check the output.
expect(stdout).to.match(/Created.+\d{13}_create_demo_users_table\.ts/);

// Check files are created.
const files = await glob(migrationPath);

expect(files.length).to.equal(1);

const migrationFile = await read(
path.join(migrationPath, queryByPattern(files, /\d{13}_create_demo_users_table\.ts/))
);
const fileOutput = await read(path.join(MIGRATION_TEMPLATE_PATH, 'create_ts.stub'));

expect(migrationFile).to.equal(interpolate(fileOutput, { table: 'demo_users' }));
});

it('should create a migration file with custom template for typescript.', async () => {
// Write sync-db.yml file.
const cwd = await mkdtemp();
Expand Down Expand Up @@ -334,4 +301,55 @@ describe('CLI: make', () => {
expect(upFile).to.equal(interpolate(upSQL, { table: 'settings' }));
expect(downFile).to.equal(interpolate(downSQL, { table: 'settings' }));
});

it('should make migration based on custom configurations with --config flag.', async () => {
samirsilwal marked this conversation as resolved.
Show resolved Hide resolved
samirsilwal marked this conversation as resolved.
Show resolved Hide resolved
// Write sync-db.yml file.
const cwd = await mkdtemp();

const migrationPath = path.join(cwd, 'src/migration');
await mkdir(migrationPath, { recursive: true });

const migrationPath1 = path.join(cwd, 'src/migration1');
await mkdir(migrationPath1, { recursive: true });

await write(
path.join(cwd, 'sync-db.yml'),
yaml.stringify({
migration: {
directory: 'migration'
}
} as Configuration)
);

await write(
path.join(cwd, 'sync-db-test.yml'),
yaml.stringify({
migration: {
directory: 'migration1',
sourceType: 'typescript'
}
} as Configuration)
);

const { stdout } = await runCli(['make', 'settings'], { cwd });

// Check the output.
expect(stdout).to.match(/Created.+\d{13}_settings\.up\.sql/);
expect(stdout).to.match(/Created.+\d{13}_settings\.down\.sql/);

// Check files are created.
const files = await glob(migrationPath);

expect(files.length).to.equal(2);

const { stdout: stdout1 } = await runCli(['make', 'settings', '--config=sync-db-test.yml'], { cwd });

// Check the output.
expect(stdout1).to.match(/Created.+\d{13}_settings\.ts/);

// Check files are created.
const files1 = await glob(migrationPath1);

expect(files1.length).to.equal(1);
});
});