From 66c47e3db8d8e967d7e39a65491b69dcdae7a1dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20O=2E=20=C2=ABTordek=C2=BB=20Freschi=60?= Date: Fri, 20 Sep 2024 10:29:05 -0300 Subject: [PATCH 1/3] Add redis devDependency for testing, testing note --- examples/cli/migrations/db.js | 2 +- package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/cli/migrations/db.js b/examples/cli/migrations/db.js index 159c435..ebf7671 100644 --- a/examples/cli/migrations/db.js +++ b/examples/cli/migrations/db.js @@ -1,6 +1,6 @@ // bad example, but you get the point ;) -// $ npm install redis +// $ npm install redis@3.0.0 // $ redis-server const redis = require('redis') diff --git a/package.json b/package.json index 6c2d2cd..4508fbf 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ }, "devDependencies": { "mocha": "^10.2.0", + "redis": "^3.0.0", "rimraf": "^5.0.1", "standard": "^17.0.0" }, From 68886b239800edba162945b717a5b10a5e52a6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20O=2E=20=C2=ABTordek=C2=BB=20Freschi=60?= Date: Fri, 20 Sep 2024 10:30:44 -0300 Subject: [PATCH 2/3] Add support for multiple .env files Updated `commander` version Changed to new `Command` module Use `opts` instead of `program` Slight reorganization in `create` due to ordering. Add test for multiple envs --- bin/migrate | 3 ++- bin/migrate-create | 52 +++++++++++++++++++------------------ bin/migrate-down | 28 ++++++++++---------- bin/migrate-init | 22 +++++++++------- bin/migrate-list | 30 +++++++++++---------- bin/migrate-up | 37 +++++++++++++------------- package.json | 2 +- test/fixtures/env/env.local | 1 + test/integration.js | 14 ++++++++++ 9 files changed, 107 insertions(+), 82 deletions(-) create mode 100644 test/fixtures/env/env.local diff --git a/bin/migrate b/bin/migrate index 11d2490..e366686 100755 --- a/bin/migrate +++ b/bin/migrate @@ -2,9 +2,10 @@ // vim: set ft=javascript: 'use strict' -const program = require('commander') +const { Command } = require('commander') const pkg = require('../package.json') +const program = new Command() program .version(pkg.version) .command('init', 'Initalize the migrations tool in a project') diff --git a/bin/migrate-create b/bin/migrate-create index f9e5db2..80def37 100755 --- a/bin/migrate-create +++ b/bin/migrate-create @@ -2,13 +2,14 @@ // vim: set ft=javascript: 'use strict' -const program = require('commander') +const { Command } = require('commander') const path = require('path') const dotenv = require('dotenv') const log = require('../lib/log') const registerCompiler = require('../lib/register-compiler') const pkg = require('../package.json') +const program = new Command() program .version(pkg.version) .option('-c, --chdir [dir]', 'Change the working directory', process.cwd()) @@ -19,52 +20,53 @@ program .option('-e, --extension [extension]', 'Use the given extension to create the file') .option('--extention [extension]', '. Use the given extension to create the file. Deprecated as of v1.2. Replace with -e or --extension.') .option('-g, --generator ', 'A template generator function', path.join(__dirname, '..', 'lib', 'template-generator')) - .option('--env [name]', 'Use dotenv to load an environment file') + .option('--env [name...]', 'Use dotenv to load an environment file') .arguments('') .action(create) .parse(process.argv) -if (program.extention) { - console.log('create', '"--extention" argument is deprecated. Use "--extension" instead') -} - -// Setup environment -if (program.env) { - const e = dotenv.config({ - path: typeof program.env === 'string' ? program.env : '.env' - }) - if (e && e.error instanceof Error) { - throw e.error - } -} - // eslint-disable-next-line no-var var _name function create (name) { + const opts = program.opts() + + if (opts.extention) { + console.log('create', '"--extention" argument is deprecated. Use "--extension" instead') + } + + // Setup environment + if (opts.env) { + const e = dotenv.config({ + path: opts.env + }) + if (e && e.error instanceof Error) { + throw e.error + } + } // Name provided? _name = name // Change the working dir - process.chdir(program.chdir) + process.chdir(opts.chdir) // Load compiler - if (program.compiler) { - registerCompiler(program.compiler) + if (opts.compiler) { + registerCompiler(opts.compiler) } // Load the template generator let gen try { - gen = require(program.generator) + gen = require(opts.generator) } catch (e) { - gen = require(path.resolve(program.generator)) + gen = require(path.resolve(opts.generator)) } gen({ name, - dateFormat: program.dateFormat, - templateFile: program.templateFile, - migrationsDirectory: program.migrationsDir, - extension: program.extension || path.extname(program.templateFile) + dateFormat: opts.dateFormat, + templateFile: opts.templateFile, + migrationsDirectory: opts.migrationsDir, + extension: opts.extension || path.extname(opts.templateFile) }, function (err, p) { if (err) { log.error('Template generation error', err.message) diff --git a/bin/migrate-down b/bin/migrate-down index b64bbd4..19e5630 100755 --- a/bin/migrate-down +++ b/bin/migrate-down @@ -2,7 +2,7 @@ // vim: set ft=javascript: 'use strict' -const program = require('commander') +const { Command } = require('commander') const path = require('path') const minimatch = require('minimatch') const dotenv = require('dotenv') @@ -12,6 +12,7 @@ const log = require('../lib/log') const registerCompiler = require('../lib/register-compiler') const pkg = require('../package.json') +const program = new Command() program .version(pkg.version) .usage('[options] ') @@ -21,17 +22,18 @@ program .option('--migrations-dir ', 'Change the migrations directory name', 'migrations') .option('--matches ', 'A glob pattern to filter migration files', '*') .option('--compiler ', 'Use the given module to compile files') - .option('--env [name]', 'Use dotenv to load an environment file') + .option('--env [name...]', 'Use dotenv to load an environment file') .option('-F, --force', 'Force through the command, ignoring warnings') .parse(process.argv) +const opts = program.opts() // Change the working dir -process.chdir(program.chdir) +process.chdir(opts.chdir) // Setup environment -if (program.env) { +if (opts.env) { const e = dotenv.config({ - path: typeof program.env === 'string' ? program.env : '.env' + path: opts.env }) if (e && e.error instanceof Error) { throw e.error @@ -39,23 +41,23 @@ if (program.env) { } // Load compiler -if (program.compiler) { - registerCompiler(program.compiler) +if (opts.compiler) { + registerCompiler(opts.compiler) } // Setup store -if (program.store[0] === '.') program.store = path.join(process.cwd(), program.store) +if (opts.store[0] === '.') opts.store = path.join(process.cwd(), opts.store) -const StoreImport = require(program.store) +const StoreImport = require(opts.store) const Store = StoreImport.default || StoreImport -const store = new Store(program.stateFile) +const store = new Store(opts.stateFile) // Load in migrations migrate.load({ stateStore: store, - migrationsDirectory: program.migrationsDir, - filterFunction: minimatch.filter(program.matches), - ignoreMissing: program.force + migrationsDirectory: opts.migrationsDir, + filterFunction: minimatch.filter(opts.matches), + ignoreMissing: opts.force }, function (err, set) { if (err) { log.error('error', err) diff --git a/bin/migrate-init b/bin/migrate-init index 6d6bfcb..a9c366e 100755 --- a/bin/migrate-init +++ b/bin/migrate-init @@ -2,7 +2,7 @@ // vim: set ft=javascript: 'use strict' -const program = require('commander') +const { Command } = require('commander') const mkdirp = require('mkdirp') const dotenv = require('dotenv') const path = require('path') @@ -10,6 +10,7 @@ const log = require('../lib/log') const pkg = require('../package.json') const registerCompiler = require('../lib/register-compiler') +const program = new Command() program .version(pkg.version) .option('-f, --state-file ', 'Set path to state file', '.migrate') @@ -19,14 +20,15 @@ program .option('-c, --chdir [dir]', 'Change the working directory', process.cwd()) .option('--env [name]', 'Use dotenv to load an environment file') .parse(process.argv) +const opts = program.opts() // Change the working dir -process.chdir(program.chdir) +process.chdir(opts.chdir) // Setup environment -if (program.env) { +if (opts.env) { const e = dotenv.config({ - path: typeof program.env === 'string' ? program.env : '.env' + path: opts.env }) if (e && e.error instanceof Error) { throw e.error @@ -34,19 +36,19 @@ if (program.env) { } // Load compiler -if (program.compiler) { - registerCompiler(program.compiler) +if (opts.compiler) { + registerCompiler(opts.compiler) } // Setup store -if (program.store[0] === '.') program.store = path.join(process.cwd(), program.store) +if (opts.store[0] === '.') opts.store = path.join(process.cwd(), opts.store) -const StoreImport = require(program.store) +const StoreImport = require(opts.store) const Store = StoreImport.default || StoreImport -const store = new Store(program.stateFile) +const store = new Store(opts.stateFile) // Create migrations dir path -const p = path.resolve(process.cwd(), program.migrationsDir) +const p = path.resolve(process.cwd(), opts.migrationsDir) log('migrations dir', p) mkdirp.sync(p) diff --git a/bin/migrate-list b/bin/migrate-list index d25b3b1..ed2ad6c 100755 --- a/bin/migrate-list +++ b/bin/migrate-list @@ -2,7 +2,7 @@ // vim: set ft=javascript: 'use strict' -const program = require('commander') +const { Command } = require('commander') const path = require('path') const dateFormat = require('dateformat') const minimatch = require('minimatch') @@ -12,6 +12,7 @@ const log = require('../lib/log') const registerCompiler = require('../lib/register-compiler') const pkg = require('../package.json') +const program = new Command() program .version(pkg.version) .usage('[options] ') @@ -22,22 +23,23 @@ program .option('--migrations-dir ', 'Change the migrations directory name', 'migrations') .option('--matches ', 'A glob pattern to filter migration files', '*') .option('--compiler ', 'Use the given module to compile files') - .option('--env [name]', 'Use dotenv to load an environment file') + .option('--env [name...]', 'Use dotenv to load an environment file') .parse(process.argv) +const opts = program.opts() // Check clean flag, exit if NODE_ENV === 'production' and force not specified -if (program.clean && process.env.NODE_ENV === 'production' && !program.force) { +if (opts.clean && process.env.NODE_ENV === 'production' && !opts.force) { log.error('error', 'Cowardly refusing to clean while node environment set to production, use --force to continue.') process.exit(1) } // Change the working dir -process.chdir(program.chdir) +process.chdir(opts.chdir) // Setup environment -if (program.env) { +if (opts.env) { const e = dotenv.config({ - path: typeof program.env === 'string' ? program.env : '.env' + path: opts.env }) if (e && e.error instanceof Error) { throw e.error @@ -45,22 +47,22 @@ if (program.env) { } // Load compiler -if (program.compiler) { - registerCompiler(program.compiler) +if (opts.compiler) { + registerCompiler(opts.compiler) } // Setup store -if (program.store[0] === '.') program.store = path.join(process.cwd(), program.store) +if (opts.store[0] === '.') opts.store = path.join(process.cwd(), opts.store) -const StoreImport = require(program.store) +const StoreImport = require(opts.store) const Store = StoreImport.default || StoreImport -const store = new Store(program.stateFile) +const store = new Store(opts.stateFile) // Load in migrations migrate.load({ stateStore: store, - migrationsDirectory: program.migrationsDir, - filterFunction: minimatch.filter(program.matches) + migrationsDirectory: opts.migrationsDir, + filterFunction: minimatch.filter(opts.matches) }, function (err, set) { if (err) { log.error('error', err) @@ -72,7 +74,7 @@ migrate.load({ } set.migrations.forEach(function (migration) { - log(migration.title + (migration.timestamp ? ' [' + dateFormat(migration.timestamp, program.dateFormat) + ']' : ' [not run]'), migration.description || '') + log(migration.title + (migration.timestamp ? ' [' + dateFormat(migration.timestamp, opts.dateFormat) + ']' : ' [not run]'), migration.description || '') }) process.exit(0) diff --git a/bin/migrate-up b/bin/migrate-up index 34549ed..5373c17 100755 --- a/bin/migrate-up +++ b/bin/migrate-up @@ -2,7 +2,7 @@ // vim: set ft=javascript: 'use strict' -const program = require('commander') +const { Command } = require('commander') const path = require('path') const minimatch = require('minimatch') const dotenv = require('dotenv') @@ -12,6 +12,7 @@ const log = require('../lib/log') const registerCompiler = require('../lib/register-compiler') const pkg = require('../package.json') +const program = new Command() program .version(pkg.version) .usage('[options] ') @@ -24,16 +25,16 @@ program .option('--migrations-dir ', 'Change the migrations directory name', 'migrations') .option('--matches ', 'A glob pattern to filter migration files', '*') .option('--compiler ', 'Use the given module to compile files') - .option('--env [name]', 'Use dotenv to load an environment file') + .option('--env [name...]', 'Use dotenv to load an environment file') .parse(process.argv) +const opts = program.opts() // Change the working dir -process.chdir(program.chdir) - +process.chdir(opts.chdir) // Setup environment -if (program.env) { +if (opts.env) { const e = dotenv.config({ - path: typeof program.env === 'string' ? program.env : '.env' + path: opts.env }) if (e && e.error instanceof Error) { throw e.error @@ -41,31 +42,31 @@ if (program.env) { } // Check clean flag, exit if NODE_ENV === 'production' and force not specified -if (program.clean && process.env.NODE_ENV === 'production' && !program.force) { +if (opts.clean && process.env.NODE_ENV === 'production' && !opts.force) { log.error('error', 'Cowardly refusing to clean while node environment set to production, use --force to continue.') process.exit(1) } // Check init flag, exit if NODE_ENV === 'production' and force not specified -if (program.init && process.env.NODE_ENV === 'production' && !program.force) { +if (opts.init && process.env.NODE_ENV === 'production' && !opts.force) { log.error('error', 'Cowardly refusing to init while node environment set to production, use --force to continue.') process.exit(1) } // Load compiler -if (program.compiler) { - registerCompiler(program.compiler) +if (opts.compiler) { + registerCompiler(opts.compiler) } // Setup store -if (program.store[0] === '.') program.store = path.join(process.cwd(), program.store) +if (opts.store[0] === '.') opts.store = path.join(process.cwd(), opts.store) -const StoreImport = require(program.store) +const StoreImport = require(opts.store) const Store = StoreImport.default || StoreImport -const store = new Store(program.stateFile) +const store = new Store(opts.stateFile) // Call store init -if (program.init && typeof store.init === 'function') { +if (opts.init && typeof store.init === 'function') { store.init(function (err) { if (err) return log.error(err) loadAndGo() @@ -78,9 +79,9 @@ if (program.init && typeof store.init === 'function') { function loadAndGo () { migrate.load({ stateStore: store, - migrationsDirectory: program.migrationsDir, - filterFunction: minimatch.filter(program.matches), - ignoreMissing: program.force + migrationsDirectory: opts.migrationsDir, + filterFunction: minimatch.filter(opts.matches), + ignoreMissing: opts.force }, function (err, set) { if (err) { log.error('error', err) @@ -96,7 +97,7 @@ function loadAndGo () { }) // Run - ;(program.clean ? cleanUp : up)(set, function (err) { + ;(opts.clean ? cleanUp : up)(set, function (err) { if (err) { log.error('error', err) process.exit(1) diff --git a/package.json b/package.json index 4508fbf..cd540b0 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "license": "MIT", "dependencies": { "chalk": "^4.1.2", - "commander": "^2.20.3", + "commander": "^12.1.0", "dateformat": "^4.6.3", "dotenv": "^16.0.0", "inherits": "^2.0.3", diff --git a/test/fixtures/env/env.local b/test/fixtures/env/env.local new file mode 100644 index 0000000..261e521 --- /dev/null +++ b/test/fixtures/env/env.local @@ -0,0 +1 @@ +DB=pets2 diff --git a/test/integration.js b/test/integration.js index f0d0bf0..67b6beb 100644 --- a/test/integration.js +++ b/test/integration.js @@ -153,4 +153,18 @@ describe('integration tests', function () { }) }) }) + + it('should support multiple --env parameters', function (done) { + run.up(ENV_DIR, ['--env', 'env', 'env.local'], function (err, out, code) { + assert(!err) + assert.strictEqual(code, 0) + assert(out.indexOf('error') === -1) + run.down(ENV_DIR, ['--env', 'env', 'env.local'], function (err, out, code) { + assert(!err) + assert.strictEqual(code, 0) + assert(out.indexOf('error') === -1) + done() + }) + }) + }) }) From 8bc316dd8a1bcf490462c7551e23004957576ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20O=2E=20=C2=ABTordek=C2=BB=20Freschi?= Date: Thu, 16 Jan 2025 19:08:50 -0300 Subject: [PATCH 3/3] Disable variadic env flag --- bin/migrate-create | 4 ++-- bin/migrate-down | 4 ++-- bin/migrate-init | 2 +- bin/migrate-list | 4 ++-- bin/migrate-up | 4 ++-- test/fixtures/env/env.local | 1 - test/integration.js | 14 -------------- 7 files changed, 9 insertions(+), 24 deletions(-) delete mode 100644 test/fixtures/env/env.local diff --git a/bin/migrate-create b/bin/migrate-create index 80def37..4c9406e 100755 --- a/bin/migrate-create +++ b/bin/migrate-create @@ -20,7 +20,7 @@ program .option('-e, --extension [extension]', 'Use the given extension to create the file') .option('--extention [extension]', '. Use the given extension to create the file. Deprecated as of v1.2. Replace with -e or --extension.') .option('-g, --generator ', 'A template generator function', path.join(__dirname, '..', 'lib', 'template-generator')) - .option('--env [name...]', 'Use dotenv to load an environment file') + .option('--env [name]', 'Use dotenv to load an environment file') .arguments('') .action(create) .parse(process.argv) @@ -37,7 +37,7 @@ function create (name) { // Setup environment if (opts.env) { const e = dotenv.config({ - path: opts.env + path: typeof opts.env === 'string' ? opts.env : '.env' }) if (e && e.error instanceof Error) { throw e.error diff --git a/bin/migrate-down b/bin/migrate-down index 19e5630..c0cd4fe 100755 --- a/bin/migrate-down +++ b/bin/migrate-down @@ -22,7 +22,7 @@ program .option('--migrations-dir ', 'Change the migrations directory name', 'migrations') .option('--matches ', 'A glob pattern to filter migration files', '*') .option('--compiler ', 'Use the given module to compile files') - .option('--env [name...]', 'Use dotenv to load an environment file') + .option('--env [name]', 'Use dotenv to load an environment file') .option('-F, --force', 'Force through the command, ignoring warnings') .parse(process.argv) const opts = program.opts() @@ -33,7 +33,7 @@ process.chdir(opts.chdir) // Setup environment if (opts.env) { const e = dotenv.config({ - path: opts.env + path: typeof opts.env === 'string' ? opts.env : '.env' }) if (e && e.error instanceof Error) { throw e.error diff --git a/bin/migrate-init b/bin/migrate-init index a9c366e..e1a551d 100755 --- a/bin/migrate-init +++ b/bin/migrate-init @@ -28,7 +28,7 @@ process.chdir(opts.chdir) // Setup environment if (opts.env) { const e = dotenv.config({ - path: opts.env + path: typeof opts.env === 'string' ? opts.env : '.env' }) if (e && e.error instanceof Error) { throw e.error diff --git a/bin/migrate-list b/bin/migrate-list index ed2ad6c..52421a2 100755 --- a/bin/migrate-list +++ b/bin/migrate-list @@ -23,7 +23,7 @@ program .option('--migrations-dir ', 'Change the migrations directory name', 'migrations') .option('--matches ', 'A glob pattern to filter migration files', '*') .option('--compiler ', 'Use the given module to compile files') - .option('--env [name...]', 'Use dotenv to load an environment file') + .option('--env [name]', 'Use dotenv to load an environment file') .parse(process.argv) const opts = program.opts() @@ -39,7 +39,7 @@ process.chdir(opts.chdir) // Setup environment if (opts.env) { const e = dotenv.config({ - path: opts.env + path: typeof opts.env === 'string' ? opts.env : '.env' }) if (e && e.error instanceof Error) { throw e.error diff --git a/bin/migrate-up b/bin/migrate-up index 5373c17..fc29f08 100755 --- a/bin/migrate-up +++ b/bin/migrate-up @@ -25,7 +25,7 @@ program .option('--migrations-dir ', 'Change the migrations directory name', 'migrations') .option('--matches ', 'A glob pattern to filter migration files', '*') .option('--compiler ', 'Use the given module to compile files') - .option('--env [name...]', 'Use dotenv to load an environment file') + .option('--env [name]', 'Use dotenv to load an environment file') .parse(process.argv) const opts = program.opts() @@ -34,7 +34,7 @@ process.chdir(opts.chdir) // Setup environment if (opts.env) { const e = dotenv.config({ - path: opts.env + path: typeof opts.env === 'string' ? opts.env : '.env' }) if (e && e.error instanceof Error) { throw e.error diff --git a/test/fixtures/env/env.local b/test/fixtures/env/env.local deleted file mode 100644 index 261e521..0000000 --- a/test/fixtures/env/env.local +++ /dev/null @@ -1 +0,0 @@ -DB=pets2 diff --git a/test/integration.js b/test/integration.js index 67b6beb..f0d0bf0 100644 --- a/test/integration.js +++ b/test/integration.js @@ -153,18 +153,4 @@ describe('integration tests', function () { }) }) }) - - it('should support multiple --env parameters', function (done) { - run.up(ENV_DIR, ['--env', 'env', 'env.local'], function (err, out, code) { - assert(!err) - assert.strictEqual(code, 0) - assert(out.indexOf('error') === -1) - run.down(ENV_DIR, ['--env', 'env', 'env.local'], function (err, out, code) { - assert(!err) - assert.strictEqual(code, 0) - assert(out.indexOf('error') === -1) - done() - }) - }) - }) })