import { readFileSync } from 'fs'; import { Command, Flags } from '@oclif/core'; import * as dotenv from 'dotenv'; export default class Start extends Command { static description = 'Run automatisch'; static flags = { env: Flags.string({ multiple: true, char: 'e', }), 'env-file': Flags.string(), }; get isProduction() { return process.env.APP_ENV === 'production'; } async prepareEnvVars(): Promise { const { flags } = await this.parse(Start); if (flags['env-file']) { const envFile = readFileSync(flags['env-file'], 'utf8'); const envConfig = dotenv.parse(envFile); for (const key in envConfig) { const value = envConfig[key]; process.env[key] = value; } } if (flags.env) { for (const env of flags.env) { const [key, value] = env.split('='); process.env[key] = value; } } // must serve until more customization is introduced delete process.env.SERVE_WEB_APP_SEPARATELY; } async createDatabaseAndUser(): Promise { const utils = await import('@automatisch/backend/database-utils'); await utils.createDatabaseAndUser( process.env.POSTGRES_DATABASE, process.env.POSTGRES_USERNAME ); } async runMigrationsIfNeeded(): Promise { const { logger } = await import('@automatisch/backend/logger'); const database = await import('@automatisch/backend/database'); const migrator = database.client.migrate; const [, pendingMigrations] = await migrator.list(); const pendingMigrationsCount = pendingMigrations.length; const needsToMigrate = pendingMigrationsCount > 0; if (needsToMigrate) { logger.info(`Processing ${pendingMigrationsCount} migrations.`); await migrator.latest(); logger.info(`Completed ${pendingMigrationsCount} migrations.`); } else { logger.info('No migrations needed.'); } } async seedUser(): Promise { const utils = await import('@automatisch/backend/database-utils'); await utils.createUser(); } async runApp(): Promise { await import('@automatisch/backend/server'); } async run(): Promise { await this.prepareEnvVars(); if (!this.isProduction) { await this.createDatabaseAndUser(); } await this.runMigrationsIfNeeded(); await this.seedUser(); await this.runApp(); } }