mirror of
https://github.com/knex/knex.git
synced 2025-09-26 08:33:59 +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'
|
'environment, default: process.env.NODE_ENV || development'
|
||||||
)
|
)
|
||||||
.option('--esm', 'Enable ESM interop.')
|
.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
|
commander
|
||||||
.command('init')
|
.command('init')
|
||||||
@ -300,6 +304,11 @@ function invoke(env) {
|
|||||||
`--stub [<relative/path/from/knexfile>|<name>]`,
|
`--stub [<relative/path/from/knexfile>|<name>]`,
|
||||||
'Specify the seed stub to use. If using <name> the file must be located in config.seeds.directory'
|
'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) => {
|
.action(async (name) => {
|
||||||
const opts = commander.opts();
|
const opts = commander.opts();
|
||||||
opts.client = opts.client || 'sqlite3'; // We don't really care about client when creating seeds
|
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;
|
configOverrides.stub = stub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts.timestampFilenamePrefix) {
|
||||||
|
configOverrides.timestampFilenamePrefix = opts.timestampFilenamePrefix;
|
||||||
|
}
|
||||||
|
|
||||||
instance.seed
|
instance.seed
|
||||||
.make(name, configOverrides)
|
.make(name, configOverrides)
|
||||||
.then((name) => {
|
.then((name) => {
|
||||||
|
@ -2,6 +2,7 @@ const path = require('path');
|
|||||||
const { writeJsFileUsingTemplate } = require('../util/template');
|
const { writeJsFileUsingTemplate } = require('../util/template');
|
||||||
const { getMergedConfig } = require('./configuration-merger');
|
const { getMergedConfig } = require('./configuration-merger');
|
||||||
const { ensureDirectoryExists } = require('../util/fs');
|
const { ensureDirectoryExists } = require('../util/fs');
|
||||||
|
const { yyyymmddhhmmss } = require('../util/timestamp');
|
||||||
|
|
||||||
class MigrationGenerator {
|
class MigrationGenerator {
|
||||||
constructor(migrationConfig, logger) {
|
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;
|
module.exports = MigrationGenerator;
|
||||||
|
@ -7,6 +7,7 @@ const extend = require('lodash/extend');
|
|||||||
const includes = require('lodash/includes');
|
const includes = require('lodash/includes');
|
||||||
const { ensureDirectoryExists, getFilepathsInFolder } = require('../util/fs');
|
const { ensureDirectoryExists, getFilepathsInFolder } = require('../util/fs');
|
||||||
const { writeJsFileUsingTemplate } = require('../util/template');
|
const { writeJsFileUsingTemplate } = require('../util/template');
|
||||||
|
const { yyyymmddhhmmss } = require('../util/timestamp');
|
||||||
|
|
||||||
const filterByLoadExtensions = (extensions) => (value) => {
|
const filterByLoadExtensions = (extensions) => (value) => {
|
||||||
const extension = path.extname(value);
|
const extension = path.extname(value);
|
||||||
@ -103,7 +104,12 @@ class Seeder {
|
|||||||
|
|
||||||
_getNewStubFileName(name) {
|
_getNewStubFileName(name) {
|
||||||
if (name[0] === '-') name = name.slice(1);
|
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) {
|
_getNewStubFilePath(name) {
|
||||||
@ -185,6 +191,7 @@ class Seeder {
|
|||||||
'.ls',
|
'.ls',
|
||||||
'.ts',
|
'.ts',
|
||||||
],
|
],
|
||||||
|
timestampFilenamePrefix: false,
|
||||||
sortDirsSeparately: false,
|
sortDirsSeparately: false,
|
||||||
recursive: 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[];
|
directory?: string | string[];
|
||||||
loadExtensions?: readonly string[];
|
loadExtensions?: readonly string[];
|
||||||
specific?: string;
|
specific?: string;
|
||||||
|
timestampFilenamePrefix?: boolean;
|
||||||
recursive?: boolean;
|
recursive?: boolean;
|
||||||
sortDirsSeparately?: boolean;
|
sortDirsSeparately?: boolean;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user