diff --git a/src/commands/dev.ts b/src/commands/dev.ts index 1f4043e5..3bd04007 100644 --- a/src/commands/dev.ts +++ b/src/commands/dev.ts @@ -1,6 +1,7 @@ import {red} from 'kleur'; import {logHelpDev} from '../help/dev.help'; import {logHelpDevStart} from '../help/dev.start.help'; +import {logHelpDevWait} from '../help/dev.wait.help'; import {logHelpFunctionsBuild} from '../help/functions.build.help'; import {logHelpFunctionsEject} from '../help/functions.eject.help'; import {start} from '../services/dev/start.services'; @@ -20,7 +21,7 @@ export const dev = async (args?: string[]) => { await stop(); break; case 'wait': - await wait(); + await wait(args); break; case 'eject': await eject(args); @@ -41,6 +42,9 @@ export const helpDev = (args?: string[]) => { case 'start': logHelpDevStart(args); break; + case 'wait': + logHelpDevWait(args); + break; case 'build': logHelpFunctionsBuild(args); break; diff --git a/src/constants/help.constants.ts b/src/constants/help.constants.ts index 2af54691..be70db58 100644 --- a/src/constants/help.constants.ts +++ b/src/constants/help.constants.ts @@ -23,6 +23,7 @@ export const WHOAMI_DESCRIPTION = 'Display your current profile, access key, and links to your satellite.'; export const DEV_START_DESCRIPTION = 'Start a local Internet Computer network in a container.'; +export const DEV_WAIT_DESCRIPTION = 'Wait until the emulator is ready.'; export const FUNCTIONS_PUBLISH_DESCRIPTION = 'Publish a new version of your serverless functions.'; export const FUNCTIONS_UPGRADE_DESCRIPTION = 'Upgrade your serverless functions.'; diff --git a/src/help/dev.help.ts b/src/help/dev.help.ts index 0087c498..6a089204 100644 --- a/src/help/dev.help.ts +++ b/src/help/dev.help.ts @@ -1,5 +1,9 @@ import {cyan, green, magenta, yellow} from 'kleur'; -import {DEV_DESCRIPTION, DEV_START_DESCRIPTION} from '../constants/help.constants'; +import { + DEV_DESCRIPTION, + DEV_START_DESCRIPTION, + DEV_WAIT_DESCRIPTION +} from '../constants/help.constants'; import {helpOutput} from './common.help'; import {TITLE} from './help'; @@ -8,7 +12,7 @@ const usage = `Usage: ${green('juno')} ${cyan('dev')} ${magenta('')} Subcommands: ${magenta('start')} ${DEV_START_DESCRIPTION} ${magenta('stop')} Stop the local network. - ${magenta('wait')} Wait until the emulator is ready. + ${magenta('wait')} ${DEV_WAIT_DESCRIPTION} ${magenta('build')} Alias for ${green('juno')} ${cyan('functions')} ${magenta('build')}. ${magenta('eject')} Alias for ${green('juno')} ${cyan('functions')} ${magenta('eject')}.`; diff --git a/src/help/dev.wait.help.ts b/src/help/dev.wait.help.ts new file mode 100644 index 00000000..43cce462 --- /dev/null +++ b/src/help/dev.wait.help.ts @@ -0,0 +1,28 @@ +import {cyan, green, magenta, yellow} from 'kleur'; +import {DEV_WAIT_DESCRIPTION, OPTION_HELP} from '../constants/help.constants'; +import {helpOutput} from './common.help'; +import {TITLE} from './help'; + +const usage = `Usage: ${green('juno')} ${cyan('dev')} ${magenta('wait')} ${yellow('[options]')} + +Options: + ${yellow('-t, --timeout')} Timeout for the emulator to be ready (in ms, default 2min). + ${OPTION_HELP}`; + +const doc = `${DEV_WAIT_DESCRIPTION} + +\`\`\` +${usage} +\`\`\` +`; + +const help = `${TITLE} + +${DEV_WAIT_DESCRIPTION} + +${usage} +`; + +export const logHelpDevWait = (args?: string[]) => { + console.log(helpOutput(args) === 'doc' ? doc : help); +}; diff --git a/src/services/dev/wait.services.ts b/src/services/dev/wait.services.ts index b974b03a..2ed19619 100644 --- a/src/services/dev/wait.services.ts +++ b/src/services/dev/wait.services.ts @@ -1,13 +1,26 @@ +import {isEmptyString} from '@dfinity/utils'; +import {nextArg} from '@junobuild/cli-tools'; import {green, red} from 'kleur'; import ora from 'ora'; import {readEmulatorConfig} from '../../configs/emulator.config'; import type {CliEmulatorConfig} from '../../types/emulator'; import {dispatchRequest} from '../emulator/emulator.admin.services'; -const TIMEOUT_IN_MILLISECONDS = 15000; +const DEFAULT_TIMEOUT_IN_MILLISECONDS = 2 * 60 * 1000; const RETRY_IN_MILLISECONDS = 500; -export const wait = async () => { +export const wait = async (args?: string[]) => { + const timeout = parseTimeout(args); + + if (!timeout.valid) { + console.log( + red( + `Invalid timeout argument. Must be a number in milliseconds greater than ${RETRY_IN_MILLISECONDS}ms.` + ) + ); + process.exit(1); + } + const parsedResult = await readEmulatorConfig(); if (!parsedResult.success) { @@ -20,7 +33,7 @@ export const wait = async () => { try { status = await waitEmulatorReady({ - count: TIMEOUT_IN_MILLISECONDS / RETRY_IN_MILLISECONDS, + count: timeout.value / RETRY_IN_MILLISECONDS, config: parsedResult.config }); } finally { @@ -35,6 +48,26 @@ export const wait = async () => { console.log(`Emulator is ${green('ready')}.`); }; +const parseTimeout = (args?: string[]): {valid: true; value: number} | {valid: false} => { + const timoutArg = nextArg({args, option: '-t'}) ?? nextArg({args, option: '--timeout'}); + + if (isEmptyString(timoutArg)) { + return {valid: true, value: DEFAULT_TIMEOUT_IN_MILLISECONDS}; + } + + const timeout = parseInt(timoutArg); + + if (isNaN(timeout)) { + return {valid: false}; + } + + if (timeout < RETRY_IN_MILLISECONDS) { + return {valid: false}; + } + + return {valid: true, value: timeout}; +}; + const waitEmulatorReady = async ({ count, config