diff --git a/packages/local-refresh/src/actions/ActionInterface.ts b/packages/local-refresh/src/actions/ActionInterface.ts index 11d7f8f267..d77df04992 100644 --- a/packages/local-refresh/src/actions/ActionInterface.ts +++ b/packages/local-refresh/src/actions/ActionInterface.ts @@ -6,7 +6,7 @@ export default interface ActionInterface { * * @return {Promise} Whether the action should be executed. */ - prompt(): Promise; + prompt(noInteraction: boolean): Promise; /** * Execute the action. diff --git a/packages/local-refresh/src/actions/ComposerInstall.ts b/packages/local-refresh/src/actions/ComposerInstall.ts index 6245aa7c7b..6a6b2daa2d 100644 --- a/packages/local-refresh/src/actions/ComposerInstall.ts +++ b/packages/local-refresh/src/actions/ComposerInstall.ts @@ -12,7 +12,11 @@ const phpAppDirectoryNames = ["api", "selfserve", "internal"]; const phpAppDirectories = phpAppDirectoryNames.map((dir) => path.resolve(__dirname, `../../../../app/${dir}`)); export default class ComposerInstall implements ActionInterface { - async prompt(): Promise { + async prompt(noInteraction: boolean): Promise { + if (noInteraction) { + return true; + } + const { shouldInstall } = await prompts({ type: "confirm", name: "shouldInstall", diff --git a/packages/local-refresh/src/actions/CopyAppDistFiles.ts b/packages/local-refresh/src/actions/CopyAppDistFiles.ts index 2196298d05..ba7c38cc0d 100644 --- a/packages/local-refresh/src/actions/CopyAppDistFiles.ts +++ b/packages/local-refresh/src/actions/CopyAppDistFiles.ts @@ -11,19 +11,21 @@ const debug = createDebug("refresh:actions:CopyAppDistFiles"); const phpAppDirectoryNames = ["api", "selfserve", "internal"]; const phpAppDirectories = phpAppDirectoryNames.map((dir) => path.resolve(__dirname, `../../../../app/${dir}`)); -export default class ResetDatabase implements ActionInterface { +export default class CopyAppDistFiles implements ActionInterface { filesToCopy: string[] = []; - async prompt(): Promise { - const { shouldCopy } = await prompts({ - type: "confirm", - name: "shouldCopy", - message: "Copy the Laminas configuration dist files?", - warn: "This will overwrite existing configuration files.", - }); + async prompt(noInteraction: boolean): Promise { + if (!noInteraction) { + const { shouldCopy } = await prompts({ + type: "confirm", + name: "shouldCopy", + message: "Copy the Laminas configuration dist files?", + warn: "This will overwrite existing configuration files.", + }); - if (!shouldCopy) { - return false; + if (!shouldCopy) { + return false; + } } let appConfigDistFiles: Map = new Map(); @@ -51,6 +53,11 @@ export default class ResetDatabase implements ActionInterface { }); } + if (noInteraction) { + this.filesToCopy = Array.from(appConfigDistFiles.keys()); + return this.filesToCopy.length > 0; + } + const { files } = await prompts({ type: "multiselect", name: "files", diff --git a/packages/local-refresh/src/actions/FlushRedis.ts b/packages/local-refresh/src/actions/FlushRedis.ts index 74c6516c65..69baac5190 100644 --- a/packages/local-refresh/src/actions/FlushRedis.ts +++ b/packages/local-refresh/src/actions/FlushRedis.ts @@ -7,7 +7,11 @@ import { GenericBar } from "cli-progress"; const debug = createDebug("refresh:actions:FlushRedis"); export default class FlushRedis implements ActionInterface { - async prompt(): Promise { + async prompt(noInteraction: boolean): Promise { + if (noInteraction) { + return true; + } + const { shouldFlush } = await prompts({ type: "confirm", name: "shouldFlush", @@ -23,6 +27,8 @@ export default class FlushRedis implements ActionInterface { exec(`docker compose exec redis redis-cli -c "FLUSHALL"`, debug); + progress.increment(1); + progress.stop(); } } diff --git a/packages/local-refresh/src/actions/ResetDatabase.ts b/packages/local-refresh/src/actions/ResetDatabase.ts index 0c7dfca145..9b2f55664d 100644 --- a/packages/local-refresh/src/actions/ResetDatabase.ts +++ b/packages/local-refresh/src/actions/ResetDatabase.ts @@ -36,7 +36,14 @@ export default class ResetDatabase implements ActionInterface { liquibasePropertiesFileName = `vol-app.liquibase.properties`; createLiquibaseProperties = false; - async prompt(): Promise { + async prompt(noInteraction: boolean): Promise { + if (noInteraction) { + this.refreshType = DatabaseRefreshEnum.FULL; + this.etlDirectory = cache.getKey("etlDirectory") || this.etlDirectory; + this.createLiquibaseProperties = true; + return true; + } + const { shouldResetDatabase, refreshType } = await prompts([ { type: "confirm", diff --git a/packages/local-refresh/src/actions/ResetLdap.ts b/packages/local-refresh/src/actions/ResetLdap.ts index 7b19f1934a..97b223b14a 100644 --- a/packages/local-refresh/src/actions/ResetLdap.ts +++ b/packages/local-refresh/src/actions/ResetLdap.ts @@ -9,7 +9,11 @@ import { GenericBar } from "cli-progress"; const debug = createDebug("refresh:actions:ResetLdap"); export default class ResetLdap implements ActionInterface { - async prompt(): Promise { + async prompt(noInteraction: boolean): Promise { + if (noInteraction) { + return true; + } + const { shouldRefresh } = await prompts({ type: "confirm", name: "shouldRefresh", diff --git a/packages/local-refresh/src/index.ts b/packages/local-refresh/src/index.ts index e40bc29d50..e9883a34ec 100644 --- a/packages/local-refresh/src/index.ts +++ b/packages/local-refresh/src/index.ts @@ -7,61 +7,70 @@ import chalk from "chalk"; import cliProgress from "cli-progress"; import ActionInterface from "./actions/ActionInterface"; -const progressBarFactory = () => { +const progressBarFactory = (name: string) => { return new cliProgress.Bar( { - clearOnComplete: true, + format: `${name.padEnd(20)} | {bar} {percentage}% | ETA: {eta_formatted} | Step: {value}/{total}`, + autopadding: true, + clearOnComplete: false, }, cliProgress.Presets.shades_classic, ); }; -program.description("Script to refresh the local VOL application").action(async () => { - const actions = await Promise.all( - fs - .readdirSync(path.resolve(__dirname, "actions")) - .filter((file) => file.endsWith(".ts") && !file.endsWith("Interface.ts")) - .map((file) => import(`./actions/${file}`)), - ); +program + .description("Script to refresh the local VOL application") + .option( + "-i, --no-interaction", + "Run in non-interactive mode; Does not ask any interactive question. All the actions will run with defaults.", + ) + .action(async (options) => { + const actions = await Promise.all( + fs + .readdirSync(path.resolve(__dirname, "actions")) + .filter((file) => file.endsWith(".ts") && !file.endsWith("Interface.ts")) + .map((file) => import(`./actions/${file}`)), + ); - const isActionInterface = (action: any): action is ActionInterface => { - return "prompt" in action && "execute" in action; - }; + const isActionInterface = (action: any): action is ActionInterface => { + return "prompt" in action && "execute" in action; + }; - for (const action of actions) { - const instance = new action.default(); + for (const action of actions) { + const instance = new action.default(); - if (isActionInterface(instance) === false) { - console.warn(chalk.red(`Error: ${instance.name} does not implement ActionInterface`)); - continue; - } + if (isActionInterface(instance) === false) { + console.warn(chalk.red(`Error: ${instance.name} does not implement ActionInterface`)); + continue; + } - const shouldRun = await instance.prompt(); + const shouldRun = await instance.prompt(!options.interaction); - if (shouldRun) { - try { - await instance.execute(progressBarFactory()); - } catch (e: unknown) { - if (e instanceof Error) { - console.error(`\n\n${chalk.red(e.message)}\n`); + if (shouldRun) { + try { + const progressBar = progressBarFactory(instance.constructor.name); + await instance.execute(progressBar); + } catch (e: unknown) { + if (e instanceof Error) { + console.error(`\n\n${chalk.red(e.message)}\n`); + } } } } - } - const hostsFile = fs.readFileSync("/etc/hosts", "utf8"); + const hostsFile = fs.readFileSync("/etc/hosts", "utf8"); - if (!hostsFile.includes("local.olcs.dev-dvsacloud.uk")) { - console.warn(chalk.yellow(`/etc/hosts has not been updated with the local domains. Please run:`)); - console.warn( - chalk.bgYellow( - `sudo echo "127.0.0.1 iuweb.local.olcs.dev-dvsacloud.uk ssweb.local.olcs.dev-dvsacloud.uk api.local.olcs.dev-dvsacloud.uk cdn.local.olcs.dev-dvsacloud.uk" >> /etc/hosts`, - ), - ); - } + if (!hostsFile.includes("local.olcs.dev-dvsacloud.uk")) { + console.warn(chalk.yellow(`/etc/hosts has not been updated with the local domains. Please run:`)); + console.warn( + chalk.bgYellow( + `sudo echo "127.0.0.1 iuweb.local.olcs.dev-dvsacloud.uk ssweb.local.olcs.dev-dvsacloud.uk api.local.olcs.dev-dvsacloud.uk cdn.local.olcs.dev-dvsacloud.uk" >> /etc/hosts`, + ), + ); + } - process.exit(0); -}); + process.exit(0); + }); program.parse(process.argv);