@@ -9,7 +9,6 @@ import * as vscode from 'vscode'
99import * as path from 'path'
1010import * as localizedText from '../localizedText'
1111import { DefaultS3Client } from '../clients/s3Client'
12- import { Wizard } from '../wizards/wizard'
1312import { DataQuickPickItem , createMultiPick , createQuickPick } from '../ui/pickerPrompter'
1413import { DefaultCloudFormationClient } from '../clients/cloudFormationClient'
1514import * as CloudFormation from '../cloudformation/cloudformation'
@@ -28,14 +27,14 @@ import { createExitPrompter } from '../ui/common/exitPrompter'
2827import { getConfigFileUri , SamConfig , validateSamSyncConfig , writeSamconfigGlobal } from './config'
2928import { cast , Optional } from '../utilities/typeConstructors'
3029import { pushIf , toRecord } from '../utilities/collectionUtils'
31- import { getOverriddenParameters } from '../../lambda/config/parameterUtils'
30+ import { getParameters } from '../../lambda/config/parameterUtils'
3231import { addTelemetryEnvVar } from './cli/samCliInvokerUtils'
3332import { samSyncParamUrl , samSyncUrl , samUpgradeUrl } from '../constants'
3433import { openUrl } from '../utilities/vsCodeUtils'
3534import { showOnce } from '../utilities/messages'
3635import { IamConnection } from '../../auth/connection'
3736import { CloudFormationTemplateRegistry } from '../fs/templateRegistry'
38- import { TreeNode } from '../treeview/resourceTreeDataProvider'
37+ import { isTreeNode , TreeNode } from '../treeview/resourceTreeDataProvider'
3938import { getSpawnEnv } from '../env/resolveEnv'
4039import {
4140 getProjectRoot ,
@@ -52,13 +51,19 @@ import { ParamsSource, createSyncParamsSourcePrompter } from '../ui/sam/paramsSo
5251import { createEcrPrompter } from '../ui/sam/ecrPrompter'
5352import { BucketSource , createBucketNamePrompter , createBucketSourcePrompter } from '../ui/sam/bucketPrompter'
5453import { runInTerminal } from './processTerminal'
54+ import {
55+ TemplateParametersForm ,
56+ TemplateParametersWizard ,
57+ } from '../../awsService/appBuilder/wizards/templateParametersWizard'
58+ import { CompositeWizard } from '../wizards/compositeWizard'
5559
5660export interface SyncParams {
5761 readonly paramsSource : ParamsSource
5862 readonly region : string
5963 readonly deployType : 'infra' | 'code'
6064 readonly projectRoot : vscode . Uri
6165 readonly template : TemplateItem
66+ readonly templateParameters : any
6267 readonly stackName : string
6368 readonly bucketSource : BucketSource
6469 readonly bucketName : string
@@ -147,7 +152,30 @@ export const syncFlagItems: DataQuickPickItem<string>[] = [
147152 } ,
148153]
149154
150- export class SyncWizard extends Wizard < SyncParams > {
155+ export enum SamSyncEntryPoints {
156+ SamTemplateFile ,
157+ SamConfigFile ,
158+ RegionNodeContextMenu ,
159+ AppBuilderNodeButton ,
160+ CommandPalette ,
161+ }
162+
163+ function getSyncEntryPoint ( arg : vscode . Uri | AWSTreeNodeBase | TreeNode | undefined ) {
164+ if ( arg instanceof vscode . Uri ) {
165+ if ( arg . path . endsWith ( 'samconfig.toml' ) ) {
166+ return SamSyncEntryPoints . SamConfigFile
167+ }
168+ return SamSyncEntryPoints . SamTemplateFile
169+ } else if ( arg instanceof AWSTreeNodeBase ) {
170+ return SamSyncEntryPoints . RegionNodeContextMenu
171+ } else if ( isTreeNode ( arg ) ) {
172+ return SamSyncEntryPoints . AppBuilderNodeButton
173+ } else {
174+ return SamSyncEntryPoints . CommandPalette
175+ }
176+ }
177+
178+ export class SyncWizard extends CompositeWizard < SyncParams > {
151179 registry : CloudFormationTemplateRegistry
152180 public constructor (
153181 state : Pick < SyncParams , 'deployType' > & Partial < SyncParams > ,
@@ -156,17 +184,38 @@ export class SyncWizard extends Wizard<SyncParams> {
156184 ) {
157185 super ( { initState : state , exitPrompterProvider : shouldPromptExit ? createExitPrompter : undefined } )
158186 this . registry = registry
187+ }
188+
189+ public override async init ( ) : Promise < this> {
159190 this . form . template . bindPrompter ( ( ) => createTemplatePrompter ( this . registry , syncMementoRootKey , samSyncUrl ) )
191+ this . form . templateParameters . bindPrompter (
192+ async ( { template } ) =>
193+ this . createWizardPrompter < TemplateParametersWizard , TemplateParametersForm > (
194+ TemplateParametersWizard ,
195+ template ! . uri ,
196+ samSyncUrl ,
197+ syncMementoRootKey
198+ ) ,
199+ {
200+ showWhen : async ( { template } ) => {
201+ const samTemplateParameters = await getParameters ( template ! . uri )
202+ return ! ! samTemplateParameters && samTemplateParameters . size > 0
203+ } ,
204+ }
205+ )
206+
160207 this . form . projectRoot . setDefault ( ( { template } ) => getProjectRoot ( template ) )
161208
162209 this . form . paramsSource . bindPrompter ( async ( { projectRoot } ) => {
163210 const existValidSamConfig : boolean | undefined = await validateSamSyncConfig ( projectRoot )
164211 return createSyncParamsSourcePrompter ( existValidSamConfig )
165212 } )
213+
166214 this . form . region . bindPrompter ( ( ) => createRegionPrompter ( ) . transform ( ( r ) => r . id ) , {
167215 showWhen : ( { paramsSource } ) =>
168216 paramsSource === ParamsSource . Specify || paramsSource === ParamsSource . SpecifyAndSave ,
169217 } )
218+
170219 this . form . stackName . bindPrompter (
171220 ( { region } ) =>
172221 createStackPrompter ( new DefaultCloudFormationClient ( region ! ) , syncMementoRootKey , samSyncUrl ) ,
@@ -210,6 +259,7 @@ export class SyncWizard extends Wizard<SyncParams> {
210259 paramsSource === ParamsSource . Specify || paramsSource === ParamsSource . SpecifyAndSave ,
211260 }
212261 )
262+ return this
213263 }
214264}
215265
@@ -296,30 +346,22 @@ export async function saveAndBindArgs(args: SyncParams): Promise<{ readonly boun
296346 return { boundArgs }
297347}
298348
299- async function loadLegacyParameterOverrides ( template : TemplateItem ) {
300- try {
301- const params = await getOverriddenParameters ( template . uri )
302- if ( ! params ) {
303- return
304- }
305-
306- return [ ...params . entries ( ) ] . map ( ( [ k , v ] ) => `${ k } =${ v } ` )
307- } catch ( err ) {
308- getLogger ( ) . warn ( `sam: unable to load legacy parameter overrides: %s` , err )
309- }
310- }
311-
312349export async function runSamSync ( args : SyncParams ) {
313350 telemetry . record ( { lambdaPackageType : args . ecrRepoUri !== undefined ? 'Image' : 'Zip' } )
314351
315352 const { path : samCliPath , parsedVersion } = await getSamCliPathAndVersion ( )
316353 const { boundArgs } = await saveAndBindArgs ( args )
317- const overrides = await loadLegacyParameterOverrides ( args . template )
318- if ( overrides !== undefined ) {
319- // Leaving this out of the definitions file as this is _very_ niche and specific to the
320- // implementation. Plus we would have to redefine `sam_sync` to add it.
321- telemetry . record ( { isUsingTemplatesJson : true } as any )
322- boundArgs . push ( '--parameter-overrides' , ...overrides )
354+
355+ if ( ! ! args . templateParameters && Object . entries ( args . templateParameters ) . length > 0 ) {
356+ const templateParameters = new Map < string , string > ( Object . entries ( args . templateParameters ) )
357+ const paramsToSet : string [ ] = [ ]
358+ for ( const [ key , value ] of templateParameters . entries ( ) ) {
359+ if ( value ) {
360+ await updateRecentResponse ( syncMementoRootKey , args . template . uri . fsPath , key , value )
361+ paramsToSet . push ( `ParameterKey=${ key } ,ParameterValue=${ value } ` )
362+ }
363+ }
364+ paramsToSet . length > 0 && boundArgs . push ( '--parameter-overrides' , paramsToSet . join ( ' ' ) )
323365 }
324366
325367 // '--no-watch' was not added until https://github.com/aws/aws-sam-cli/releases/tag/v1.77.0
@@ -431,21 +473,30 @@ export async function prepareSyncParams(
431473) : Promise < Partial < SyncParams > > {
432474 // Skip creating dependency layers by default for backwards compat
433475 const baseParams : Partial < SyncParams > = { skipDependencyLayer : true }
476+ const entryPoint = getSyncEntryPoint ( arg )
434477
435- if ( arg instanceof AWSTreeNodeBase ) {
436- // "Deploy" command was invoked on a regionNode.
437- return { ...baseParams , region : arg . regionCode }
438- } else if ( arg instanceof vscode . Uri ) {
439- if ( arg . path . endsWith ( 'samconfig.toml' ) ) {
440- // "Deploy" command was invoked on a samconfig.toml file.
441- // TODO: add step to verify samconfig content to skip param source prompter
442- const config = await SamConfig . fromConfigFileUri ( arg )
478+ switch ( entryPoint ) {
479+ case SamSyncEntryPoints . SamTemplateFile : {
480+ const entryPointArg = arg as vscode . Uri
481+ const template = {
482+ uri : entryPointArg ,
483+ data : await CloudFormation . load ( entryPointArg . fsPath , validate ) ,
484+ }
485+
486+ return {
487+ ...baseParams ,
488+ template : template ,
489+ projectRoot : getProjectRootUri ( template . uri ) ,
490+ }
491+ }
492+ case SamSyncEntryPoints . SamConfigFile : {
493+ const config = await SamConfig . fromConfigFileUri ( arg as vscode . Uri )
443494 const params = getSyncParamsFromConfig ( config )
444495 const projectRoot = vscode . Uri . joinPath ( config . location , '..' )
445496 const templateUri = params . templatePath
446497 ? vscode . Uri . file ( path . resolve ( projectRoot . fsPath , params . templatePath ) )
447498 : undefined
448- const template = templateUri
499+ const samConfigFileTemplate = templateUri
449500 ? {
450501 uri : templateUri ,
451502 data : await CloudFormation . load ( templateUri . fsPath ) ,
@@ -454,29 +505,38 @@ export async function prepareSyncParams(
454505 // Always use the dependency layer if the user specified to do so
455506 const skipDependencyLayer = ! config . getCommandParam ( 'sync' , 'dependency_layer' )
456507
457- return { ...baseParams , ...params , template, projectRoot, skipDependencyLayer } as SyncParams
508+ return {
509+ ...baseParams ,
510+ ...params ,
511+ template : samConfigFileTemplate ,
512+ projectRoot,
513+ skipDependencyLayer,
514+ } as SyncParams
458515 }
459-
460- // "Deploy" command was invoked on a template.yaml file.
461- const template = {
462- uri : arg ,
463- data : await CloudFormation . load ( arg . fsPath , validate ) ,
516+ case SamSyncEntryPoints . RegionNodeContextMenu : {
517+ const entryPointArg = arg as AWSTreeNodeBase
518+ return { ...baseParams , region : entryPointArg . regionCode }
464519 }
465-
466- return { ...baseParams , template, projectRoot : getProjectRootUri ( template . uri ) }
467- } else if ( arg && arg . getTreeItem ( ) ) {
468- // "Deploy" command was invoked on a TreeNode on the AppBuilder.
469- const templateUri = ( arg . getTreeItem ( ) as vscode . TreeItem ) . resourceUri
470- if ( templateUri ) {
471- const template = {
472- uri : templateUri ,
473- data : await CloudFormation . load ( templateUri . fsPath , validate ) ,
520+ case SamSyncEntryPoints . AppBuilderNodeButton : {
521+ const entryPointArg = arg as TreeNode
522+ const templateUri = ( entryPointArg . getTreeItem ( ) as vscode . TreeItem ) . resourceUri
523+ if ( templateUri ) {
524+ const template = {
525+ uri : templateUri ,
526+ data : await CloudFormation . load ( templateUri . fsPath , validate ) ,
527+ }
528+ return {
529+ ...baseParams ,
530+ template,
531+ projectRoot : getProjectRootUri ( templateUri ) ,
532+ }
474533 }
475- return { ... baseParams , template , projectRoot : getProjectRootUri ( template . uri ) }
534+ return baseParams
476535 }
536+ case SamSyncEntryPoints . CommandPalette :
537+ default :
538+ return baseParams
477539 }
478-
479- return baseParams
480540}
481541
482542export type SamSyncResult = {
0 commit comments