Skip to content
20 changes: 17 additions & 3 deletions packages/amazonq/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1330,26 +1330,40 @@
"fontCharacter": "\\f1de"
}
},
"aws-schemas-registry": {
"aws-sagemaker-code-editor": {
"description": "AWS Contributed Icon",
"default": {
"fontPath": "./resources/fonts/aws-toolkit-icons.woff",
"fontCharacter": "\\f1df"
}
},
"aws-schemas-schema": {
"aws-sagemaker-jupyter-lab": {
"description": "AWS Contributed Icon",
"default": {
"fontPath": "./resources/fonts/aws-toolkit-icons.woff",
"fontCharacter": "\\f1e0"
}
},
"aws-stepfunctions-preview": {
"aws-schemas-registry": {
"description": "AWS Contributed Icon",
"default": {
"fontPath": "./resources/fonts/aws-toolkit-icons.woff",
"fontCharacter": "\\f1e1"
}
},
"aws-schemas-schema": {
"description": "AWS Contributed Icon",
"default": {
"fontPath": "./resources/fonts/aws-toolkit-icons.woff",
"fontCharacter": "\\f1e2"
}
},
"aws-stepfunctions-preview": {
"description": "AWS Contributed Icon",
"default": {
"fontPath": "./resources/fonts/aws-toolkit-icons.woff",
"fontCharacter": "\\f1e3"
}
}
},
"walkthroughs": [
Expand Down
3 changes: 3 additions & 0 deletions packages/core/resources/icons/vscode/light/cloud-upload.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/core/resources/icons/vscode/light/run.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 6 additions & 6 deletions packages/core/resources/markdown/lambdaEdit.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Welcome to Lambda Local Development
# Welcome to Lambda local development

Learn how to view your Lambda Function locally, iterate, and deploy changes to the AWS Cloud.
Learn how to view your Lambda function locally, iterate, and deploy changes to the AWS Cloud.

## Edit your Lambda function

Expand All @@ -9,11 +9,11 @@ Learn how to view your Lambda Function locally, iterate, and deploy changes to t

## Manage your Lambda functions

- Select the AWS icon in the left sidebar and select **EXPLORER**
- Select the AWS Toolkit icon in the left sidebar and select **EXPLORER**
- In your desired region, select the Lambda dropdown menu:
- To save and deploy a previously edited Lambda function, select the cloud deploy icon next to your Lambda function.
- To remotely invoke a function, select the play icon next to your Lambda function.
- To save and deploy a previously edited Lambda function, select the ![deploy](./deploy.svg) icon next to your Lambda function.
- To remotely invoke a function, select the ![invoke](./invoke.svg) icon next to your Lambda function.

## Advanced Features
## Advanced features

- To convert to a Lambda function to an AWS SAM application, select the ![createStack](./create-stack.svg) icon next to your Lambda function. For details on what AWS SAM is and how it can help you, see the [AWS Serverless Application Model Developer Guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html).
142 changes: 110 additions & 32 deletions packages/core/src/lambda/activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { ExtContext } from '../shared/extensions'
import { invokeRemoteLambda } from './vue/remoteInvoke/invokeLambda'
import { registerSamDebugInvokeVueCommand, registerSamInvokeVueCommand } from './vue/configEditor/samInvokeBackend'
import { Commands } from '../shared/vscode/commands2'
import { DefaultLambdaClient, getFunctionWithCredentials } from '../shared/clients/lambdaClient'
import { DefaultLambdaClient } from '../shared/clients/lambdaClient'
import { copyLambdaUrl } from './commands/copyLambdaUrl'
import { ResourceNode } from '../awsService/appBuilder/explorer/nodes/resourceNode'
import { isTreeNode, TreeNode } from '../shared/treeview/resourceTreeDataProvider'
Expand All @@ -29,47 +29,125 @@ import { ToolkitError, isError } from '../shared/errors'
import { LogStreamFilterResponse } from '../awsService/cloudWatchLogs/wizard/liveTailLogStreamSubmenu'
import { tempDirPath } from '../shared/filesystemUtilities'
import fs from '../shared/fs/fs'
import { deployFromTemp, editLambda, getReadme, openLambdaFolderForEdit } from './commands/editLambda'
import { getTempLocation } from './utils'
import {
confirmOutdatedChanges,
deleteFilesInFolder,
deployFromTemp,
getReadme,
openLambdaFolderForEdit,
watchForUpdates,
} from './commands/editLambda'
import { compareCodeSha, getFunctionInfo, getTempLocation, setFunctionInfo } from './utils'
import { registerLambdaUriHandler } from './uriHandlers'
import globals from '../shared/extensionGlobals'

const localize = nls.loadMessageBundle()

/**
* Activates Lambda components.
*/
export async function activate(context: ExtContext): Promise<void> {
try {
if (vscode.workspace.workspaceFolders) {
for (const workspaceFolder of vscode.workspace.workspaceFolders) {
// Making the comparison case insensitive because Windows can have `C\` or `c\`
const workspacePath = workspaceFolder.uri.fsPath.toLowerCase()
const tempPath = path.join(tempDirPath, 'lambda').toLowerCase()
if (workspacePath.startsWith(tempPath)) {
const name = path.basename(workspaceFolder.uri.fsPath)
const region = path.basename(path.dirname(workspaceFolder.uri.fsPath))
const getFunctionOutput = await getFunctionWithCredentials(region, name)
const configuration = getFunctionOutput.Configuration
await editLambda(
{
name,
region,
// Configuration as any due to the difference in types between sdkV2 and sdkV3
configuration: configuration as any,
},
true
async function openReadme() {
const readmeUri = vscode.Uri.file(await getReadme())
// We only want to do it if there's not a readme already
const isPreviewOpen = vscode.window.tabGroups.all.some((group) =>
group.tabs.some((tab) => tab.label.includes('README'))
)
if (!isPreviewOpen) {
await vscode.commands.executeCommand('markdown.showPreviewToSide', readmeUri)
}
}

async function quickEditActivation() {
if (vscode.workspace.workspaceFolders) {
for (const workspaceFolder of vscode.workspace.workspaceFolders) {
// Making the comparison case insensitive because Windows can have `C\` or `c\`
const workspacePath = workspaceFolder.uri.fsPath.toLowerCase()
const tempPath = path.join(tempDirPath, 'lambda').toLowerCase()
if (workspacePath.includes(tempPath)) {
const name = path.basename(workspaceFolder.uri.fsPath)
const region = path.basename(path.dirname(workspaceFolder.uri.fsPath))

const lambda = { name, region, configuration: undefined }

watchForUpdates(lambda, vscode.Uri.file(workspacePath))

await openReadme()

// Open handler function
try {
const handler = await getFunctionInfo(lambda, 'handlerFile')
const lambdaLocation = path.join(workspacePath, handler)
await openLambdaFile(lambdaLocation, vscode.ViewColumn.One)
} catch (e) {
void vscode.window.showWarningMessage(
localize('AWS.lambda.openFile.failure', `Failed to determine handler location: ${e}`)
)
}

const readmeUri = vscode.Uri.file(await getReadme())
await vscode.commands.executeCommand('markdown.showPreview', readmeUri, vscode.ViewColumn.Two)
// Check if there are changes that need overwritten
try {
// Checking if there are changes that need to be overwritten
const prompt = localize(
'AWS.lambda.download.confirmOutdatedSync',
'There are changes to your function in the cloud since you last edited locally, do you want to overwrite your local changes?'
)

// Adding delay to give the authentication time to catch up
await new Promise((resolve) => globals.clock.setTimeout(resolve, 1000))

const overwriteChanges = !(await compareCodeSha(lambda))
? await confirmOutdatedChanges(prompt)
: false
if (overwriteChanges) {
// Close all open tabs from this workspace
const workspaceUri = vscode.Uri.file(workspacePath)
for (const tabGroup of vscode.window.tabGroups.all) {
const tabsToClose = tabGroup.tabs.filter(
(tab) =>
tab.input instanceof vscode.TabInputText &&
tab.input.uri.fsPath.startsWith(workspaceUri.fsPath)
)
if (tabsToClose.length > 0) {
await vscode.window.tabGroups.close(tabsToClose)
}
}

// Delete all files in the directory
await deleteFilesInFolder(workspacePath)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this confirm deleted all data in folder but didn't download anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we want to clear the folder so that next time we try to open the code, editLambda knows it needs to redownload the freshest code.


// Remove workspace folder
const workspaceIndex = vscode.workspace.workspaceFolders?.findIndex(
(folder) => folder.uri.fsPath.toLowerCase() === workspacePath
)
if (workspaceIndex !== undefined && workspaceIndex >= 0) {
vscode.workspace.updateWorkspaceFolders(workspaceIndex, 1)
}

await setFunctionInfo(lambda, { undeployed: false })

// Show message to user about next steps
void vscode.window.showInformationMessage(
localize(
'AWS.lambda.refresh.complete',
'Local workspace cleared. Navigate to the Toolkit explorer to get fresh code from the cloud.'
)
)
}
} catch (e) {
void vscode.window.showWarningMessage(
localize(
'AWS.lambda.pull.failure',
`Failed to pull latest changes from the cloud, you can still edit locally: ${e}`
)
)
}
}
}
} catch (e) {
void vscode.window.showWarningMessage(
localize('AWS.lambda.open.failure', `Unable to edit Lambda Function locally: ${e}`)
)
}
}

/**
* Activates Lambda components.
*/
export async function activate(context: ExtContext): Promise<void> {
await quickEditActivation()

context.extensionContext.subscriptions.push(
Commands.register('aws.deleteLambda', async (node: LambdaFunctionNode | TreeNode) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/lambda/commands/downloadLambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ async function downloadAndUnzipLambda(
}
}

export async function openLambdaFile(lambdaLocation: string): Promise<void> {
export async function openLambdaFile(lambdaLocation: string, viewColumn?: vscode.ViewColumn): Promise<void> {
if (!(await fs.exists(lambdaLocation))) {
const warning = localize(
'AWS.lambda.download.fileNotFound',
Expand All @@ -206,7 +206,7 @@ export async function openLambdaFile(lambdaLocation: string): Promise<void> {
throw new Error()
}
const doc = await vscode.workspace.openTextDocument(vscode.Uri.file(lambdaLocation))
await vscode.window.showTextDocument(doc)
await vscode.window.showTextDocument(doc, viewColumn)
}

async function addLaunchConfigEntry(
Expand Down
Loading
Loading