@@ -12,7 +12,12 @@ import * as AdmZip from 'adm-zip'
12
12
import * as fs from 'fs-extra'
13
13
import * as path from 'path'
14
14
import { showConfirmationMessage , showViewLogsMessage } from '../../shared/utilities/messages'
15
- import { fileExists , findFile , makeTemporaryToolkitFolder , tryRemoveFolder } from '../../shared/filesystemUtilities'
15
+ import {
16
+ fileExists ,
17
+ cloud9Findfile ,
18
+ makeTemporaryToolkitFolder ,
19
+ tryRemoveFolder ,
20
+ } from '../../shared/filesystemUtilities'
16
21
import * as localizedText from '../../shared/localizedText'
17
22
import { getLogger } from '../../shared/logger'
18
23
import { SamCliBuildInvocation } from '../../shared/sam/cli/samCliBuild'
@@ -35,6 +40,41 @@ import { toArrayAsync } from '../../shared/utilities/collectionUtils'
35
40
import { fromExtensionManifest } from '../../shared/settings'
36
41
import { createRegionPrompter } from '../../shared/ui/common/region'
37
42
43
+ interface SavedLambdas {
44
+ [ profile : string ] : { [ region : string ] : string }
45
+ }
46
+
47
+ class LambdaSettings extends fromExtensionManifest ( 'aws.lambda' , { recentlyUploaded : Object } ) {
48
+ static #instance: LambdaSettings
49
+
50
+ public getRecentLambdas ( ) : SavedLambdas | undefined {
51
+ try {
52
+ return this . get ( 'recentlyUploaded' )
53
+ } catch ( error ) {
54
+ this . delete ( 'recentlyUploaded' )
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Adds a new "recently used Lambda" to user settings for the given profile
60
+ * and region (limit of one item per profile+region).
61
+ */
62
+ public setRecentLambda ( profile : string , region : string , lambdaName : string ) : Promise < boolean > {
63
+ const oldLambdas = this . getRecentLambdas ( )
64
+ return this . update ( 'recentlyUploaded' , {
65
+ ...oldLambdas ,
66
+ [ profile ] : {
67
+ ...( oldLambdas ?. [ profile ] ?? { } ) ,
68
+ [ region ] : lambdaName ,
69
+ } ,
70
+ } )
71
+ }
72
+
73
+ public static get instance ( ) {
74
+ return ( this . #instance ??= new this ( ) )
75
+ }
76
+ }
77
+
38
78
interface LambdaFunction {
39
79
readonly name : string
40
80
readonly region : string
@@ -84,7 +124,7 @@ export async function uploadLambdaCommand(lambdaArg?: LambdaFunction, path?: vsc
84
124
if ( result === 'Succeeded' ) {
85
125
const profile = globals . awsContext . getCredentialProfileName ( )
86
126
if ( profile && lambda ) {
87
- updateSavedLambda ( profile , lambda . region , lambda . name )
127
+ LambdaSettings . instance . setRecentLambda ( profile , lambda . region , lambda . name )
88
128
}
89
129
}
90
130
}
@@ -442,27 +482,34 @@ async function uploadZipBuffer(
442
482
)
443
483
}
444
484
445
- export async function findApplicationJsonFile ( startPath : vscode . Uri ) : Promise < vscode . Uri | undefined > {
446
- const isTemplateFile = / t e m p l a t e .( y a m l | y m l | j s o n ) $ / . test ( startPath . fsPath )
447
- const parentDir = isTemplateFile ? vscode . Uri . joinPath ( startPath , '..' ) : startPath
448
-
449
- if ( isCloud9 ( ) ) {
450
- const found = await findFile ( parentDir . fsPath , '.application.json' )
451
- if ( ! found ) {
452
- getLogger ( ) . debug (
453
- 'lambda: .application.json file not found in parent directory or sub directories of %s' ,
454
- parentDir . fsPath
455
- )
456
- }
457
- return found ? vscode . Uri . file ( found ) : undefined
458
- } else {
459
- const found = await vscode . workspace . findFiles (
460
- new vscode . RelativePattern ( parentDir . path , '**/*.application.json' ) ,
461
- undefined ,
462
- 1
485
+ export async function findApplicationJsonFile (
486
+ startPath : vscode . Uri ,
487
+ cloud9 = isCloud9 ( )
488
+ ) : Promise < vscode . Uri | undefined > {
489
+ if ( ! ( await fileExists ( startPath . fsPath ) ) ) {
490
+ getLogger ( ) . error (
491
+ 'findApplicationJsonFile() invalid path (not accessible or does not exist): "%s"' ,
492
+ startPath . fsPath
463
493
)
464
- return found [ 0 ]
494
+ return undefined
465
495
}
496
+ const isdir = fs . statSync ( startPath . fsPath ) . isDirectory ( )
497
+ const parentDir = isdir ? startPath . fsPath : path . dirname ( startPath . fsPath )
498
+ const found = cloud9
499
+ ? await cloud9Findfile ( parentDir , '.application.json' )
500
+ : await vscode . workspace . findFiles (
501
+ new vscode . RelativePattern ( parentDir , '**/.application.json' ) ,
502
+ // exclude:
503
+ // - null = NO excludes apply
504
+ // - undefined = default excludes apply (e.g. the `files.exclude` setting but not `search.exclude`).
505
+ // eslint-disable-next-line no-null/no-null
506
+ null ,
507
+ 1
508
+ )
509
+ if ( ! found || found . length === 0 ) {
510
+ getLogger ( ) . debug ( 'uploadLambda: .application.json not found in: "%s"' , parentDir )
511
+ }
512
+ return found [ 0 ]
466
513
}
467
514
468
515
export function getFunctionNames ( file : vscode . Uri , region : string ) : string [ ] | undefined {
@@ -489,45 +536,56 @@ export function getFunctionNames(file: vscode.Uri, region: string): string[] | u
489
536
490
537
async function listAllLambdaNames ( region : string , path ?: vscode . Uri ) {
491
538
const lambdaFunctionNames : DataQuickPickItem < string > [ ] = [ ]
539
+
540
+ // Get Lambda functions from .application.json #2588
492
541
if ( path ) {
493
- const namesFromAppFile = await getLambdaNamesFromApplicationFile ( region , path )
494
- if ( namesFromAppFile ) {
542
+ const appFile = await findApplicationJsonFile ( path )
543
+ const namesFromAppFile = appFile ? getFunctionNames ( appFile , region ) : undefined
544
+ if ( ! appFile ) {
545
+ getLogger ( ) . debug ( 'lambda: .application.json not found' )
546
+ } else if ( ! namesFromAppFile ) {
547
+ getLogger ( ) . debug ( 'lambda: no functions in .application.json for region: %s' , region )
548
+ } else {
495
549
lambdaFunctionNames . push (
496
550
...namesFromAppFile . map ( n => {
497
551
return {
498
552
label : n ,
499
- description : localize ( 'AWS.lambda.upload.fromC9AppFile ' , 'from appliication .json' ) ,
553
+ description : localize ( 'AWS.lambda.upload.fromAppJson ' , 'from .application .json' ) ,
500
554
data : n ,
501
555
}
502
556
} )
503
557
)
504
558
}
505
559
}
560
+
561
+ // Get Lambda functions from user AWS account.
506
562
const lambdaClient = globals . toolkitClientBuilder . createLambdaClient ( region )
507
563
try {
508
564
const foundLambdas = await toArrayAsync ( listLambdaFunctions ( lambdaClient ) )
509
565
for ( const l of foundLambdas ) {
510
566
lambdaFunctionNames . push ( { label : l . FunctionName ! , data : l . FunctionName } )
511
567
}
512
568
} catch ( error ) {
513
- getLogger ( ) . error ( 'upload lambda: Error listing lambdas : %s' , ( error as Error ) . message )
569
+ getLogger ( ) . error ( 'lambda: failed to list Lambda functions : %s' , ( error as Error ) . message )
514
570
}
515
- const previousLambdas = getSavedLambdas ( )
571
+
572
+ // Get "recently used" Lambda functions.
573
+ const recent = LambdaSettings . instance . getRecentLambdas ( )
516
574
const profile = globals . awsContext . getCredentialProfileName ( )
517
- if ( previousLambdas && profile && previousLambdas [ profile ] && previousLambdas [ profile ] [ region ] ) {
575
+ if ( profile && recent ?. [ profile ] ?. [ region ] ) {
518
576
let isInList = false
519
577
for ( const l of lambdaFunctionNames ) {
520
- if ( l . label === previousLambdas [ profile ] [ region ] ) {
578
+ if ( l . label === recent [ profile ] [ region ] ) {
521
579
l . description = localizedText . recentlyUsed
522
580
l . recentlyUsed = true
523
581
isInList = true
524
582
}
525
583
}
526
584
if ( ! isInList ) {
527
585
lambdaFunctionNames . splice ( 0 , 0 , {
528
- label : previousLambdas [ profile ] [ region ] ,
586
+ label : recent [ profile ] [ region ] ,
529
587
recentlyUsed : true ,
530
- data : previousLambdas [ profile ] [ region ] ,
588
+ data : recent [ profile ] [ region ] ,
531
589
description : localizedText . recentlyUsed ,
532
590
} )
533
591
}
@@ -558,39 +616,3 @@ function createFunctionNamePrompter(region: string, path?: vscode.Uri) {
558
616
} )
559
617
return prompter
560
618
}
561
-
562
- interface SavedLambdas {
563
- [ profile : string ] : { [ region : string ] : string }
564
- }
565
-
566
- function getSavedLambdas ( ) : SavedLambdas | undefined {
567
- const settings = new LambdaSettings ( )
568
- try {
569
- return settings . get ( 'recentlyUploaded' )
570
- } catch ( error ) {
571
- getLogger ( ) . error ( 'settings: Error retreiving saved lambdas from settings: %s' , ( error as Error ) . message )
572
- }
573
- }
574
-
575
- async function updateSavedLambda ( profile : string , region : string , lambdaName : string ) : Promise < boolean > {
576
- const settings = new LambdaSettings ( )
577
- const oldLambdas = getSavedLambdas ( )
578
- return settings . update ( 'recentlyUploaded' , {
579
- ...oldLambdas ,
580
- [ profile ] : {
581
- ...( oldLambdas ?. [ profile ] ?? { } ) ,
582
- [ region ] : lambdaName ,
583
- } ,
584
- } )
585
- }
586
-
587
- async function getLambdaNamesFromApplicationFile ( region : string , path : vscode . Uri ) {
588
- const appFile = await findApplicationJsonFile ( path )
589
- if ( appFile ) {
590
- return getFunctionNames ( appFile , region )
591
- } else {
592
- getLogger ( ) . debug ( 'lambda: No .application.json files found' )
593
- }
594
- }
595
-
596
- class LambdaSettings extends fromExtensionManifest ( 'aws.lambda' , { recentlyUploaded : Object } ) { }
0 commit comments