@@ -4,7 +4,9 @@ import * as cxapi from '@aws-cdk/cx-api';
4
4
import * as chalk from 'chalk' ;
5
5
import * as chokidar from 'chokidar' ;
6
6
import * as fs from 'fs-extra' ;
7
+ import { minimatch } from 'minimatch' ;
7
8
import * as promptly from 'promptly' ;
9
+ import * as semver from 'semver' ;
8
10
import * as uuid from 'uuid' ;
9
11
import { DeploymentMethod } from './api' ;
10
12
import { SdkProvider } from './api/aws-auth' ;
@@ -29,6 +31,7 @@ import { validateSnsTopicArn } from './util/validate-notification-arn';
29
31
import { Concurrency , WorkGraph } from './util/work-graph' ;
30
32
import { WorkGraphBuilder } from './util/work-graph-builder' ;
31
33
import { AssetBuildNode , AssetPublishNode , StackNode } from './util/work-graph-types' ;
34
+ import { versionNumber } from './version' ;
32
35
import { environmentsFromDescriptors , globEnvironmentsFromStacks , looksLikeGlob } from '../lib/api/cxapp/environments' ;
33
36
34
37
export interface CdkToolkitProps {
@@ -589,6 +592,9 @@ export class CdkToolkit {
589
592
stacks = stacks . reversed ( ) ;
590
593
591
594
if ( ! options . force ) {
595
+ if ( stacks . stackArtifacts . length === 0 ) {
596
+ return ;
597
+ }
592
598
// eslint-disable-next-line max-len
593
599
const confirmed = await promptly . confirm ( `Are you sure you want to delete: ${ chalk . blue ( stacks . stackArtifacts . map ( s => s . hierarchicalId ) . join ( ', ' ) ) } (y/n)?` ) ;
594
600
if ( ! confirmed ) {
@@ -882,9 +888,43 @@ export class CdkToolkit {
882
888
extend : exclusively ? ExtendedStackSelection . None : ExtendedStackSelection . Downstream ,
883
889
defaultBehavior : DefaultSelection . OnlySingle ,
884
890
} ) ;
891
+ const selectorWithoutPatterns : StackSelector = {
892
+ ...selector ,
893
+ allTopLevel : true ,
894
+ patterns : [ ] ,
895
+ } ;
896
+ const stacksWithoutPatterns = await assembly . selectStacks ( selectorWithoutPatterns , {
897
+ extend : exclusively ? ExtendedStackSelection . None : ExtendedStackSelection . Downstream ,
898
+ defaultBehavior : DefaultSelection . OnlySingle ,
899
+ } ) ;
885
900
886
- // No validation
901
+ const patterns = selector . patterns . map ( pattern => {
902
+ const notExist = ! stacks . stackArtifacts . find ( stack =>
903
+ minimatch ( stack . hierarchicalId , pattern ) || ( stack . id === pattern && semver . major ( versionNumber ( ) ) < 2 ) ,
904
+ ) ;
887
905
906
+ const closelyMatched = notExist ? stacksWithoutPatterns . stackArtifacts . map ( stack => {
907
+ if ( minimatch ( stack . hierarchicalId . toLowerCase ( ) , pattern . toLowerCase ( ) ) ) {
908
+ return stack . hierarchicalId ;
909
+ }
910
+ if ( stack . id . toLowerCase ( ) === pattern . toLowerCase ( ) && semver . major ( versionNumber ( ) ) < 2 ) {
911
+ return stack . id ;
912
+ }
913
+ return ;
914
+ } ) . filter ( ( stack ) : stack is string => stack !== undefined ) : [ ] ;
915
+ return {
916
+ pattern,
917
+ notExist,
918
+ closelyMatched,
919
+ } ;
920
+ } ) ;
921
+
922
+ patterns . forEach ( pattern => {
923
+ if ( pattern . notExist ) {
924
+ const closelyMatched = pattern . closelyMatched . length > 0 ? ` Do you mean ${ pattern . closelyMatched . join ( ', ' ) } ?` : '' ;
925
+ warning ( `${ pattern . pattern } does not exist.${ closelyMatched } ` ) ;
926
+ }
927
+ } ) ;
888
928
return stacks ;
889
929
}
890
930
0 commit comments