Skip to content

Commit

Permalink
CLI: add --stub option to migration:make (#3316)
Browse files Browse the repository at this point in the history
  • Loading branch information
the-vampiire authored and kibertoad committed Jul 4, 2019
1 parent a0e9be5 commit 2b63332
Show file tree
Hide file tree
Showing 7 changed files with 464 additions and 214 deletions.
73 changes: 12 additions & 61 deletions bin/cli.js
Expand Up @@ -13,49 +13,15 @@ const cliPkg = require('../package');
const {
mkConfigObj,
resolveKnexFilePath,
resolveEnvironmentConfig,
exit,
success,
checkLocalModule,
getMigrationExtension,
getStubPath,
} = require('./utils/cli-config-utils');
const { DEFAULT_EXT } = require('./utils/constants');

function exit(text) {
if (text instanceof Error) {
console.error(
color.red(`${text.detail ? `${text.detail}\n` : ''}${text.stack}`)
);
} else {
console.error(color.red(text));
}
process.exit(1);
}

function success(text) {
console.log(text);
process.exit(0);
}

function checkLocalModule(env) {
if (!env.modulePath) {
console.log(
color.red('No local knex install found in:'),
color.magenta(tildify(env.cwd))
);
exit('Try running: npm install knex');
}
}

function getMigrationExtension(env, opts) {
const config = resolveEnvironmentConfig(opts, env.configuration);

let ext = DEFAULT_EXT;
if (argv.x) {
ext = argv.x;
} else if (config.migrations && config.migrations.extension) {
ext = config.migrations.extension;
} else if (config.ext) {
ext = config.ext;
}
return ext.toLowerCase();
}

function initKnex(env, opts) {
checkLocalModule(env);
if (process.cwd() !== env.cwd) {
Expand Down Expand Up @@ -102,26 +68,6 @@ function initKnex(env, opts) {
return knex(resolvedConfig);
}

function resolveEnvironmentConfig(opts, allConfigs) {
const environment = opts.env || process.env.NODE_ENV || 'development';
const result = allConfigs[environment] || allConfigs;

if (allConfigs[environment]) {
console.log('Using environment:', color.magenta(environment));
}

if (!result) {
console.log(color.red('Warning: unable to read knexfile config'));
process.exit(1);
}

if (argv.debug !== undefined) {
result.debug = argv.debug;
}

return result;
}

function invoke(env) {
env.modulePath = env.modulePath || env.knexpath || process.env.KNEX_PATH;

Expand Down Expand Up @@ -199,13 +145,18 @@ function invoke(env) {
`-x [${filetypes.join('|')}]`,
'Specify the stub extension (default js)'
)
.option(
`--stub [<relative/path/from/knexfile>|<name>]`,
'Specify the migration stub to use. If using <name> the file must be located in config.migrations.directory'
)
.action((name) => {
const opts = commander.opts();
opts.client = opts.client || 'sqlite3'; // We don't really care about client when creating migrations
const instance = initKnex(env, opts);
const ext = getMigrationExtension(env, opts);
const stub = getStubPath(env, opts);
pending = instance.migrate
.make(name, { extension: ext })
.make(name, { extension: ext, stub })
.then((name) => {
success(color.green(`Created Migration: ${name}`));
})
Expand Down
91 changes: 91 additions & 0 deletions bin/utils/cli-config-utils.js
@@ -1,6 +1,10 @@
const { DEFAULT_EXT, DEFAULT_TABLE_NAME } = require('./constants');
const { resolveClientNameWithAliases } = require('../../src/helpers');
const fs = require('fs');
const path = require('path');
const tildify = require('tildify');
const color = require('colorette');
const argv = require('getopts')(process.argv.slice(2));

function mkConfigObj(opts) {
if (!opts.client) {
Expand Down Expand Up @@ -55,7 +59,94 @@ function resolveDefaultKnexfilePath(extension) {
return process.cwd() + `/knexfile.${extension}`;
}

function resolveEnvironmentConfig(opts, allConfigs) {
const environment = opts.env || process.env.NODE_ENV || 'development';
const result = allConfigs[environment] || allConfigs;

if (allConfigs[environment]) {
console.log('Using environment:', color.magenta(environment));
}

if (!result) {
console.log(color.red('Warning: unable to read knexfile config'));
process.exit(1);
}

if (argv.debug !== undefined) {
result.debug = argv.debug;
}

return result;
}

function exit(text) {
if (text instanceof Error) {
console.error(
color.red(`${text.detail ? `${text.detail}\n` : ''}${text.stack}`)
);
} else {
console.error(color.red(text));
}
process.exit(1);
}

function success(text) {
console.log(text);
process.exit(0);
}

function checkLocalModule(env) {
if (!env.modulePath) {
console.log(
color.red('No local knex install found in:'),
color.magenta(tildify(env.cwd))
);
exit('Try running: npm install knex');
}
}

function getMigrationExtension(env, opts) {
const config = resolveEnvironmentConfig(opts, env.configuration);

let ext = DEFAULT_EXT;
if (argv.x) {
ext = argv.x;
} else if (config.migrations && config.migrations.extension) {
ext = config.migrations.extension;
} else if (config.ext) {
ext = config.ext;
}
return ext.toLowerCase();
}

function getStubPath(env, opts) {
const config = resolveEnvironmentConfig(opts, env.configuration);
const stubDirectory = config.migrations && config.migrations.directory;

const { stub } = argv;
if (!stub) {
return null;
} else if (stub.includes('/')) {
// relative path to stub
return stub;
}

// using stub <name> must have config.migrations.directory defined
if (!stubDirectory) {
console.log(color.red('Failed to load stub'), color.magenta(stub));
exit('config.migrations.directory in knexfile must be defined');
}

return path.join(stubDirectory, stub);
}

module.exports = {
mkConfigObj,
resolveKnexFilePath,
resolveEnvironmentConfig,
exit,
success,
checkLocalModule,
getMigrationExtension,
getStubPath,
};
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -54,7 +54,7 @@
"JSONStream": "^1.3.5",
"chai": "^4.2.0",
"chai-subset-in-order": "^2.1.3",
"cli-testlab": "^1.6.0",
"cli-testlab": "^1.7.0",
"coveralls": "^3.0.4",
"cross-env": "^5.2.0",
"dtslint": "^0.8.0",
Expand Down
56 changes: 56 additions & 0 deletions test/cli/cli-test-utils.js
@@ -0,0 +1,56 @@
'use strict';

const path = require('path');
const { FileTestHelper } = require('cli-testlab');

function migrationStubOptionSetup(fileHelper) {
const migrationGlobPath = 'test/jake-util/knexfile_migrations/*_somename.js';

fileHelper.registerGlobForCleanup(migrationGlobPath);
fileHelper.createFile(
process.cwd() + '/knexfile.js',
`
module.exports = {
development: {
client: 'sqlite3',
connection: {
filename: __dirname + '/test/jake-util/test.sqlite3',
},
migrations: {
directory: __dirname + '/test/jake-util/knexfile_migrations',
},
}
};
`,
{ isPathAbsolute: true }
);

return { migrationGlobPath };
}

function migrationMatchesStub(stubPath, migrationGlobPath, fileHelper) {
// accepts full or relative stub path
const relativeStubPath = stubPath.replace('test/jake-util/', '');
const stubContent = fileHelper.getFileTextContent(relativeStubPath);
const [migrationContent] = fileHelper.getFileGlobTextContent(
migrationGlobPath
);

return stubContent === migrationContent;
}

function setupFileHelper() {
const fileHelper = new FileTestHelper(
path.resolve(__dirname, '../jake-util')
);
fileHelper.deleteFile('test.sqlite3');
fileHelper.registerForCleanup('test.sqlite3');

return fileHelper;
}

module.exports = {
migrationStubOptionSetup,
migrationMatchesStub,
setupFileHelper,
};

0 comments on commit 2b63332

Please sign in to comment.