From d2987fa7836969e8821b148258bb8a8c0c6d6094 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Fri, 12 Sep 2025 11:52:08 +0200 Subject: [PATCH 1/8] Skip setup check if file watcher is not ready --- src/utils/setup-status.ts | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/utils/setup-status.ts b/src/utils/setup-status.ts index 08b31d6..0a8f561 100644 --- a/src/utils/setup-status.ts +++ b/src/utils/setup-status.ts @@ -47,10 +47,30 @@ export async function createSetupStatusTracker( ); const checkStatusNow = async () => { + const statusesInitialized = Object.values({ + awsProfileTracker: awsProfileTracker.status(), + authTracker: localStackAuthenticationTracker.status(), + licenseTracker: licenseTracker.status(), + }).every((check) => check !== undefined); + + if (!statusesInitialized) { + outputChannel.trace( + `[setup-status] File watchers not initialized yet, skipping status check : ${JSON.stringify( + { + awsProfileTracker: awsProfileTracker.status() ?? "undefined", + authTracker: + localStackAuthenticationTracker.status() ?? "undefined", + licenseTracker: licenseTracker.status() ?? "undefined", + }, + )}`, + ); + return; + } + statuses = await checkSetupStatus(outputChannel); const setupRequired = [ - Object.values(statuses), + ...Object.values(statuses), awsProfileTracker.status() === "ok", localStackAuthenticationTracker.status() === "ok", licenseTracker.status() === "ok", @@ -95,6 +115,16 @@ export async function createSetupStatusTracker( return Promise.resolve(); }); + outputChannel.trace( + `[setup-status.aws-profile] status before the first check : ${awsProfileTracker.status()}`, + ); + outputChannel.trace( + `[setup-status.auth] status before the first checkk : ${localStackAuthenticationTracker.status()}`, + ); + outputChannel.trace( + `[setup-status.license] status before the first check : ${licenseTracker.status()}`, + ); + await checkStatusNow(); return { From 2a9d7821ce4fece9991ffc4478769a94b7ee43a3 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Fri, 12 Sep 2025 12:01:15 +0200 Subject: [PATCH 2/8] Add file trackers status to status change log --- src/utils/setup-status.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/utils/setup-status.ts b/src/utils/setup-status.ts index 0a8f561..5fc0048 100644 --- a/src/utils/setup-status.ts +++ b/src/utils/setup-status.ts @@ -80,7 +80,12 @@ export async function createSetupStatusTracker( if (status !== newStatus) { status = newStatus; outputChannel.trace( - `[setup-status] Status changed to ${JSON.stringify(statuses)}`, + `[setup-status] Status changed to ${JSON.stringify({ + ...statuses, + awsProfileTracker: awsProfileTracker.status() ?? "undefined", + authTracker: localStackAuthenticationTracker.status() ?? "undefined", + licenseTracker: licenseTracker.status() ?? "undefined", + })}`, ); await emitter.emit(status); } From 188a8efdea8b76c8d4ae28478971636863c54bea Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Fri, 12 Sep 2025 13:13:51 +0200 Subject: [PATCH 3/8] Update file tracker status on tracker init --- src/utils/setup-status.ts | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/src/utils/setup-status.ts b/src/utils/setup-status.ts index 5fc0048..c922db9 100644 --- a/src/utils/setup-status.ts +++ b/src/utils/setup-status.ts @@ -47,26 +47,6 @@ export async function createSetupStatusTracker( ); const checkStatusNow = async () => { - const statusesInitialized = Object.values({ - awsProfileTracker: awsProfileTracker.status(), - authTracker: localStackAuthenticationTracker.status(), - licenseTracker: licenseTracker.status(), - }).every((check) => check !== undefined); - - if (!statusesInitialized) { - outputChannel.trace( - `[setup-status] File watchers not initialized yet, skipping status check : ${JSON.stringify( - { - awsProfileTracker: awsProfileTracker.status() ?? "undefined", - authTracker: - localStackAuthenticationTracker.status() ?? "undefined", - licenseTracker: licenseTracker.status() ?? "undefined", - }, - )}`, - ); - return; - } - statuses = await checkSetupStatus(outputChannel); const setupRequired = [ @@ -120,16 +100,6 @@ export async function createSetupStatusTracker( return Promise.resolve(); }); - outputChannel.trace( - `[setup-status.aws-profile] status before the first check : ${awsProfileTracker.status()}`, - ); - outputChannel.trace( - `[setup-status.auth] status before the first checkk : ${localStackAuthenticationTracker.status()}`, - ); - outputChannel.trace( - `[setup-status.license] status before the first check : ${licenseTracker.status()}`, - ); - await checkStatusNow(); return { @@ -213,6 +183,9 @@ function createFileStatusTracker( outputChannel.error(error instanceof Error ? error : String(error)); }); + // Update the status immediately on file tracker initialization + void updateStatus(); + return { status() { return status; From 782fbe3614e626693eb62b6023b7c74af431d92e Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Fri, 12 Sep 2025 13:36:38 +0200 Subject: [PATCH 4/8] Move refresh status bar after the last setup step --- src/plugins/setup.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index 3455661..1e83939 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -296,8 +296,6 @@ export default createPlugin( }), ); - void commands.executeCommand("localstack.refreshStatusBar"); - progress.report({ message: 'Finished configuring the AWS profile named "localstack".', @@ -326,6 +324,8 @@ export default createPlugin( return; } + void commands.executeCommand("localstack.refreshStatusBar"); + ///////////////////////////////////////////////////////////////////// if (localStackStatusTracker.status() === "running") { window From 2bfdc93b68e06d134283ea548fe09f390dfd6209 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Fri, 12 Sep 2025 13:36:57 +0200 Subject: [PATCH 5/8] Watch both auth and license file for license check --- src/utils/setup-status.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/setup-status.ts b/src/utils/setup-status.ts index c922db9..c00d892 100644 --- a/src/utils/setup-status.ts +++ b/src/utils/setup-status.ts @@ -255,7 +255,7 @@ function createLicenseStatusTracker( return createFileStatusTracker( outputChannel, "[setup-status.license]", - [LICENSE_FILENAME], + [LOCALSTACK_AUTH_FILENAME, LICENSE_FILENAME], async () => (await checkIsLicenseValid(outputChannel)) ? "ok" : "setup_required", ); From 7f453574eeff92879dd06d21c4d187d963a1d578 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Fri, 12 Sep 2025 13:53:38 +0200 Subject: [PATCH 6/8] Add TODO --- src/utils/setup-status.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/setup-status.ts b/src/utils/setup-status.ts index c00d892..16e8c82 100644 --- a/src/utils/setup-status.ts +++ b/src/utils/setup-status.ts @@ -255,7 +255,7 @@ function createLicenseStatusTracker( return createFileStatusTracker( outputChannel, "[setup-status.license]", - [LOCALSTACK_AUTH_FILENAME, LICENSE_FILENAME], + [LOCALSTACK_AUTH_FILENAME, LICENSE_FILENAME], //TODO rewrite to depend on change in localStackAuthenticationTracker async () => (await checkIsLicenseValid(outputChannel)) ? "ok" : "setup_required", ); From 036ffc7af65e98f5aded65301f29afde9fe71b1b Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Fri, 12 Sep 2025 14:44:00 +0200 Subject: [PATCH 7/8] Show Setup Wizard pop-up once setup is required This ensures that pop-up appears if setup is required at the start. Instead of synchronizing changes at the start we decided to have pop-up appearing every time the setup is broken. This shouldn't happen normally, but when it happens then setup wizard pop-up in addition to painting setup bar red can actually be helpful. --- src/plugins/setup.ts | 29 +++++++++++++++++------------ src/utils/setup-status.ts | 22 +++++++++++++++++++++- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index 1e83939..6f92d12 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -368,17 +368,22 @@ export default createPlugin( ), ); - if (setupStatusTracker.status() === "setup_required") { - window - .showInformationMessage("Setup LocalStack to get started.", { - title: "Setup", - command: "localstack.setup", - }) - .then((selected) => { - if (selected) { - commands.executeCommand(selected.command, "extension_startup"); - } - }); - } + setupStatusTracker.onChange((status) => { + if (status === "setup_required") { + void window + .showInformationMessage("Setup LocalStack to get started.", { + title: "Setup", + command: "localstack.setup", + }) + .then((selected) => { + if (selected) { + void commands.executeCommand( + selected.command, + "extension_startup", + ); + } + }); + } + }); }, ); diff --git a/src/utils/setup-status.ts b/src/utils/setup-status.ts index 16e8c82..e984dde 100644 --- a/src/utils/setup-status.ts +++ b/src/utils/setup-status.ts @@ -47,6 +47,26 @@ export async function createSetupStatusTracker( ); const checkStatusNow = async () => { + const allStatusesInitialized = Object.values({ + awsProfileTracker: awsProfileTracker.status(), + authTracker: localStackAuthenticationTracker.status(), + licenseTracker: licenseTracker.status(), + }).every((check) => check !== undefined); + + if (!allStatusesInitialized) { + outputChannel.trace( + `[setup-status] File watchers not initialized yet, skipping status check : ${JSON.stringify( + { + awsProfileTracker: awsProfileTracker.status() ?? "undefined", + authTracker: + localStackAuthenticationTracker.status() ?? "undefined", + licenseTracker: licenseTracker.status() ?? "undefined", + }, + )}`, + ); + return; + } + statuses = await checkSetupStatus(outputChannel); const setupRequired = [ @@ -255,7 +275,7 @@ function createLicenseStatusTracker( return createFileStatusTracker( outputChannel, "[setup-status.license]", - [LOCALSTACK_AUTH_FILENAME, LICENSE_FILENAME], //TODO rewrite to depend on change in localStackAuthenticationTracker + [LOCALSTACK_AUTH_FILENAME, LICENSE_FILENAME], //TODO rewrite to depend on change in localStackAuthenticationTrackerl async () => (await checkIsLicenseValid(outputChannel)) ? "ok" : "setup_required", ); From 4083f51ef6f7a8b0e2f7c9de9bd7284d2c4e76d9 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Fri, 12 Sep 2025 14:48:29 +0200 Subject: [PATCH 8/8] Fix typo --- src/utils/setup-status.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/setup-status.ts b/src/utils/setup-status.ts index e984dde..c3b70e0 100644 --- a/src/utils/setup-status.ts +++ b/src/utils/setup-status.ts @@ -275,7 +275,7 @@ function createLicenseStatusTracker( return createFileStatusTracker( outputChannel, "[setup-status.license]", - [LOCALSTACK_AUTH_FILENAME, LICENSE_FILENAME], //TODO rewrite to depend on change in localStackAuthenticationTrackerl + [LOCALSTACK_AUTH_FILENAME, LICENSE_FILENAME], //TODO rewrite to depend on change in localStackAuthenticationTracker async () => (await checkIsLicenseValid(outputChannel)) ? "ok" : "setup_required", );