From 591dc9a6167a62dce6b206d4c6d41b89362efd1a Mon Sep 17 00:00:00 2001 From: Scott Smith <154380171+scottwritescode@users.noreply.github.com> Date: Mon, 2 Dec 2024 17:29:01 -0600 Subject: [PATCH 01/13] fix(amazon q): add pl/1, bms filetypes #6067 ## Problem The codefileExtensions does not contain an extension type for `.pli` which is the common extension for PL/1, or for `.bms` which is Basic Mapping Support and common for screen definition files in IBM mainframe. Because of this, the files and code in them are not accessible in the workspace context for Amazon Q using the `/dev` quick action. When using the Q quick action '\dev' for `.pli` or `.bms` files, Q responds with the following message: > This appears to be an empty program or workspace with no source files present. There is nothing to explain at this time since no code or files are available for analysis. ## Solution - Add `.pli` and `.bms` as a known code file extension types. --- .../Bug Fix-80f16b7a-440d-4e06-89ad-1454c58ff28f.json | 4 ++++ packages/core/src/shared/filetypes.ts | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 packages/amazonq/.changes/next-release/Bug Fix-80f16b7a-440d-4e06-89ad-1454c58ff28f.json diff --git a/packages/amazonq/.changes/next-release/Bug Fix-80f16b7a-440d-4e06-89ad-1454c58ff28f.json b/packages/amazonq/.changes/next-release/Bug Fix-80f16b7a-440d-4e06-89ad-1454c58ff28f.json new file mode 100644 index 00000000000..0200cbbad42 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Bug Fix-80f16b7a-440d-4e06-89ad-1454c58ff28f.json @@ -0,0 +1,4 @@ +{ + "type": "Feature", + "description": "Q feature dev: recognize .bms, .pli code files" +} diff --git a/packages/core/src/shared/filetypes.ts b/packages/core/src/shared/filetypes.ts index 1e6027bb12b..5a469d3c423 100644 --- a/packages/core/src/shared/filetypes.ts +++ b/packages/core/src/shared/filetypes.ts @@ -161,6 +161,7 @@ export const codefileExtensions = new Set([ '.bash', '.bat', '.boo', + '.bms', '.c', '.cbl', '.cc', @@ -267,6 +268,7 @@ export const codefileExtensions = new Set([ '.pike', '.pir', '.pl', + '.pli', '.pm', '.pmod', '.pp', From d4b0ede08d8c42f0b061109a1efd834342f3d26f Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Mon, 2 Dec 2024 13:47:27 -1000 Subject: [PATCH 02/13] test(codewhisperer): disable Auto Scan after test case #6122 ## Problem fix #6078 ## Solution Turn off CodeWhisper scanning after test suite completes. --- .../src/test/awsService/appBuilder/walkthrough.test.ts | 7 +++++++ .../src/test/codewhisperer/commands/basicCommands.test.ts | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts index 9700b756c23..72dfb5c0ae2 100644 --- a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts +++ b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts @@ -25,6 +25,7 @@ import { ChildProcess } from '../../../shared/utilities/processUtils' import { assertTelemetryCurried } from '../../testUtil' import { HttpResourceFetcher } from '../../../shared/resourcefetcher/httpResourceFetcher' import { SamCliInfoInvocation } from '../../../shared/sam/cli/samCliInfo' +import { CodeScansState } from '../../../codewhisperer' interface TestScenario { toolID: AwsClis @@ -81,6 +82,12 @@ const scenarios: TestScenario[] = [ ] describe('AppBuilder Walkthrough', function () { + before(async function () { + // ensure auto scan is disabled before testrun + await CodeScansState.instance.setScansEnabled(false) + assert.strictEqual(CodeScansState.instance.isScansEnabled(), false) + }) + describe('Reopen template after reload', function () { let sandbox: sinon.SinonSandbox let spyExecuteCommand: sinon.SinonSpy diff --git a/packages/core/src/test/codewhisperer/commands/basicCommands.test.ts b/packages/core/src/test/codewhisperer/commands/basicCommands.test.ts index 43c8b668581..8455a084fb0 100644 --- a/packages/core/src/test/codewhisperer/commands/basicCommands.test.ts +++ b/packages/core/src/test/codewhisperer/commands/basicCommands.test.ts @@ -74,6 +74,12 @@ describe('CodeWhisperer-basicCommands', function () { sinon.restore() }) + after(async function () { + // disable auto scan after testrun + await CodeScansState.instance.setScansEnabled(false) + assert.strictEqual(CodeScansState.instance.isScansEnabled(), false) + }) + describe('toggleCodeSuggestion', function () { class TestCodeSuggestionsState extends CodeSuggestionsState { public constructor(initialState?: boolean) { From 6d5e016e7e063c85d38a692d0c710f920890bf6c Mon Sep 17 00:00:00 2001 From: Nikolas Komonen <118216176+nkomonen-amazon@users.noreply.github.com> Date: Tue, 3 Dec 2024 14:56:44 -0500 Subject: [PATCH 03/13] refactor(logs): drop "Amazon Q Logs" channel and just have "Amazon Q" (#6114) ## Problem We didn't have much use for the old "Amazon Q" channel in addition to "Amazon Q Logs". All the logs we used were in "Amazon Q Logs". ## Solution - Now, just have the useful "Amazon Q Logs" channel. - Move the Amazon Q Language Server logs in to Amazon Q Logs to unify all logs --- License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Signed-off-by: nkomonen-amazon --- .../Feature-fd23658e-ecc3-4d17-8944-240cbe24a7cc.json | 4 ++++ packages/amazonq/src/extension.ts | 4 +--- packages/core/src/amazonq/lsp/lspClient.ts | 5 ++++- packages/core/src/extension.ts | 2 +- packages/core/src/shared/logger/activation.ts | 8 +++++--- 5 files changed, 15 insertions(+), 8 deletions(-) create mode 100644 packages/amazonq/.changes/next-release/Feature-fd23658e-ecc3-4d17-8944-240cbe24a7cc.json diff --git a/packages/amazonq/.changes/next-release/Feature-fd23658e-ecc3-4d17-8944-240cbe24a7cc.json b/packages/amazonq/.changes/next-release/Feature-fd23658e-ecc3-4d17-8944-240cbe24a7cc.json new file mode 100644 index 00000000000..c7df441d68b --- /dev/null +++ b/packages/amazonq/.changes/next-release/Feature-fd23658e-ecc3-4d17-8944-240cbe24a7cc.json @@ -0,0 +1,4 @@ +{ + "type": "Feature", + "description": "Amazon Q: Simplify log channel" +} diff --git a/packages/amazonq/src/extension.ts b/packages/amazonq/src/extension.ts index add823b5a9e..f5cc7274426 100644 --- a/packages/amazonq/src/extension.ts +++ b/packages/amazonq/src/extension.ts @@ -97,10 +97,8 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is globals.manifestPaths.endpoints = context.asAbsolutePath(join('resources', 'endpoints.json')) globals.regionProvider = RegionProvider.fromEndpointsProvider(makeEndpointsProvider()) - const qOutputChannel = vscode.window.createOutputChannel('Amazon Q', { log: true }) const qLogChannel = vscode.window.createOutputChannel('Amazon Q Logs', { log: true }) - await activateLogger(context, amazonQContextPrefix, qOutputChannel, qLogChannel) - globals.outputChannel = qOutputChannel + await activateLogger(context, amazonQContextPrefix, qLogChannel) globals.logOutputChannel = qLogChannel globals.loginManager = new LoginManager(globals.awsContext, new CredentialsStore()) diff --git a/packages/core/src/amazonq/lsp/lspClient.ts b/packages/core/src/amazonq/lsp/lspClient.ts index 1d3dd2743e9..359d8d24256 100644 --- a/packages/core/src/amazonq/lsp/lspClient.ts +++ b/packages/core/src/amazonq/lsp/lspClient.ts @@ -32,7 +32,7 @@ import { } from './types' import { Writable } from 'stream' import { CodeWhispererSettings } from '../../codewhisperer/util/codewhispererSettings' -import { fs, getLogger } from '../../shared' +import { fs, getLogger, globals } from '../../shared' const localize = nls.loadMessageBundle() @@ -228,6 +228,9 @@ export async function activate(extensionContext: ExtensionContext) { // this is used by LSP to determine index cache path, move to this folder so that when extension updates index is not deleted. extensionPath: path.join(fs.getUserHomeDir(), '.aws', 'amazonq', 'cache'), }, + // Log to the Amazon Q Logs so everything is in a single channel + // TODO: Add prefix to the language server logs so it is easier to search + outputChannel: globals.logOutputChannel, } // Create the language client and start the client. diff --git a/packages/core/src/extension.ts b/packages/core/src/extension.ts index 3f1039fbba7..ef4131c6f26 100644 --- a/packages/core/src/extension.ts +++ b/packages/core/src/extension.ts @@ -89,7 +89,7 @@ export async function activateCommon( // Setup the logger const toolkitOutputChannel = vscode.window.createOutputChannel('AWS Toolkit', { log: true }) const toolkitLogChannel = vscode.window.createOutputChannel('AWS Toolkit Logs', { log: true }) - await activateLogger(context, contextPrefix, toolkitOutputChannel, toolkitLogChannel) + await activateLogger(context, contextPrefix, toolkitLogChannel, toolkitOutputChannel) globals.outputChannel = toolkitOutputChannel globals.logOutputChannel = toolkitLogChannel diff --git a/packages/core/src/shared/logger/activation.ts b/packages/core/src/shared/logger/activation.ts index ac740d1b0f3..9cbce46e6fd 100644 --- a/packages/core/src/shared/logger/activation.ts +++ b/packages/core/src/shared/logger/activation.ts @@ -17,12 +17,14 @@ import { isBeta } from '../vscode/env' /** * Activate Logger functionality for the extension. + * + * @param outputChannel optional output channel for less granular logs */ export async function activate( extensionContext: vscode.ExtensionContext, contextPrefix: string, - outputChannel: vscode.LogOutputChannel, - logChannel: vscode.LogOutputChannel + logChannel: vscode.LogOutputChannel, + outputChannel?: vscode.LogOutputChannel ): Promise { const settings = Settings.instance.getSection('aws') const devLogfile = settings.get('dev.logfile', '') @@ -52,7 +54,7 @@ export async function activate( setLogger( makeLogger({ logLevel: chanLogLevel, - outputChannels: [outputChannel, logChannel], + outputChannels: outputChannel ? [outputChannel, logChannel] : [logChannel], useConsoleLog: true, }), 'debugConsole' From 59acbc6516c34959c628a4f01ab7fd9cc2a6ce7e Mon Sep 17 00:00:00 2001 From: Elvin Hwang <31689968+elvin-hwang@users.noreply.github.com> Date: Wed, 4 Dec 2024 09:53:37 -0800 Subject: [PATCH 04/13] feat(toolkit): Upgrade amazon-states-language-service to 1.13.0 #6139 ref #6118 ref aws/amazon-states-language-service#159 ref aws/amazon-states-language-service#160 --- package-lock.json | 7 ++++--- packages/core/package.json | 2 +- .../Feature-76bb396d-6268-4d24-9373-4c7c0e91cbc4.json | 4 ++++ 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 packages/toolkit/.changes/next-release/Feature-76bb396d-6268-4d24-9373-4c7c0e91cbc4.json diff --git a/package-lock.json b/package-lock.json index 1ddd49baa35..936298a6639 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9162,8 +9162,9 @@ "link": true }, "node_modules/amazon-states-language-service": { - "version": "1.11.0", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/amazon-states-language-service/-/amazon-states-language-service-1.13.0.tgz", + "integrity": "sha512-XT/7LL9+TRCB8H3t0kM6h2uivHa7Pn2lZGpvHKujH1MM+lQ7aaprAKrnZkfSk9++VFNbFJBAnKW+5NN2xVcvlA==", "dependencies": { "js-yaml": "^4.1.0", "vscode-json-languageservice": "5.3.5", @@ -20046,7 +20047,7 @@ "@vscode/debugprotocol": "^1.57.0", "@zip.js/zip.js": "^2.7.41", "adm-zip": "^0.5.10", - "amazon-states-language-service": "^1.11.0", + "amazon-states-language-service": "^1.13.0", "async-lock": "^1.4.0", "aws-sdk": "^2.1384.0", "aws-ssm-document-language-service": "^1.0.0", diff --git a/packages/core/package.json b/packages/core/package.json index 0550107f734..9fbabf3a561 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -517,7 +517,7 @@ "@vscode/debugprotocol": "^1.57.0", "@zip.js/zip.js": "^2.7.41", "adm-zip": "^0.5.10", - "amazon-states-language-service": "^1.11.0", + "amazon-states-language-service": "^1.13.0", "async-lock": "^1.4.0", "aws-sdk": "^2.1384.0", "aws-ssm-document-language-service": "^1.0.0", diff --git a/packages/toolkit/.changes/next-release/Feature-76bb396d-6268-4d24-9373-4c7c0e91cbc4.json b/packages/toolkit/.changes/next-release/Feature-76bb396d-6268-4d24-9373-4c7c0e91cbc4.json new file mode 100644 index 00000000000..76f458362f4 --- /dev/null +++ b/packages/toolkit/.changes/next-release/Feature-76bb396d-6268-4d24-9373-4c7c0e91cbc4.json @@ -0,0 +1,4 @@ +{ + "type": "Feature", + "description": "Step Functions: Upgrade amazon-states-language-service to 1.13. This new version adds support for [JSONata and Variables](https://aws.amazon.com/blogs/compute/simplifying-developer-experience-with-variables-and-jsonata-in-aws-step-functions/)." +} From 2905eb8af1d8c39cd80ec49cbd46372eb55ecdde Mon Sep 17 00:00:00 2001 From: Hweinstock <42325418+Hweinstock@users.noreply.github.com> Date: Wed, 4 Dec 2024 16:48:15 -0500 Subject: [PATCH 05/13] deps(cross-spawn): update cross-spawn to 7.0.5 #6147 ## Problem https://github.com/advisories/GHSA-3xgq-45jj-v275 ## Solution Use version 7.0.5 --- packages/core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/package.json b/packages/core/package.json index 6d6bbcdda32..41fb9e1c962 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -523,7 +523,7 @@ "aws-ssm-document-language-service": "^1.0.0", "bytes": "^3.1.2", "cross-fetch": "^4.0.0", - "cross-spawn": "^7.0.3", + "cross-spawn": "^7.0.5", "diff": "^5.1.0", "fast-json-patch": "^3.1.1", "glob": "^10.3.10", From c8bfe2f840a775a69fe0feda476822b4598ade89 Mon Sep 17 00:00:00 2001 From: Hweinstock <42325418+Hweinstock@users.noreply.github.com> Date: Wed, 4 Dec 2024 17:56:15 -0500 Subject: [PATCH 06/13] test(flaky): fix unresolved promise causing linux failures (#6088) ## Problem https://github.com/aws/aws-toolkit-vscode/issues/6043 To reproduce, add a 5 second delay to the `after` hook at the top level. One way to do this is to insert this at line 84. ``` after(async function () { clock.uninstall() await sleep(5000) }) ``` Despite asserting that the promise rejects within the test, the promise rejects after the test as well. Not entirely sure why this happening. - Tried manually wrapping in try-catch with an `await` instead of `assert.rejects` and it still fails. - Tried wrapping the promise in another promise before passing to `assert.rejects`. ## Solution What does appear to work, is manually handling the callback of the promise. That is, explicitly defining a `then` and `catch` method to assert the rejection, and awaiting the promise at the end of the test to ensure it resolves before the test finishes. Not sure why this works, but I am unable to reproduce the error with this change. ## Notes - `assert.rejects` implementation: https://github.com/nodejs/node/blob/3178a762d6a2b1a37b74f02266eea0f3d86603be/lib/assert.js#L653. Doesn't appear to be the problem because the same is observed when manually wrapping. - `await` docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await --- License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- buildspec/shared/common.sh | 2 +- .../sso/ssoAccessTokenProvider.test.ts | 20 ++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/buildspec/shared/common.sh b/buildspec/shared/common.sh index cce614e4406..a0dbc2e5837 100644 --- a/buildspec/shared/common.sh +++ b/buildspec/shared/common.sh @@ -8,7 +8,7 @@ # - "waiting for browser": from `ssoAccessTokenProvider.test.ts`, unclear how to fix it. # - "HTTPError: Response code …": caused by github rate-limiting. # - "npm WARN deprecated querystring": transitive dep of aws sdk v2 (check `npm ls querystring`), so that's blocked until we migrate to v3. -_ignore_pat='Timed-out waiting for browser login flow\|HTTPError: Response code 403\|HTTPError: Response code 404\|npm WARN deprecated querystring\|npm WARN deprecated' +_ignore_pat='HTTPError: Response code 403\|HTTPError: Response code 404\|npm WARN deprecated querystring\|npm WARN deprecated' # Do not print (noisy) lines matching these patterns. # - "ERROR:bus… Failed to connect to the bus": noise related to "xvfb". https://github.com/cypress-io/cypress/issues/19299 diff --git a/packages/core/src/test/credentials/sso/ssoAccessTokenProvider.test.ts b/packages/core/src/test/credentials/sso/ssoAccessTokenProvider.test.ts index 1bde91b26d8..b662556e0aa 100644 --- a/packages/core/src/test/credentials/sso/ssoAccessTokenProvider.test.ts +++ b/packages/core/src/test/credentials/sso/ssoAccessTokenProvider.test.ts @@ -310,13 +310,6 @@ describe('SsoAccessTokenProvider', function () { }) it('respects the device authorization expiration time', async function () { - // XXX: Don't know how to fix this "unhandled rejection" caused by this test: - // rejected promise not handled within 1 second: Error: Timed-out waiting for browser login flow to complete - // at poll (…/src/auth/sso/ssoAccessTokenProvider.ts:251:15) - // at async SsoAccessTokenProvider.authorize (…/src/auth/sso/ssoAccessTokenProvider.ts:188:23) - // at async SsoAccessTokenProvider.runFlow (…/src/auth/sso/ssoAccessTokenProvider.ts:113:20) - // at async SsoAccessTokenProvider.createToken (…/src/auth/sso/ssoAccessTokenProvider.ts:102:24) - setupFlow() stubOpen() const exception = new AuthorizationPendingException({ message: '', $metadata: {} }) @@ -324,13 +317,22 @@ describe('SsoAccessTokenProvider', function () { oidcClient.createToken.rejects(exception) oidcClient.startDeviceAuthorization.resolves(authorization) - const resp = sut.createToken() + const resp = sut + .createToken() + .then(() => assert.fail('Should not resolve')) + .catch((e) => { + assert.ok( + e instanceof ToolkitError && + e.message === 'Timed-out waiting for browser login flow to complete' + ) + }) + const progress = await getTestWindow().waitForMessage(/login page opened/i) await clock.tickAsync(750) assert.ok(progress.visible) await clock.tickAsync(750) assert.ok(!progress.visible) - await assert.rejects(resp, ToolkitError) + await resp assertTelemetry('aws_loginWithBrowser', { result: 'Failed', isReAuth: undefined, From e46500e7f0326c89e6a7af86dc2476190e49a9c1 Mon Sep 17 00:00:00 2001 From: Hweinstock <42325418+Hweinstock@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:32:41 -0500 Subject: [PATCH 07/13] fix(logs): avoid logging EC2 ARN on commands #6152 ## Problem The EC2 ARN sneaks its away into the logs via the `Ec2InstanceNode` tooltip property from `packages/core/src/awsService/ec2/explorer/ec2InstanceNode.ts`. When we run any command on this instance, we get the following logs with the middle section omitted for brevity. ``` 2024-12-04 17:25:10.859 [debug] command: running "aws.ec2.openTerminal" with arguments: [ { collapsibleState: 0, label: 'testInstance ({INSTANCE_ID}) RUNNING', ... contextValue: 'awsEc2RunningNode', iconPath: { id: 'pass', color: undefined }, tooltip: 'testInstance\n' + '{INSTANCE_ID}\n' + 'running\n' + 'arn:aws:ec2:us-east-1:{ACCOUNT_ID}:instance/{INSTANCE_ID}', id: '{INSTANCE_ID}' }, undefined ] ``` The actual AWS account ID in use is included in the logs. What makes this difficult is that this node is passed directly from VSCode here: https://github.com/aws/aws-toolkit-vscode/blob/d74f96c61f79716edf8a9a706a86c587887d3b9b/packages/core/src/awsService/ec2/activation.ts#L32-L37 and is processed by our commands wrapper here: https://github.com/aws/aws-toolkit-vscode/blob/d74f96c61f79716edf8a9a706a86c587887d3b9b/packages/core/src/shared/vscode/commands2.ts#L649-L660 The wrapper is logging the node directly from vscode, not giving us a chance to use `partialClone` on it first. ## Solution - omit all tooltips from the logs, since this is usually redundant information anyway. --- packages/core/src/shared/vscode/commands2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/shared/vscode/commands2.ts b/packages/core/src/shared/vscode/commands2.ts index 9de79d60d24..527862faebb 100644 --- a/packages/core/src/shared/vscode/commands2.ts +++ b/packages/core/src/shared/vscode/commands2.ts @@ -656,7 +656,7 @@ async function runCommand(fn: T, info: CommandInfo): Prom logger.debug( `command: running ${label} with arguments: %O`, - partialClone(args, 3, ['clientSecret', 'accessToken', 'refreshToken'], '[omitted]') + partialClone(args, 3, ['clientSecret', 'accessToken', 'refreshToken', 'tooltip'], '[omitted]') ) try { From 4c38aab31ebf420c6423a61b953c607f53fa8b6d Mon Sep 17 00:00:00 2001 From: Hweinstock <42325418+Hweinstock@users.noreply.github.com> Date: Thu, 5 Dec 2024 10:24:14 -0500 Subject: [PATCH 08/13] feat(ec2): dry run connection script to surface errors earlier. (#6037) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem Follow up to https://github.com/aws/aws-toolkit-vscode/pull/6018#discussion_r1844284580 ## Solution - Run `ssh` within the same env as it will be run on real connection. - Log any resulting errors, and inform user where the process failed. - Also part of this PR is moving some functions to `remoteSession.ts` that are general enough to be there. Error msg: Screenshot 2024-11-15 at 5 53 51 PM --- License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Co-authored-by: Justin M. Keyes --- packages/core/src/awsService/ec2/model.ts | 50 +++++++---- packages/core/src/codecatalyst/model.ts | 25 +----- packages/core/src/shared/extensions/ssh.ts | 37 ++++++++- packages/core/src/shared/remoteSession.ts | 22 ++++- .../src/test/shared/extensions/ssh.test.ts | 83 ++++++++++++++++++- 5 files changed, 173 insertions(+), 44 deletions(-) diff --git a/packages/core/src/awsService/ec2/model.ts b/packages/core/src/awsService/ec2/model.ts index fa7bbee71b7..085bfa0674b 100644 --- a/packages/core/src/awsService/ec2/model.ts +++ b/packages/core/src/awsService/ec2/model.ts @@ -13,6 +13,7 @@ import { SsmClient } from '../../shared/clients/ssmClient' import { Ec2Client } from '../../shared/clients/ec2Client' import { VscodeRemoteConnection, + createBoundProcess, ensureDependencies, getDeniedSsmActions, openRemoteTerminal, @@ -20,8 +21,13 @@ import { } from '../../shared/remoteSession' import { DefaultIamClient } from '../../shared/clients/iamClient' import { ErrorInformation } from '../../shared/errors' -import { sshAgentSocketVariable, startSshAgent, startVscodeRemote } from '../../shared/extensions/ssh' -import { createBoundProcess } from '../../codecatalyst/model' +import { + sshAgentSocketVariable, + SshError, + startSshAgent, + startVscodeRemote, + testSshConnection, +} from '../../shared/extensions/ssh' import { getLogger } from '../../shared/logger/logger' import { CancellationError, Timeout } from '../../shared/utilities/timeoutUtils' import { showMessageWithCancel } from '../../shared/utilities/messages' @@ -149,13 +155,6 @@ export class Ec2Connecter implements vscode.Disposable { } } - public throwGeneralConnectionError(selection: Ec2Selection, error: Error) { - this.throwConnectionError('Unable to connect to target instance. ', selection, { - code: 'EC2SSMConnect', - cause: error, - }) - } - public async checkForStartSessionError(selection: Ec2Selection): Promise { await this.checkForInstanceStatusError(selection) @@ -184,7 +183,7 @@ export class Ec2Connecter implements vscode.Disposable { const response = await this.ssmClient.startSession(selection.instanceId) await this.openSessionInTerminal(response, selection) } catch (err: unknown) { - this.throwGeneralConnectionError(selection, err as Error) + this.throwConnectionError('', selection, err as Error) } } @@ -193,11 +192,21 @@ export class Ec2Connecter implements vscode.Disposable { const remoteUser = await this.getRemoteUser(selection.instanceId) const remoteEnv = await this.prepareEc2RemoteEnvWithProgress(selection, remoteUser) - + const testSession = await this.ssmClient.startSession(selection.instanceId, 'AWS-StartSSHSession') try { + await testSshConnection( + remoteEnv.SessionProcess, + remoteEnv.hostname, + remoteEnv.sshPath, + remoteUser, + testSession + ) await startVscodeRemote(remoteEnv.SessionProcess, remoteEnv.hostname, '/', remoteEnv.vscPath, remoteUser) } catch (err) { - this.throwGeneralConnectionError(selection, err as Error) + const message = err instanceof SshError ? 'Testing SSH connection to instance failed' : '' + this.throwConnectionError(message, selection, err as Error) + } finally { + await this.ssmClient.terminateSession(testSession) } } @@ -208,12 +217,19 @@ export class Ec2Connecter implements vscode.Disposable { return remoteEnv } + private async startSSMSession(instanceId: string): Promise { + const ssmSession = await this.ssmClient.startSession(instanceId, 'AWS-StartSSHSession') + await this.addActiveSession(instanceId, ssmSession.SessionId!) + return ssmSession + } + public async prepareEc2RemoteEnv(selection: Ec2Selection, remoteUser: string): Promise { const logger = this.configureRemoteConnectionLogger(selection.instanceId) const { ssm, vsc, ssh } = (await ensureDependencies()).unwrap() const keyPair = await this.configureSshKeys(selection, remoteUser) - const hostNamePrefix = 'aws-ec2-' - const sshConfig = new SshConfig(ssh, hostNamePrefix, 'ec2_connect', keyPair.getPrivateKeyPath()) + const hostnamePrefix = 'aws-ec2-' + const hostname = `${hostnamePrefix}${selection.instanceId}` + const sshConfig = new SshConfig(ssh, hostnamePrefix, 'ec2_connect', keyPair.getPrivateKeyPath()) const config = await sshConfig.ensureValid() if (config.isErr()) { @@ -222,8 +238,8 @@ export class Ec2Connecter implements vscode.Disposable { throw err } - const ssmSession = await this.ssmClient.startSession(selection.instanceId, 'AWS-StartSSHSession') - await this.addActiveSession(selection.instanceId, ssmSession.SessionId!) + + const ssmSession = await this.startSSMSession(selection.instanceId) const vars = getEc2SsmEnv(selection, ssm, ssmSession) const envProvider = async () => { @@ -236,7 +252,7 @@ export class Ec2Connecter implements vscode.Disposable { }) return { - hostname: `${hostNamePrefix}${selection.instanceId}`, + hostname, envProvider, sshPath: ssh, vscPath: vsc, diff --git a/packages/core/src/codecatalyst/model.ts b/packages/core/src/codecatalyst/model.ts index b2ba6912106..768a97890ee 100644 --- a/packages/core/src/codecatalyst/model.ts +++ b/packages/core/src/codecatalyst/model.ts @@ -19,7 +19,6 @@ import { getLogger } from '../shared/logger' import { AsyncCollection, toCollection } from '../shared/utilities/asyncCollection' import { getCodeCatalystSpaceName, getCodeCatalystProjectName, getCodeCatalystDevEnvId } from '../shared/vscode/env' import { sshAgentSocketVariable, startSshAgent, startVscodeRemote } from '../shared/extensions/ssh' -import { ChildProcess } from '../shared/utilities/processUtils' import { isDevenvVscode } from './utils' import { Timeout } from '../shared/utilities/timeoutUtils' import { Commands } from '../shared/vscode/commands2' @@ -28,7 +27,7 @@ import { fileExists } from '../shared/filesystemUtilities' import { CodeCatalystAuthenticationProvider } from './auth' import { ToolkitError } from '../shared/errors' import { Result } from '../shared/utilities/result' -import { VscodeRemoteConnection, ensureDependencies } from '../shared/remoteSession' +import { EnvProvider, VscodeRemoteConnection, createBoundProcess, ensureDependencies } from '../shared/remoteSession' import { SshConfig, sshLogFileLocation } from '../shared/sshConfig' import { fs } from '../shared' @@ -111,28 +110,6 @@ export function createCodeCatalystEnvProvider( } } -type EnvProvider = () => Promise - -/** - * Creates a new {@link ChildProcess} class bound to a specific dev environment. All instances of this - * derived class will have SSM session information injected as environment variables as-needed. - */ -export function createBoundProcess(envProvider: EnvProvider): typeof ChildProcess { - type Run = ChildProcess['run'] - return class SessionBoundProcess extends ChildProcess { - public override async run(...args: Parameters): ReturnType { - const options = args[0] - const envVars = await envProvider() - const spawnOptions = { - ...options?.spawnOptions, - env: { ...envVars, ...options?.spawnOptions?.env }, - } - - return super.run({ ...options, spawnOptions }) - } - } -} - export async function cacheBearerToken(bearerToken: string, devenvId: string): Promise { await fs.writeFile(bearerTokenCacheLocation(devenvId), `${bearerToken}`, 'utf8') } diff --git a/packages/core/src/shared/extensions/ssh.ts b/packages/core/src/shared/extensions/ssh.ts index ff9046b3225..1e75f9921aa 100644 --- a/packages/core/src/shared/extensions/ssh.ts +++ b/packages/core/src/shared/extensions/ssh.ts @@ -8,15 +8,26 @@ import * as path from 'path' import * as nls from 'vscode-nls' import fs from '../fs/fs' import { getLogger } from '../logger' -import { ChildProcess } from '../utilities/processUtils' +import { ChildProcess, ChildProcessResult } from '../utilities/processUtils' import { ArrayConstructor, NonNullObject } from '../utilities/typeConstructors' import { Settings } from '../settings' import { VSCODE_EXTENSION_ID } from '../extensions' +import { SSM } from 'aws-sdk' +import { ErrorInformation, ToolkitError } from '../errors' const localize = nls.loadMessageBundle() export const sshAgentSocketVariable = 'SSH_AUTH_SOCK' +export class SshError extends ToolkitError { + constructor(message: string, options: ErrorInformation) { + super(message, { + ...options, + code: SshError.name, + }) + } +} + export function getSshConfigPath(): string { const sshConfigDir = path.join(fs.getUserHomeDir(), '.ssh') return path.join(sshConfigDir, 'config') @@ -119,6 +130,30 @@ export class RemoteSshSettings extends Settings.define('remote.SSH', remoteSshTy } } +export async function testSshConnection( + ProcessClass: typeof ChildProcess, + hostname: string, + sshPath: string, + user: string, + session: SSM.StartSessionResponse +): Promise { + try { + const env = { SESSION_ID: session.SessionId, STREAM_URL: session.StreamUrl, TOKEN: session.TokenValue } + const result = await new ProcessClass(sshPath, [ + '-T', + `${user}@${hostname}`, + 'echo "test connection succeeded" && exit', + ]).run({ + spawnOptions: { + env, + }, + }) + return result + } catch (error) { + throw new SshError('SSH connection test failed', { cause: error as Error }) + } +} + export async function startVscodeRemote( ProcessClass: typeof ChildProcess, hostname: string, diff --git a/packages/core/src/shared/remoteSession.ts b/packages/core/src/shared/remoteSession.ts index 95c45832fa8..9f51c747de7 100644 --- a/packages/core/src/shared/remoteSession.ts +++ b/packages/core/src/shared/remoteSession.ts @@ -77,7 +77,7 @@ interface DependencyPaths { readonly ssh: string } -type EnvProvider = () => Promise +export type EnvProvider = () => Promise export interface VscodeRemoteConnection { readonly sshPath: string @@ -251,3 +251,23 @@ export async function getDeniedSsmActions(client: IamClient, roleArn: string): P return deniedActions } + +/** + * Creates a new {@link ChildProcess} class bound to a specific remote environment. All instances of this + * derived class will have SSM session information injected as environment variables as-needed. + */ +export function createBoundProcess(envProvider: EnvProvider): typeof ChildProcess { + type Run = ChildProcess['run'] + return class SessionBoundProcess extends ChildProcess { + public override async run(...args: Parameters): ReturnType { + const options = args[0] + const envVars = await envProvider() + const spawnOptions = { + ...options?.spawnOptions, + env: { ...envVars, ...options?.spawnOptions?.env }, + } + + return super.run({ ...options, spawnOptions }) + } + } +} diff --git a/packages/core/src/test/shared/extensions/ssh.test.ts b/packages/core/src/test/shared/extensions/ssh.test.ts index c7abc7095cd..38874e2df68 100644 --- a/packages/core/src/test/shared/extensions/ssh.test.ts +++ b/packages/core/src/test/shared/extensions/ssh.test.ts @@ -4,7 +4,14 @@ */ import * as assert from 'assert' import { ChildProcess } from '../../../shared/utilities/processUtils' -import { startSshAgent } from '../../../shared/extensions/ssh' +import { startSshAgent, testSshConnection } from '../../../shared/extensions/ssh' +import { createBoundProcess } from '../../../shared/remoteSession' +import { createExecutableFile, createTestWorkspaceFolder } from '../../testUtil' +import { WorkspaceFolder } from 'vscode' +import path from 'path' +import { SSM } from 'aws-sdk' +import { fs } from '../../../shared/fs/fs' +import { isWin } from '../../../shared/vscode/env' describe('SSH Agent', function () { it('can start the agent on windows', async function () { @@ -29,3 +36,77 @@ describe('SSH Agent', function () { assert.strictEqual(await getStatus(), 'Running') }) }) + +function echoEnvVarsCmd(varNames: string[]) { + const toShell = (s: string) => (isWin() ? `%${s}%` : `$${s}`) + return `echo "${varNames.map(toShell).join(' ')}"` +} + +/** + * Trim noisy windows ChildProcess result to final line for easier testing. + */ +function assertOutputContains(rawOutput: string, expectedString: string): void | never { + const output = rawOutput.trim().split('\n').at(-1)?.replace('"', '') ?? '' + assert.ok(output.includes(expectedString), `Expected output to contain "${expectedString}", but got "${output}"`) +} + +describe('testSshConnection', function () { + let testWorkspace: WorkspaceFolder + let sshPath: string + + before(async function () { + testWorkspace = await createTestWorkspaceFolder() + sshPath = path.join(testWorkspace.uri.fsPath, `fakeSSH${isWin() ? '.cmd' : ''}`) + }) + + after(async function () { + await fs.delete(testWorkspace.uri.fsPath, { recursive: true, force: true }) + await fs.delete(sshPath, { force: true }) + }) + + it('runs in bound process', async function () { + const envProvider = async () => ({ MY_VAR: 'yes' }) + const process = createBoundProcess(envProvider) + const session = { + SessionId: 'testSession', + StreamUrl: 'testUrl', + TokenValue: 'testToken', + } as SSM.StartSessionResponse + + await createExecutableFile(sshPath, echoEnvVarsCmd(['MY_VAR'])) + const r = await testSshConnection(process, 'localhost', sshPath, 'test-user', session) + assertOutputContains(r.stdout, 'yes') + }) + + it('injects new session into env', async function () { + const oldSession = { + SessionId: 'testSession1', + StreamUrl: 'testUrl1', + TokenValue: 'testToken1', + } as SSM.StartSessionResponse + const newSession = { + SessionId: 'testSession2', + StreamUrl: 'testUrl2', + TokenValue: 'testToken2', + } as SSM.StartSessionResponse + const envProvider = async () => ({ + SESSION_ID: oldSession.SessionId, + STREAM_URL: oldSession.StreamUrl, + TOKEN: oldSession.TokenValue, + }) + const process = createBoundProcess(envProvider) + + await createExecutableFile(sshPath, echoEnvVarsCmd(['SESSION_ID', 'STREAM_URL', 'TOKEN'])) + const r = await testSshConnection(process, 'localhost', sshPath, 'test-user', newSession) + assertOutputContains(r.stdout, `${newSession.SessionId} ${newSession.StreamUrl} ${newSession.TokenValue}`) + }) + + it('passes proper args to the ssh invoke', async function () { + const executableFileContent = isWin() ? `echo "%1 %2"` : `echo "$1 $2"` + const process = createBoundProcess(async () => ({})) + await createExecutableFile(sshPath, executableFileContent) + const r = await testSshConnection(process, 'localhost', sshPath, 'test-user', {} as SSM.StartSessionResponse) + assertOutputContains(r.stdout, '-T') + assertOutputContains(r.stdout, 'test-user@localhost') + }) +}) From 95b777ca3869762d0e81e19c7670fe5f17bb23d9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 5 Dec 2024 08:18:12 -0800 Subject: [PATCH 09/13] ci: require space at start of // comment #6112 Problem: Inconsistent comment style. Solution: Add a lint rule. --- .eslintrc.js | 16 +- package-lock.json | 214 +++++++++++++++++- package.json | 1 + .../controller/messenger/messengerUtils.ts | 2 +- packages/amazonq/src/extension.ts | 2 +- .../core/resources/js/graphStateMachine.js | 2 +- packages/core/src/amazonq/commons/types.ts | 4 +- .../core/src/amazonq/lsp/lspController.ts | 2 +- packages/core/src/amazonq/lsp/types.ts | 2 +- .../webview/ui/apps/testChatConnector.ts | 2 +- packages/core/src/amazonq/webview/ui/main.ts | 8 +- .../webview/ui/quickActions/generator.ts | 2 +- .../amazonqTest/chat/controller/controller.ts | 20 +- .../chat/controller/messenger/messenger.ts | 4 +- .../controller/messenger/messengerUtils.ts | 2 +- .../src/amazonqTest/chat/session/session.ts | 6 +- .../core/src/amazonqTest/models/constants.ts | 4 +- .../accessanalyzer/vue/iamPolicyChecks.ts | 8 +- .../cloudWatchLogs/timeFilterSubmenu.ts | 2 +- .../iot/commands/attachCertificate.ts | 2 +- .../src/awsService/iot/commands/createCert.ts | 8 +- .../awsService/iot/commands/createPolicy.ts | 4 +- .../iot/commands/createPolicyVersion.ts | 4 +- .../awsService/iot/commands/createThing.ts | 2 +- .../src/awsService/iot/commands/deleteCert.ts | 2 +- .../awsService/iot/commands/deletePolicy.ts | 2 +- .../iot/commands/deletePolicyVersion.ts | 2 +- .../awsService/iot/commands/deleteThing.ts | 2 +- .../src/awsService/iot/commands/detachCert.ts | 2 +- .../iot/explorer/iotCertificateNode.ts | 4 +- .../iot/explorer/iotPolicyFolderNode.ts | 4 +- .../src/awsService/redshift/activation.ts | 2 +- .../redshift/explorer/redshiftNode.ts | 2 +- .../notebook/redshiftNotebookController.ts | 4 +- .../src/awsService/s3/commands/uploadFile.ts | 8 +- .../codewhisperer/commands/basicCommands.ts | 2 +- .../commands/gettingStartedPageCommands.ts | 2 +- .../commands/startTestGeneration.ts | 8 +- .../src/codewhisperer/models/constants.ts | 6 +- .../core/src/codewhisperer/models/model.ts | 2 +- .../service/securityScanHandler.ts | 4 +- .../codewhisperer/service/testGenHandler.ts | 12 +- .../transformationResultsViewProvider.ts | 6 +- .../crossFileContextUtil.ts | 2 +- .../src/codewhisperer/util/telemetryHelper.ts | 2 +- .../core/src/codewhisperer/util/zipUtil.ts | 4 +- .../core/src/codewhisperer/vue/backend.ts | 16 +- .../controllers/chat/messenger/messenger.ts | 2 +- .../editor/context/file/javaImportReader.ts | 6 +- .../commands/downloadSchemaItemCode.ts | 8 +- .../eventSchemas/commands/viewSchemaItem.ts | 2 +- .../providers/schemasDataProvider.ts | 2 +- packages/core/src/extension.ts | 4 +- .../vue/configEditor/samInvokeFrontend.ts | 2 +- packages/core/src/shared/clients/iotClient.ts | 2 +- .../core/src/shared/clients/redshiftClient.ts | 2 +- packages/core/src/shared/constants.ts | 6 +- packages/core/src/shared/env/resolveEnv.ts | 2 +- .../languageServer/languageModelCache.ts | 2 +- .../src/shared/languageServer/utils/runner.ts | 2 +- .../src/shared/logger/sharedFileTransport.ts | 2 +- .../src/shared/sam/debugger/javaSamDebug.ts | 2 +- packages/core/src/shared/sam/deploy.ts | 4 +- packages/core/src/shared/sam/utils.ts | 2 +- .../core/src/shared/utilities/vsCodeUtils.ts | 2 +- ...etStateMachineDefinitionFromCfnTemplate.ts | 4 +- .../accessanalyzer/iamPolicyChecks.test.ts | 2 +- .../commands/downloadSchemaItemCode.test.ts | 14 +- .../commands/searchSchemas.test.ts | 6 +- .../explorer/registryItemNode.test.ts | 2 +- .../core/src/test/fakeExtensionContext.ts | 2 +- packages/core/src/test/globalSetup.test.ts | 2 +- .../lambda/local/debugConfiguration.test.ts | 2 +- .../shared/debug/launchConfiguration.test.ts | 2 +- .../debugger/samDebugConfigProvider.test.ts | 4 +- .../shared/ui/sam/templatePrompter.test.ts | 2 +- .../src/test/shared/wizards/wizard.test.ts | 2 +- .../codewhisperer/referenceTracker.test.ts | 14 +- .../codewhisperer/securityScan.test.ts | 14 +- .../codewhisperer/serviceInvocations.test.ts | 10 +- packages/core/src/testInteg/sam.test.ts | 2 +- .../commands/createNewThreatComposerFile.ts | 2 +- packages/core/types/git.d.ts | 2 +- packages/webpack.base.config.js | 6 +- packages/webpack.vue.config.js | 8 +- packages/webpack.web.config.js | 2 +- 86 files changed, 403 insertions(+), 178 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 5d196c59541..a25a9d18003 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -12,7 +12,7 @@ module.exports = { mocha: true, es2024: true, }, - plugins: ['@typescript-eslint', 'unicorn', 'header', 'security-node', 'aws-toolkits'], + plugins: ['@typescript-eslint', '@stylistic', 'unicorn', 'header', 'security-node', 'aws-toolkits'], extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/eslint-recommended', @@ -113,6 +113,20 @@ module.exports = { 'no-constant-condition': ['error', { checkLoops: false }], 'no-empty': 'off', + // https://eslint.style/rules/default/spaced-comment + // Require space after // comment. + '@stylistic/spaced-comment': [ + 'error', + 'always', + { + block: { + markers: ['!'], // Allow the /*!…*/ license header. + // exceptions: ['*'], + // balanced: true + }, + }, + ], + // Rules from https://github.com/sindresorhus/eslint-plugin-unicorn // TODO: 'unicorn/no-useless-promise-resolve-reject': 'error', // TODO: 'unicorn/prefer-at': 'error', diff --git a/package-lock.json b/package-lock.json index f79eb31977c..2924d26c889 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "devDependencies": { "@aws-toolkits/telemetry": "^1.0.284", "@playwright/browser-chromium": "^1.43.1", + "@stylistic/eslint-plugin": "^2.11.0", "@types/he": "^1.2.3", "@types/vscode": "^1.68.0", "@types/vscode-webview": "^1.57.1", @@ -7736,6 +7737,213 @@ "node": ">=16.0.0" } }, + "node_modules/@stylistic/eslint-plugin": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.11.0.tgz", + "integrity": "sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.13.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz", + "integrity": "sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.16.0.tgz", + "integrity": "sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz", + "integrity": "sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.16.0.tgz", + "integrity": "sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz", + "integrity": "sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", "license": "MIT", @@ -9046,7 +9254,9 @@ } }, "node_modules/acorn": { - "version": "8.12.0", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", "bin": { @@ -20053,7 +20263,7 @@ "aws-ssm-document-language-service": "^1.0.0", "bytes": "^3.1.2", "cross-fetch": "^4.0.0", - "cross-spawn": "^7.0.3", + "cross-spawn": "^7.0.5", "diff": "^5.1.0", "fast-json-patch": "^3.1.1", "glob": "^10.3.10", diff --git a/package.json b/package.json index bc03c2b8395..5e5a67af5ed 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "devDependencies": { "@aws-toolkits/telemetry": "^1.0.284", "@playwright/browser-chromium": "^1.43.1", + "@stylistic/eslint-plugin": "^2.11.0", "@types/he": "^1.2.3", "@types/vscode": "^1.68.0", "@types/vscode-webview": "^1.57.1", diff --git a/packages/amazonq/src/app/amazonqScan/chat/controller/messenger/messengerUtils.ts b/packages/amazonq/src/app/amazonqScan/chat/controller/messenger/messengerUtils.ts index 67351c3eb6e..455a4ebf4af 100644 --- a/packages/amazonq/src/app/amazonqScan/chat/controller/messenger/messengerUtils.ts +++ b/packages/amazonq/src/app/amazonqScan/chat/controller/messenger/messengerUtils.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 * */ -//TODO: Refactor the common functionality between Transform, FeatureDev, CWSPRChat, Scan and UTG to a new Folder. +// TODO: Refactor the common functionality between Transform, FeatureDev, CWSPRChat, Scan and UTG to a new Folder. export default class MessengerUtils { static stringToEnumValue = ( diff --git a/packages/amazonq/src/extension.ts b/packages/amazonq/src/extension.ts index f5cc7274426..a4b53dbf66d 100644 --- a/packages/amazonq/src/extension.ts +++ b/packages/amazonq/src/extension.ts @@ -53,7 +53,7 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is errors.init(fs.getUsername(), env.isAutomation()) await initializeComputeRegion() - globals.contextPrefix = 'amazonq.' //todo: disconnect from above line + globals.contextPrefix = 'amazonq.' // todo: disconnect from above line // Avoid activation if older toolkit is installed // Amazon Q is only compatible with AWS Toolkit >= 3.0.0 diff --git a/packages/core/resources/js/graphStateMachine.js b/packages/core/resources/js/graphStateMachine.js index d2ec7ca11ab..9ccff2145fa 100644 --- a/packages/core/resources/js/graphStateMachine.js +++ b/packages/core/resources/js/graphStateMachine.js @@ -108,7 +108,7 @@ zoomoutBtn.addEventListener('click', () => { // Message passing from extension to webview. // Capture state machine definition -window.addEventListener('message', event => { +window.addEventListener('message', (event) => { // event.data is object passed in from postMessage from vscode const message = event.data switch (message.command) { diff --git a/packages/core/src/amazonq/commons/types.ts b/packages/core/src/amazonq/commons/types.ts index 1016f5c0669..f5724a13872 100644 --- a/packages/core/src/amazonq/commons/types.ts +++ b/packages/core/src/amazonq/commons/types.ts @@ -4,7 +4,7 @@ */ export enum FollowUpTypes { - //UnitTestGeneration + // UnitTestGeneration ViewDiff = 'ViewDiff', AcceptCode = 'AcceptCode', RejectCode = 'RejectCode', @@ -14,7 +14,7 @@ export enum FollowUpTypes { InstallDependenciesAndContinue = 'InstallDependenciesAndContinue', ContinueBuildAndExecute = 'ContinueBuildAndExecute', ViewCodeDiffAfterIteration = 'ViewCodeDiffAfterIteration', - //FeatureDev + // FeatureDev GenerateCode = 'GenerateCode', InsertCode = 'InsertCode', ProvideFeedbackAndRegenerateCode = 'ProvideFeedbackAndRegenerateCode', diff --git a/packages/core/src/amazonq/lsp/lspController.ts b/packages/core/src/amazonq/lsp/lspController.ts index 7a74318dd14..1b948625e76 100644 --- a/packages/core/src/amazonq/lsp/lspController.ts +++ b/packages/core/src/amazonq/lsp/lspController.ts @@ -360,7 +360,7 @@ export class LspController { }) } } catch (error) { - //TODO: use telemetry.run() + // TODO: use telemetry.run() getLogger().error(`LspController: Failed to build index of project`) telemetry.amazonq_indexWorkspace.emit({ duration: performance.now() - start, diff --git a/packages/core/src/amazonq/lsp/types.ts b/packages/core/src/amazonq/lsp/types.ts index fe1df5ed3bc..3af943cb97d 100644 --- a/packages/core/src/amazonq/lsp/types.ts +++ b/packages/core/src/amazonq/lsp/types.ts @@ -66,7 +66,7 @@ export const QueryVectorIndexRequestType: RequestType = new RequestType( diff --git a/packages/core/src/amazonq/webview/ui/apps/testChatConnector.ts b/packages/core/src/amazonq/webview/ui/apps/testChatConnector.ts index 3fa53cd97f8..cefc2b8818f 100644 --- a/packages/core/src/amazonq/webview/ui/apps/testChatConnector.ts +++ b/packages/core/src/amazonq/webview/ui/apps/testChatConnector.ts @@ -33,7 +33,7 @@ export interface MessageData { tabID: string type: TestMessageType } -//TODO: Refactor testChatConnector, scanChatConnector and other apps connector files post RIV +// TODO: Refactor testChatConnector, scanChatConnector and other apps connector files post RIV export class Connector extends BaseConnector { override getTabType(): TabType { return 'testgen' diff --git a/packages/core/src/amazonq/webview/ui/main.ts b/packages/core/src/amazonq/webview/ui/main.ts index 58511517e7a..43f5c798296 100644 --- a/packages/core/src/amazonq/webview/ui/main.ts +++ b/packages/core/src/amazonq/webview/ui/main.ts @@ -43,7 +43,7 @@ export const createMynahUI = ( let mynahUI: MynahUI // eslint-disable-next-line prefer-const let connector: Connector - //Store the mapping between messageId and messageUserIntent for amazonq_interactWithMessage telemetry + // Store the mapping between messageId and messageUserIntent for amazonq_interactWithMessage telemetry const responseMetadata = new Map() window.addEventListener('error', (e) => { @@ -107,7 +107,7 @@ export const createMynahUI = ( let featureConfigs: Map = tryNewMap(featureConfigsSerialized) function getCodeBlockActions(messageData: any) { - //Show ViewDiff and AcceptDiff for allowedCommands in CWC + // Show ViewDiff and AcceptDiff for allowedCommands in CWC const isEnabled = featureConfigs.get('ViewDiffInChat')?.variation === 'TREATMENT' const tab = tabsStorage.getTab(messageData?.tabID || '') const allowedCommands = [ @@ -133,13 +133,13 @@ export const createMynahUI = ( }, } } - //Show only "Copy" option for codeblocks in Q Test Tab + // Show only "Copy" option for codeblocks in Q Test Tab if (tab?.type === 'testgen') { return { 'insert-to-cursor': undefined, } } - //Default will show "Copy" and "Insert at cursor" for codeblocks + // Default will show "Copy" and "Insert at cursor" for codeblocks return {} } diff --git a/packages/core/src/amazonq/webview/ui/quickActions/generator.ts b/packages/core/src/amazonq/webview/ui/quickActions/generator.ts index 2f86f8e2d1c..7020a00d185 100644 --- a/packages/core/src/amazonq/webview/ui/quickActions/generator.ts +++ b/packages/core/src/amazonq/webview/ui/quickActions/generator.ts @@ -39,7 +39,7 @@ export class QuickActionGenerator { return [] } - //TODO: Update acc to UX + // TODO: Update acc to UX const quickActionCommands = [ { groupName: `Q Developer agentic capabilities`, diff --git a/packages/core/src/amazonqTest/chat/controller/controller.ts b/packages/core/src/amazonqTest/chat/controller/controller.ts index 065eeb70297..6149e28ee56 100644 --- a/packages/core/src/amazonqTest/chat/controller/controller.ts +++ b/packages/core/src/amazonqTest/chat/controller/controller.ts @@ -433,7 +433,7 @@ export class TestController { session.hasUserPromptSupplied = message.prompt.length > 0 - //displaying user message prompt in Test tab + // displaying user message prompt in Test tab this.messenger.sendMessage(userMessage, tabID, 'prompt') this.messenger.sendChatInputEnabled(tabID, false) this.sessionStorage.getSession().conversationState = ConversationState.IN_PROGRESS @@ -715,7 +715,7 @@ export class TestController { const document = await vscode.workspace.openTextDocument(absolutePath) await vscode.window.showTextDocument(document) // TODO: send the message once again once build is enabled - //this.messenger.sendMessage('Accepted', message.tabID, 'prompt') + // this.messenger.sendMessage('Accepted', message.tabID, 'prompt') telemetry.ui_click.emit({ elementId: 'unitTestGeneration_acceptDiff' }) telemetry.amazonq_utgGenerateTests.emit({ generatedCount: session.numberOfTestsGenerated, @@ -802,7 +802,7 @@ export class TestController { filePath: string ) { try { - //TODO: Write this entire gen response to basiccommands and call here. + // TODO: Write this entire gen response to basiccommands and call here. const editorText = await fs.readFileText(filePath) const triggerPayload = { @@ -836,7 +836,7 @@ export class TestController { } } - //TODO: Check if there are more cases to endSession if yes create a enum or type for step + // TODO: Check if there are more cases to endSession if yes create a enum or type for step private async endSession(data: any, step: FollowUpTypes) { const session = this.sessionStorage.getSession() if (step === FollowUpTypes.RejectCode) { @@ -878,7 +878,7 @@ export class TestController { */ private startInitialBuild(data: any) { - //TODO: Remove the fallback build command after stable version of backend build command. + // TODO: Remove the fallback build command after stable version of backend build command. const userMessage = `Would you like me to help build and execute the test? I will need you to let me know what build command to run if you do.` const followUps: FollowUps = { text: '', @@ -910,7 +910,7 @@ export class TestController { private async checkForInstallationDependencies(data: any) { // const session: Session = this.sessionStorage.getSession() // const listOfInstallationDependencies = session.testGenerationJob?.shortAnswer?.installationDependencies || [] - //MOCK: As there is no installation dependencies in shortAnswer + // MOCK: As there is no installation dependencies in shortAnswer const listOfInstallationDependencies = [''] const installationDependencies = listOfInstallationDependencies.join('\n') @@ -961,7 +961,7 @@ export class TestController { private async startLocalBuildExecution(data: any) { const session: Session = this.sessionStorage.getSession() // const installationDependencies = session.shortAnswer?.installationDependencies ?? [] - //MOCK: ignoring the installation case until backend send response + // MOCK: ignoring the installation case until backend send response const installationDependencies: string[] = [] const buildCommands = session.updatedBuildCommands if (!buildCommands) { @@ -991,7 +991,7 @@ export class TestController { }) const status = await runBuildCommand(installationDependencies) - //TODO: Add separate status for installation dependencies + // TODO: Add separate status for installation dependencies session.buildStatus = status if (status === BuildStatus.FAILURE) { this.messenger.sendBuildProgressMessage({ @@ -1110,7 +1110,7 @@ export class TestController { false ) } - //TODO: Skip this if startTestGenerationProcess timeouts + // TODO: Skip this if startTestGenerationProcess timeouts if (session.generatedFilePath) { await this.showTestCaseSummary(data) } @@ -1297,7 +1297,7 @@ export class TestController { if (session.tabID) { getLogger().debug('Setting input state with tabID: %s', session.tabID) this.messenger.sendChatInputEnabled(session.tabID, true) - this.messenger.sendUpdatePlaceholder(session.tabID, '/test Generate unit tests') //TODO: Change according to the UX + this.messenger.sendUpdatePlaceholder(session.tabID, '/test Generate unit tests') // TODO: Change according to the UX } getLogger().debug( 'Deleting output.log and temp result directory. testGenerationLogsDir: %s', diff --git a/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts b/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts index 6051a9b51ad..e68eb6f9737 100644 --- a/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts +++ b/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts @@ -177,7 +177,7 @@ export class Messenger { ) } - //To show the response of unsupported languages to the user in the Q-Test tab + // To show the response of unsupported languages to the user in the Q-Test tab public async sendAIResponse( response: GenerateAssistantResponseCommandOutput, session: Session, @@ -308,7 +308,7 @@ export class Messenger { }) } - //To show the Build progress in the chat + // To show the Build progress in the chat public sendBuildProgressMessage(params: SendBuildProgressMessageParams) { const { tabID, diff --git a/packages/core/src/amazonqTest/chat/controller/messenger/messengerUtils.ts b/packages/core/src/amazonqTest/chat/controller/messenger/messengerUtils.ts index 647951daef8..9e8fec4594e 100644 --- a/packages/core/src/amazonqTest/chat/controller/messenger/messengerUtils.ts +++ b/packages/core/src/amazonqTest/chat/controller/messenger/messengerUtils.ts @@ -14,7 +14,7 @@ export enum ButtonActions { STOP_BUILD = 'Stop-Build-Process', } -//TODO: Refactor the common functionality between Transform, FeatureDev, CWSPRChat, Scan and UTG to a new Folder. +// TODO: Refactor the common functionality between Transform, FeatureDev, CWSPRChat, Scan and UTG to a new Folder. export default class MessengerUtils { static stringToEnumValue = ( diff --git a/packages/core/src/amazonqTest/chat/session/session.ts b/packages/core/src/amazonqTest/chat/session/session.ts index cd188c10c0f..e0590f2301f 100644 --- a/packages/core/src/amazonqTest/chat/session/session.ts +++ b/packages/core/src/amazonqTest/chat/session/session.ts @@ -28,7 +28,7 @@ export class Session { // A tab may or may not be currently open public tabID: string | undefined - //This is unique per each test generation cycle + // This is unique per each test generation cycle public testGenerationJobGroupName: string | undefined = undefined public listOfTestGenerationJobId: string[] = [] public testGenerationJob: TestGenerationJob | undefined @@ -56,8 +56,8 @@ export class Session { public charsOfCodeAccepted: number = 0 public latencyOfTestGeneration: number = 0 - //TODO: Take values from ShortAnswer or TestGenerationJob - //Build loop + // TODO: Take values from ShortAnswer or TestGenerationJob + // Build loop public buildStatus: BuildStatus = BuildStatus.SUCCESS public updatedBuildCommands: string[] | undefined = undefined public testCoveragePercentage: number = 90 diff --git a/packages/core/src/amazonqTest/models/constants.ts b/packages/core/src/amazonqTest/models/constants.ts index fa0c00d59cc..8370d4d3ca7 100644 --- a/packages/core/src/amazonqTest/models/constants.ts +++ b/packages/core/src/amazonqTest/models/constants.ts @@ -111,12 +111,12 @@ export const testGenBuildProgressMessage = (currentStep: TestGenerationBuildStep ${session.shortAnswer?.testCoverage ? `- Unit test coverage ${session.shortAnswer?.testCoverage}%` : ``} ${icon} Build ${statusText} ${icon} Assertion ${statusText}` - //TODO: Update Assertion % + // TODO: Update Assertion % } return message.trim() } -//TODO: Work on UX to show the build error in the progress message +// TODO: Work on UX to show the build error in the progress message const updateStepStatuses = (currentStep: TestGenerationBuildStep, status?: string) => { for (let step = TestGenerationBuildStep.INSTALL_DEPENDENCIES; step <= currentStep; step++) { const stepStatus: StepStatus = { diff --git a/packages/core/src/awsService/accessanalyzer/vue/iamPolicyChecks.ts b/packages/core/src/awsService/accessanalyzer/vue/iamPolicyChecks.ts index 406b04a6d75..d32b7ba9dd1 100644 --- a/packages/core/src/awsService/accessanalyzer/vue/iamPolicyChecks.ts +++ b/packages/core/src/awsService/accessanalyzer/vue/iamPolicyChecks.ts @@ -588,7 +588,7 @@ export class IamPolicyChecksWebview extends VueWebview { }) } catch (err: any) { if (err.status === 2) { - //CLI responds with a status code of 2 when findings are discovered + // CLI responds with a status code of 2 when findings are discovered const findingsCount = this.handleValidatePolicyCliResponse(err.stdout.toString()) span.record({ findingsCount: findingsCount, @@ -652,7 +652,7 @@ export class IamPolicyChecksWebview extends VueWebview { }) } catch (err: any) { if (err.status === 2) { - //CLI responds with a status code of 2 when findings are discovered + // CLI responds with a status code of 2 when findings are discovered const findingsCount = this.handleCustomPolicyChecksCliResponse(err.stdout.toString()) span.record({ findingsCount: findingsCount, @@ -752,7 +752,7 @@ export async function renderIamPolicyChecks(context: ExtContext): Promise { } } -//Check if Cfn and Tf tools are installed +// Check if Cfn and Tf tools are installed export function arePythonToolsInstalled(): boolean { const logger: Logger = getLogger() let cfnToolInstalled = true diff --git a/packages/core/src/awsService/cloudWatchLogs/timeFilterSubmenu.ts b/packages/core/src/awsService/cloudWatchLogs/timeFilterSubmenu.ts index 1f4dbc1d28a..0bb3cd9670d 100644 --- a/packages/core/src/awsService/cloudWatchLogs/timeFilterSubmenu.ts +++ b/packages/core/src/awsService/cloudWatchLogs/timeFilterSubmenu.ts @@ -38,7 +38,7 @@ export class TimeFilterSubmenu extends Prompter { private get recentTimeItems(): DataQuickPickItem[] { const options: DataQuickPickItem[] = [] - //appromixate 31 days as month length (better to overshoot) + // appromixate 31 days as month length (better to overshoot) options.push({ label: 'All time', data: 0, diff --git a/packages/core/src/awsService/iot/commands/attachCertificate.ts b/packages/core/src/awsService/iot/commands/attachCertificate.ts index ef45917f7a0..c77f1d36d44 100644 --- a/packages/core/src/awsService/iot/commands/attachCertificate.ts +++ b/packages/core/src/awsService/iot/commands/attachCertificate.ts @@ -46,7 +46,7 @@ export async function attachCertificateCommand(node: IotThingNode, promptFun = p getLogger().debug('Attached certificate %O', cert.certificateId) - //Refresh the Thing node + // Refresh the Thing node await node.refreshNode() } diff --git a/packages/core/src/awsService/iot/commands/createCert.ts b/packages/core/src/awsService/iot/commands/createCert.ts index 22db3136831..3f6eae413db 100644 --- a/packages/core/src/awsService/iot/commands/createCert.ts +++ b/packages/core/src/awsService/iot/commands/createCert.ts @@ -14,7 +14,7 @@ import { Iot } from 'aws-sdk' import { fs } from '../../../shared' // eslint-disable-next-line @typescript-eslint/naming-convention -const MODE_RW_R_R = 0o644 //File permission 0644 rw-r--r-- for PEM files. +const MODE_RW_R_R = 0o644 // File permission 0644 rw-r--r-- for PEM files. // eslint-disable-next-line @typescript-eslint/naming-convention const PEM_FILE_ENCODING = 'ascii' @@ -60,10 +60,10 @@ export async function createCertificateCommand( getLogger().info(`Downloaded certificate ${certId}`) void vscode.window.showInformationMessage(localize('AWS.iot.createCert.success', 'Created certificate {0}', certId)) - //Save resources + // Save resources const saveSuccessful = await saveFunc(folderLocation, certId!, certPem, privateKey, publicKey) if (!saveSuccessful) { - //Delete the certificate if the key pair cannot be saved + // Delete the certificate if the key pair cannot be saved try { await node.iot.deleteCertificate({ certificateId: certId! }) } catch (e) { @@ -72,7 +72,7 @@ export async function createCertificateCommand( } } - //Refresh the Certificate Folder node + // Refresh the Certificate Folder node await node.refreshNode() } diff --git a/packages/core/src/awsService/iot/commands/createPolicy.ts b/packages/core/src/awsService/iot/commands/createPolicy.ts index 7a91de4fb5d..ba082811e34 100644 --- a/packages/core/src/awsService/iot/commands/createPolicy.ts +++ b/packages/core/src/awsService/iot/commands/createPolicy.ts @@ -33,7 +33,7 @@ export async function createPolicyCommand(node: IotPolicyFolderNode, getPolicyDo } try { - //Parse to ensure this is a valid JSON + // Parse to ensure this is a valid JSON const policyJSON = JSON.parse(data.toString()) await node.iot.createPolicy({ policyName, policyDocument: JSON.stringify(policyJSON) }) void vscode.window.showInformationMessage( @@ -45,7 +45,7 @@ export async function createPolicyCommand(node: IotPolicyFolderNode, getPolicyDo return } - //Refresh the Policy Folder node + // Refresh the Policy Folder node await node.refreshNode() } diff --git a/packages/core/src/awsService/iot/commands/createPolicyVersion.ts b/packages/core/src/awsService/iot/commands/createPolicyVersion.ts index 979c8d50beb..257626489f6 100644 --- a/packages/core/src/awsService/iot/commands/createPolicyVersion.ts +++ b/packages/core/src/awsService/iot/commands/createPolicyVersion.ts @@ -27,7 +27,7 @@ export async function createPolicyVersionCommand( } try { - //Parse to ensure this is a valid JSON + // Parse to ensure this is a valid JSON const policyJSON = JSON.parse(data.toString()) await node.iot.createPolicyVersion({ policyName, @@ -45,6 +45,6 @@ export async function createPolicyVersionCommand( return } - //Refresh the node + // Refresh the node node.refresh() } diff --git a/packages/core/src/awsService/iot/commands/createThing.ts b/packages/core/src/awsService/iot/commands/createThing.ts index 6981e48f192..2d9b1f11d4e 100644 --- a/packages/core/src/awsService/iot/commands/createThing.ts +++ b/packages/core/src/awsService/iot/commands/createThing.ts @@ -43,7 +43,7 @@ export async function createThingCommand(node: IotThingFolderNode): Promise { void showViewLogsMessage(localize('AWS.iot.deleteThing.error', 'Failed to delete Thing: {0}', thingName)) } - //Refresh the Things Folder node + // Refresh the Things Folder node await node.parent.refreshNode() } diff --git a/packages/core/src/awsService/iot/commands/detachCert.ts b/packages/core/src/awsService/iot/commands/detachCert.ts index 11489fa841d..a8384e34b79 100644 --- a/packages/core/src/awsService/iot/commands/detachCert.ts +++ b/packages/core/src/awsService/iot/commands/detachCert.ts @@ -49,6 +49,6 @@ export async function detachThingCertCommand(node: IotThingCertNode): Promise = Settings.instance ) { - //Show only 8 characters in the explorer instead of the full 64. The entire - //ID can be copied from the context menu or viewed when hovered over. + // Show only 8 characters in the explorer instead of the full 64. The entire + // ID can be copied from the context menu or viewed when hovered over. super(truncate(certificate.id, 8), collapsibleState) this.tooltip = localize( diff --git a/packages/core/src/awsService/iot/explorer/iotPolicyFolderNode.ts b/packages/core/src/awsService/iot/explorer/iotPolicyFolderNode.ts index 8d9e1ce809e..36af63cf495 100644 --- a/packages/core/src/awsService/iot/explorer/iotPolicyFolderNode.ts +++ b/packages/core/src/awsService/iot/explorer/iotPolicyFolderNode.ts @@ -19,10 +19,10 @@ import { IotNode } from './iotNodes' import { Settings } from '../../../shared/settings' import { ClassToInterfaceType } from '../../../shared/utilities/tsUtils' -//Length of certificate ID. The certificate ID is the last segment of the ARN. +// Length of certificate ID. The certificate ID is the last segment of the ARN. const certIdLength = 64 -//Number of digits of the certificate ID to show +// Number of digits of the certificate ID to show const certPreviewLength = 8 /** diff --git a/packages/core/src/awsService/redshift/activation.ts b/packages/core/src/awsService/redshift/activation.ts index 58dea2e0075..e7af970c26a 100644 --- a/packages/core/src/awsService/redshift/activation.ts +++ b/packages/core/src/awsService/redshift/activation.ts @@ -99,7 +99,7 @@ function getNotebookConnectClickedHandler(ctx: ExtContext, redshiftNotebookContr connectionParams = undefined } const edit = new vscode.WorkspaceEdit() - //NotebookEdit is only available for engine version > 1.68.0 + // NotebookEdit is only available for engine version > 1.68.0 const nbEdit = (vscode as any).NotebookEdit.updateNotebookMetadata({ connectionParams: connectionParams, }) diff --git a/packages/core/src/awsService/redshift/explorer/redshiftNode.ts b/packages/core/src/awsService/redshift/explorer/redshiftNode.ts index 52eb470283b..4c245b7f4de 100644 --- a/packages/core/src/awsService/redshift/explorer/redshiftNode.ts +++ b/packages/core/src/awsService/redshift/explorer/redshiftNode.ts @@ -143,7 +143,7 @@ export class RedshiftNode extends AWSTreeNodeBase implements LoadMoreNode { } public async createCluster(clusterName: string): Promise { - //Code for creating redshiftClient cluster + // Code for creating redshiftClient cluster } public [inspect.custom](): string { diff --git a/packages/core/src/awsService/redshift/notebook/redshiftNotebookController.ts b/packages/core/src/awsService/redshift/notebook/redshiftNotebookController.ts index 3a0c3ca2d9d..1db972314d3 100644 --- a/packages/core/src/awsService/redshift/notebook/redshiftNotebookController.ts +++ b/packages/core/src/awsService/redshift/notebook/redshiftNotebookController.ts @@ -122,13 +122,13 @@ export class RedshiftNotebookController { } let tableHtml = `

Results from ${connectionParams.warehouseIdentifier} - database: ${connectionParams.database}

` - //Adding column headers + // Adding column headers for (const column of columns) { tableHtml += `` } tableHtml += '' - //Adding data rows + // Adding data rows for (const row of records) { tableHtml += '' for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) { diff --git a/packages/core/src/awsService/s3/commands/uploadFile.ts b/packages/core/src/awsService/s3/commands/uploadFile.ts index ca77617af4e..41093a96f2f 100644 --- a/packages/core/src/awsService/s3/commands/uploadFile.ts +++ b/packages/core/src/awsService/s3/commands/uploadFile.ts @@ -111,8 +111,8 @@ export async function uploadFileCommand( const filesToUpload = await getFile(document) if (!filesToUpload || filesToUpload.length === 0) { - //if file is undefined, means the back button was pressed(there is no step before) or no file was selected - //thus break the loop of the 'wizard' + // if file is undefined, means the back button was pressed(there is no step before) or no file was selected + // thus break the loop of the 'wizard' showOutputMessage( localize( 'AWS.message.error.uploadFileCommand.noFileSelected', @@ -232,7 +232,7 @@ async function runBatchUploads(uploadRequests: UploadRequest[], outputChannel = outputChannel ) } - //at least one request failed + // at least one request failed const response = await vscode.window.showErrorMessage( localize( 'AWS.s3.uploadFile.retryPrompt', @@ -325,7 +325,7 @@ async function uploadBatchOfFiles( }) if (uploadResult) { - //this request failed to upload + // this request failed to upload failedRequests.push(uploadResult) } diff --git a/packages/core/src/codewhisperer/commands/basicCommands.ts b/packages/core/src/codewhisperer/commands/basicCommands.ts index 8f428419853..00555af5cfe 100644 --- a/packages/core/src/codewhisperer/commands/basicCommands.ts +++ b/packages/core/src/codewhisperer/commands/basicCommands.ts @@ -222,7 +222,7 @@ export const showFileScan = Commands.declare( scanUuid ) } else if (onDemandFileScanState.isRunning()) { - //TODO: Pending with progress bar implementation in the Q chat Panel + // TODO: Pending with progress bar implementation in the Q chat Panel // User intends to stop the scan from Q chat panel. // Cancel only when the file scan state is "Running" await confirmStopSecurityScan( diff --git a/packages/core/src/codewhisperer/commands/gettingStartedPageCommands.ts b/packages/core/src/codewhisperer/commands/gettingStartedPageCommands.ts index 110a2adf011..5036a9d3b5b 100644 --- a/packages/core/src/codewhisperer/commands/gettingStartedPageCommands.ts +++ b/packages/core/src/codewhisperer/commands/gettingStartedPageCommands.ts @@ -19,7 +19,7 @@ export class CodeWhispererCommandBackend { } const prompts = AmazonQPromptSettings.instance - //To check the condition If the user has already seen the welcome message + // To check the condition If the user has already seen the welcome message if (!(await prompts.isPromptEnabled('codeWhispererNewWelcomeMessage'))) { telemetry.ui_click.emit({ elementId: 'codewhisperer_Learn_ButtonClick', passive: true }) } diff --git a/packages/core/src/codewhisperer/commands/startTestGeneration.ts b/packages/core/src/codewhisperer/commands/startTestGeneration.ts index c4f6d06b939..39750a8b3ff 100644 --- a/packages/core/src/codewhisperer/commands/startTestGeneration.ts +++ b/packages/core/src/codewhisperer/commands/startTestGeneration.ts @@ -37,7 +37,7 @@ export async function startTestGenerationProcess( ) { const logger = getLogger() const session = ChatSessionManager.Instance.getSession() - //TODO: Step 0: Initial Test Gen telemetry + // TODO: Step 0: Initial Test Gen telemetry try { logger.verbose(`Starting Test Generation `) logger.verbose(`Tab ID: ${tabID} !== ${session.tabID}`) @@ -118,7 +118,7 @@ export async function startTestGenerationProcess( fileName, initialExecution ) - //TODO: Send status to test summary + // TODO: Send status to test summary if (jobStatus === TestGenerationJobStatus.FAILED) { logger.verbose(`Test generation failed.`) throw new TestGenFailedError() @@ -130,7 +130,7 @@ export async function startTestGenerationProcess( /** * Step 5: Process and show the view diff by getting the results from exportResultsArchive */ - //https://github.com/aws/aws-toolkit-vscode/blob/0164d4145e58ae036ddf3815455ea12a159d491d/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts#L314-L405 + // https://github.com/aws/aws-toolkit-vscode/blob/0164d4145e58ae036ddf3815455ea12a159d491d/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts#L314-L405 await exportResultsArchive( artifactMap.SourceCode, testJob.testGenerationJob.testGenerationJobGroupName, @@ -141,7 +141,7 @@ export async function startTestGenerationProcess( ) } catch (error) { logger.error(`startTestGenerationProcess failed: %O`, error) - //TODO: Send error message to Chat + // TODO: Send error message to Chat testGenState.getChatControllers()?.errorThrown.fire({ tabID: session.tabID, error: error, diff --git a/packages/core/src/codewhisperer/models/constants.ts b/packages/core/src/codewhisperer/models/constants.ts index 7020de28c31..620a292cd81 100644 --- a/packages/core/src/codewhisperer/models/constants.ts +++ b/packages/core/src/codewhisperer/models/constants.ts @@ -257,9 +257,9 @@ export const codeScanZipExt = '.zip' export const contextTruncationTimeoutSeconds = 10 -export const codeScanJobTimeoutSeconds = 60 * 10 //10 minutes +export const codeScanJobTimeoutSeconds = 60 * 10 // 10 minutes -export const codeFileScanJobTimeoutSeconds = 60 * 10 //10 minutes +export const codeFileScanJobTimeoutSeconds = 60 * 10 // 10 minutes export const codeFixJobTimeoutMs = 60_000 @@ -396,7 +396,7 @@ export const failedToConnectIamIdentityCenter = `Failed to connect to IAM Identi export const stopScanMessage = 'Stop security review? This review will be counted as one complete review towards your monthly security review limits.' -//TODO: Change the Text according to the UX +// TODO: Change the Text according to the UX export const stopScanMessageInChat = 'Review is stopped. Retry reviews by selecting below options' export const showScannedFilesMessage = 'View Code Issues' diff --git a/packages/core/src/codewhisperer/models/model.ts b/packages/core/src/codewhisperer/models/model.ts index ade478ad875..d54370a7102 100644 --- a/packages/core/src/codewhisperer/models/model.ts +++ b/packages/core/src/codewhisperer/models/model.ts @@ -370,7 +370,7 @@ enum TestGenStatus { Running, Cancelling, } -//TODO: Refactor model of /scan and /test +// TODO: Refactor model of /scan and /test export class TestGenState { // Define a constructor for this class private testGenState: TestGenStatus = TestGenStatus.NotStarted diff --git a/packages/core/src/codewhisperer/service/securityScanHandler.ts b/packages/core/src/codewhisperer/service/securityScanHandler.ts index 537638b52c9..d328034d560 100644 --- a/packages/core/src/codewhisperer/service/securityScanHandler.ts +++ b/packages/core/src/codewhisperer/service/securityScanHandler.ts @@ -339,7 +339,7 @@ export function throwIfCancelled(scope: CodeWhispererConstants.CodeAnalysisScope break } } -//TODO: Refactor this +// TODO: Refactor this export async function uploadArtifactToS3( fileName: string, resp: CreateUploadUrlResponse, @@ -376,7 +376,7 @@ export async function uploadArtifactToS3( } } -//TODO: Refactor this +// TODO: Refactor this export function getLoggerForScope(scope?: CodeWhispererConstants.CodeAnalysisScope) { return scope === CodeWhispererConstants.CodeAnalysisScope.FILE_AUTO ? getNullLogger() : getLogger() } diff --git a/packages/core/src/codewhisperer/service/testGenHandler.ts b/packages/core/src/codewhisperer/service/testGenHandler.ts index 218864ce256..e0027c2ac33 100644 --- a/packages/core/src/codewhisperer/service/testGenHandler.ts +++ b/packages/core/src/codewhisperer/service/testGenHandler.ts @@ -25,9 +25,9 @@ import path from 'path' import { ExportIntent } from '@amzn/codewhisperer-streaming' import { glob } from 'glob' -//TODO: Get TestFileName and Framework and to error message +// TODO: Get TestFileName and Framework and to error message export function throwIfCancelled() { - //TODO: fileName will be '' if user gives propt without opening + // TODO: fileName will be '' if user gives propt without opening if (testGenState.isCancelling()) { throw Error(CodeWhispererConstants.unitTestGenerationCancelMessage) } @@ -146,7 +146,7 @@ export async function pollTestJobStatus( if (shortAnswerString) { const parsedShortAnswer = JSON.parse(shortAnswerString) const shortAnswer: ShortAnswer = JSON.parse(parsedShortAnswer) - //Stop the Unit test generation workflow if IDE receive stopIteration = true + // Stop the Unit test generation workflow if IDE receive stopIteration = true if (shortAnswer.stopIteration === 'true') { session.stopIteration = true throw new TestGenFailedError(shortAnswer.planSummary) @@ -181,7 +181,7 @@ export async function pollTestJobStatus( ChatSessionManager.Instance.getSession().shortAnswer = shortAnswer } if (resp.testGenerationJob?.status !== TestGenerationJobStatus.IN_PROGRESS) { - //This can be FAILED or COMPLETED + // This can be FAILED or COMPLETED status = resp.testGenerationJob?.status as TestGenerationJobStatus logger.verbose(`testgen job status: ${status}`) logger.verbose(`Complete polling test job status.`) @@ -210,7 +210,7 @@ export async function exportResultsArchive( projectPath: string, initialExecution: boolean ) { - //TODO: Make a common Temp folder + // TODO: Make a common Temp folder const pathToArchiveDir = path.join(tempDirPath, 'q-testgen') const archivePathExists = await fs.existsDir(pathToArchiveDir) @@ -239,7 +239,7 @@ export async function exportResultsArchive( projectName, }) - //If User accepts the diff + // If User accepts the diff testGenState.getChatControllers()?.sendUpdatePromptProgress.fire({ tabID: ChatSessionManager.Instance.getSession().tabID, status: 'Completed', diff --git a/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts b/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts index fbbe937c0a0..13951f7508a 100644 --- a/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts +++ b/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts @@ -39,7 +39,7 @@ export abstract class ProposedChangeNode { try { this.saveFile() } catch (err) { - //to do: file system-related error handling + // to do: file system-related error handling if (err instanceof Error) { getLogger().error(err.message) } @@ -468,7 +468,7 @@ export class ProposedTransformationExplorer { } else { patchFiles.push(singlePatchFile) } - //Because multiple patches are returned once the ZIP is downloaded, we want to show the first one to start + // Because multiple patches are returned once the ZIP is downloaded, we want to show the first one to start diffModel.parseDiff( patchFiles[0], transformByQState.getProjectPath(), @@ -549,7 +549,7 @@ export class ProposedTransformationExplorer { void vscode.window.showInformationMessage(CodeWhispererConstants.changesAppliedNotificationOneDiff) } - //We do this to ensure that the changesAppliedChatMessage is only sent to user when they accept the first diff.patch + // We do this to ensure that the changesAppliedChatMessage is only sent to user when they accept the first diff.patch transformByQState.getChatControllers()?.transformationFinished.fire({ message: CodeWhispererConstants.changesAppliedChatMessageMultipleDiffs( diffModel.currentPatchIndex, diff --git a/packages/core/src/codewhisperer/util/supplementalContext/crossFileContextUtil.ts b/packages/core/src/codewhisperer/util/supplementalContext/crossFileContextUtil.ts index 2a9423e6159..a85bb8e66d5 100644 --- a/packages/core/src/codewhisperer/util/supplementalContext/crossFileContextUtil.ts +++ b/packages/core/src/codewhisperer/util/supplementalContext/crossFileContextUtil.ts @@ -240,7 +240,7 @@ export async function fetchOpentabsContext( function findBestKChunkMatches(chunkInput: Chunk, chunkReferences: Chunk[], k: number): Chunk[] { const chunkContentList = chunkReferences.map((chunk) => chunk.content) - //performBM25Scoring returns the output in a sorted order (descending of scores) + // performBM25Scoring returns the output in a sorted order (descending of scores) const top3: BM25Document[] = new BM25Okapi(chunkContentList).topN(chunkInput.content, crossFileContextConfig.topK) return top3.map((doc) => { diff --git a/packages/core/src/codewhisperer/util/telemetryHelper.ts b/packages/core/src/codewhisperer/util/telemetryHelper.ts index 5176ffee2be..bdb63b45727 100644 --- a/packages/core/src/codewhisperer/util/telemetryHelper.ts +++ b/packages/core/src/codewhisperer/util/telemetryHelper.ts @@ -245,7 +245,7 @@ export class TelemetryHelper { events.push(event) }) - //aggregate suggestion references count + // aggregate suggestion references count const referenceCount = this.getAggregatedSuggestionReferenceCount(events) // aggregate user decision events at requestId level diff --git a/packages/core/src/codewhisperer/util/zipUtil.ts b/packages/core/src/codewhisperer/util/zipUtil.ts index 7678f9dcb12..663a7e85f47 100644 --- a/packages/core/src/codewhisperer/util/zipUtil.ts +++ b/packages/core/src/codewhisperer/util/zipUtil.ts @@ -450,7 +450,7 @@ export class ZipUtil { } protected async processTestCoverageFiles(targetPath: string) { - //TODO: will be removed post release + // TODO: will be removed post release const coverageFilePatterns = ['**/coverage.xml', '**/coverage.json', '**/coverage.txt'] let files: vscode.Uri[] = [] @@ -616,7 +616,7 @@ export class ZipUtil { throw error } } - //TODO: Refactor this + // TODO: Refactor this public async removeTmpFiles(zipMetadata: ZipMetadata, scope?: CodeWhispererConstants.CodeAnalysisScope) { const logger = getLoggerForScope(scope) logger.verbose(`Cleaning up temporary files...`) diff --git a/packages/core/src/codewhisperer/vue/backend.ts b/packages/core/src/codewhisperer/vue/backend.ts index e2561cad87c..ec1ed818ec0 100644 --- a/packages/core/src/codewhisperer/vue/backend.ts +++ b/packages/core/src/codewhisperer/vue/backend.ts @@ -29,7 +29,7 @@ export class CodeWhispererWebview extends VueWebview { private isFileSaved: boolean = false private getLocalFilePath(fileName: string): string { - //This will store the files in the global storage path of VSCode + // This will store the files in the global storage path of VSCode return path.join(globals.context.globalStorageUri.fsPath, fileName) } @@ -81,22 +81,22 @@ export class CodeWhispererWebview extends VueWebview { } } - //This function returns the OS type of the machine used in Shortcuts and Generate Suggestion Sections + // This function returns the OS type of the machine used in Shortcuts and Generate Suggestion Sections public getOSType(): OSType { return os.platform() === 'darwin' ? 'Mac' : 'RestOfOS' } - //This function opens the Keyboard shortcuts in VSCode + // This function opens the Keyboard shortcuts in VSCode async openShortCuts(): Promise { await vscode.commands.executeCommand('workbench.action.openGlobalKeybindings', 'codewhisperer') } - //This function opens the Feedback CodeWhisperer page in the webview + // This function opens the Feedback CodeWhisperer page in the webview async openFeedBack(): Promise { return submitFeedback(placeholder, 'Amazon Q') } - //------Telemetry------ + // ------Telemetry------ /** This represents the cause for the webview to open, whether a certain button was clicked or it opened automatically */ #codeWhispererSource?: CodeWhispererSource @@ -113,7 +113,7 @@ export class CodeWhispererWebview extends VueWebview { passive: true, }) } - //Telemetry for CodeWhisperer Try Example with two params Language and Task Type + // Telemetry for CodeWhisperer Try Example with two params Language and Task Type emitTryExampleClick(languageSelected: CodewhispererLanguage, taskType: CodewhispererGettingStartedTask) { telemetry.codewhisperer_onboardingClick.emit({ codewhispererLanguage: languageSelected, @@ -121,7 +121,7 @@ export class CodeWhispererWebview extends VueWebview { }) } } -//List of all events that are emitted from the webview of CodeWhisperer +// List of all events that are emitted from the webview of CodeWhisperer export type CodeWhispererUiClick = | 'codewhisperer_Resources_Documentation' | 'codewhisperer_Resources_Feedback' @@ -160,7 +160,7 @@ export async function showCodeWhispererWebview( }), ] const prompts = AmazonQPromptSettings.instance - //To check the condition If the user has already seen the welcome message + // To check the condition If the user has already seen the welcome message if (await prompts.isPromptEnabled('codeWhispererNewWelcomeMessage')) { telemetry.ui_click.emit({ elementId: 'codewhisperer_Learn_PageOpen', passive: true }) } else { diff --git a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts index af6a3a2a3ce..6604fd7bb21 100644 --- a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts +++ b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts @@ -91,7 +91,7 @@ export class Messenger { * @returns count of multi-line code blocks in response. */ public async countTotalNumberOfCodeBlocks(message: string): Promise { - //TODO: remove this when moved to server-side. + // TODO: remove this when moved to server-side. if (message === undefined) { return 0 } diff --git a/packages/core/src/codewhispererChat/editor/context/file/javaImportReader.ts b/packages/core/src/codewhispererChat/editor/context/file/javaImportReader.ts index 332829868a4..b66a6c44936 100644 --- a/packages/core/src/codewhispererChat/editor/context/file/javaImportReader.ts +++ b/packages/core/src/codewhispererChat/editor/context/file/javaImportReader.ts @@ -24,13 +24,13 @@ export function extractContextFromJavaImports(names: any): string[] { if (commonJavaImportsPrefixesRegex.test(importStatement)) { return '' } else if (importStatement.startsWith(awsJavaSdkV1Prefix)) { - //@ts-ignore + // @ts-ignore return javaImport.packages?.at(1) ?? '' } else if (importStatement.startsWith(awsJavaSdkV2Prefix)) { - //@ts-ignore + // @ts-ignore return javaImport.packages?.at(2) ?? '' } else { - //@ts-ignore + // @ts-ignore return javaImport.packages?.at(0) ?? javaImport.organisation ?? javaImport.tld } }) diff --git a/packages/core/src/eventSchemas/commands/downloadSchemaItemCode.ts b/packages/core/src/eventSchemas/commands/downloadSchemaItemCode.ts index 5077b21c909..3ee5d8c865c 100644 --- a/packages/core/src/eventSchemas/commands/downloadSchemaItemCode.ts +++ b/packages/core/src/eventSchemas/commands/downloadSchemaItemCode.ts @@ -139,7 +139,7 @@ export class SchemaCodeDownloader { } catch (err) { const error = err as Error if (error.name === 'ResourceNotFound') { - //If the code generation wasn't previously kicked off, do so + // If the code generation wasn't previously kicked off, do so void vscode.window.showInformationMessage( localize( 'AWS.message.info.schemas.downloadCodeBindings.generate', @@ -149,10 +149,10 @@ export class SchemaCodeDownloader { ) await this.generator.generate(request) - //Then, poll for completion + // Then, poll for completion await this.poller.pollForCompletion(request) - //Download generated code bindings + // Download generated code bindings void vscode.window.showInformationMessage( localize( 'AWS.message.info.schemas.downloadCodeBindings.downloading', @@ -294,7 +294,7 @@ export class CodeExtractor { const codeZipFile = path.join(codeZipDir, fileName) const destinationDirectory = request.destinationDirectory.fsPath - //write binary data into a temp zip file in a temp directory + // write binary data into a temp zip file in a temp directory const zipContentsBinary = new Uint8Array(zipContents) const fd = fs.openSync(codeZipFile, 'w') fs.writeSync(fd, zipContentsBinary, 0, zipContentsBinary.byteLength, 0) diff --git a/packages/core/src/eventSchemas/commands/viewSchemaItem.ts b/packages/core/src/eventSchemas/commands/viewSchemaItem.ts index 5ad255e65c6..f3eca0428e5 100644 --- a/packages/core/src/eventSchemas/commands/viewSchemaItem.ts +++ b/packages/core/src/eventSchemas/commands/viewSchemaItem.ts @@ -51,5 +51,5 @@ export async function showSchemaContent( language: 'json', }) const editor = await vscode.window.showTextDocument(newDoc, vscode.ViewColumn.One, false) - await editor.edit((edit) => edit.insert(new vscode.Position(/*line*/ 0, /*character*/ 0), prettySchemaContent)) + await editor.edit((edit) => edit.insert(new vscode.Position(/* line*/ 0, /* character*/ 0), prettySchemaContent)) } diff --git a/packages/core/src/eventSchemas/providers/schemasDataProvider.ts b/packages/core/src/eventSchemas/providers/schemasDataProvider.ts index 23c43c1915f..ec280238183 100644 --- a/packages/core/src/eventSchemas/providers/schemasDataProvider.ts +++ b/packages/core/src/eventSchemas/providers/schemasDataProvider.ts @@ -76,7 +76,7 @@ export class SchemasDataProvider { if (!schemas || schemas.length === 0) { schemas = await toArrayAsync(client.listSchemas(registryName)) const singleItem: registrySchemasMap = { registryName: registryName, schemaList: schemas } - //wizard setup always calls getRegistries method prior to getSchemas, so this shouldn't be undefined + // wizard setup always calls getRegistries method prior to getSchemas, so this shouldn't be undefined if (!registrySchemasMapList) { this.pushRegionDataIntoCache(region, [], [singleItem], credentials) } diff --git a/packages/core/src/extension.ts b/packages/core/src/extension.ts index ef4131c6f26..00fd730b490 100644 --- a/packages/core/src/extension.ts +++ b/packages/core/src/extension.ts @@ -75,7 +75,7 @@ export async function activateCommon( errors.init(fs.getUsername(), isAutomation()) await initializeComputeRegion() - globals.contextPrefix = '' //todo: disconnect supplied argument + globals.contextPrefix = '' // todo: disconnect supplied argument registerCommandErrorHandler((info, error) => { const defaultMessage = localize('AWS.generic.message.error', 'Failed to run command: {0}', info.id) @@ -112,7 +112,7 @@ export async function activateCommon( ) } - //setup globals + // setup globals globals.machineId = await getMachineId() globals.awsContext = new DefaultAwsContext() globals.sdkClientBuilder = new DefaultAWSClientBuilder(globals.awsContext) diff --git a/packages/core/src/lambda/vue/configEditor/samInvokeFrontend.ts b/packages/core/src/lambda/vue/configEditor/samInvokeFrontend.ts index 95f0fa9a14f..551be9d09cf 100644 --- a/packages/core/src/lambda/vue/configEditor/samInvokeFrontend.ts +++ b/packages/core/src/lambda/vue/configEditor/samInvokeFrontend.ts @@ -268,7 +268,7 @@ export default defineComponent({ if (!field) { return undefined } - //Reg ex for a comma with 0 or more whitespace before and/or after + // Reg ex for a comma with 0 or more whitespace before and/or after const re = /\s*,\s*/g return field.trim().split(re) }, diff --git a/packages/core/src/shared/clients/iotClient.ts b/packages/core/src/shared/clients/iotClient.ts index ca91cca7556..a926c5edfd3 100644 --- a/packages/core/src/shared/clients/iotClient.ts +++ b/packages/core/src/shared/clients/iotClient.ts @@ -26,7 +26,7 @@ export type IotPolicy = IotThing export type IotClient = InterfaceNoSymbol const iotServiceArn = 'iot' -//Pattern to extract the certificate ID from the parsed ARN resource. +// Pattern to extract the certificate ID from the parsed ARN resource. const certArnResourcePattern = /cert\/(\w+)/ export interface ListThingCertificatesResponse { diff --git a/packages/core/src/shared/clients/redshiftClient.ts b/packages/core/src/shared/clients/redshiftClient.ts index b2ca65eff8d..a0e98bc405e 100644 --- a/packages/core/src/shared/clients/redshiftClient.ts +++ b/packages/core/src/shared/clients/redshiftClient.ts @@ -31,7 +31,7 @@ export interface ExecuteQueryResponse { executionId: string } -//Type definition for Provisioned and Serverless +// Type definition for Provisioned and Serverless export class DefaultRedshiftClient { public constructor( public readonly regionCode: string, diff --git a/packages/core/src/shared/constants.ts b/packages/core/src/shared/constants.ts index c72db98c21a..0b095e23df6 100644 --- a/packages/core/src/shared/constants.ts +++ b/packages/core/src/shared/constants.ts @@ -84,12 +84,12 @@ export const samSyncParamUrl = vscode.Uri.parse( 'https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-sync.html' ) -//URLs for "sam build" wizard. +// URLs for "sam build" wizard. export const samBuildUrl = vscode.Uri.parse( 'https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-building.html' ) -//URLs for "sam deploy" wizard. +// URLs for "sam deploy" wizard. export const samDeployUrl = vscode.Uri.parse( 'https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-deploy.html' ) @@ -168,7 +168,7 @@ export const apprunnerCreateServiceDocUrl = { // TODO: update docs to add the file viewer feature export const s3FileViewerHelpUrl = 'https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/s3.html' -//URL for Redshift +// URL for Redshift export const redshiftHelpUrl = 'https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/redshift.html' // URL for Amazon Q diff --git a/packages/core/src/shared/env/resolveEnv.ts b/packages/core/src/shared/env/resolveEnv.ts index 5c6db4bc2c1..2c50169f984 100644 --- a/packages/core/src/shared/env/resolveEnv.ts +++ b/packages/core/src/shared/env/resolveEnv.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -/*--------------------------------------------------------------------------------------------- +/* --------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ diff --git a/packages/core/src/shared/languageServer/languageModelCache.ts b/packages/core/src/shared/languageServer/languageModelCache.ts index dddac1625b2..1e1dd73f045 100644 --- a/packages/core/src/shared/languageServer/languageModelCache.ts +++ b/packages/core/src/shared/languageServer/languageModelCache.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -/*--------------------------------------------------------------------------------------------- +/* --------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ diff --git a/packages/core/src/shared/languageServer/utils/runner.ts b/packages/core/src/shared/languageServer/utils/runner.ts index 51563565d46..8116f4dee1b 100644 --- a/packages/core/src/shared/languageServer/utils/runner.ts +++ b/packages/core/src/shared/languageServer/utils/runner.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -/*--------------------------------------------------------------------------------------------- +/* --------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ diff --git a/packages/core/src/shared/logger/sharedFileTransport.ts b/packages/core/src/shared/logger/sharedFileTransport.ts index e9bf376d8f4..59227812df0 100644 --- a/packages/core/src/shared/logger/sharedFileTransport.ts +++ b/packages/core/src/shared/logger/sharedFileTransport.ts @@ -101,7 +101,7 @@ export class SharedFileTransport extends TransportStream { // Remove the logs that were written to the file from the buffer. // But we have to keep in mind new logs may have been - //asynchronously added to the buffer, so we only remove what we have flushed. + // asynchronously added to the buffer, so we only remove what we have flushed. this.bufferedLogEntries = this.bufferedLogEntries.slice(latestLogIndex + 1) const newText = logMessages.join('\n') + '\n' diff --git a/packages/core/src/shared/sam/debugger/javaSamDebug.ts b/packages/core/src/shared/sam/debugger/javaSamDebug.ts index aa1cbf5fd8b..26ebad889d6 100644 --- a/packages/core/src/shared/sam/debugger/javaSamDebug.ts +++ b/packages/core/src/shared/sam/debugger/javaSamDebug.ts @@ -58,7 +58,7 @@ function getJavaOptionsEnvVar(config: SamLaunchRequestArgs): string { // https://github.com/aws/aws-sam-cli/blob/90aa5cf11e1c5cbfbe66aea2e2de10d478d48231/samcli/local/docker/lambda_debug_settings.py#L86 return `-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=*:${config.debugPort} -XX:MaxHeapSize=2834432k -XX:+UseSerialGC -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Djava.net.preferIPv4Stack=true` case 'java21': - //https://github.com/aws/aws-sam-cli/blob/90aa5cf11e1c5cbfbe66aea2e2de10d478d48231/samcli/local/docker/lambda_debug_settings.py#L96 + // https://github.com/aws/aws-sam-cli/blob/90aa5cf11e1c5cbfbe66aea2e2de10d478d48231/samcli/local/docker/lambda_debug_settings.py#L96 return `-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=*:${config.debugPort} -XX:MaxHeapSize=2834432k -XX:+UseSerialGC -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Djava.net.preferIPv4Stack=true` default: return `-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=${config.debugPort} -XX:MaxHeapSize=2834432k -XX:MaxMetaspaceSize=163840k -XX:ReservedCodeCacheSize=81920k -XX:+UseSerialGC -XX:-TieredCompilation -Djava.net.preferIPv4Stack=true -Xshare:off` diff --git a/packages/core/src/shared/sam/deploy.ts b/packages/core/src/shared/sam/deploy.ts index 566ba03cb21..6353c46a0e5 100644 --- a/packages/core/src/shared/sam/deploy.ts +++ b/packages/core/src/shared/sam/deploy.ts @@ -335,7 +335,7 @@ export async function runDeploy(arg: any, wizardParams?: DeployParams): Promise< }) try { - //Run SAM build in Terminal + // Run SAM build in Terminal await runInTerminal(buildProcess, 'build') } catch (error) { throw ToolkitError.chain(error, 'Failed to build SAM template', { details: { ...buildFlags } }) @@ -349,7 +349,7 @@ export async function runDeploy(arg: any, wizardParams?: DeployParams): Promise< }), }) - //Run SAM deploy in Terminal + // Run SAM deploy in Terminal const { paramsSource, stackName, region, projectRoot } = params const shouldWriteDeploySamconfigGlobal = paramsSource !== ParamsSource.SamConfig && !!stackName && !!region try { diff --git a/packages/core/src/shared/sam/utils.ts b/packages/core/src/shared/sam/utils.ts index b6da18e9055..99331bba830 100644 --- a/packages/core/src/shared/sam/utils.ts +++ b/packages/core/src/shared/sam/utils.ts @@ -135,7 +135,7 @@ export function throwIfErrorMatches(result: ChildProcessResult, terminal?: vscod export function getTerminalFromError(error: any): vscode.Terminal { return error.details?.['terminal'] as unknown as vscode.Terminal - //return vscode.window.activeTerminal as vscode.Terminal + // return vscode.window.activeTerminal as vscode.Terminal } export enum SamCliErrorTypes { diff --git a/packages/core/src/shared/utilities/vsCodeUtils.ts b/packages/core/src/shared/utilities/vsCodeUtils.ts index 5d14da6d3d2..03229cf104a 100644 --- a/packages/core/src/shared/utilities/vsCodeUtils.ts +++ b/packages/core/src/shared/utilities/vsCodeUtils.ts @@ -179,7 +179,7 @@ export function isUntitledScheme(uri: vscode.Uri): boolean { * Example: `['foo', '**\/bar/'] => "["foo", "bar"]"` */ export function globDirPatterns(dirs: string[]): string[] { - //The patterns themselves are not useful, but with postformating like "**/${pattern}/" they become glob dir patterns + // The patterns themselves are not useful, but with postformating like "**/${pattern}/" they become glob dir patterns return dirs.map((current) => { // Trim all "*" and "/" chars. // Note that the replace() patterns and order is intentionaly so that "**/*foo*/**" yields "*foo*". diff --git a/packages/core/src/stepFunctions/commands/visualizeStateMachine/getStateMachineDefinitionFromCfnTemplate.ts b/packages/core/src/stepFunctions/commands/visualizeStateMachine/getStateMachineDefinitionFromCfnTemplate.ts index 2f665839260..29b2dd817a1 100644 --- a/packages/core/src/stepFunctions/commands/visualizeStateMachine/getStateMachineDefinitionFromCfnTemplate.ts +++ b/packages/core/src/stepFunctions/commands/visualizeStateMachine/getStateMachineDefinitionFromCfnTemplate.ts @@ -25,7 +25,7 @@ export function getStateMachineDefinitionFromCfnTemplate(uniqueIdentifier: strin const matchingKeyList: string[] = [] for (const key of Object.keys(resources)) { - //the resources list always contains 'CDKMetadata' + // the resources list always contains 'CDKMetadata' if (key === 'CDKMetadata') { continue } @@ -37,7 +37,7 @@ export function getStateMachineDefinitionFromCfnTemplate(uniqueIdentifier: strin if (matchingKeyList.length === 0) { return '' } else { - //return minimum length key in matchingKeyList + // return minimum length key in matchingKeyList matchingKey = matchingKeyList.reduce((a, b) => (a.length <= b.length ? a : b)) } diff --git a/packages/core/src/test/awsService/accessanalyzer/iamPolicyChecks.test.ts b/packages/core/src/test/awsService/accessanalyzer/iamPolicyChecks.test.ts index 7e99b46ded6..536ec3e224c 100644 --- a/packages/core/src/test/awsService/accessanalyzer/iamPolicyChecks.test.ts +++ b/packages/core/src/test/awsService/accessanalyzer/iamPolicyChecks.test.ts @@ -354,7 +354,7 @@ describe('customChecks', function () { await fakePolicyChecksWebview.checkNoNewAccess(documentType, policyType, referenceDocument, cfnParameterPath) - //We do not want to validate the path of the temporary folder, so we check every other field instead of the entire args + // We do not want to validate the path of the temporary folder, so we check every other field instead of the entire args assert(executeCustomPolicyChecksCommandStub.called) const actualCommand = executeCustomPolicyChecksCommandStub.getCalls()[0].args[0] assert.deepStrictEqual(actualCommand.command, 'tf-policy-validator') diff --git a/packages/core/src/test/eventSchemas/commands/downloadSchemaItemCode.test.ts b/packages/core/src/test/eventSchemas/commands/downloadSchemaItemCode.test.ts index e772bab0d92..9b630eed07d 100644 --- a/packages/core/src/test/eventSchemas/commands/downloadSchemaItemCode.test.ts +++ b/packages/core/src/test/eventSchemas/commands/downloadSchemaItemCode.test.ts @@ -470,7 +470,7 @@ describe('CodeExtractor', function () { let zipHandler = createZipFileInTempDirectory(fileName, 'First file content', zipName) zipHandler.extractAllTo(destinationDirectory) - //Create a zip file that clashes with destination content + // Create a zip file that clashes with destination content zipHandler = createZipFileInTempDirectory(fileName, 'Second file content', zipName) const collisionOccured = codeExtractor.checkFileCollisions(zipName, destinationDirectory) @@ -487,7 +487,7 @@ describe('CodeExtractor', function () { let zipHandler = createZipFileInTempDirectory(fileName1, 'First file content', zipName) zipHandler.extractAllTo(destinationDirectory) - //Create a zip file with same directory path but diff fileName + // Create a zip file with same directory path but diff fileName const fileName2 = 'test2.txt' zipHandler = createZipFileInTempDirectory(fileName2, 'Second file content', zipName) @@ -550,7 +550,7 @@ describe('CodeExtractor', function () { assert.ok(await fs.exists(file1Path), `${file1Path} should exist`) assert.ok(await fs.exists(file2Path), `${file2Path} should exist`) - //confirm file contents + // confirm file contents const file1Content = await fs.readFileText(file1Path) const file2Content = await fs.readFileText(file2Path) @@ -569,7 +569,7 @@ describe('CodeExtractor', function () { const zipHandler = createZipFileInTempDirectory(fileName1, expectedFileContent, zipFileName) zipHandler.extractAllTo(destinationDirectory) - //same file name - collision occurs + // same file name - collision occurs const fileName2 = fileName1 const zip = new admZip() zip.addFile(fileName2, Buffer.from('Second file content')) @@ -594,7 +594,7 @@ describe('CodeExtractor', function () { const zipHandler = createZipFileInTempDirectory(fileName1, initialFileContent, zipFileName) zipHandler.extractAllTo(destinationDirectory) - //same file name, different file content - collision occurs + // same file name, different file content - collision occurs const fileName2 = fileName1 const zip = new admZip() const overridenFileContent = 'Replaced file content' @@ -621,7 +621,7 @@ describe('CodeExtractor', function () { const zipHandler = createZipFileInTempDirectory(fileName1, expectedFileContent, zipFileName) zipHandler.extractAllTo(destinationDirectory) - //same file name - collision occurs + // same file name - collision occurs const fileName2 = fileName1 const zip = new admZip() zip.addFile(fileName2, Buffer.from('Second file content')) @@ -640,7 +640,7 @@ describe('CodeExtractor', function () { }) it('should return coreCodeFilePath if it exists inside zip content', async function () { - //grab the title from schemaName + // grab the title from schemaName const title = testSchemaName.split('.').pop() const fileName = title!.concat('.java') diff --git a/packages/core/src/test/eventSchemas/commands/searchSchemas.test.ts b/packages/core/src/test/eventSchemas/commands/searchSchemas.test.ts index 328a821d35a..089a971a40c 100644 --- a/packages/core/src/test/eventSchemas/commands/searchSchemas.test.ts +++ b/packages/core/src/test/eventSchemas/commands/searchSchemas.test.ts @@ -116,7 +116,7 @@ describe('Search Schemas', function () { const client = stub(DefaultSchemaClient, { regionCode: 'region-1' }) const displayMessage = `Unable to search registry ${failRegistry}` - //make an api call with non existent registryName - should return empty results + // make an api call with non existent registryName - should return empty results const results = await getSearchListForSingleRegistry(client, failRegistry, 'randomText') assert.strictEqual(results.length, 0, 'should return 0 summaries') @@ -145,7 +145,7 @@ describe('Search Schemas', function () { assert.strictEqual(results.length, 3, 'should return 3 summaries') - //results are unordered, sort for testing purposes + // results are unordered, sort for testing purposes results.sort(function (a, b) { return a.RegistryName > b.RegistryName ? 1 : b.RegistryName > a.RegistryName ? -1 : 0 }) @@ -165,7 +165,7 @@ describe('Search Schemas', function () { assert.strictEqual(results[1].VersionList.length, 1, 'second summary has 1 version') assert.strictEqual(results[2].VersionList.length, 1, 'third summary has 1 version') - //failed registries + // failed registries const errorMessages = getTestWindow().shownMessages.filter((m) => m.severity === SeverityLevel.Error) assert.strictEqual(errorMessages.length, 2, 'should display 2 error message, 1 per each failed registry') errorMessages[0].assertMessage(displayMessage) diff --git a/packages/core/src/test/eventSchemas/explorer/registryItemNode.test.ts b/packages/core/src/test/eventSchemas/explorer/registryItemNode.test.ts index 7153b617266..5fdd61e5c42 100644 --- a/packages/core/src/test/eventSchemas/explorer/registryItemNode.test.ts +++ b/packages/core/src/test/eventSchemas/explorer/registryItemNode.test.ts @@ -141,7 +141,7 @@ describe('DefaultRegistryNode', function () { }) it('handles error', async function () { - //typo in the name of the method + // typo in the name of the method class ThrowErrorDefaultSchemaRegistrynNode extends SchemasNode { public constructor() { super(createSchemaClient()) diff --git a/packages/core/src/test/fakeExtensionContext.ts b/packages/core/src/test/fakeExtensionContext.ts index d16bd8a1dd4..8c89302900e 100644 --- a/packages/core/src/test/fakeExtensionContext.ts +++ b/packages/core/src/test/fakeExtensionContext.ts @@ -52,7 +52,7 @@ export class FakeExtensionContext implements vscode.ExtensionContext { public storagePath: string | undefined public logPath: string = '' public extensionUri: vscode.Uri = vscode.Uri.file(this._extensionPath) - public environmentVariableCollection: any //vscode.EnvironmentVariableCollection = {} as vscode.EnvironmentVariableCollection + public environmentVariableCollection: any // vscode.EnvironmentVariableCollection = {} as vscode.EnvironmentVariableCollection public storageUri: vscode.Uri | undefined public logUri: vscode.Uri = vscode.Uri.file('file://fake/log/uri') public extensionMode: vscode.ExtensionMode = vscode.ExtensionMode.Test diff --git a/packages/core/src/test/globalSetup.test.ts b/packages/core/src/test/globalSetup.test.ts index 57a17261338..e33270e0471 100644 --- a/packages/core/src/test/globalSetup.test.ts +++ b/packages/core/src/test/globalSetup.test.ts @@ -26,7 +26,7 @@ import { GlobalState } from '../shared/globalState' import { FeatureConfigProvider } from '../shared/featureConfig' import { mockFeatureConfigsData } from './fake/mockFeatureConfigData' import { fs } from '../shared' -import { promises as nodefs } from 'fs' //eslint-disable-line no-restricted-imports +import { promises as nodefs } from 'fs' // eslint-disable-line no-restricted-imports disableAwsSdkWarning() const testReportDir = join(__dirname, '../../../../../.test-reports') // Root project, not subproject diff --git a/packages/core/src/test/lambda/local/debugConfiguration.test.ts b/packages/core/src/test/lambda/local/debugConfiguration.test.ts index a57651341e6..12192127eeb 100644 --- a/packages/core/src/test/lambda/local/debugConfiguration.test.ts +++ b/packages/core/src/test/lambda/local/debugConfiguration.test.ts @@ -60,7 +60,7 @@ describe('makeCoreCLRDebugConfiguration', function () { templatePath: '/fake/sam/path', samLocalInvokeCommand: new DefaultSamLocalInvokeCommand(), - //debuggerPath?: + // debuggerPath?: invokeTarget: { target: 'code', diff --git a/packages/core/src/test/shared/debug/launchConfiguration.test.ts b/packages/core/src/test/shared/debug/launchConfiguration.test.ts index bc9f37578b9..120e4f12c67 100644 --- a/packages/core/src/test/shared/debug/launchConfiguration.test.ts +++ b/packages/core/src/test/shared/debug/launchConfiguration.test.ts @@ -209,7 +209,7 @@ describe('getReferencedHandlerPaths', function () { const resultSet = await getReferencedHandlerPaths(mockLaunchConfig) const workspaceFolder = mockLaunchConfig.workspaceFolder!.uri.fsPath - //template type handlers, these are all false as we throw all of these out + // template type handlers, these are all false as we throw all of these out assert.strictEqual(resultSet.has('resource'), false) assert.strictEqual(resultSet.has('relativePathGoodTemplate'), false) assert.strictEqual(resultSet.has('relativePathBadTemplate'), false) diff --git a/packages/core/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts b/packages/core/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts index 60edb29af07..cf9586c9a28 100644 --- a/packages/core/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts +++ b/packages/core/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts @@ -510,8 +510,8 @@ describe('SamDebugConfigurationProvider', async function () { target: TEMPLATE_TARGET_TYPE, templatePath: relPath, logicalId: 'TestResource', - //lambdaHandler: 'sick handles', - //projectRoot: 'root as in beer' + // lambdaHandler: 'sick handles', + // projectRoot: 'root as in beer' }, }) assert.strictEqual(resolved!.name, name) diff --git a/packages/core/src/test/shared/ui/sam/templatePrompter.test.ts b/packages/core/src/test/shared/ui/sam/templatePrompter.test.ts index 0906d14f598..483b4fe8bc6 100644 --- a/packages/core/src/test/shared/ui/sam/templatePrompter.test.ts +++ b/packages/core/src/test/shared/ui/sam/templatePrompter.test.ts @@ -22,7 +22,7 @@ describe('createTemplatePrompter', () => { beforeEach(() => { sandbox = sinon.createSandbox() - //Create a mock instance of CloudFormationTemplateRegistry + // Create a mock instance of CloudFormationTemplateRegistry registry = { items: [ { path: '/path/to/template1.yaml', item: {} } as WatchedItem, diff --git a/packages/core/src/test/shared/wizards/wizard.test.ts b/packages/core/src/test/shared/wizards/wizard.test.ts index 0aee4f66502..04c3ac62fb4 100644 --- a/packages/core/src/test/shared/wizards/wizard.test.ts +++ b/packages/core/src/test/shared/wizards/wizard.test.ts @@ -110,7 +110,7 @@ class TestPrompter extends Prompter { this.acceptedEstimators.push(estimator) } - //----------------------------Test helper methods go below this line----------------------------// + // ----------------------------Test helper methods go below this line----------------------------// public acceptState(state: StateWithCache): this { this.acceptedStates[this.promptCount] = state diff --git a/packages/core/src/testE2E/codewhisperer/referenceTracker.test.ts b/packages/core/src/testE2E/codewhisperer/referenceTracker.test.ts index f52132dad75..0038795ad89 100644 --- a/packages/core/src/testE2E/codewhisperer/referenceTracker.test.ts +++ b/packages/core/src/testE2E/codewhisperer/referenceTracker.test.ts @@ -55,14 +55,14 @@ describe('CodeWhisperer service invocation', async function () { beforeEach(function () { void resetCodeWhispererGlobalVariables() RecommendationHandler.instance.clearRecommendations() - //TODO: remove this line (this.skip()) when these tests no longer auto-skipped + // TODO: remove this line (this.skip()) when these tests no longer auto-skipped this.skip() - //valid connection required to run tests + // valid connection required to run tests skipTestIfNoValidConn(validConnection, this) }) it('trigger known to return recs with references returns rec with reference', async function () { - //check that handler is empty before invocation + // check that handler is empty before invocation const requestIdBefore = RecommendationHandler.instance.requestId const sessionIdBefore = session.sessionId const validRecsBefore = RecommendationHandler.instance.isValidResponse() @@ -89,13 +89,13 @@ describe('CodeWhisperer service invocation', async function () { assert.ok(sessionId.length > 0) assert.ok(validRecs) assert.ok(references !== undefined) - //TODO: uncomment this assert when this test is no longer auto-skipped + // TODO: uncomment this assert when this test is no longer auto-skipped // assert.ok(references.length > 0) }) - //This test will fail if user is logged in with IAM identity center + // This test will fail if user is logged in with IAM identity center it('trigger known to return rec with references does not return rec with references when reference tracker setting is off', async function () { - //check that handler is empty before invocation + // check that handler is empty before invocation const requestIdBefore = RecommendationHandler.instance.requestId const sessionIdBefore = session.sessionId const validRecsBefore = RecommendationHandler.instance.isValidResponse() @@ -119,7 +119,7 @@ describe('CodeWhisperer service invocation', async function () { assert.ok(requestId.length > 0) assert.ok(sessionId.length > 0) - //no recs returned because example request returns 1 rec with reference, so no recs returned when references off + // no recs returned because example request returns 1 rec with reference, so no recs returned when references off assert.ok(!validRecs) }) }) diff --git a/packages/core/src/testE2E/codewhisperer/securityScan.test.ts b/packages/core/src/testE2E/codewhisperer/securityScan.test.ts index 7f6fe65e15c..730b9628290 100644 --- a/packages/core/src/testE2E/codewhisperer/securityScan.test.ts +++ b/packages/core/src/testE2E/codewhisperer/securityScan.test.ts @@ -58,7 +58,7 @@ describe('CodeWhisperer security scan', async function () { beforeEach(function () { void resetCodeWhispererGlobalVariables() - //valid connection required to run tests + // valid connection required to run tests skipTestIfNoValidConn(validConnection, this) }) @@ -112,19 +112,19 @@ describe('CodeWhisperer security scan', async function () { } it('codescan request with valid input params and no security issues completes scan and returns no recommendations', async function () { - //set up file and editor + // set up file and editor const appRoot = path.join(workspaceFolder, 'python3.7-plain-sam-app') const appCodePath = path.join(appRoot, 'hello_world', 'app.py') const editor = await openTestFile(appCodePath) - //run security scan + // run security scan const securityJobSetupResult = await securityJobSetup(editor) const artifactMap = securityJobSetupResult.artifactMap const projectPaths = securityJobSetupResult.projectPaths const scope = CodeWhispererConstants.CodeAnalysisScope.PROJECT - //get job status and result + // get job status and result const scanJob = await createScanJob( client, artifactMap, @@ -152,7 +152,7 @@ describe('CodeWhisperer security scan', async function () { }) it('codescan request with valid input params and security issues completes scan and returns recommendations', async function () { - //set up file and editor + // set up file and editor tempFolder = await makeTemporaryToolkitFolder() const tempFile = path.join(tempFolder, 'test.py') await testutil.toFile(filePromptWithSecurityIssues, tempFile) @@ -160,7 +160,7 @@ describe('CodeWhisperer security scan', async function () { const scope = CodeWhispererConstants.CodeAnalysisScope.PROJECT - //run security scan + // run security scan const securityJobSetupResult = await securityJobSetup(editor) const artifactMap = securityJobSetupResult.artifactMap const projectPaths = securityJobSetupResult.projectPaths @@ -172,7 +172,7 @@ describe('CodeWhisperer security scan', async function () { securityJobSetupResult.codeScanName ) - //get job status and result + // get job status and result const jobStatus = await pollScanJobStatus( client, scanJob.jobId, diff --git a/packages/core/src/testE2E/codewhisperer/serviceInvocations.test.ts b/packages/core/src/testE2E/codewhisperer/serviceInvocations.test.ts index 7ea8f2f5e84..d4265d13982 100644 --- a/packages/core/src/testE2E/codewhisperer/serviceInvocations.test.ts +++ b/packages/core/src/testE2E/codewhisperer/serviceInvocations.test.ts @@ -38,12 +38,12 @@ describe('CodeWhisperer service invocation', async function () { beforeEach(function () { void resetCodeWhispererGlobalVariables() RecommendationHandler.instance.clearRecommendations() - //valid connection required to run tests + // valid connection required to run tests skipTestIfNoValidConn(validConnection, this) }) it('manual trigger returns valid recommendation response', async function () { - //check that handler is empty before invocation + // check that handler is empty before invocation const requestIdBefore = RecommendationHandler.instance.requestId const sessionIdBefore = session.sessionId const validRecsBefore = RecommendationHandler.instance.isValidResponse() @@ -65,7 +65,7 @@ describe('CodeWhisperer service invocation', async function () { }) it('auto trigger returns valid recommendation response', async function () { - //check that handler is empty before invocation + // check that handler is empty before invocation const requestIdBefore = RecommendationHandler.instance.requestId const sessionIdBefore = session.sessionId const validRecsBefore = RecommendationHandler.instance.isValidResponse() @@ -83,7 +83,7 @@ describe('CodeWhisperer service invocation', async function () { ) await KeyStrokeHandler.instance.processKeyStroke(mockEvent, mockEditor, client, config) - //wait for 5 seconds to allow time for response to be generated + // wait for 5 seconds to allow time for response to be generated await sleep(5000) const requestId = RecommendationHandler.instance.requestId @@ -100,7 +100,7 @@ describe('CodeWhisperer service invocation', async function () { const appRoot = path.join(workspaceFolder, 'go1-plain-sam-app') const appCodePath = path.join(appRoot, 'hello-world', 'main.go') - //check that handler is empty before invocation + // check that handler is empty before invocation const requestIdBefore = RecommendationHandler.instance.requestId const sessionIdBefore = session.sessionId const validRecsBefore = RecommendationHandler.instance.isValidResponse() diff --git a/packages/core/src/testInteg/sam.test.ts b/packages/core/src/testInteg/sam.test.ts index 8a500b405d4..487c2aef1b7 100644 --- a/packages/core/src/testInteg/sam.test.ts +++ b/packages/core/src/testInteg/sam.test.ts @@ -754,7 +754,7 @@ describe('SAM Integration Tests', async function () { const item1 = input.items[2] as DataQuickPickItem const item2 = input.items[4] as DataQuickPickItem const item3 = input.items[7] as DataQuickPickItem - input.acceptItems(item1, item2, item3) //--cached, --parallel, --use-container + input.acceptItems(item1, item2, item3) // --cached, --parallel, --use-container assert.strictEqual(item1.data as string, '--cached') assert.strictEqual(item2.data as string, '--parallel') diff --git a/packages/core/src/threatComposer/commands/createNewThreatComposerFile.ts b/packages/core/src/threatComposer/commands/createNewThreatComposerFile.ts index 81fddff2c52..dbcf6c29047 100644 --- a/packages/core/src/threatComposer/commands/createNewThreatComposerFile.ts +++ b/packages/core/src/threatComposer/commands/createNewThreatComposerFile.ts @@ -32,7 +32,7 @@ const createNewThreatComposerFile = async () => { return } - const fileContent = '' //Empty content would be accepted by TC which will save default structure automatically + const fileContent = '' // Empty content would be accepted by TC which will save default structure automatically const filePath = path.join(rootFolder, `${title}.tc.json`) await fs.writeFile(filePath, fileContent) diff --git a/packages/core/types/git.d.ts b/packages/core/types/git.d.ts index 4b0c12cec68..e037dfdac9e 100644 --- a/packages/core/types/git.d.ts +++ b/packages/core/types/git.d.ts @@ -7,7 +7,7 @@ // https://github.com/microsoft/vscode/blob/7ed4699079f647ef53807f511ac87ff06a7b37b5/extensions/git/src/api/git.d.ts // Note that this file should be imported as 'git.d' since it contains enums and thus must be compiled. -/*--------------------------------------------------------------------------------------------- +/* --------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ diff --git a/packages/webpack.base.config.js b/packages/webpack.base.config.js index 7d61588108b..652249e6577 100644 --- a/packages/webpack.base.config.js +++ b/packages/webpack.base.config.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -//@ts-check +// @ts-check 'use strict' @@ -20,7 +20,7 @@ const packageJsonFile = path.join(currentDir, 'package.json') const packageJson = JSON.parse(fs.readFileSync(packageJsonFile, 'utf8')) const packageId = `${packageJson.publisher}.${packageJson.name}` -//@ts-check +// @ts-check /** @typedef {import('webpack').Configuration} WebpackConfig **/ module.exports = (env = {}, argv = {}) => { @@ -59,7 +59,7 @@ module.exports = (env = {}, argv = {}) => { }, }, node: { - __dirname: false, //preserve the default node.js behavior for __dirname + __dirname: false, // preserve the default node.js behavior for __dirname }, module: { rules: [ diff --git a/packages/webpack.vue.config.js b/packages/webpack.vue.config.js index 00a177fac71..1ca91ceed4d 100644 --- a/packages/webpack.vue.config.js +++ b/packages/webpack.vue.config.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -//@ts-check +// @ts-check 'use strict' @@ -14,7 +14,7 @@ const baseConfigFactory = require('./webpack.base.config') const { merge } = require('webpack-merge') const currentDir = process.cwd() -//@ts-check +// @ts-check /** @typedef {import('webpack').Configuration} WebpackConfig **/ /** @@ -22,7 +22,7 @@ const currentDir = process.cwd() * Example: `src/lambda/vue/index.ts` -> `dist/src/lambda/vue/index.js` * @param {string} file */ -const createVueBundleName = file => { +const createVueBundleName = (file) => { return path.relative(currentDir, file).split('.').slice(0, -1).join(path.sep) } @@ -33,7 +33,7 @@ const createVueBundleName = file => { const createVueEntries = (targetPattern = 'index.ts') => { return glob .sync(path.resolve(currentDir, 'src', '**', 'vue', '**', targetPattern).replace(/\\/g, '/')) - .map(f => ({ name: createVueBundleName(f), path: f })) + .map((f) => ({ name: createVueBundleName(f), path: f })) .reduce((a, b) => ((a[b.name] = b.path), a), {}) } diff --git a/packages/webpack.web.config.js b/packages/webpack.web.config.js index 5734481a942..fc6ca86d1d9 100644 --- a/packages/webpack.web.config.js +++ b/packages/webpack.web.config.js @@ -71,7 +71,7 @@ module.exports = (env, argv) => { http: false, // http: require.resolve('stream-http'), https: false, // https: require.resolve('https-browserify'), zlib: false, // zlib: require.resolve('browserify-zlib'), - constants: false, //constants: require.resolve('constants-browserify'), + constants: false, // constants: require.resolve('constants-browserify'), // These do not have a straight forward replacement child_process: false, // Reason for error: 'TypeError: The "original" argument must be of type Function' async_hooks: false, From 7f90d5660736136a2c309f9c240a36c370997755 Mon Sep 17 00:00:00 2001 From: Hweinstock <42325418+Hweinstock@users.noreply.github.com> Date: Thu, 5 Dec 2024 11:19:51 -0500 Subject: [PATCH 10/13] refactor(ec2): avoid logging somewhat sensitive data (#6149) ## Problem We currently log `STREAM_URL` and `TOKEN` which are used to establish the SSM session. However, these could be used to establish a connection outside the toolkit. ## Solution - Omit these from the logs. - Also add a logging statement to make it easier to find these `connect_script` logs. --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- packages/core/resources/ec2_connect | 4 ++-- packages/core/src/awsService/ec2/model.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core/resources/ec2_connect b/packages/core/resources/ec2_connect index 518a5e86f58..1fae562899b 100755 --- a/packages/core/resources/ec2_connect +++ b/packages/core/resources/ec2_connect @@ -47,8 +47,8 @@ _main() { _require AWS_SSM_CLI "${AWS_SSM_CLI:-}" _require AWS_REGION "${AWS_REGION:-}" - _require STREAM_URL "${STREAM_URL:-}" - _require TOKEN "${TOKEN:-}" + _require_nolog STREAM_URL "${STREAM_URL:-}" + _require_nolog TOKEN "${TOKEN:-}" _require SESSION_ID "${SESSION_ID:-}" _require LOG_FILE_LOCATION "${LOG_FILE_LOCATION:-}" diff --git a/packages/core/src/awsService/ec2/model.ts b/packages/core/src/awsService/ec2/model.ts index 085bfa0674b..17769ff4575 100644 --- a/packages/core/src/awsService/ec2/model.ts +++ b/packages/core/src/awsService/ec2/model.ts @@ -242,6 +242,7 @@ export class Ec2Connecter implements vscode.Disposable { const ssmSession = await this.startSSMSession(selection.instanceId) const vars = getEc2SsmEnv(selection, ssm, ssmSession) + getLogger().info(`ec2: connect script logs at ${vars.LOG_FILE_LOCATION}`) const envProvider = async () => { return { [sshAgentSocketVariable]: await startSshAgent(), ...vars } } From 83aac85e7d41381a6388edf15f395f4293d860a6 Mon Sep 17 00:00:00 2001 From: Avi Alpert <131792194+avi-alpert@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:49:08 -0500 Subject: [PATCH 11/13] fix(amazonq): prompt to choose a folder for /doc #6159 ## Problem When a user clicks the "Change folder" button when creating or updating a README, the "Generating answer..." loading text appears, even though there is no answer being generated, since we are waiting for the user to choose a folder. This is an especially confusing UX if the user is connected to an SSH host. ## Solution When the user clicks the "Change folder" button, send a "Choose a folder to continue" message in the chat. --- .../Bug Fix-570a8c06-4da6-4585-b589-be1fba2ce20f.json | 4 ++++ packages/core/package.nls.json | 2 ++ .../src/amazonqDoc/controllers/chat/controller.ts | 11 +++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 packages/amazonq/.changes/next-release/Bug Fix-570a8c06-4da6-4585-b589-be1fba2ce20f.json diff --git a/packages/amazonq/.changes/next-release/Bug Fix-570a8c06-4da6-4585-b589-be1fba2ce20f.json b/packages/amazonq/.changes/next-release/Bug Fix-570a8c06-4da6-4585-b589-be1fba2ce20f.json new file mode 100644 index 00000000000..fe0706a5bd8 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Bug Fix-570a8c06-4da6-4585-b589-be1fba2ce20f.json @@ -0,0 +1,4 @@ +{ + "type": "Bug Fix", + "description": "Amazon Q /doc: Prompt user to choose a folder in chat" +} diff --git a/packages/core/package.nls.json b/packages/core/package.nls.json index a0a79329f70..e07958a856f 100644 --- a/packages/core/package.nls.json +++ b/packages/core/package.nls.json @@ -374,6 +374,8 @@ "AWS.amazonq.doc.answer.generating": "Generating documentation", "AWS.amazonq.doc.answer.creating": "Okay, I'm creating a README for your project. This may take a few minutes.", "AWS.amazonq.doc.answer.updating": "Okay, I'm updating the README to reflect your code changes. This may take a few minutes.", + "AWS.amazonq.doc.answer.chooseFolder": "Choose a folder to continue.", + "AWS.amazonq.doc.error.noFolderSelected": "It looks like you didn't choose a folder. Choose a folder to continue.", "AWS.amazonq.doc.error.contentLengthError": "Your workspace is too large for me to review. Your workspace must be within the quota, even if you choose a smaller folder. For more information on quotas, see the Amazon Q Developer documentation.", "AWS.amazonq.doc.error.readmeTooLarge": "The README in your folder is too large for me to review. Try reducing the size of your README, or choose a folder with a smaller README. For more information on quotas, see the Amazon Q Developer documentation.", "AWS.amazonq.doc.error.workspaceEmpty": "The folder you chose did not contain any source files in a supported language. Choose another folder and try again. For more information on supported languages, see the Amazon Q Developer documentation.", diff --git a/packages/core/src/amazonqDoc/controllers/chat/controller.ts b/packages/core/src/amazonqDoc/controllers/chat/controller.ts index e8ecceff0ca..40fcf037181 100644 --- a/packages/core/src/amazonqDoc/controllers/chat/controller.ts +++ b/packages/core/src/amazonqDoc/controllers/chat/controller.ts @@ -116,10 +116,17 @@ export class DocController { } /** Prompts user to choose a folder in current workspace for README creation/update. - * After user chooses a folder, displays confimraiton message to user with selected path. + * After user chooses a folder, displays confirmation message to user with selected path. * */ private async folderSelector(data: any) { + this.messenger.sendAnswer({ + type: 'answer', + tabID: data.tabID, + message: i18n('AWS.amazonq.doc.answer.chooseFolder'), + disableChatInput: true, + }) + const uri = await createSingleFileDialog({ canSelectFolders: true, canSelectFiles: false, @@ -133,7 +140,7 @@ export class DocController { this.messenger.sendAnswer({ type: 'answer', tabID: data.tabID, - message: 'No folder was selected, please try again.', + message: i18n('AWS.amazonq.doc.error.noFolderSelected'), followUps: retryFollowUps, disableChatInput: true, }) From 11c35ae3ca7af4d0223ad5a6f1ba7bc08bd98467 Mon Sep 17 00:00:00 2001 From: Hweinstock <42325418+Hweinstock@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:26:17 -0500 Subject: [PATCH 12/13] docs(ec2): add details about `authorized_keys`override (#6157) ## Problem Missing documentation about current behavior of ec2 remote window connect. ## Solution Add some detail to the docs. --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- docs/arch_features.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/arch_features.md b/docs/arch_features.md index c76874f7b6e..e697874678d 100644 --- a/docs/arch_features.md +++ b/docs/arch_features.md @@ -43,6 +43,7 @@ For EC2 specifically, there are a few additional steps: 1. If connecting to EC2 instance via remote window, the toolkit generates temporary SSH keys (30 second lifetime), with the public key sent to the remote instance. - Key type is ed25519 if supported, or RSA otherwise. + - This connection will overwrite the `.ssh/authorized_keys` file on the remote machine with each connection. 1. If insufficient permissions are detected on the attached IAM role, toolkit will prompt to add an inline policy with the necessary actions. 1. If SSM sessions remain open after closing the window/terminal, the toolkit will terminate them on-shutdown, or when starting another session to the same instance. From 3f2ee9ef8ee5f75a46e2c21e974e4dd25a7d2a5d Mon Sep 17 00:00:00 2001 From: Hweinstock <42325418+Hweinstock@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:26:49 -0500 Subject: [PATCH 13/13] refactor(ec2): pass log level to connect script (#6161) ## Problem We want to only log file paths when in debug mode, but the connect script has no way of determining this. ## Solution - pass log level to connect script. - use it to determine what to log. Example logs: ``` 2024/12/05 15:50:24 ============================================================================== 2024/12/05 15:50:24 LOG_LEVEL=3 2024/12/05 15:50:24 AWS_REGION=us-east-1 2024/12/05 15:50:24 SESSION_ID=... 2024/12/05 15:51:11 ============================================================================== 2024/12/05 15:51:11 LOG_LEVEL=1 2024/12/05 15:51:11 AWS_REGION=us-east-1 2024/12/05 15:51:11 SESSION_ID=... 2024/12/05 15:51:11 AWS_SSM_CLI=.../Amazon/sessionmanagerplugin/bin/session-manager-plugin 2024/12/05 15:51:11 LOG_FILE_LOCATION=/.../ec2.{instanceId}.log 2024/12/05 15:51:55 ============================================================================== 2024/12/05 15:51:55 LOG_LEVEL=2 2024/12/05 15:51:55 AWS_REGION=us-east-1 2024/12/05 15:51:55 SESSION_ID=default-uk9cv4h86y5rdbrzarlkj9opci 2024/12/05 15:51:56 AWS_SSM_CLI=../Amazon/sessionmanagerplugin/bin/session-manager-plugin 2024/12/05 15:51:56 LOG_FILE_LOCATION=/.../ec2.{instanceId}.log ``` --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- packages/core/resources/ec2_connect | 18 +++++++++++++----- packages/core/src/awsService/ec2/model.ts | 3 ++- packages/core/src/awsService/ec2/utils.ts | 2 ++ packages/core/src/shared/logger/activation.ts | 7 +++++-- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/core/resources/ec2_connect b/packages/core/resources/ec2_connect index 1fae562899b..06ae8d39686 100755 --- a/packages/core/resources/ec2_connect +++ b/packages/core/resources/ec2_connect @@ -2,7 +2,7 @@ # Usage: # When connecting to a dev environment -# AWS_REGION=… AWS_SSM_CLI=… STREAM_URL=… TOKEN=… LOG_FILE_LOCATION==… ./ec2_connect +# AWS_REGION=… AWS_SSM_CLI=… STREAM_URL=… TOKEN=… LOG_FILE_LOCATION==… DEBUG_LOG=… ./ec2_connect set -e set -u @@ -44,13 +44,21 @@ _ec2() { _main() { _log "==============================================================================" - - _require AWS_SSM_CLI "${AWS_SSM_CLI:-}" + _require DEBUG_LOG "${DEBUG_LOG:-}" _require AWS_REGION "${AWS_REGION:-}" + + _require SESSION_ID "${SESSION_ID:-}" _require_nolog STREAM_URL "${STREAM_URL:-}" _require_nolog TOKEN "${TOKEN:-}" - _require SESSION_ID "${SESSION_ID:-}" - _require LOG_FILE_LOCATION "${LOG_FILE_LOCATION:-}" + + # Only log file paths when debug level is enabled. + if [ "${DEBUG_LOG:-}" -eq 1 ]; then + _require AWS_SSM_CLI "${AWS_SSM_CLI:-}" + _require LOG_FILE_LOCATION "${LOG_FILE_LOCATION:-}" + else + _require_nolog AWS_SSM_CLI "${AWS_SSM_CLI:-}" + _require_nolog LOG_FILE_LOCATION "${LOG_FILE_LOCATION:-}" + fi _ec2 "$AWS_SSM_CLI" "$AWS_REGION" "$STREAM_URL" "$TOKEN" "$SESSION_ID" } diff --git a/packages/core/src/awsService/ec2/model.ts b/packages/core/src/awsService/ec2/model.ts index 17769ff4575..0c10539b1ca 100644 --- a/packages/core/src/awsService/ec2/model.ts +++ b/packages/core/src/awsService/ec2/model.ts @@ -242,7 +242,8 @@ export class Ec2Connecter implements vscode.Disposable { const ssmSession = await this.startSSMSession(selection.instanceId) const vars = getEc2SsmEnv(selection, ssm, ssmSession) - getLogger().info(`ec2: connect script logs at ${vars.LOG_FILE_LOCATION}`) + getLogger().debug(`ec2: connect script logs at ${vars.LOG_FILE_LOCATION}`) + const envProvider = async () => { return { [sshAgentSocketVariable]: await startSshAgent(), ...vars } } diff --git a/packages/core/src/awsService/ec2/utils.ts b/packages/core/src/awsService/ec2/utils.ts index 306887f3270..105d2da06ff 100644 --- a/packages/core/src/awsService/ec2/utils.ts +++ b/packages/core/src/awsService/ec2/utils.ts @@ -8,6 +8,7 @@ import { copyToClipboard } from '../../shared/utilities/messages' import { Ec2Selection } from './prompter' import { sshLogFileLocation } from '../../shared/sshConfig' import { SSM } from 'aws-sdk' +import { getLogger } from '../../shared/logger' export function getIconCode(instance: SafeEc2Instance) { if (instance.LastSeenStatus === 'running') { @@ -42,6 +43,7 @@ export function getEc2SsmEnv( STREAM_URL: session.StreamUrl, SESSION_ID: session.SessionId, TOKEN: session.TokenValue, + DEBUG_LOG: getLogger().logLevelEnabled('debug') ? 1 : 0, }, process.env ) diff --git a/packages/core/src/shared/logger/activation.ts b/packages/core/src/shared/logger/activation.ts index 9cbce46e6fd..9d590b226fd 100644 --- a/packages/core/src/shared/logger/activation.ts +++ b/packages/core/src/shared/logger/activation.ts @@ -13,7 +13,7 @@ import { resolvePath } from '../utilities/pathUtils' import fs from '../../shared/fs/fs' import { isWeb } from '../extensionGlobals' import { getUserAgent } from '../telemetry/util' -import { isBeta } from '../vscode/env' +import { isBeta, isDebugInstance } from '../vscode/env' /** * Activate Logger functionality for the extension. @@ -46,7 +46,10 @@ export async function activate( const newLogLevel = fromVscodeLogLevel(logLevel) mainLogger.setLogLevel(newLogLevel) // Also logs a message. }) - mainLogger.setLogLevel('debug') // HACK: set to "debug" when debugging the extension. + + if (isDebugInstance()) { + mainLogger.setLogLevel('debug') // HACK: set to "debug" when debugging the extension. + } setLogger(mainLogger)
${column}