2015-05-09 13:58:18 -04:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
|
|
|
|
|
var Liftoff = require('liftoff');
|
|
|
|
var Promise = require('bluebird');
|
|
|
|
var interpret = require('interpret');
|
|
|
|
var path = require('path');
|
|
|
|
var chalk = require('chalk');
|
|
|
|
var tildify = require('tildify');
|
|
|
|
var commander = require('commander');
|
|
|
|
var cliPkg = require('../../package');
|
|
|
|
var argv = require('minimist')(process.argv.slice(2));
|
|
|
|
var fs = Promise.promisifyAll(require('fs'));
|
|
|
|
|
|
|
|
function exit(text) {
|
|
|
|
if (text instanceof Error) {
|
|
|
|
chalk.red(console.error(text.stack));
|
|
|
|
} else {
|
|
|
|
chalk.red(console.error(text));
|
|
|
|
}
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
function success(text) {
|
|
|
|
console.log(text);
|
|
|
|
process.exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
function checkLocalModule(env) {
|
|
|
|
if (!env.modulePath) {
|
|
|
|
console.log(chalk.red('No local knex install found in:'), chalk.magenta(tildify(env.cwd)));
|
|
|
|
exit('Try running: npm install knex.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function initKnex(env) {
|
|
|
|
|
|
|
|
checkLocalModule(env);
|
|
|
|
|
|
|
|
if (!env.configPath) {
|
|
|
|
exit('No knexfile found in this directory. Specify a path with --knexfile');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process.cwd() !== env.cwd) {
|
|
|
|
process.chdir(env.cwd);
|
|
|
|
console.log('Working directory changed to', chalk.magenta(tildify(env.cwd)));
|
|
|
|
}
|
|
|
|
|
|
|
|
var environment = commander.env || process.env.NODE_ENV;
|
|
|
|
var defaultEnv = 'development';
|
|
|
|
var config = require(env.configPath);
|
2015-07-28 02:06:24 -05:00
|
|
|
|
2015-05-09 13:58:18 -04:00
|
|
|
if (!environment && typeof config[defaultEnv] === 'object') {
|
|
|
|
environment = defaultEnv;
|
|
|
|
}
|
2015-12-17 10:57:11 -06:00
|
|
|
|
2015-05-09 13:58:18 -04:00
|
|
|
if (environment) {
|
|
|
|
console.log('Using environment:', chalk.magenta(environment));
|
2015-12-17 10:57:11 -06:00
|
|
|
config = config[environment] || config;
|
2015-05-09 13:58:18 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!config) {
|
|
|
|
console.log(chalk.red('Warning: unable to read knexfile config'));
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argv.debug !== undefined)
|
|
|
|
config.debug = argv.debug;
|
|
|
|
var knex = require(env.modulePath);
|
|
|
|
return knex(config);
|
|
|
|
}
|
|
|
|
|
|
|
|
function invoke(env) {
|
|
|
|
|
2015-07-28 02:06:24 -05:00
|
|
|
var pending, filetypes = ['js', 'coffee', 'eg', 'ls'];
|
2015-05-09 13:58:18 -04:00
|
|
|
|
|
|
|
commander
|
|
|
|
.version(
|
|
|
|
chalk.blue('Knex CLI version: ', chalk.green(cliPkg.version)) + '\n' +
|
|
|
|
chalk.blue('Local Knex version: ', chalk.green(env.modulePackage.version)) + '\n'
|
|
|
|
)
|
|
|
|
.option('--debug', 'Run with debugging.')
|
|
|
|
.option('--knexfile [path]', 'Specify the knexfile path.')
|
|
|
|
.option('--cwd [path]', 'Specify the working directory.')
|
|
|
|
.option('--env [name]', 'environment, default: process.env.NODE_ENV || development');
|
|
|
|
|
|
|
|
|
|
|
|
commander
|
|
|
|
.command('init')
|
|
|
|
.description(' Create a fresh knexfile.')
|
|
|
|
.option('-x [' + filetypes.join('|') + ']', 'Specify the knexfile extension (default js)')
|
|
|
|
.action(function() {
|
|
|
|
var type = (argv.x || 'js').toLowerCase();
|
|
|
|
if (filetypes.indexOf(type) === -1) {
|
|
|
|
exit('Invalid filetype specified: ' + type);
|
|
|
|
}
|
|
|
|
if (env.configPath) {
|
|
|
|
exit('Error: ' + env.configPath + ' already exists');
|
|
|
|
}
|
|
|
|
checkLocalModule(env);
|
|
|
|
var stubPath = './knexfile.' + type;
|
|
|
|
pending = fs.readFileAsync(path.dirname(env.modulePath) + '/lib/migrate/stub/knexfile-' + type + '.stub')
|
|
|
|
.then(function(code) {
|
|
|
|
return fs.writeFileAsync(stubPath, code);
|
|
|
|
}).then(function() {
|
|
|
|
success(chalk.green('Created ' + stubPath));
|
|
|
|
}).catch(exit);
|
|
|
|
});
|
|
|
|
|
|
|
|
commander
|
|
|
|
.command('migrate:make <name>')
|
|
|
|
.description(' Create a named migration file.')
|
|
|
|
.option('-x [' + filetypes.join('|') + ']', 'Specify the stub extension (default js)')
|
|
|
|
.action(function(name) {
|
|
|
|
var ext = (argv.x || env.configPath.split('.').pop()).toLowerCase();
|
|
|
|
pending = initKnex(env).migrate.make(name, {extension: ext}).then(function(name) {
|
|
|
|
success(chalk.green('Created Migration: ' + name));
|
|
|
|
}).catch(exit);
|
|
|
|
});
|
|
|
|
|
|
|
|
commander
|
|
|
|
.command('migrate:latest')
|
|
|
|
.description(' Run all migrations that have not yet been run.')
|
|
|
|
.action(function() {
|
|
|
|
pending = initKnex(env).migrate.latest().spread(function(batchNo, log) {
|
|
|
|
if (log.length === 0) {
|
|
|
|
success(chalk.cyan('Already up to date'));
|
|
|
|
}
|
|
|
|
success(chalk.green('Batch ' + batchNo + ' run: ' + log.length + ' migrations \n' + chalk.cyan(log.join('\n'))));
|
|
|
|
}).catch(exit);
|
|
|
|
});
|
|
|
|
|
|
|
|
commander
|
|
|
|
.command('migrate:rollback')
|
|
|
|
.description(' Rollback the last set of migrations performed.')
|
|
|
|
.action(function() {
|
|
|
|
pending = initKnex(env).migrate.rollback().spread(function(batchNo, log) {
|
|
|
|
if (log.length === 0) {
|
|
|
|
success(chalk.cyan('Already at the base migration'));
|
|
|
|
}
|
|
|
|
success(chalk.green('Batch ' + batchNo + ' rolled back: ' + log.length + ' migrations \n') + chalk.cyan(log.join('\n')));
|
|
|
|
}).catch(exit);
|
|
|
|
});
|
|
|
|
|
|
|
|
commander
|
|
|
|
.command('migrate:currentVersion')
|
|
|
|
.description(' View the current version for the migration.')
|
|
|
|
.action(function () {
|
|
|
|
pending = initKnex(env).migrate.currentVersion().then(function(version) {
|
|
|
|
success(chalk.green('Current Version: ') + chalk.blue(version));
|
|
|
|
}).catch(exit);
|
|
|
|
});
|
|
|
|
|
|
|
|
commander
|
|
|
|
.command('seed:make <name>')
|
|
|
|
.description(' Create a named seed file.')
|
|
|
|
.option('-x [' + filetypes.join('|') + ']', 'Specify the stub extension (default js)')
|
|
|
|
.action(function(name) {
|
|
|
|
var ext = (argv.x || env.configPath.split('.').pop()).toLowerCase();
|
|
|
|
pending = initKnex(env).seed.make(name, {extension: ext}).then(function(name) {
|
|
|
|
success(chalk.green('Created seed file: ' + name));
|
|
|
|
}).catch(exit);
|
|
|
|
});
|
|
|
|
|
|
|
|
commander
|
|
|
|
.command('seed:run')
|
|
|
|
.description(' Run seed files.')
|
|
|
|
.action(function() {
|
|
|
|
pending = initKnex(env).seed.run().spread(function(log) {
|
|
|
|
if (log.length === 0) {
|
|
|
|
success(chalk.cyan('No seed files exist'));
|
|
|
|
}
|
|
|
|
success(chalk.green('Ran ' + log.length + ' seed files \n' + chalk.cyan(log.join('\n'))));
|
|
|
|
}).catch(exit);
|
|
|
|
});
|
|
|
|
|
|
|
|
commander.parse(process.argv);
|
|
|
|
|
|
|
|
Promise.resolve(pending).then(function() {
|
|
|
|
commander.help();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
var cli = new Liftoff({
|
|
|
|
name: 'knex',
|
|
|
|
extensions: interpret.jsVariants,
|
|
|
|
v8flags: require('v8flags')
|
|
|
|
});
|
|
|
|
|
|
|
|
cli.on('require', function(name) {
|
|
|
|
console.log('Requiring external module', chalk.magenta(name));
|
|
|
|
});
|
|
|
|
|
|
|
|
cli.on('requireFail', function(name) {
|
|
|
|
console.log(chalk.red('Failed to load external module'), chalk.magenta(name));
|
|
|
|
});
|
|
|
|
|
|
|
|
cli.launch({
|
|
|
|
cwd: argv.cwd,
|
|
|
|
configPath: argv.knexfile,
|
|
|
|
require: argv.require,
|
|
|
|
completion: argv.completion
|
|
|
|
}, invoke);
|