feat: new config parameter / CLI flag to prefixing seed filename with a timestamp (#3873)

This commit is contained in:
Christiano Marques 2020-09-19 10:11:05 -03:00 committed by GitHub
parent 2bf17e0509
commit a481dde82c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 106 additions and 22 deletions

View File

@ -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) => {

View File

@ -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;

View File

@ -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
View 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 };

View File

@ -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
View File

@ -1968,6 +1968,7 @@ declare namespace Knex {
directory?: string | string[];
loadExtensions?: readonly string[];
specific?: string;
timestampFilenamePrefix?: boolean;
recursive?: boolean;
sortDirsSeparately?: boolean;
}