From 65a0e37314612ff87cd0800e21bd6185b0b91dee Mon Sep 17 00:00:00 2001 From: Bryce Ito Date: Tue, 26 May 2020 16:20:35 -0700 Subject: [PATCH 1/3] Code-type codelenses now prompt for a runtime --- src/lambda/models/samLambdaRuntime.ts | 63 +++++++++++++++++++ src/lambda/wizards/samInitWizard.ts | 24 ++----- .../sam/debugger/awsSamDebugConfiguration.ts | 8 +-- .../commands/addSamDebugConfiguration.ts | 31 ++++++--- .../debugger/samDebugConfigProvider.test.ts | 2 +- 5 files changed, 94 insertions(+), 34 deletions(-) diff --git a/src/lambda/models/samLambdaRuntime.ts b/src/lambda/models/samLambdaRuntime.ts index abe25e0ed94..a0d9232a9c9 100644 --- a/src/lambda/models/samLambdaRuntime.ts +++ b/src/lambda/models/samLambdaRuntime.ts @@ -3,8 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +import * as nls from 'vscode-nls' +const localize = nls.loadMessageBundle() + +import * as vscode from 'vscode' import { Runtime } from 'aws-sdk/clients/lambda' import { Map, Set } from 'immutable' +import * as picker from '../../shared/ui/picker' export enum RuntimeFamily { Unknown, @@ -24,6 +29,9 @@ const DEFAULT_RUNTIMES = Map([ export const samLambdaRuntimes: Set = Set.union([nodeJsRuntimes, pythonRuntimes, dotNetRuntimes]) +// Filter out node8 until local debugging is no longer supported, and it can be removed from samLambdaRuntimes +export const samLambdaCreatableRuntimes: Set = samLambdaRuntimes.filter(runtime => runtime !== 'nodejs8.10') + export type DependencyManager = 'cli-package' | 'mod' | 'gradle' | 'pip' | 'npm' | 'maven' | 'bundler' // TODO: Make this return an array of DependencyManagers when we add runtimes with multiple dependency managers @@ -88,3 +96,58 @@ export function getRuntimeFamily(langId: string): RuntimeFamily { export function getDefaultRuntime(runtime: RuntimeFamily): string | undefined { return DEFAULT_RUNTIMES.get(runtime) } + +/** + * Returns a set of runtimes for a specified runtime family or undefined if not found. + * @param family Runtime family to get runtimes for + */ +function getRuntimesForFamily(family: RuntimeFamily): Set | undefined { + switch (family) { + case RuntimeFamily.NodeJS: + return nodeJsRuntimes + case RuntimeFamily.Python: + return pythonRuntimes + case RuntimeFamily.DotNetCore: + return dotNetRuntimes + default: + return undefined + } +} + +/** + * Creates a quick pick for a Runtime with the following parameters (all optional) + * @param params buttons: array of buttons to add to the quick pick; + * currRuntime: Runtime to set a "Selected Previously" mark to; + * runtimeFamily: a RuntimeFamily that will define the list of runtimes to show (default: samLambdaCreatableRuntimes) + */ +export function promptForRuntime(params: { + buttons?: vscode.QuickInputButton[] + currRuntime?: Runtime + runtimeFamily?: RuntimeFamily +}): vscode.QuickPick { + const runtimes = params.runtimeFamily + ? getRuntimesForFamily(params.runtimeFamily) ?? samLambdaCreatableRuntimes + : samLambdaCreatableRuntimes + + return picker.createQuickPick({ + options: { + ignoreFocusOut: true, + title: localize('AWS.samcli.initWizard.runtime.prompt', 'Select a SAM Application Runtime'), + value: params.currRuntime ? params.currRuntime : '', + }, + buttons: [...(params.buttons ?? []), vscode.QuickInputButtons.Back], + items: runtimes + // remove uncreatable runtimes + .filter(value => samLambdaCreatableRuntimes.has(value)) + .toArray() + .sort(compareSamLambdaRuntime) + .map(runtime => ({ + label: runtime, + alwaysShow: runtime === params.currRuntime, + description: + runtime === params.currRuntime + ? localize('AWS.wizard.selectedPreviously', 'Selected Previously') + : '', + })), + }) +} diff --git a/src/lambda/wizards/samInitWizard.ts b/src/lambda/wizards/samInitWizard.ts index 1c90cc9105d..f7003affbe8 100644 --- a/src/lambda/wizards/samInitWizard.ts +++ b/src/lambda/wizards/samInitWizard.ts @@ -27,7 +27,7 @@ import { WizardStep, WorkspaceFolderQuickPickItem, } from '../../shared/wizards/multiStepWizard' -import { compareSamLambdaRuntime, samLambdaRuntimes } from '../models/samLambdaRuntime' +import { samLambdaCreatableRuntimes, promptForRuntime } from '../models/samLambdaRuntime' import { eventBridgeStarterAppTemplate, getSamTemplateWizardOption, @@ -54,8 +54,7 @@ export interface CreateNewSamAppWizardContext { } export class DefaultCreateNewSamAppWizardContext extends WizardContext implements CreateNewSamAppWizardContext { - // Filter out node8 until local debugging is no longer supported, and it can be removed from samLambdaRuntimes - public readonly lambdaRuntimes = samLambdaRuntimes.filter(runtime => runtime !== 'nodejs8.10') + public readonly lambdaRuntimes = samLambdaCreatableRuntimes private readonly helpButton = createHelpButton(localize('AWS.command.help', 'View Documentation')) private readonly currentCredentials: Credentials | undefined private readonly schemasRegions: Region[] @@ -67,22 +66,9 @@ export class DefaultCreateNewSamAppWizardContext extends WizardContext implement } public async promptUserForRuntime(currRuntime?: Runtime): Promise { - const quickPick = picker.createQuickPick({ - options: { - ignoreFocusOut: true, - title: localize('AWS.samcli.initWizard.runtime.prompt', 'Select a SAM Application Runtime'), - value: currRuntime ? currRuntime : '', - }, - buttons: [this.helpButton, vscode.QuickInputButtons.Back], - items: this.lambdaRuntimes - .toArray() - .sort(compareSamLambdaRuntime) - .map(runtime => ({ - label: runtime, - alwaysShow: runtime === currRuntime, - description: - runtime === currRuntime ? localize('AWS.wizard.selectedPreviously', 'Selected Previously') : '', - })), + const quickPick = promptForRuntime({ + buttons: [this.helpButton], + currRuntime, }) const choices = await picker.promptUser({ diff --git a/src/shared/sam/debugger/awsSamDebugConfiguration.ts b/src/shared/sam/debugger/awsSamDebugConfiguration.ts index 280f9c66c34..307e331dec0 100644 --- a/src/shared/sam/debugger/awsSamDebugConfiguration.ts +++ b/src/shared/sam/debugger/awsSamDebugConfiguration.ts @@ -5,7 +5,7 @@ import * as vscode from 'vscode' import * as path from 'path' -import { getDefaultRuntime, RuntimeFamily } from '../../../lambda/models/samLambdaRuntime' +import { Runtime } from 'aws-sdk/clients/lambda' import { getNormalizedRelativePath } from '../../utilities/pathUtils' import { AwsSamDebuggerConfiguration, @@ -155,14 +155,10 @@ export function createCodeAwsSamDebugConfig( folder: vscode.WorkspaceFolder | undefined, lambdaHandler: string, projectRoot: string, - runtimeFamily?: RuntimeFamily + runtime: Runtime ): AwsSamDebuggerConfiguration { const workspaceRelativePath = folder ? getNormalizedRelativePath(folder.uri.fsPath, projectRoot) : projectRoot const parentDir = path.basename(path.dirname(projectRoot)) - const runtime = runtimeFamily ? getDefaultRuntime(runtimeFamily) : undefined - if (!runtime) { - throw new Error('Invalid or missing runtime family') - } return { type: AWS_SAM_DEBUG_TYPE, diff --git a/src/shared/sam/debugger/commands/addSamDebugConfiguration.ts b/src/shared/sam/debugger/commands/addSamDebugConfiguration.ts index 928d6879de3..56fa650a401 100644 --- a/src/shared/sam/debugger/commands/addSamDebugConfiguration.ts +++ b/src/shared/sam/debugger/commands/addSamDebugConfiguration.ts @@ -5,10 +5,12 @@ import * as path from 'path' import * as vscode from 'vscode' +import { Runtime } from 'aws-sdk/clients/lambda' import { getExistingConfiguration } from '../../../../lambda/config/templates' -import { getDefaultRuntime, RuntimeFamily } from '../../../../lambda/models/samLambdaRuntime' +import { getDefaultRuntime, RuntimeFamily, promptForRuntime } from '../../../../lambda/models/samLambdaRuntime' import { CloudFormationTemplateRegistry } from '../../../cloudformation/templateRegistry' import { LaunchConfiguration } from '../../../debug/launchConfiguration' +import * as picker from '../../../ui/picker' import { localize } from '../../../utilities/vsCodeUtils' import { AwsSamDebuggerConfiguration, @@ -93,13 +95,26 @@ export async function addSamDebugConfiguration( preloadedConfig ) } else if (type === CODE_TARGET_TYPE) { - // strip the manifest's URI to the manifest's dir here. More reliable to do this here than converting back and forth between URI/string up the chain. - samDebugConfig = createCodeAwsSamDebugConfig( - workspaceFolder, - resourceName, - path.dirname(rootUri.fsPath), - runtimeFamily - ) + const quickPick = promptForRuntime({ + runtimeFamily, + }) + + const choices = await picker.promptUser({ + picker: quickPick, + }) + const val = picker.verifySinglePickerOutput(choices) + if (val) { + // strip the manifest's URI to the manifest's dir here. More reliable to do this here than converting back and forth between URI/string up the chain. + samDebugConfig = createCodeAwsSamDebugConfig( + workspaceFolder, + resourceName, + path.dirname(rootUri.fsPath), + val.label as Runtime + ) + } else { + // User backed out of runtime selection. Abandon config creation. + return + } } else { throw new Error('Unrecognized debug target type') } diff --git a/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts b/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts index bbf3e232554..2089b279575 100644 --- a/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts +++ b/src/test/shared/sam/debugger/samDebugConfigProvider.test.ts @@ -967,7 +967,7 @@ it('ensureRelativePaths', () => { undefined, 'testName1', '/test1/project', - lambdaModel.RuntimeFamily.NodeJS + lambdaModel.getDefaultRuntime(lambdaModel.RuntimeFamily.NodeJS) ?? '' ) assert.strictEqual((codeConfig.invokeTarget as CodeTargetProperties).projectRoot, '/test1/project') ensureRelativePaths(workspace, codeConfig) From 6568c75e8e33bf054c01c2315fb3135ba83accc3 Mon Sep 17 00:00:00 2001 From: Bryce Ito Date: Tue, 26 May 2020 17:18:19 -0700 Subject: [PATCH 2/3] Better function name --- src/lambda/models/samLambdaRuntime.ts | 2 +- src/lambda/wizards/samInitWizard.ts | 4 ++-- src/shared/sam/debugger/commands/addSamDebugConfiguration.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lambda/models/samLambdaRuntime.ts b/src/lambda/models/samLambdaRuntime.ts index a0d9232a9c9..27a6ef5a0c7 100644 --- a/src/lambda/models/samLambdaRuntime.ts +++ b/src/lambda/models/samLambdaRuntime.ts @@ -120,7 +120,7 @@ function getRuntimesForFamily(family: RuntimeFamily): Set | undefined { * currRuntime: Runtime to set a "Selected Previously" mark to; * runtimeFamily: a RuntimeFamily that will define the list of runtimes to show (default: samLambdaCreatableRuntimes) */ -export function promptForRuntime(params: { +export function createRuntimeQuickPick(params: { buttons?: vscode.QuickInputButton[] currRuntime?: Runtime runtimeFamily?: RuntimeFamily diff --git a/src/lambda/wizards/samInitWizard.ts b/src/lambda/wizards/samInitWizard.ts index f7003affbe8..1bede8aa46f 100644 --- a/src/lambda/wizards/samInitWizard.ts +++ b/src/lambda/wizards/samInitWizard.ts @@ -27,7 +27,7 @@ import { WizardStep, WorkspaceFolderQuickPickItem, } from '../../shared/wizards/multiStepWizard' -import { samLambdaCreatableRuntimes, promptForRuntime } from '../models/samLambdaRuntime' +import { createRuntimeQuickPick, samLambdaCreatableRuntimes } from '../models/samLambdaRuntime' import { eventBridgeStarterAppTemplate, getSamTemplateWizardOption, @@ -66,7 +66,7 @@ export class DefaultCreateNewSamAppWizardContext extends WizardContext implement } public async promptUserForRuntime(currRuntime?: Runtime): Promise { - const quickPick = promptForRuntime({ + const quickPick = createRuntimeQuickPick({ buttons: [this.helpButton], currRuntime, }) diff --git a/src/shared/sam/debugger/commands/addSamDebugConfiguration.ts b/src/shared/sam/debugger/commands/addSamDebugConfiguration.ts index 56fa650a401..6ff43dbd050 100644 --- a/src/shared/sam/debugger/commands/addSamDebugConfiguration.ts +++ b/src/shared/sam/debugger/commands/addSamDebugConfiguration.ts @@ -7,7 +7,7 @@ import * as path from 'path' import * as vscode from 'vscode' import { Runtime } from 'aws-sdk/clients/lambda' import { getExistingConfiguration } from '../../../../lambda/config/templates' -import { getDefaultRuntime, RuntimeFamily, promptForRuntime } from '../../../../lambda/models/samLambdaRuntime' +import { createRuntimeQuickPick, getDefaultRuntime, RuntimeFamily } from '../../../../lambda/models/samLambdaRuntime' import { CloudFormationTemplateRegistry } from '../../../cloudformation/templateRegistry' import { LaunchConfiguration } from '../../../debug/launchConfiguration' import * as picker from '../../../ui/picker' @@ -95,7 +95,7 @@ export async function addSamDebugConfiguration( preloadedConfig ) } else if (type === CODE_TARGET_TYPE) { - const quickPick = promptForRuntime({ + const quickPick = createRuntimeQuickPick({ runtimeFamily, }) From 099729a0f9489797510c539b0f04a16a97f67b95 Mon Sep 17 00:00:00 2001 From: Bryce Ito Date: Tue, 26 May 2020 20:28:51 -0700 Subject: [PATCH 3/3] Correcting comments --- src/lambda/models/samLambdaRuntime.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lambda/models/samLambdaRuntime.ts b/src/lambda/models/samLambdaRuntime.ts index 27a6ef5a0c7..9568429483c 100644 --- a/src/lambda/models/samLambdaRuntime.ts +++ b/src/lambda/models/samLambdaRuntime.ts @@ -18,6 +18,8 @@ export enum RuntimeFamily { DotNetCore, } +// TODO: Consolidate all of the runtime constructs into a single > map +// We should be able to eliminate a fair amount of redundancy with that. export const nodeJsRuntimes: Set = Set(['nodejs12.x', 'nodejs10.x', 'nodejs8.10']) export const pythonRuntimes: Set = Set(['python3.8', 'python3.7', 'python3.6', 'python2.7']) export const dotNetRuntimes: Set = Set(['dotnetcore2.1']) @@ -116,9 +118,10 @@ function getRuntimesForFamily(family: RuntimeFamily): Set | undefined { /** * Creates a quick pick for a Runtime with the following parameters (all optional) - * @param params buttons: array of buttons to add to the quick pick; - * currRuntime: Runtime to set a "Selected Previously" mark to; - * runtimeFamily: a RuntimeFamily that will define the list of runtimes to show (default: samLambdaCreatableRuntimes) + * @param {Object} params Optional parameters for creating a QuickPick for runtimes: + * @param {vscode.QuickInputButton[]} params.buttons Array of buttons to add to the quick pick; + * @param {Runtime} params.currRuntime Runtime to set a "Selected Previously" mark to; + * @param {RuntimeFamily} params.runtimeFamily RuntimeFamily that will define the list of runtimes to show (default: samLambdaCreatableRuntimes) */ export function createRuntimeQuickPick(params: { buttons?: vscode.QuickInputButton[]