Skip to content

Commit

Permalink
CLI: adds support for asynchronous knexfile loading (#3748)
Browse files Browse the repository at this point in the history
(cherry picked from commit 41d02ba)
  • Loading branch information
flovilmart authored and kibertoad committed Apr 12, 2020
1 parent 7575946 commit efca605
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 15 deletions.
35 changes: 20 additions & 15 deletions bin/cli.js
Expand Up @@ -22,8 +22,11 @@ const { readFile, writeFile } = require('./../lib/util/fs');

const { listMigrations } = require('./utils/migrationsLister');

function openKnexfile(configPath) {
const config = require(configPath);
async function openKnexfile(configPath) {
let config = require(configPath);
if (typeof config === 'function') {
config = await config();
}

// FYI: By default, the extension for the migration files is inferred
// from the knexfile's extension. So, the following lines are in
Expand All @@ -33,7 +36,7 @@ function openKnexfile(configPath) {
return config;
}

function initKnex(env, opts) {
async function initKnex(env, opts) {
checkLocalModule(env);
if (process.cwd() !== env.cwd) {
process.chdir(env.cwd);
Expand All @@ -49,7 +52,7 @@ function initKnex(env, opts) {
}

env.configuration = env.configPath
? openKnexfile(env.configPath)
? await openKnexfile(env.configPath)
: mkConfigObj(opts);

const resolvedConfig = resolveEnvironmentConfig(opts, env.configuration);
Expand Down Expand Up @@ -138,10 +141,10 @@ function invoke(env) {
`--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) => {
.action(async (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 instance = await initKnex(env, opts);
const ext = getMigrationExtension(env, opts);
const configOverrides = { extension: ext };

Expand All @@ -164,7 +167,7 @@ function invoke(env) {
.option('--verbose', 'verbose')
.action(() => {
pending = initKnex(env, commander.opts())
.migrate.latest()
.then((instance) => instance.migrate.latest())
.then(([batchNo, log]) => {
if (log.length === 0) {
success(color.cyan('Already up to date'));
Expand All @@ -184,7 +187,7 @@ function invoke(env) {
)
.action((name) => {
pending = initKnex(env, commander.opts())
.migrate.up({ name })
.then((instance) => instance.migrate.up({ name }))
.then(([batchNo, log]) => {
if (log.length === 0) {
success(color.cyan('Already up to date'));
Expand All @@ -210,7 +213,7 @@ function invoke(env) {
const { all } = cmd;

pending = initKnex(env, commander.opts())
.migrate.rollback(null, all)
.then((instance) => instance.migrate.rollback(null, all))
.then(([batchNo, log]) => {
if (log.length === 0) {
success(color.cyan('Already at the base migration'));
Expand All @@ -231,7 +234,7 @@ function invoke(env) {
)
.action((name) => {
pending = initKnex(env, commander.opts())
.migrate.down({ name })
.then((instance) => instance.migrate.down({ name }))
.then(([batchNo, log]) => {
if (log.length === 0) {
success(color.cyan('Already at the base migration'));
Expand All @@ -253,7 +256,7 @@ function invoke(env) {
.description(' View the current version for the migration.')
.action(() => {
pending = initKnex(env, commander.opts())
.migrate.currentVersion()
.then((instance) => instance.migrate.currentVersion())
.then((version) => {
success(color.green('Current Version: ') + color.blue(version));
})
Expand All @@ -266,7 +269,9 @@ function invoke(env) {
.description(' List all migrations files with status.')
.action(() => {
pending = initKnex(env, commander.opts())
.migrate.list()
.then((instance) => {
return instance.migrate.list();
})
.then(([completed, newMigrations]) => {
listMigrations(completed, newMigrations);
})
Expand All @@ -284,10 +289,10 @@ function invoke(env) {
`--stub [<relative/path/from/knexfile>|<name>]`,
'Specify the seed stub to use. If using <name> the file must be located in config.seeds.directory'
)
.action((name) => {
.action(async (name) => {
const opts = commander.opts();
opts.client = opts.client || 'sqlite3'; // We don't really care about client when creating seeds
const instance = initKnex(env, opts);
const instance = await initKnex(env, opts);
const ext = getSeedExtension(env, opts);
const configOverrides = { extension: ext };
const stub = getStubPath('seeds', env, opts);
Expand All @@ -310,7 +315,7 @@ function invoke(env) {
.option('--specific', 'run specific seed file')
.action(() => {
pending = initKnex(env, commander.opts())
.seed.run({ specific: argv.specific })
.then((instance) => instance.seed.run({ specific: argv.specific }))
.then(([log]) => {
if (log.length === 0) {
success(color.cyan('No seed files exist'));
Expand Down
27 changes: 27 additions & 0 deletions test/cli/knexfile-test.spec.js
Expand Up @@ -65,6 +65,33 @@ module.exports = {
);
});

it('Run migrations with knexfile returning function passed', () => {
return execCommand(
`node ${KNEX} migrate:latest --knexfile=test/jake-util/knexfile/knexfile_func.js --knexpath=../knex.js`,
{
expectedOutput: 'Batch 1 run: 1 migrations',
}
);
});

it('Run migrations with knexfile with async passed', () => {
return execCommand(
`node ${KNEX} migrate:latest --knexfile=test/jake-util/knexfile/knexfile_async.js --knexpath=../knex.js`,
{
expectedOutput: 'Batch 1 run: 1 migrations',
}
);
});

it('Run migrations with knexfile with promise passed', () => {
return execCommand(
`node ${KNEX} migrate:latest --knexfile=test/jake-util/knexfile/knexfile_promise.js --knexpath=../knex.js`,
{
expectedOutput: 'Batch 1 run: 1 migrations',
}
);
});

it("changes the process's cwd to the directory that contains the knexfile", () => {
const knexfile = 'test/jake-util/knexfile-relative/knexfile.js';
const expectedCWD = tildify(path.resolve(path.dirname(knexfile)));
Expand Down
10 changes: 10 additions & 0 deletions test/cli/seed.spec.js
Expand Up @@ -20,6 +20,16 @@ describe('seed:run', () => {
);
});

it('supports async configuration', () => {
return execCommand(
`node ${KNEX} seed:run --knexfile=test/jake-util/seeds-knexfile-async.js`,
{
expectedOutput: 'Ran 2 seed files',
notExpectedOutput: ['first.js', 'second.js'],
}
);
});

it('prints verbose logs', () => {
return execCommand(
`node ${KNEX} seed:run --knexfile=test/jake-util/seeds-knexfile.js --verbose`,
Expand Down
12 changes: 12 additions & 0 deletions test/jake-util/knexfile/knexfile_async.js
@@ -0,0 +1,12 @@
module.exports = async () => ({
client: 'sqlite3',
connection: {
filename: __dirname + '/../test.sqlite3',
},
migrations: {
directory: __dirname + '/../knexfile_migrations',
},
seeds: {
directory: __dirname + '/../knexfile_seeds',
},
});
12 changes: 12 additions & 0 deletions test/jake-util/knexfile/knexfile_func.js
@@ -0,0 +1,12 @@
module.exports = () => ({
client: 'sqlite3',
connection: {
filename: __dirname + '/../test.sqlite3',
},
migrations: {
directory: __dirname + '/../knexfile_migrations',
},
seeds: {
directory: __dirname + '/../knexfile_seeds',
},
});
12 changes: 12 additions & 0 deletions test/jake-util/knexfile/knexfile_promise.js
@@ -0,0 +1,12 @@
module.exports = Promise.resolve({
client: 'sqlite3',
connection: {
filename: __dirname + '/../test.sqlite3',
},
migrations: {
directory: __dirname + '/../knexfile_migrations',
},
seeds: {
directory: __dirname + '/../knexfile_seeds',
},
});
9 changes: 9 additions & 0 deletions test/jake-util/seeds-knexfile-async.js
@@ -0,0 +1,9 @@
module.exports = async () => ({
client: 'sqlite3',
connection: {
filename: __dirname + '/../test.sqlite3',
},
seeds: {
directory: __dirname + '/seeds',
},
});

0 comments on commit efca605

Please sign in to comment.