Skip to content

Commit 68cef89

Browse files
committed
Merge remote-tracking branch 'origin/master' into feature/dynamodb
2 parents 79396b9 + 2f5ff3a commit 68cef89

File tree

189 files changed

+5677
-2223
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

189 files changed

+5677
-2223
lines changed

.github/workflows/node.js.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ jobs:
2121
env:
2222
VSCODE_TEST_VERSION: ${{ matrix.vscode-version }}
2323
NODE_OPTIONS: '--max-old-space-size=8192'
24+
AWS_TOOLKIT_TEST_CACHE_DIR: '/tmp/.vscode-test/'
25+
AWS_TOOLKIT_TEST_USER_DIR: '/tmp/.vscode-test/user-data/'
2426
steps:
2527
- uses: actions/checkout@v4
2628
- name: Use Node.js ${{ matrix.node-version }}
@@ -88,6 +90,8 @@ jobs:
8890
env:
8991
VSCODE_TEST_VERSION: ${{ matrix.vscode-version }}
9092
NODE_OPTIONS: '--max-old-space-size=8192'
93+
AWS_TOOLKIT_TEST_CACHE_DIR: '/tmp/.vscode-test/'
94+
AWS_TOOLKIT_TEST_USER_DIR: '/tmp/.vscode-test/user-data/'
9195
steps:
9296
- uses: actions/checkout@v4
9397
- name: Use Node.js ${{ matrix.node-version }}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ __pycache__
2020

2121
# Auto generated definitions
2222
packages/*/src/**/*.gen.ts
23+
!packages/core/src/**/awsSamDebugConfiguration.gen.ts
24+
!packages/core/src/shared/settings-*.gen.ts
2325
src.gen/*
2426

2527
# Test reports

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ You can also use these NPM tasks (see `npm run` for the full list):
132132
133133
1. Declare a global unhandledRejection handler.
134134
```ts
135-
process.on('unhandledRejection', e => {
135+
process.on('unhandledRejection', (e) => {
136136
getLogger('channel').error(
137137
localize(
138138
'AWS.channel.aws.toolkit.activation.error',
@@ -549,7 +549,7 @@ For extensions to contribute their own codicons, VSCode requires a font file as
549549
As a simple example, let's say I wanted to add a new icon for CloudWatch log streams. I would do the following:
550550

551551
1. Place the icon in `resources/icons/aws/cloudwatch`. I'l name the icon `log-stream.svg`.
552-
1. Use `npm run generatePackage` to update `package.json`. Commit this change with the new icon.
552+
1. Use `npm run generateIcons` to update `package.json`. Commit this change with the new icon.
553553
1. You can now use the icon in the Toolkit:
554554

555555
```ts

codecov.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,21 @@ coverage:
2727
- packages/core/src/amazonqFeatureDev/*
2828
flags:
2929
- 'amazonqFeatureDev'
30+
amazonqGumby:
31+
paths:
32+
- packages/core/src/amazonqGumby/*
33+
codewhispererChat:
34+
paths:
35+
- packages/core/src/codewhispererChat/*
36+
applicationcomposer:
37+
paths:
38+
- packages/core/src/applicationcomposer/*
39+
stepFunctions:
40+
paths:
41+
- packages/core/src/stepFunctions/*
42+
threatComposer:
43+
paths:
44+
- packages/core/src/threatComposer/*
3045
patch: no
3146
changes: no
3247

docs/TESTPLAN.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Checking the state works well if user interactions are not required by the code
104104
To handle this, test code can register event handler that listen for when a certain type of UI element is shown. For example, if we wanted to always accept the first item of a quick pick we can do this:
105105

106106
```ts
107-
getTestWindow().onDidShowQuickPick(async picker => {
107+
getTestWindow().onDidShowQuickPick(async (picker) => {
108108
// Some pickers load items asychronously
109109
// Wait until the picker is not busy before accepting an item
110110
await picker.untilReady()
@@ -121,3 +121,9 @@ const secondPicker = await pickers.next()
121121
```
122122

123123
Exceptions thrown within one of these handlers will cause the current test to fail. This allows you to make assertions within the callback without worrying about causing the test to hang.
124+
125+
## Common issues
126+
127+
### Stubbing VSCode outside of core
128+
129+
- Stubbing VSCode imports (like executeCommand) does not work outside of core. For now you will need to put any tests that require spying/stubbing VSCode imports in core until we move more source files into the amazon q package

docs/arch_develop.md

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -71,39 +71,37 @@ Some components of the core library depend on the `package.json`s of the extensi
7171
- Does not restore, it is a superset of what exists in `packages/core` for `configuration.properties`.
7272
- To develop for the Amazon Q extension: add all changes to `packages/amazonq/package.json`, EXCEPT for settings that are references by code in the core library, or settings that already exist in the core `package.json`
7373

74-
## Shared vs Common names
74+
If you are modifying or registering new debuggers in VS Code via the `debuggers` contribution point, you may need to regenerate the [definitions file](../packages/core/src/shared/sam/debugger/awsSamDebugConfiguration.gen.ts). After updating ['toolkit/package.json'](../packages/toolkit/package.json), run `npm run generateConfigurationAttributes -w packages/toolkit`
7575

76-
In this repo, the keywords **"shared"** and **"common"** have specific meanings in the context of file/folder names.
76+
## `web`, `node`, `common`, `shared` naming conventions
7777

78-
### "common"
78+
This project can run in different environments, eg Web mode (in the browser with no compute backend), or in Node.js on your desktop (the most common way).
79+
A problem arises when we use code that is exclusive to one environment, an example being Node.js' Filesystem module which will fail in Web mode.
7980

80-
Code within a folder/file that has the "common" keyword implies that it can run in any environment. Examples of environments are: Web mode, or Node.js (local desktop)
81+
To ensure developers use compatible code for their environment we have subfolders in each topic which contains environment specific code in a single place.
8182

82-
We need this distinction since not all code can run in any environment. A common example is filesystem code, where the actual implementation used could work in Node.js but not in Web mode.
83+
Using this file tree as reference, here are the rules:
8384

84-
### "shared"
85-
86-
Code within a folder/file that has the "shared" keyword implies that it is intended to be reused wherever it can be. This is generalized code that "Feature A" or "Feature B" could use if it works for their use case.
87-
88-
An example is the `waitUntil()` function which continuously invokes an arbitrary callback function until it succeeds.
89-
90-
> NOTE: Something that is "shared" does not mean it is "common", as it could be reused in different places but only work in Node.js for example.
85+
```
86+
src/
87+
├── myTopic/
88+
│ ├── {file}.ts
89+
│ ├── node/
90+
│ │ └── {file}.ts
91+
│ └── web/
92+
│ └── {file}.ts
93+
└── shared/
94+
```
9195

92-
### How to apply this
96+
- `myTopic/` is the general name of the folder, eg `request` for http requests.
97+
- `myTopic/{file}.ts` is for code that works in any environment, we refer to this as `"common"` code.
98+
- `node/{file}.ts` is for code that works exclusively in Node.js.
99+
- `web/{file}.ts` is for code that works exclusively in Web mode.
100+
- `shared/` is for code that is intended to be reused, i.e general purpose utils.
101+
- Note environment specific code should be place in to a `web/` or `node/` subfolder.
102+
- If the code is not in a subfolder then it is considered `shared common` code.
93103

94-
- Aim to make code compatible with "common" from the beginning.
95-
- In a "topic" folder, if you have common code, create a subfolder named "common" and add your common code to there.
96-
```
97-
src/
98-
|
99-
myTopic/
100-
|
101-
common/
102-
nonCommon.ts
103-
```
104-
- See if yours, or existing code can be moved in to a "shared" folder. Maybe it can be easily modified to become "shared".
105-
- If there is no "shared" or "common" naming used for the file/folder, then assume it only works in Node.js.
106-
- In the rare case your code only works in Web mode, create a `web` subfolder for that code.
104+
> IMPORTANT: The current codebase does not fully follow this convention yet, the transition is being done incrementally. Due to this, code that is `"common"` may not actually be common yet. If you run in to this, please move that code to the appropriate subfolder.
107105
108106
## Commands
109107

@@ -292,22 +290,22 @@ Commands and events are defined on the backend via sub-classes of `VueWebview`.
292290
```ts
293291
client
294292
.foo()
295-
.then(response => console.log(response))
296-
.catch(err => console.log(err))
293+
.then((response) => console.log(response))
294+
.catch((err) => console.log(err))
297295
```
298296

299297
The backend protocol is allowed to throw errors. These result in rejected Promises on the frontend.
300298

301299
- Registering for events:
302300

303301
```ts
304-
client.onBar(num => console.log(num))
302+
client.onBar((num) => console.log(num))
305303
```
306304

307305
- Methods called `init` will only return data on the initial webview load:
308306

309307
```ts
310-
client.init(data => (this.data = data ?? this.data))
308+
client.init((data) => (this.data = data ?? this.data))
311309
```
312310

313311
## Webviews (non Vue)
@@ -493,8 +491,8 @@ class ExampleWizard extends Wizard<ExampleState> {
493491
{ label: '1', data: 1 },
494492
{ label: '2', data: 2 },
495493
]
496-
this.form.bar.bindPrompter(state => createQuickPick(items, { title: `Select a number (${state.foo})` }), {
497-
showWhen: state => state.foo?.length > 5,
494+
this.form.bar.bindPrompter((state) => createQuickPick(items, { title: `Select a number (${state.foo})` }), {
495+
showWhen: (state) => state.foo?.length > 5,
498496
})
499497
}
500498
}

docs/icons.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
# Icons
22

3-
All icons that are used in the Toolkit can be found in `resources/icons`.
3+
All icons that are used in the extensions can be found in `resources/icons`.
44

5-
A [build script](../../scripts/build/generateIcons.ts) generates Toolkit artifacts:
5+
A [build script](../scripts/generateIcons.ts) generates extension artifacts in [core/](../packages/core/):
66

77
- `resources/icons/cloud9/generated`
88
- `resources/fonts/aws-toolkit-icons.woff`
99
- `resources/css/icons.css`
10-
- `contributes.icons` in [package.json](../../package.json)
10+
- `contributes.icons` in [amazonq package.json](../packages/amazonq/package.json) and [toolkit package.json](../packages/toolkit/package.json)
1111

12-
This script should be ran using `npm run generatePackage` after making updates. Any changes made to `package.json` should be committed with the relevant icons.
12+
This script should be ran using `npm run generateIcons` after making updates. Any changes made to `package.json` should be committed with the relevant icons. Type checking in `core/` relies on the entries in `core/package.json`. However, the individual extensions require entries in their `package.json`s as well. Currently, resources (including icons) are shared between `core/` and the individual extensions. If `contributes.icons` in each of the extensions does not match the entry in `core/`, then CI will fail.
13+
14+
To sync the icons to the individual extensions, run `npm run copyFiles && npm run generateIcons` for each extension.
1315

1416
## Fonts
1517

docs/telemetry.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,124 @@ Finally, if `setupStep2()` was the thing that failed we would see a metric like:
139139
...
140140
}
141141
```
142+
143+
## Adding a "Stack Trace" to your metric
144+
145+
### Problem
146+
147+
Common example: _"I have a function, `thisFailsSometimes()` that is called in multiple places. The function sometimes fails, I know from telemetry, but I do not know if it is failing when it is a specific caller. If I knew the call stack/trace that it took to call my function that would help me debug."_
148+
149+
```typescript
150+
function outerA() {
151+
thisFailsSometimes(1) // this succeeds
152+
}
153+
154+
function outerB() {
155+
thisFailsSometimes(0) // this fails
156+
}
157+
158+
function thisFailsSometimes(num: number) {
159+
return telemetry.my_Metric.run(() => {
160+
if (number === 0) {
161+
throw Error('Cannot be 0')
162+
}
163+
...
164+
})
165+
}
166+
```
167+
168+
### Solution
169+
170+
Add a value to `function` in the options of a `run()`. This will result in a stack of functions identifiers that were previously called
171+
before `thisFailsSometimes()` was run. You can then retrieve the stack in the `run()` of your final metric using `getFunctionStack()`.
172+
173+
```typescript
174+
function outerA() {
175+
telemetry.my_Metric.run(() => thisFailsSometimes(1), { functionId: { name: 'outerA' }})
176+
}
177+
178+
function outerB() {
179+
telemetry.my_Metric.run(() => thisFailsSometimes(0), { functionId: { source: 'outerB' }})
180+
}
181+
182+
function thisFailsSometimes(num: number) {
183+
return telemetry.my_Metric.run(() => {
184+
telemetry.record({ theCallStack: asStringifiedStack(telemetry.getFunctionStack())})
185+
if (number === 0) {
186+
throw Error('Cannot be 0')
187+
}
188+
...
189+
}, { functionId: { name: 'thisFailsSometimes' }})
190+
}
191+
192+
// Results in a metric: { theCallStack: 'outerB:thisFailsSometimes', result: 'Failed' }
193+
// { theCallStack: 'outerB:thisFailsSometimes' } implies 'outerB' was run first, then 'thisFailsSometimes'. See docstrings for more info.
194+
outerB()
195+
```
196+
197+
### Important Notes
198+
199+
- If a nested function does not use a `run()` then it will not be part of the call stack.
200+
201+
```typescript
202+
function a() {
203+
return telemetry.my_Metric.run(() => b(), { functionId: { name: 'a' } })
204+
}
205+
206+
function b() {
207+
return c()
208+
}
209+
210+
function c() {
211+
return telemetry.my_Metric.run(() => asStringifiedStack(telemetry.getFunctionStack()), {
212+
functionId: { name: 'c' },
213+
})
214+
}
215+
216+
c() // result: 'a:c', note that 'b' is not included
217+
```
218+
219+
- If you are using `run()` with a class method, you can also add the class to the entry for more context
220+
221+
```typescript
222+
class A {
223+
a() {
224+
return telemetry.my_Metric.run(() => this.b(), { functionId: { name: 'a', class: 'A' } })
225+
}
226+
227+
b() {
228+
return telemetry.my_Metric.run(() => asStringifiedStack(telemetry.getFunctionStack()), {
229+
functionId: { name: 'b', class: 'A' },
230+
})
231+
}
232+
}
233+
234+
const inst = new A()
235+
inst.a() // 'A#a,b'
236+
```
237+
238+
- If you do not want your `run()` to emit telemetry, set `emit: false` in the options
239+
240+
```typescript
241+
function a() {
242+
return telemetry.my_Metric.run(() => b(), { functionId: { name: 'a' }, emit: false })
243+
}
244+
```
245+
246+
- If you want to add to the function stack, but don't have a specific metric to use,
247+
use the metric named `function_call`. Also look to set `emit: false` if you do not
248+
want it to emit telemetry.
249+
250+
```typescript
251+
function a() {
252+
return telemetry.function_call.run(() => b(), { functionId: { name: 'a' }, emit: false })
253+
}
254+
```
255+
256+
- If your function name is generic, look to make it unique so there is no confusion.
257+
258+
```typescript
259+
function a() {
260+
return telemetry.my_Metric.run(() => b(), { functionId: { name: 'aButMoreUnique' } })
261+
}
262+
```

docs/web.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ VS Code window, in the background it is running in a Browser context.
8585

8686
## Adding Web mode specific npm modules
8787

88-
If you need to manage npm modules required for Web mode, such as a [browserfied module](https://www.npmjs.com/package/os-browserify), see [the documentation here](../packages/core/src/web/README.md).
88+
If you need to manage npm modules required for Web mode, such as a [browserfied module](https://www.npmjs.com/package/os-browserify), see [the documentation here](../packages/core/src/web/README.md#packagejson).
8989

9090
## Finding incompatible transitive dependencies
9191

0 commit comments

Comments
 (0)