mirror of
https://github.com/knex/knex.git
synced 2025-09-25 16:15:56 +00:00
feat: new config parameter / CLI flag to prefixing seed filename with a timestamp (#3873)
This commit is contained in:
parent
2bf17e0509
commit
a481dde82c
15
bin/cli.js
15
bin/cli.js
@ -93,7 +93,11 @@ function invoke(env) {
|
||||
'environment, default: process.env.NODE_ENV || development'
|
||||
)
|
||||
.option('--esm', 'Enable ESM interop.')
|
||||
.option('--specific [path]', 'Specify one seed file to execute.');
|
||||
.option('--specific [path]', 'Specify one seed file to execute.')
|
||||
.option(
|
||||
'--timestamp-filename-prefix',
|
||||
'Enable a timestamp prefix on name of generated seed files.'
|
||||
);
|
||||
|
||||
commander
|
||||
.command('init')
|
||||
@ -300,6 +304,11 @@ 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'
|
||||
)
|
||||
.option(
|
||||
'--timestamp-filename-prefix',
|
||||
'Enable a timestamp prefix on name of generated seed files.',
|
||||
false
|
||||
)
|
||||
.action(async (name) => {
|
||||
const opts = commander.opts();
|
||||
opts.client = opts.client || 'sqlite3'; // We don't really care about client when creating seeds
|
||||
@ -311,6 +320,10 @@ function invoke(env) {
|
||||
configOverrides.stub = stub;
|
||||
}
|
||||
|
||||
if (opts.timestampFilenamePrefix) {
|
||||
configOverrides.timestampFilenamePrefix = opts.timestampFilenamePrefix;
|
||||
}
|
||||
|
||||
instance.seed
|
||||
.make(name, configOverrides)
|
||||
.then((name) => {
|
||||
|
@ -2,6 +2,7 @@ const path = require('path');
|
||||
const { writeJsFileUsingTemplate } = require('../util/template');
|
||||
const { getMergedConfig } = require('./configuration-merger');
|
||||
const { ensureDirectoryExists } = require('../util/fs');
|
||||
const { yyyymmddhhmmss } = require('../util/timestamp');
|
||||
|
||||
class MigrationGenerator {
|
||||
constructor(migrationConfig, logger) {
|
||||
@ -79,24 +80,4 @@ class MigrationGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that we have 2 places for each of the date segments.
|
||||
function padDate(segment) {
|
||||
segment = segment.toString();
|
||||
return segment[1] ? segment : `0${segment}`;
|
||||
}
|
||||
|
||||
// Get a date object in the correct format, without requiring a full out library
|
||||
// like "moment.js".
|
||||
function yyyymmddhhmmss() {
|
||||
const d = new Date();
|
||||
return (
|
||||
d.getFullYear().toString() +
|
||||
padDate(d.getMonth() + 1) +
|
||||
padDate(d.getDate()) +
|
||||
padDate(d.getHours()) +
|
||||
padDate(d.getMinutes()) +
|
||||
padDate(d.getSeconds())
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = MigrationGenerator;
|
||||
|
@ -7,6 +7,7 @@ const extend = require('lodash/extend');
|
||||
const includes = require('lodash/includes');
|
||||
const { ensureDirectoryExists, getFilepathsInFolder } = require('../util/fs');
|
||||
const { writeJsFileUsingTemplate } = require('../util/template');
|
||||
const { yyyymmddhhmmss } = require('../util/timestamp');
|
||||
|
||||
const filterByLoadExtensions = (extensions) => (value) => {
|
||||
const extension = path.extname(value);
|
||||
@ -103,7 +104,12 @@ class Seeder {
|
||||
|
||||
_getNewStubFileName(name) {
|
||||
if (name[0] === '-') name = name.slice(1);
|
||||
return name + '.' + this.config.extension;
|
||||
|
||||
if (this.config.timestampFilenamePrefix === true) {
|
||||
name = `${yyyymmddhhmmss()}_${name}`;
|
||||
}
|
||||
|
||||
return `${name}.${this.config.extension}`;
|
||||
}
|
||||
|
||||
_getNewStubFilePath(name) {
|
||||
@ -185,6 +191,7 @@ class Seeder {
|
||||
'.ls',
|
||||
'.ts',
|
||||
],
|
||||
timestampFilenamePrefix: false,
|
||||
sortDirsSeparately: false,
|
||||
recursive: false,
|
||||
},
|
||||
|
16
lib/util/timestamp.js
Normal file
16
lib/util/timestamp.js
Normal file
@ -0,0 +1,16 @@
|
||||
// Get a date object in the correct format, without requiring a full out library
|
||||
// like "moment.js".
|
||||
function yyyymmddhhmmss() {
|
||||
const d = new Date();
|
||||
|
||||
return (
|
||||
d.getFullYear().toString() +
|
||||
(d.getMonth() + 1).toString().padStart(2, '0') +
|
||||
d.getDate().toString().padStart(2, '0') +
|
||||
d.getHours().toString().padStart(2, '0') +
|
||||
d.getMinutes().toString().padStart(2, '0') +
|
||||
d.getSeconds().toString().padStart(2, '0')
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = { yyyymmddhhmmss };
|
@ -378,4 +378,70 @@ development: {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('--timestamp-filename-prefix option: make seed with timestamp filename prefix', () => {
|
||||
/**
|
||||
* @type FileTestHelper
|
||||
*/
|
||||
let fileHelper;
|
||||
|
||||
beforeEach(() => {
|
||||
fileHelper = setupFileHelper();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fileHelper.cleanup();
|
||||
});
|
||||
|
||||
it('Creates a new seed using --timestamp-filename-prefix CLI flag', async () => {
|
||||
const seedGlobPath = `${process.cwd()}/seeds/*_somename.js`;
|
||||
fileHelper.registerGlobForCleanup(seedGlobPath);
|
||||
|
||||
await execCommand(
|
||||
`${NODE} ${KNEX} seed:make somename --timestamp-filename-prefix --knexpath=../knex.js`,
|
||||
{
|
||||
expectedOutput: 'Created seed file',
|
||||
}
|
||||
);
|
||||
|
||||
const fileCount = fileHelper.fileGlobExists(seedGlobPath);
|
||||
|
||||
expect(fileCount).to.equal(1);
|
||||
});
|
||||
|
||||
it('Creates a new seed using timestampFilenamePrefix parameter in knexfile', async () => {
|
||||
const seedsDirectory = `${process.cwd()}/seeds`;
|
||||
const seedGlobPath = `${seedsDirectory}/*_somename.js`;
|
||||
fileHelper.registerGlobForCleanup(seedGlobPath);
|
||||
|
||||
const knexfileContents = `
|
||||
module.exports = {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: __dirname + '/test/jake-util/test.sqlite3',
|
||||
},
|
||||
seeds: {
|
||||
directory: '${seedsDirectory}',
|
||||
timestampFilenamePrefix: true
|
||||
},
|
||||
};`;
|
||||
|
||||
fileHelper.createFile(
|
||||
path.join(process.cwd(), 'knexfile.js'),
|
||||
knexfileContents,
|
||||
{ isPathAbsolute: true }
|
||||
);
|
||||
|
||||
await execCommand(
|
||||
`${NODE} ${KNEX} seed:make somename --knexpath=../knex.js`,
|
||||
{
|
||||
expectedOutput: 'Created seed file',
|
||||
}
|
||||
);
|
||||
|
||||
const fileCount = fileHelper.fileGlobExists(seedGlobPath);
|
||||
|
||||
expect(fileCount).to.equal(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
1
types/index.d.ts
vendored
1
types/index.d.ts
vendored
@ -1968,6 +1968,7 @@ declare namespace Knex {
|
||||
directory?: string | string[];
|
||||
loadExtensions?: readonly string[];
|
||||
specific?: string;
|
||||
timestampFilenamePrefix?: boolean;
|
||||
recursive?: boolean;
|
||||
sortDirsSeparately?: boolean;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user