From f00c838e51e18967e55db7302e9413dd2577c619 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Fri, 20 Feb 2026 12:44:57 +0100 Subject: [PATCH 1/2] feat: juno emulator clear Signed-off-by: David Dal Busco --- src/commands/emulator.ts | 4 ++++ src/commands/hosting.ts | 4 ++-- src/constants/help.constants.ts | 1 + src/help/emulator.help.ts | 2 ++ src/help/hosting.clear.help.ts | 2 +- src/services/emulator/_runner.services.ts | 4 ++++ src/services/emulator/clear.services.ts | 5 +++++ 7 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 src/services/emulator/clear.services.ts diff --git a/src/commands/emulator.ts b/src/commands/emulator.ts index b6e8bb7e..002dfa3c 100644 --- a/src/commands/emulator.ts +++ b/src/commands/emulator.ts @@ -2,6 +2,7 @@ import {red} from 'kleur'; 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 {start} from '../services/emulator/start.services'; import {stop} from '../services/emulator/stop.services'; import {wait} from '../services/emulator/wait.services'; @@ -19,6 +20,9 @@ export const emulator = async (args?: string[]) => { case 'wait': await wait(args); break; + case 'clear': + await clear(); + break; default: console.log(red('Unknown subcommand.')); logHelpEmulator(args); diff --git a/src/commands/hosting.ts b/src/commands/hosting.ts index 7f9d8dce..02f4b92c 100644 --- a/src/commands/hosting.ts +++ b/src/commands/hosting.ts @@ -1,5 +1,5 @@ import {red} from 'kleur'; -import {logHelpEmulatorClear} from '../help/hosting.clear.help'; +import {logHelpHostingClear} from '../help/hosting.clear.help'; import {logHelpHostingDeploy} from '../help/hosting.deploy.help'; import {logHelpHosting} from '../help/hosting.help'; import {clear} from '../services/assets/clear.services'; @@ -29,7 +29,7 @@ export const helpHosting = (args?: string[]) => { logHelpHostingDeploy(args); break; case 'clear': - logHelpEmulatorClear(args); + logHelpHostingClear(args); break; default: logHelpHosting(args); diff --git a/src/constants/help.constants.ts b/src/constants/help.constants.ts index a570bb55..d90eee1e 100644 --- a/src/constants/help.constants.ts +++ b/src/constants/help.constants.ts @@ -31,6 +31,7 @@ export const HOSTING_CLEAR_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 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 57905e37..a5786903 100644 --- a/src/help/emulator.help.ts +++ b/src/help/emulator.help.ts @@ -1,5 +1,6 @@ import {cyan, green, magenta, yellow} from 'kleur'; import { + EMULATOR_CLEAR_DESCRIPTION, EMULATOR_DESCRIPTION, EMULATOR_START_DESCRIPTION, EMULATOR_WAIT_DESCRIPTION @@ -10,6 +11,7 @@ import {TITLE} from './help'; const usage = `Usage: ${green('juno')} ${cyan('emulator')} ${magenta('')} ${yellow('[options]')} Subcommands: + ${magenta('clear')} ${EMULATOR_CLEAR_DESCRIPTION} ${magenta('start')} ${EMULATOR_START_DESCRIPTION} ${magenta('stop')} Stop the local network. ${magenta('wait')} ${EMULATOR_WAIT_DESCRIPTION}`; diff --git a/src/help/hosting.clear.help.ts b/src/help/hosting.clear.help.ts index 0cac26db..dc25e600 100644 --- a/src/help/hosting.clear.help.ts +++ b/src/help/hosting.clear.help.ts @@ -24,6 +24,6 @@ ${HOSTING_CLEAR_DESCRIPTION} ${usage} `; -export const logHelpEmulatorClear = (args?: string[]) => { +export const logHelpHostingClear = (args?: string[]) => { console.log(helpOutput(args) === 'doc' ? doc : help); }; diff --git a/src/services/emulator/_runner.services.ts b/src/services/emulator/_runner.services.ts index 81948f2a..07342640 100644 --- a/src/services/emulator/_runner.services.ts +++ b/src/services/emulator/_runner.services.ts @@ -72,6 +72,10 @@ export const stopContainer = async () => { await stopEmulator({config}); }; +export const clearContainerAndVolume = async () => { + // TODO +}; + const promptEmulatorType = async (): Promise<{emulatorType: Exclude}> => { const {emulatorType}: {emulatorType: Exclude | undefined} = await prompts({ diff --git a/src/services/emulator/clear.services.ts b/src/services/emulator/clear.services.ts new file mode 100644 index 00000000..78c6070e --- /dev/null +++ b/src/services/emulator/clear.services.ts @@ -0,0 +1,5 @@ +import {clearContainerAndVolume} from './_runner.services'; + +export const clear = async () => { + await clearContainerAndVolume(); +}; From b92f2a0a9efecdd14d62c320dd1a82200c1f3d13 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Fri, 20 Feb 2026 13:18:26 +0100 Subject: [PATCH 2/2] feat: implement clear Signed-off-by: David Dal Busco --- src/services/emulator/_runner.services.ts | 42 ++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/services/emulator/_runner.services.ts b/src/services/emulator/_runner.services.ts index c3064895..002c046e 100644 --- a/src/services/emulator/_runner.services.ts +++ b/src/services/emulator/_runner.services.ts @@ -19,6 +19,7 @@ import { type EmulatorType } from '../../types/emulator'; import {isHeadless} from '../../utils/process.utils'; +import {confirmAndExit} from '../../utils/prompt.utils'; import { assertContainerRunnerRunning, checkDockerVersion, @@ -46,6 +47,14 @@ export const stopContainer = async () => { await runWithConfig({fn}); }; +export const clearContainerAndVolume = async () => { + const fn: RunWithConfigFn = async (args) => { + await clearEmulator(args); + }; + + await runWithConfig({fn}); +}; + type RunWithConfigFn = (params: {config: CliEmulatorConfig}) => Promise; const runWithConfig = async ({fn}: {fn: RunWithConfigFn}) => { @@ -69,10 +78,6 @@ const runWithConfig = async ({fn}: {fn: RunWithConfigFn}) => { await fn({config}); }; -export const clearContainerAndVolume = async () => { - // TODO -}; - const promptEmulatorType = async (): Promise<{emulatorType: Exclude}> => { const {emulatorType}: {emulatorType: Exclude | undefined} = await prompts({ @@ -266,6 +271,35 @@ const stopEmulator = async ({config: {derivedConfig}}: {config: CliEmulatorConfi }); }; +const clearEmulator = async ({config: {config, derivedConfig}}: {config: CliEmulatorConfig}) => { + const {containerName, runner} = derivedConfig; + + const {running} = await assertContainerRunning({containerName, runner}); + + if (running) { + console.log(yellow(`The ${runner} container ${containerName} must be stopped first.`)); + return; + } + + const volume = config.runner?.volume ?? containerName.replaceAll('-', '_'); + + await confirmAndExit( + `Are you sure you want to clear the emulator container "${containerName}" and volume "${volume}"?` + ); + + await spawn({ + command: runner, + args: ['container', 'rm', containerName], + silentOut: true + }); + + await spawn({ + command: runner, + args: ['volume', 'rm', volume], + silentOut: true + }); +}; + const assertContainerRunning = async ({ containerName, runner