diff --git a/src/commands/emulator.ts b/src/commands/emulator.ts index 002dfa3..8a89260 100644 --- a/src/commands/emulator.ts +++ b/src/commands/emulator.ts @@ -3,6 +3,7 @@ import {logHelpEmulator} from '../help/emulator.help'; import {logHelpEmulatorStart} from '../help/emulator.start.help'; import {logHelpEmulatorWait} from '../help/emulator.wait.help'; import {clear} from '../services/emulator/clear.services'; +import {pull} from '../services/emulator/pull.services'; import {start} from '../services/emulator/start.services'; import {stop} from '../services/emulator/stop.services'; import {wait} from '../services/emulator/wait.services'; @@ -23,6 +24,9 @@ export const emulator = async (args?: string[]) => { case 'clear': await clear(); break; + case 'pull': + await pull(); + break; default: console.log(red('Unknown subcommand.')); logHelpEmulator(args); diff --git a/src/constants/help.constants.ts b/src/constants/help.constants.ts index 32fc76f..d5e913b 100644 --- a/src/constants/help.constants.ts +++ b/src/constants/help.constants.ts @@ -34,6 +34,7 @@ export const HOSTING_PRUNE_DESCRIPTION = export const EMULATOR_START_DESCRIPTION = 'Start the emulator for local development.'; export const EMULATOR_WAIT_DESCRIPTION = 'Wait until the emulator is ready.'; export const EMULATOR_CLEAR_DESCRIPTION = 'Clear the local emulator state (volume and container).'; +export const EMULATOR_PULL_DESCRIPTION = 'Pull the latest emulator image.'; 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/emulator.help.ts b/src/help/emulator.help.ts index a578690..91b940d 100644 --- a/src/help/emulator.help.ts +++ b/src/help/emulator.help.ts @@ -2,6 +2,7 @@ import {cyan, green, magenta, yellow} from 'kleur'; import { EMULATOR_CLEAR_DESCRIPTION, EMULATOR_DESCRIPTION, + EMULATOR_PULL_DESCRIPTION, EMULATOR_START_DESCRIPTION, EMULATOR_WAIT_DESCRIPTION } from '../constants/help.constants'; @@ -12,6 +13,7 @@ const usage = `Usage: ${green('juno')} ${cyan('emulator')} ${magenta(' { await runWithConfig({fn}); }; +export const pullImage = async () => { + const fn: RunWithConfigFn = async (args) => { + await pullEmulator(args); + }; + + await runWithConfig({fn}); +}; + type RunWithConfigFn = (params: {config: CliEmulatorConfig}) => Promise; const runWithConfig = async ({fn}: {fn: RunWithConfigFn}) => { @@ -299,6 +308,39 @@ const clearEmulator = async ({config: {config, derivedConfig}}: {config: CliEmul }); }; +const pullEmulator = async ({config: {derivedConfig}}: {config: CliEmulatorConfig}) => { + const {runner, image} = derivedConfig; + + await confirmAndExit( + `Are you sure you want to pull the emulator image "${image}"? You will need to ${yellow('clear')} the emulator afterward to apply the update.` + ); + + const spinner = ora('Pulling...').start(); + + try { + await spawn({ + command: runner, + args: ['pull', image], + stdout: (o) => { + // We print out to display some sort of progression + console.log(o); + }, + silentOut: true + }); + + spinner.stop(); + + console.log('\nDone ✅\n'); + + console.log( + `Run ${yellow('juno emulator clear')} to reset the state, then ${green('juno emulator start')} to use the updated image.` + ); + } catch (error: unknown) { + spinner.stop(); + throw error; + } +}; + const assertContainerRunning = async ({ containerName, runner diff --git a/src/services/emulator/pull.services.ts b/src/services/emulator/pull.services.ts new file mode 100644 index 0000000..f0b388c --- /dev/null +++ b/src/services/emulator/pull.services.ts @@ -0,0 +1,5 @@ +import {pullImage} from './_runner.services'; + +export const pull = async () => { + await pullImage(); +};