Skip to content

Instantly share code, notes, and snippets.

@Obapelumi
Last active December 7, 2020 04:18
Show Gist options
  • Save Obapelumi/65e3d67ddc6493489dcdb8e88a02d4ca to your computer and use it in GitHub Desktop.
Save Obapelumi/65e3d67ddc6493489dcdb8e88a02d4ca to your computer and use it in GitHub Desktop.
// Adonis.js Dependencies
import { ApplicationContract } from "@ioc:Adonis/Core/Application";
import { BaseCommand, Kernel } from "@adonisjs/ace";
import { Ioc } from "@adonisjs/fold";
import Database from "@ioc:Adonis/Lucid/Database";
// External Dependencies
import _ from "lodash";
import prettyHrTime from "pretty-hrtime";
import requireAll from "require-all";
export default class Seed extends BaseCommand {
public static commandName = "db:seed";
public static description = "";
/**
* This command loads the application, since we need the runtime
* to find the migration directories for a given connection
*/
static settings = {
loadApp: true,
};
/**
* Path to database seeders
*/
_seedsPath: any;
/**
* Force run seeders in production
*/
force: boolean;
/**
* File name or names seperated by a comma
*/
files: string;
/**
* Whether or not to close the connection after seeding is complete
*/
keepAlive: boolean;
constructor(app: ApplicationContract, kernel: Kernel) {
super(app, kernel);
this._seedsPath = app.seedsPath();
// this.files = this.files ? this.files : "DatabaseSeeder.js";
}
/**
* Returns an object of all schema files
*
* @method _getSeedFiles
*
* @return {Object}
*
* @private
*/
_getSeedFiles(selectedFiles) {
return requireAll({
dirname: this._seedsPath,
filter: (fileName) => {
if (!selectedFiles && fileName.match(/(.*)\.js$/)) {
return fileName;
}
return _.find(selectedFiles, (file) => file.trim().endsWith(fileName));
},
});
}
/**
* Throws exception when trying to run migrations are
* executed in production and not using force flag.
*
* @method _validateState
*
* @param {Boolean} force
*
* @return {void}
*
* @private
*
* @throws {Error} If NODE_ENV is production
*/
_validateState(force) {
if (process.env.NODE_ENV === "production" && !force) {
throw new Error(
"Cannot run seeds in production. Use --force flag to continue"
);
}
}
/**
* Method called when command is executed. This method will
* require all files from the migrations directory
* and execute all pending schema files
*
* @method handle
*
* @param {Object} args
* @param {Boolean} options.force
* @param {String} options.files
* @param {String} options.keepAlive
*
* @return {void|Array}
*/
async handle(): Promise<void> {
const args = this.parsed || this;
try {
this._validateState(args.force);
const startTime = process.hrtime();
const files =
typeof args.files === "string" ? args.files.split(",") : null;
const allFiles = this._getSeedFiles(files);
if (!_.size(allFiles)) {
this.logger.info("Nothing to seed");
return;
}
for (const file of _.keys(allFiles)) {
const seedInstance = new Ioc().make(allFiles[file]).default;
if (typeof seedInstance.run === "function") {
await seedInstance.run();
} else {
this.logger.warn(
`${seedInstance.constructor.name} does not have a run method`
);
}
}
const endTime = process.hrtime(startTime);
this.logger.success(`Seeded database in ${prettyHrTime(endTime)}`);
} catch (error) {
console.log(error);
}
/**
* Close the connection when seeder are executed and keep alive is
* not passed
*/
if (!args.keepAlive) {
await Database.manager.closeAll();
}
}
}
@a21y
Copy link

a21y commented Jun 14, 2020

Ran into a small issue when trying to run this command in production: the --force wasn't being picked up. It seems like the flags are nested in the this.parsed object, rather than directly in this as they are referenced in the handle() function here.

My workaround was simply adding const args = this.parsed || this as the first line of the handle() function, and then updating the references to the arguments inside the function:
this.force -> args.force
this.files -> args.files
this.keepAlive -> args.keepAlive

@Obapelumi
Copy link
Author

Hi,
Sorry about my delayed response.
I had been having issues parsing the arguments in, thanks a lot for helping me out. Cheers!

@a21y
Copy link

a21y commented Jun 28, 2020

No problem! Looks like seeding has been officially documented for v5 now anyway: https://preview.adonisjs.com/guides/database/seeds 😄

@Obapelumi
Copy link
Author

Yes, it has this was just a temporary quick fix. Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment