Skip to content

Commit

Permalink
Merge #5288 from justinmk3/setcontext
Browse files Browse the repository at this point in the history
feat(setContext): hoist setContext into a shared module
  • Loading branch information
justinmk3 authored Jul 11, 2024
2 parents a3d127b + 80e715b commit 31bd1f9
Show file tree
Hide file tree
Showing 41 changed files with 295 additions and 151 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ module.exports = {

'aws-toolkits/no-only-in-tests': 'error',
'aws-toolkits/no-await-on-vscode-msg': 'error',
'aws-toolkits/no-banned-usages': 'error',
'aws-toolkits/no-incorrect-once-usage': 'error',
'aws-toolkits/no-string-exec-for-child-process': 'error',

Expand Down
3 changes: 2 additions & 1 deletion docs/arch_runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ TODO: move from CONTRIBUTING.md
## VSCode context keys

VScode extensions can use vscode 'setContext' command to set special context keys which are
available in `package.json`.
available in `package.json`. Use this only if there is no other alternative (it's shared, global,
mutable state).

### Defining a new setContext key

Expand Down
5 changes: 2 additions & 3 deletions packages/amazonq/src/extensionCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { join } from 'path'
import {
activate as activateCodeWhisperer,
shutdown as shutdownCodeWhisperer,
amazonQDismissedKey,
AuthUtil,
} from 'aws-core-vscode/codewhispererCommon'
import {
Expand All @@ -27,7 +26,7 @@ import {
getMachineId,
messages,
} from 'aws-core-vscode/shared'
import { fs, errors } from 'aws-core-vscode/shared'
import { fs, errors, setContext } from 'aws-core-vscode/shared'
import { initializeAuth, CredentialsStore, LoginManager, AuthUtils, SsoConnection } from 'aws-core-vscode/auth'
import { CommonAuthWebview } from 'aws-core-vscode/login'
import { VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils'
Expand Down Expand Up @@ -117,7 +116,7 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is
registerCommands(context)

// Hide the Amazon Q tree in toolkit explorer
await vscode.commands.executeCommand('setContext', amazonQDismissedKey, true)
await setContext('aws.toolkit.amazonq.dismissed', true)

// reload webviews
await vscode.commands.executeCommand('workbench.action.webview.reloadWebviewAction')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import * as vscode from 'vscode'
import * as sinon from 'sinon'
import {
onAcceptance,
userGroupKey,
UserGroup,
AcceptedSuggestionEntry,
session,
Expand Down Expand Up @@ -80,7 +79,7 @@ describe('onAcceptance', function () {
})

it('Should report telemetry that records this user decision event', async function () {
await globals.context.globalState.update(userGroupKey, {
await globals.context.globalState.update('CODEWHISPERER_USER_GROUP', {
group: UserGroup.Control,
version: extensionVersion,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
AuthUtil,
session,
CodeWhispererUserGroupSettings,
userGroupKey,
UserGroup,
} from 'aws-core-vscode/codewhisperer'
import { globals } from 'aws-core-vscode/shared'
Expand Down Expand Up @@ -58,7 +57,7 @@ describe('onInlineAcceptance', function () {
})

it('Should report telemetry that records this user decision event', async function () {
await globals.context.globalState.update(userGroupKey, {
await globals.context.globalState.update('CODEWHISPERER_USER_GROUP', {
group: UserGroup.Classifier,
version: extensionVersion,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
ConfigurationEntry,
RecommendationHandler,
CodeWhispererCodeCoverageTracker,
userGroupKey,
UserGroup,
supplementalContextUtil,
} from 'aws-core-vscode/codewhisperer'
Expand Down Expand Up @@ -115,7 +114,7 @@ describe('recommendationHandler', function () {
})

it('should call telemetry function that records a CodeWhisperer service invocation', async function () {
await globals.context.globalState.update(userGroupKey, {
await globals.context.globalState.update('CODEWHISPERER_USER_GROUP', {
group: UserGroup.CrossFile,
version: extensionVersion,
})
Expand Down Expand Up @@ -167,7 +166,7 @@ describe('recommendationHandler', function () {
})

it('should call telemetry function that records a Empty userDecision event', async function () {
await globals.context.globalState.update(userGroupKey, {
await globals.context.globalState.update('CODEWHISPERER_USER_GROUP', {
group: UserGroup.CrossFile,
version: extensionVersion,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
vsCodeState,
TelemetryHelper,
AuthUtil,
userGroupKey,
UserGroup,
CodeWhispererUserGroupSettings,
} from 'aws-core-vscode/codewhisperer'
Expand Down Expand Up @@ -524,7 +523,7 @@ describe('codewhispererCodecoverageTracker', function () {
})

it('should emit correct code coverage telemetry in python file', async function () {
await globals.context.globalState.update(userGroupKey, {
await globals.globalState.update('CODEWHISPERER_USER_GROUP', {
group: UserGroup.Control,
version: extensionVersion,
})
Expand All @@ -547,7 +546,7 @@ describe('codewhispererCodecoverageTracker', function () {
})

it('should emit correct code coverage telemetry when success count = 0', async function () {
await globals.context.globalState.update(userGroupKey, {
await globals.globalState.update('CODEWHISPERER_USER_GROUP', {
group: UserGroup.Control,
version: extensionVersion,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { assertTelemetryCurried } from 'aws-core-vscode/test'
import {
AuthUtil,
CodeWhispererTracker,
userGroupKey,
UserGroup,
CodeWhispererUserGroupSettings,
} from 'aws-core-vscode/codewhisperer'
Expand Down Expand Up @@ -96,7 +95,7 @@ describe('codewhispererTracker', function () {
})

it('Should call recordCodewhispererUserModification with suggestion event', async function () {
await globals.context.globalState.update(userGroupKey, {
await globals.context.globalState.update('CODEWHISPERER_USER_GROUP', {
group: UserGroup.CrossFile,
version: extensionVersion,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ describe('getCodeWhispererUserGroup', function () {
})

it('getUserGroup should set the group and version if there is none', async function () {
await globals.context.globalState.update(CodeWhispererConstants.userGroupKey, undefined)
await globals.globalState.update('CODEWHISPERER_USER_GROUP', undefined)

assert.ok(!globals.context.globalState.get(CodeWhispererConstants.userGroupKey))
assert.ok(!globals.globalState.get('CODEWHISPERER_USER_GROUP'))

assert.ok(CodeWhispererUserGroupSettings.getUserGroup())
assert.ok(CodeWhispererUserGroupSettings.instance.version)
Expand All @@ -30,7 +30,7 @@ describe('getCodeWhispererUserGroup', function () {
})

it('should return the same result', async function () {
await globals.context.globalState.update(CodeWhispererConstants.userGroupKey, undefined)
await globals.globalState.update('CODEWHISPERER_USER_GROUP', undefined)

const group0 = CodeWhispererUserGroupSettings.getUserGroup()
const group1 = CodeWhispererUserGroupSettings.getUserGroup()
Expand All @@ -44,7 +44,7 @@ describe('getCodeWhispererUserGroup', function () {
})

it('should return result stored in the extension context if the plugin version remains the same', async function () {
await globals.context.globalState.update(CodeWhispererConstants.userGroupKey, {
await globals.globalState.update('CODEWHISPERER_USER_GROUP', {
group: CodeWhispererConstants.UserGroup.Control,
version: extensionVersion,
})
Expand All @@ -56,7 +56,7 @@ describe('getCodeWhispererUserGroup', function () {
})

it('should return different result if the plugin version is not the same', async function () {
await globals.context.globalState.update(CodeWhispererConstants.userGroupKey, {
await globals.globalState.update('CODEWHISPERER_USER_GROUP', {
group: CodeWhispererConstants.UserGroup.Control,
version: 'fake-extension-version',
})
Expand Down
7 changes: 3 additions & 4 deletions packages/core/src/amazonq/explorer/amazonQChildrenNodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import { installAmazonQExtension } from '../../codewhisperer/commands/basicComma
import { amazonQHelpUrl } from '../../shared/constants'
import { cwTreeNodeSource } from '../../codewhisperer/commands/types'
import { VSCODE_EXTENSION_ID } from '../../shared/extensions'
import { globals } from '../../shared'
import { amazonQDismissedKey } from '../../codewhisperer/models/constants'
import { globals, setContext } from '../../shared'
import { ExtStartUpSources, telemetry } from '../../shared/telemetry'
import { ExtensionUse } from '../../auth/utils'

Expand All @@ -34,8 +33,8 @@ export const dismissQTree = Commands.declare(
source: ExtensionUse.instance.isFirstUse() ? ExtStartUpSources.firstStartUp : ExtStartUpSources.none,
})

await globals.context.globalState.update(amazonQDismissedKey, true)
await vscode.commands.executeCommand('setContext', amazonQDismissedKey, true)
await globals.globalState.update('aws.toolkit.amazonq.dismissed', true)
await setContext('aws.toolkit.amazonq.dismissed', true)

telemetry.record({ action: 'dismissQExplorerTree' })
})
Expand Down
6 changes: 2 additions & 4 deletions packages/core/src/amazonq/util/viewBadgeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ import { window, TreeItem, TreeView, ViewBadge } from 'vscode'
import { getLogger } from '../../shared/logger'
import globals from '../../shared/extensionGlobals'
import { AuthUtil } from '../../codewhisperer/util/authUtil'
import { GlobalState } from '../../shared/globalState'

let badgeHelperView: TreeView<void> | undefined
const mementoKey = 'hasAlreadyOpenedAmazonQ'

/**
* invisible view meant exclusively to handle the view badge, note declaration has `"when": false`.
Expand Down Expand Up @@ -44,7 +42,7 @@ export function changeViewBadge(badge?: ViewBadge) {
* Removes the view badge from the badge helper view and prevents it from showing up ever again
*/
export function deactivateInitialViewBadge() {
GlobalState.instance.tryUpdate(mementoKey, true)
globals.globalState.tryUpdate('hasAlreadyOpenedAmazonQ', true)
changeViewBadge()
}

Expand Down Expand Up @@ -74,7 +72,7 @@ async function showInitialViewBadge() {
*/
export async function shouldShowBadge(): Promise<boolean> {
const memento = globals.context.globalState
const hasAlreadyShown = memento.get(mementoKey)
const hasAlreadyShown = memento.get('hasAlreadyOpenedAmazonQ')
if (!hasAlreadyShown) {
const state = await AuthUtil.instance.getChatAuthState()
if (state.codewhispererCore === 'connected' && state.codewhispererChat !== 'connected') {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/amazonqGumby/activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ import { ProposedTransformationExplorer } from '../codewhisperer/service/transfo
import { CodeTransformTelemetryState } from './telemetry/codeTransformTelemetryState'
import { telemetry } from '../shared/telemetry/telemetry'
import { CancelActionPositions } from './telemetry/codeTransformTelemetry'
import { setContext } from '../shared'

export async function activate(context: ExtContext) {
void vscode.commands.executeCommand('setContext', 'gumby.wasQCodeTransformationUsed', false)
void setContext('gumby.wasQCodeTransformationUsed', false)

const transformationHubViewProvider = new TransformationHubViewProvider()
new ProposedTransformationExplorer(context.extensionContext)
Expand Down
7 changes: 2 additions & 5 deletions packages/core/src/auth/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { extensionVersion } from '../shared/vscode/env'
import { ExtStartUpSources } from '../shared/telemetry'
import { CommonAuthWebview } from '../login/webview/vue/backend'
import { AuthSource } from '../login/webview/util'
import { setContext } from '../shared/vscode/setContext'

// iam-only excludes Builder ID and IAM Identity Center from the list of valid connections
// TODO: Understand if "iam" should include these from the list at all
Expand Down Expand Up @@ -480,11 +481,7 @@ export class AuthNode implements TreeNode<Auth> {
CommonAuthWebview.authSource = ExtensionUse.instance.isFirstUse()
? ExtStartUpSources.firstStartUp
: ExtStartUpSources.reload
void vscode.commands.executeCommand(
'setContext',
'aws.explorer.showAuthView',
!this.resource.hasConnections
)
void setContext('aws.explorer.showAuthView', !this.resource.hasConnections)
})
.catch(e => {
getLogger().error('tryAutoConnect failed: %s', (e as Error).message)
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/awsService/s3/commands/uploadFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import { CancellationError } from '../../../shared/utilities/timeoutUtils'
import { progressReporter } from '../progressReporter'
import globals from '../../../shared/extensionGlobals'
import { telemetry } from '../../../shared/telemetry/telemetry'
import { GlobalState } from '../../../shared/globalState'

export interface FileSizeBytes {
/**
Expand Down Expand Up @@ -102,7 +101,7 @@ export async function uploadFileCommand(
})
)
if (node instanceof S3FolderNode) {
GlobalState.instance.tryUpdate('aws.lastUploadedToS3Folder', {
globals.globalState.tryUpdate('aws.lastUploadedToS3Folder', {
bucket: node.bucket,
folder: node.folder,
})
Expand Down Expand Up @@ -166,7 +165,7 @@ export async function uploadFileCommand(
)

if (bucketResponse.folder) {
GlobalState.instance.tryUpdate('aws.lastUploadedToS3Folder', {
globals.globalState.tryUpdate('aws.lastUploadedToS3Folder', {
bucket: bucketResponse.bucket,
folder: bucketResponse.folder,
})
Expand Down
9 changes: 4 additions & 5 deletions packages/core/src/awsexplorer/activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ import { CodeCatalystRootNode } from '../codecatalyst/explorer'
import { CodeCatalystAuthenticationProvider } from '../codecatalyst/auth'
import { S3FolderNode } from '../awsService/s3/explorer/s3FolderNode'
import { AmazonQNode, refreshAmazonQ, refreshAmazonQRootNode } from '../amazonq/explorer/amazonQTreeNode'
import { GlobalState } from '../shared/globalState'
import { activateViewsShared, registerToolView } from './activationShared'
import { isExtensionInstalled } from '../shared/utilities'
import { amazonQDismissedKey } from '../codewhisperer/models/constants'
import { CommonAuthViewProvider } from '../login/webview'
import { setContext } from '../shared'

/**
* Activates the AWS Explorer UI and related functionality.
Expand All @@ -53,7 +52,7 @@ export async function activate(args: {
})
view.onDidExpandElement(element => {
if (element.element instanceof S3FolderNode) {
GlobalState.instance.tryUpdate('aws.lastTouchedS3Folder', {
globals.globalState.tryUpdate('aws.lastTouchedS3Folder', {
bucket: element.element.bucket,
folder: element.element.folder,
})
Expand Down Expand Up @@ -110,9 +109,9 @@ export async function activate(args: {
if (!isCloud9()) {
if (
isExtensionInstalled(VSCODE_EXTENSION_ID.amazonq) ||
globals.context.globalState.get<boolean>(amazonQDismissedKey)
globals.globalState.get<boolean>('aws.toolkit.amazonq.dismissed')
) {
await vscode.commands.executeCommand('setContext', amazonQDismissedKey, true)
await setContext('aws.toolkit.amazonq.dismissed', true)
}

// We should create the tree even if it's dismissed, in case the user installs Amazon Q later.
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/codecatalyst/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { createBuilderIdConnection } from '../auth/utils'
import { builderIdStartUrl } from '../auth/sso/model'
import { showReauthenticateMessage } from '../shared/utilities/messages'
import { ToolkitPromptSettings } from '../shared/settings'
import { setContext } from '../shared/vscode/setContext'

// Secrets stored on the macOS keychain appear as individual entries for each key
// This is fine so long as the user has only a few accounts. Otherwise this should
Expand Down Expand Up @@ -55,7 +56,7 @@ export const isUpgradeableConnection = (conn: Connection): conn is SsoConnection
isSsoConnection(conn) && !isValidCodeCatalystConnection(conn)

export function setCodeCatalystConnectedContext(isConnected: boolean) {
return vscode.commands.executeCommand('setContext', 'aws.codecatalyst.connected', isConnected)
return setContext('aws.codecatalyst.connected', isConnected)
}

type ConnectionState = {
Expand Down
2 changes: 0 additions & 2 deletions packages/core/src/codecatalyst/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,5 +362,3 @@ export interface DevEnvMemento {
/** CodeCatalyst Alias */
alias: string | undefined
}

export const codecatalystReconnectKey = 'CODECATALYST_RECONNECT'
Loading

0 comments on commit 31bd1f9

Please sign in to comment.