From 96033d09644376528cf4a1de3ca765b79ac33dc9 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Mon, 23 Mar 2020 15:34:57 -0400 Subject: [PATCH 1/2] adds support for asynchronous knexfile loading --- bin/cli.js | 39 ++++++++++++--------- test/cli/knexfile-test.spec.js | 27 ++++++++++++++ test/jake-util/knexfile/knexfile_async.js | 12 +++++++ test/jake-util/knexfile/knexfile_func.js | 12 +++++++ test/jake-util/knexfile/knexfile_promise.js | 12 +++++++ 5 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 test/jake-util/knexfile/knexfile_async.js create mode 100644 test/jake-util/knexfile/knexfile_func.js create mode 100644 test/jake-util/knexfile/knexfile_promise.js diff --git a/bin/cli.js b/bin/cli.js index 771425c6c0..17508c2e29 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -28,9 +28,14 @@ const fsPromised = { writeFile: promisify(fs.writeFile), }; -function openKnexfile(configPath) { - const config = require(configPath); - +async function openKnexfile(configPath) { + let config = require(configPath); + if (typeof config === 'function') { + config = config(); + } + if (config instanceof Promise) { + 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 // place for backwards compatibility purposes. @@ -39,7 +44,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); @@ -55,7 +60,7 @@ function initKnex(env, opts) { } env.configuration = env.configPath - ? openKnexfile(env.configPath) + ? await openKnexfile(env.configPath) : mkConfigObj(opts); const resolvedConfig = resolveEnvironmentConfig(opts, env.configuration); @@ -145,10 +150,10 @@ function invoke(env) { `--stub [|]`, 'Specify the migration stub to use. If using 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 }; @@ -171,7 +176,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')); @@ -191,7 +196,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')); @@ -217,7 +222,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')); @@ -238,7 +243,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')); @@ -260,7 +265,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)); }) @@ -273,7 +278,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); }) @@ -291,10 +298,10 @@ function invoke(env) { `--stub [|]`, 'Specify the seed stub to use. If using 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); @@ -317,7 +324,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')); diff --git a/test/cli/knexfile-test.spec.js b/test/cli/knexfile-test.spec.js index 159e94d088..cd8b48c126 100644 --- a/test/cli/knexfile-test.spec.js +++ b/test/cli/knexfile-test.spec.js @@ -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))); diff --git a/test/jake-util/knexfile/knexfile_async.js b/test/jake-util/knexfile/knexfile_async.js new file mode 100644 index 0000000000..a4481b03be --- /dev/null +++ b/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', + }, +}); diff --git a/test/jake-util/knexfile/knexfile_func.js b/test/jake-util/knexfile/knexfile_func.js new file mode 100644 index 0000000000..14bd1d3379 --- /dev/null +++ b/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', + }, +}); diff --git a/test/jake-util/knexfile/knexfile_promise.js b/test/jake-util/knexfile/knexfile_promise.js new file mode 100644 index 0000000000..36c7314f67 --- /dev/null +++ b/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', + }, +}); From 2517ca257d5ed0fdd264f9ffa9e493c7ea215da4 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Mon, 23 Mar 2020 16:27:13 -0400 Subject: [PATCH 2/2] adds tests for seeder --- bin/cli.js | 6 ++---- test/cli/seed.spec.js | 10 ++++++++++ test/jake-util/seeds-knexfile-async.js | 9 +++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 test/jake-util/seeds-knexfile-async.js diff --git a/bin/cli.js b/bin/cli.js index 17508c2e29..5b595d3d04 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -31,11 +31,9 @@ const fsPromised = { async function openKnexfile(configPath) { let config = require(configPath); if (typeof config === 'function') { - config = config(); - } - if (config instanceof Promise) { - config = await config; + 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 // place for backwards compatibility purposes. diff --git a/test/cli/seed.spec.js b/test/cli/seed.spec.js index cd8ea63c7e..dd46c03365 100644 --- a/test/cli/seed.spec.js +++ b/test/cli/seed.spec.js @@ -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`, diff --git a/test/jake-util/seeds-knexfile-async.js b/test/jake-util/seeds-knexfile-async.js new file mode 100644 index 0000000000..a104ac53a2 --- /dev/null +++ b/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', + }, +});