From e98cdcd5149c549d9ecb8d99e4987ec8ad547de1 Mon Sep 17 00:00:00 2001 From: Ivan Duplenskikh Date: Thu, 7 Dec 2023 16:27:43 +0100 Subject: [PATCH 1/7] Add doNotAskAgain buttons for Sign In and Select Organization --- src/schema-association-service.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/schema-association-service.ts b/src/schema-association-service.ts index 7f9a3df8..9d0cf3a1 100644 --- a/src/schema-association-service.ts +++ b/src/schema-association-service.ts @@ -98,13 +98,16 @@ async function autoDetectSchema( workspaceFolder: vscode.WorkspaceFolder): Promise { const azureAccountApi = await getAzureAccountExtensionApi(); + const doNotAskAgainSignIn = context.globalState.get('doNotAskAgainSignIn'); + logger.log(`doNotAskAgainSignIn status: ${doNotAskAgainSignIn}`); + // We could care less about the subscriptions; all we need are the sessions. // However, there's no waitForSessions API, and waitForLogin returns before // the underlying account information is guaranteed to finish loading. // The next-best option is then waitForSubscriptions which, by definition, // can't return until the sessions are also available. // This only returns false if there is no login. - if (!(await azureAccountApi.waitForSubscriptions())) { + if (!(await azureAccountApi.waitForSubscriptions()) && !doNotAskAgainSignIn) { logger.log(`Waiting for login`, 'SchemaDetection'); try { @@ -117,7 +120,7 @@ async function autoDetectSchema( // Don't await this message so that we can return the fallback schema instead of blocking. // We'll detect the login in extension.ts and then re-request the schema. - void vscode.window.showInformationMessage(Messages.signInForEnhancedIntelliSense, Messages.signInLabel) + void vscode.window.showInformationMessage(Messages.signInForEnhancedIntelliSense, Messages.signInLabel, Messages.doNotAskAgain) .then(async action => { if (action === Messages.signInLabel) { await vscode.window.withProgress({ @@ -126,6 +129,8 @@ async function autoDetectSchema( }, async () => { await vscode.commands.executeCommand("azure-account.login"); }); + } else if (action === Messages.doNotAskAgain) { + await context.globalState.update('doNotAskAgainSignIn', true); } }); @@ -177,6 +182,13 @@ async function autoDetectSchema( } else { logger.log(`${workspaceFolder.name} has no remote URL or is not an Azure repo`, 'SchemaDetection'); + const doNotAskAgainSelectOrg = context.globalState.get('doNotAskAgainSelectOrg'); + logger.log(`doNotAskAgainSelectOrg status: ${doNotAskAgainSelectOrg}`); + + if (doNotAskAgainSelectOrg) { + return; + } + const azurePipelinesDetails = context.workspaceState.get<{ [folder: string]: { organization: string; tenant: string; } }>('azurePipelinesDetails'); @@ -199,7 +211,7 @@ async function autoDetectSchema( // We'll detect when they choose the organization in extension.ts and then re-request the schema. void vscode.window.showInformationMessage( format(Messages.selectOrganizationForEnhancedIntelliSense, workspaceFolder.name), - Messages.selectOrganizationLabel) + Messages.selectOrganizationLabel, Messages.doNotAskAgain) .then(async action => { if (action === Messages.selectOrganizationLabel) { // Lazily construct list of organizations so that we can immediately show the quick pick, @@ -237,6 +249,8 @@ async function autoDetectSchema( }); selectOrganizationEvent.fire(workspaceFolder); + } else if (action === Messages.doNotAskAgain) { + await context.globalState.update('doNotAskAgainSelectOrg', true); } }); return undefined; From 0b578dc45a1b78672c966157289e525cc311848c Mon Sep 17 00:00:00 2001 From: Ivan Duplenskikh Date: Mon, 8 Jan 2024 10:57:19 +0100 Subject: [PATCH 2/7] Add reset state command, move check to separate line and change log messages --- package.json | 5 ++++ src/extension.ts | 4 +++- src/schema-association-service.ts | 39 ++++++++++++++++++++----------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index effb14c1..5a6eee4c 100644 --- a/package.json +++ b/package.json @@ -115,6 +115,11 @@ "command": "azure-pipelines.configure-pipeline", "title": "Configure Pipeline", "category": "Azure Pipelines" + }, + { + "command": "azure-pipelines.reset-state", + "title": "Reset state", + "category": "Azure Pipelines" } ], "menus": { diff --git a/src/extension.ts b/src/extension.ts index 71e1def0..3d3c727a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -8,7 +8,7 @@ import * as vscode from 'vscode'; import * as languageclient from 'vscode-languageclient/node'; import * as logger from './logger'; -import { getSchemaAssociation, locateSchemaFile, onDidSelectOrganization, SchemaAssociationNotification } from './schema-association-service'; +import { getSchemaAssociation, locateSchemaFile, onDidSelectOrganization, resetState, SchemaAssociationNotification } from './schema-association-service'; import { schemaContributor, CUSTOM_SCHEMA_REQUEST, CUSTOM_CONTENT_REQUEST } from './schema-contributor'; import { telemetryHelper } from './helpers/telemetryHelper'; import { getAzureAccountExtensionApi } from './extensionApis'; @@ -115,6 +115,8 @@ async function activateYmlContributor(context: vscode.ExtensionContext) { context.subscriptions.push(onDidSelectOrganization(async workspaceFolder => { await loadSchema(context, client, workspaceFolder); })); + + context.subscriptions.push(vscode.commands.registerCommand("azure-pipelines.reset-state", async () => await resetState(context))); } // Find the schema and notify the server. diff --git a/src/schema-association-service.ts b/src/schema-association-service.ts index 9d0cf3a1..353ae04d 100644 --- a/src/schema-association-service.ts +++ b/src/schema-association-service.ts @@ -28,8 +28,17 @@ export const onDidSelectOrganization = selectOrganizationEvent.event; const seenOrganizations = new Set(); const lastUpdated1ESPTSchema = new Map(); +export const DO_NOT_ASK_SIGN_IN_KEY = "DO_NOT_ASK_SIGN_IN_KEY"; +export const DO_NOT_ASK_SELECT_ORG_KEY = "DO_NOT_ASK_SELECT_ORG_KEY"; + let repoId1espt: string | undefined = undefined; +export async function resetState(context: vscode.ExtensionContext) { + await context.globalState.update(DO_NOT_ASK_SIGN_IN_KEY, undefined); + await context.globalState.update(DO_NOT_ASK_SELECT_ORG_KEY, undefined); + logger.log(`State is reset`); +} + export async function locateSchemaFile( context: vscode.ExtensionContext, workspaceFolder: vscode.WorkspaceFolder | undefined): Promise { @@ -98,16 +107,17 @@ async function autoDetectSchema( workspaceFolder: vscode.WorkspaceFolder): Promise { const azureAccountApi = await getAzureAccountExtensionApi(); - const doNotAskAgainSignIn = context.globalState.get('doNotAskAgainSignIn'); - logger.log(`doNotAskAgainSignIn status: ${doNotAskAgainSignIn}`); - - // We could care less about the subscriptions; all we need are the sessions. - // However, there's no waitForSessions API, and waitForLogin returns before - // the underlying account information is guaranteed to finish loading. - // The next-best option is then waitForSubscriptions which, by definition, - // can't return until the sessions are also available. - // This only returns false if there is no login. - if (!(await azureAccountApi.waitForSubscriptions()) && !doNotAskAgainSignIn) { + const doNotAskAgainSignIn = context.globalState.get(DO_NOT_ASK_SIGN_IN_KEY); + logger.log(`Exiting early. Do not ask again for signing in ${doNotAskAgainSignIn}`); + + if (!doNotAskAgainSignIn) { + // We could care less about the subscriptions; all we need are the sessions. + // However, there's no waitForSessions API, and waitForLogin returns before + // the underlying account information is guaranteed to finish loading. + // The next-best option is then waitForSubscriptions which, by definition, + // can't return until the sessions are also available. + // This only returns false if there is no login. + if (!(await azureAccountApi.waitForSubscriptions())) { logger.log(`Waiting for login`, 'SchemaDetection'); try { @@ -130,10 +140,11 @@ async function autoDetectSchema( await vscode.commands.executeCommand("azure-account.login"); }); } else if (action === Messages.doNotAskAgain) { - await context.globalState.update('doNotAskAgainSignIn', true); + await context.globalState.update(DO_NOT_ASK_SIGN_IN_KEY, true); } }); + } return undefined; } @@ -182,8 +193,8 @@ async function autoDetectSchema( } else { logger.log(`${workspaceFolder.name} has no remote URL or is not an Azure repo`, 'SchemaDetection'); - const doNotAskAgainSelectOrg = context.globalState.get('doNotAskAgainSelectOrg'); - logger.log(`doNotAskAgainSelectOrg status: ${doNotAskAgainSelectOrg}`); + const doNotAskAgainSelectOrg = context.globalState.get(DO_NOT_ASK_SELECT_ORG_KEY); + logger.log(`Exiting early. Do not ask selecting organization: ${doNotAskAgainSelectOrg}`); if (doNotAskAgainSelectOrg) { return; @@ -250,7 +261,7 @@ async function autoDetectSchema( selectOrganizationEvent.fire(workspaceFolder); } else if (action === Messages.doNotAskAgain) { - await context.globalState.update('doNotAskAgainSelectOrg', true); + await context.globalState.update(DO_NOT_ASK_SELECT_ORG_KEY, true); } }); return undefined; From 0e41644aae26c55158e0c4d9df040c504f04bd11 Mon Sep 17 00:00:00 2001 From: Ivan Duplenskikh Date: Mon, 8 Jan 2024 11:05:48 +0100 Subject: [PATCH 3/7] Update indent --- src/schema-association-service.ts | 46 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/schema-association-service.ts b/src/schema-association-service.ts index 353ae04d..05e6257c 100644 --- a/src/schema-association-service.ts +++ b/src/schema-association-service.ts @@ -118,31 +118,31 @@ async function autoDetectSchema( // can't return until the sessions are also available. // This only returns false if there is no login. if (!(await azureAccountApi.waitForSubscriptions())) { - logger.log(`Waiting for login`, 'SchemaDetection'); + logger.log(`Waiting for login`, 'SchemaDetection'); - try { - await delete1ESPTSchemaFileIfPresent(context); - logger.log("1ESPTSchema folder deleted as user is not signed in", 'SchemaDetection') - } - catch (error) { - logger.log(`Error ${String(error)} while trying to delete 1ESPTSchema folder. Either the folder does not exist or there is an actual error.`, 'SchemaDetection') - } + try { + await delete1ESPTSchemaFileIfPresent(context); + logger.log("1ESPTSchema folder deleted as user is not signed in", 'SchemaDetection') + } + catch (error) { + logger.log(`Error ${String(error)} while trying to delete 1ESPTSchema folder. Either the folder does not exist or there is an actual error.`, 'SchemaDetection') + } - // Don't await this message so that we can return the fallback schema instead of blocking. - // We'll detect the login in extension.ts and then re-request the schema. - void vscode.window.showInformationMessage(Messages.signInForEnhancedIntelliSense, Messages.signInLabel, Messages.doNotAskAgain) - .then(async action => { - if (action === Messages.signInLabel) { - await vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title: Messages.waitForAzureSignIn, - }, async () => { - await vscode.commands.executeCommand("azure-account.login"); - }); - } else if (action === Messages.doNotAskAgain) { - await context.globalState.update(DO_NOT_ASK_SIGN_IN_KEY, true); - } - }); + // Don't await this message so that we can return the fallback schema instead of blocking. + // We'll detect the login in extension.ts and then re-request the schema. + void vscode.window.showInformationMessage(Messages.signInForEnhancedIntelliSense, Messages.signInLabel, Messages.doNotAskAgain) + .then(async action => { + if (action === Messages.signInLabel) { + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: Messages.waitForAzureSignIn, + }, async () => { + await vscode.commands.executeCommand("azure-account.login"); + }); + } else if (action === Messages.doNotAskAgain) { + await context.globalState.update(DO_NOT_ASK_SIGN_IN_KEY, true); + } + }); } return undefined; From 8a5f1153c5fe19aa289e05772cf6088d47d26c50 Mon Sep 17 00:00:00 2001 From: Winston Liu Date: Fri, 12 Jan 2024 14:41:15 -0800 Subject: [PATCH 4/7] Clarify what the setting does --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5a6eee4c..bf003f85 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ }, { "command": "azure-pipelines.reset-state", - "title": "Reset state", + "title": "Reset 'do not ask again' messages", "category": "Azure Pipelines" } ], From d339c4fc29b1392dc699b3f3d6596cccdcd3d9b7 Mon Sep 17 00:00:00 2001 From: Winston Liu Date: Fri, 12 Jan 2024 14:46:24 -0800 Subject: [PATCH 5/7] Only check DNAA right before the prompts --- src/schema-association-service.ts | 87 ++++++++++++++++--------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/src/schema-association-service.ts b/src/schema-association-service.ts index 05e6257c..5c1fee01 100644 --- a/src/schema-association-service.ts +++ b/src/schema-association-service.ts @@ -107,44 +107,46 @@ async function autoDetectSchema( workspaceFolder: vscode.WorkspaceFolder): Promise { const azureAccountApi = await getAzureAccountExtensionApi(); - const doNotAskAgainSignIn = context.globalState.get(DO_NOT_ASK_SIGN_IN_KEY); - logger.log(`Exiting early. Do not ask again for signing in ${doNotAskAgainSignIn}`); - - if (!doNotAskAgainSignIn) { - // We could care less about the subscriptions; all we need are the sessions. - // However, there's no waitForSessions API, and waitForLogin returns before - // the underlying account information is guaranteed to finish loading. - // The next-best option is then waitForSubscriptions which, by definition, - // can't return until the sessions are also available. - // This only returns false if there is no login. - if (!(await azureAccountApi.waitForSubscriptions())) { - logger.log(`Waiting for login`, 'SchemaDetection'); - - try { - await delete1ESPTSchemaFileIfPresent(context); - logger.log("1ESPTSchema folder deleted as user is not signed in", 'SchemaDetection') - } - catch (error) { - logger.log(`Error ${String(error)} while trying to delete 1ESPTSchema folder. Either the folder does not exist or there is an actual error.`, 'SchemaDetection') - } - - // Don't await this message so that we can return the fallback schema instead of blocking. - // We'll detect the login in extension.ts and then re-request the schema. - void vscode.window.showInformationMessage(Messages.signInForEnhancedIntelliSense, Messages.signInLabel, Messages.doNotAskAgain) - .then(async action => { - if (action === Messages.signInLabel) { - await vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title: Messages.waitForAzureSignIn, - }, async () => { - await vscode.commands.executeCommand("azure-account.login"); - }); - } else if (action === Messages.doNotAskAgain) { - await context.globalState.update(DO_NOT_ASK_SIGN_IN_KEY, true); - } - }); + // We could care less about the subscriptions; all we need are the sessions. + // However, there's no waitForSessions API, and waitForLogin returns before + // the underlying account information is guaranteed to finish loading. + // The next-best option is then waitForSubscriptions which, by definition, + // can't return until the sessions are also available. + // This only returns false if there is no login. + if (!(await azureAccountApi.waitForSubscriptions())) { + const doNotAskAgainSignIn = context.globalState.get(DO_NOT_ASK_SIGN_IN_KEY); + if (doNotAskAgainSignIn) { + logger.log(`Not prompting for login - do not ask again was set`, 'SchemaDetection'); + return undefined; + } + + if (!doNotAskAgainSignIn) { + logger.log(`Waiting for login`, 'SchemaDetection'); + try { + await delete1ESPTSchemaFileIfPresent(context); + logger.log("1ESPTSchema folder deleted as user is not signed in", 'SchemaDetection') + } + catch (error) { + logger.log(`Error ${String(error)} while trying to delete 1ESPTSchema folder. Either the folder does not exist or there is an actual error.`, 'SchemaDetection') } + + // Don't await this message so that we can return the fallback schema instead of blocking. + // We'll detect the login in extension.ts and then re-request the schema. + void vscode.window.showInformationMessage(Messages.signInForEnhancedIntelliSense, Messages.signInLabel, Messages.doNotAskAgain) + .then(async action => { + if (action === Messages.signInLabel) { + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: Messages.waitForAzureSignIn, + }, async () => { + await vscode.commands.executeCommand("azure-account.login"); + }); + } else if (action === Messages.doNotAskAgain) { + await context.globalState.update(DO_NOT_ASK_SIGN_IN_KEY, true); + } + }); + return undefined; } @@ -193,13 +195,6 @@ async function autoDetectSchema( } else { logger.log(`${workspaceFolder.name} has no remote URL or is not an Azure repo`, 'SchemaDetection'); - const doNotAskAgainSelectOrg = context.globalState.get(DO_NOT_ASK_SELECT_ORG_KEY); - logger.log(`Exiting early. Do not ask selecting organization: ${doNotAskAgainSelectOrg}`); - - if (doNotAskAgainSelectOrg) { - return; - } - const azurePipelinesDetails = context.workspaceState.get<{ [folder: string]: { organization: string; tenant: string; } }>('azurePipelinesDetails'); @@ -213,6 +208,12 @@ async function autoDetectSchema( `Using cached information for ${workspaceFolder.name}: ${organizationName}, ${session?.tenantId}`, 'SchemaDetection'); } else { + const doNotAskAgainSelectOrg = context.globalState.get(DO_NOT_ASK_SELECT_ORG_KEY); + if (doNotAskAgainSelectOrg) { + logger.log(`Not prompting for organization - do not ask again was set`, 'SchemaDetection'); + return; + } + logger.log(`Prompting for organization for ${workspaceFolder.name}`, 'SchemaDetection'); // Otherwise, we need to manually prompt. From 8f4ab5d8fb66f19d7c2e0e26b9393b43643c1321 Mon Sep 17 00:00:00 2001 From: Winston Liu Date: Fri, 12 Jan 2024 14:47:43 -0800 Subject: [PATCH 6/7] Delete missed line --- src/schema-association-service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/schema-association-service.ts b/src/schema-association-service.ts index 5c1fee01..bd959438 100644 --- a/src/schema-association-service.ts +++ b/src/schema-association-service.ts @@ -120,7 +120,6 @@ async function autoDetectSchema( return undefined; } - if (!doNotAskAgainSignIn) { logger.log(`Waiting for login`, 'SchemaDetection'); try { From 02e155f7fafd621b73528f450d86e14cf02ca6d1 Mon Sep 17 00:00:00 2001 From: Ivan Duplenskikh Date: Mon, 12 Feb 2024 12:03:11 +0100 Subject: [PATCH 7/7] Clarify the method name --- src/extension.ts | 4 ++-- src/schema-association-service.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 3d3c727a..b24482c4 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -8,7 +8,7 @@ import * as vscode from 'vscode'; import * as languageclient from 'vscode-languageclient/node'; import * as logger from './logger'; -import { getSchemaAssociation, locateSchemaFile, onDidSelectOrganization, resetState, SchemaAssociationNotification } from './schema-association-service'; +import { getSchemaAssociation, locateSchemaFile, onDidSelectOrganization, resetDoNotAskState, SchemaAssociationNotification } from './schema-association-service'; import { schemaContributor, CUSTOM_SCHEMA_REQUEST, CUSTOM_CONTENT_REQUEST } from './schema-contributor'; import { telemetryHelper } from './helpers/telemetryHelper'; import { getAzureAccountExtensionApi } from './extensionApis'; @@ -116,7 +116,7 @@ async function activateYmlContributor(context: vscode.ExtensionContext) { await loadSchema(context, client, workspaceFolder); })); - context.subscriptions.push(vscode.commands.registerCommand("azure-pipelines.reset-state", async () => await resetState(context))); + context.subscriptions.push(vscode.commands.registerCommand("azure-pipelines.reset-state", async () => await resetDoNotAskState(context))); } // Find the schema and notify the server. diff --git a/src/schema-association-service.ts b/src/schema-association-service.ts index bd959438..67c5c569 100644 --- a/src/schema-association-service.ts +++ b/src/schema-association-service.ts @@ -33,10 +33,10 @@ export const DO_NOT_ASK_SELECT_ORG_KEY = "DO_NOT_ASK_SELECT_ORG_KEY"; let repoId1espt: string | undefined = undefined; -export async function resetState(context: vscode.ExtensionContext) { +export async function resetDoNotAskState(context: vscode.ExtensionContext) { await context.globalState.update(DO_NOT_ASK_SIGN_IN_KEY, undefined); await context.globalState.update(DO_NOT_ASK_SELECT_ORG_KEY, undefined); - logger.log(`State is reset`); + logger.log("State is reset"); } export async function locateSchemaFile(