1
+ import sys
2
+ import copy
1
3
import json
2
4
import jmespath
3
5
4
6
import botocore .session
5
7
from botocore import xform_name
6
8
7
9
from awsshell .resource import index
8
- from awsshell .interaction import InteractionLoader
10
+ from awsshell .interaction import InteractionLoader , SimpleSelect
11
+
12
+ from prompt_toolkit .shortcuts import confirm
9
13
10
14
11
15
class WizardException (Exception ):
@@ -118,6 +122,13 @@ def _load_stages(self, stages):
118
122
for stage in stages :
119
123
self .stages [stage .name ] = stage
120
124
125
+ def _select_stage_prompt (self ):
126
+ stages = [s .name for (s , _ ) in self .env ._stage_history ]
127
+ selector = SimpleSelect ({}, 'Select a Stage to return to: ' )
128
+ current_stage = selector .execute (stages )
129
+ self .env .pop_stages (stages .index (current_stage ))
130
+ return current_stage
131
+
121
132
def execute (self ):
122
133
"""Run the wizard. Execute Stages until a final stage is reached.
123
134
@@ -128,8 +139,18 @@ def execute(self):
128
139
stage = self .stages .get (current_stage )
129
140
if not stage :
130
141
raise WizardException ('Stage not found: %s' % current_stage )
131
- stage .execute ()
132
- current_stage = stage .get_next_stage ()
142
+ try :
143
+ stage .execute ()
144
+ current_stage = stage .get_next_stage ()
145
+ except EOFError :
146
+ current_stage = self ._select_stage_prompt ()
147
+ except Exception as e :
148
+ sys .stdout .write ('{0}\n ' .format (e ))
149
+ sys .stdout .flush ()
150
+ if confirm ('Select a previous stage? (y/n) ' ):
151
+ current_stage = self ._select_stage_prompt ()
152
+ else :
153
+ raise
133
154
134
155
135
156
class Stage (object ):
@@ -245,6 +266,7 @@ def execute(self):
245
266
2) Perform Interaction on retrieved data.
246
267
3) Perform Resolution to store data in the environment.
247
268
"""
269
+ self ._env .push_stage (self )
248
270
retrieved_options = self ._handle_retrieval ()
249
271
selected_data = self ._handle_interaction (retrieved_options )
250
272
self ._handle_resolution (selected_data )
@@ -253,8 +275,9 @@ def execute(self):
253
275
class Environment (object ):
254
276
"""Store vars into a dict and retrives them with JMESPath queries."""
255
277
256
- def __init__ (self ):
278
+ def __init__ (self , stage_history = [] ):
257
279
self ._variables = {}
280
+ self ._stage_history = stage_history
258
281
259
282
def __str__ (self ):
260
283
return json .dumps (self ._variables , indent = 4 , sort_keys = True )
@@ -291,6 +314,14 @@ def resolve_parameters(self, keys):
291
314
:rtype: dict
292
315
:return: The dict of with all of the paths resolved to their values.
293
316
"""
317
+ resolved_dict = {}
294
318
for key in keys :
295
- keys [key ] = self .retrieve (keys [key ])
296
- return keys
319
+ resolved_dict [key ] = self .retrieve (keys [key ])
320
+ return resolved_dict
321
+
322
+ def push_stage (self , stage ):
323
+ self ._stage_history .append ((stage , copy .deepcopy (self ._variables )))
324
+
325
+ def pop_stages (self , stage_index ):
326
+ self ._variables = self ._stage_history [stage_index ][1 ]
327
+ self ._stage_history = self ._stage_history [:stage_index ]
0 commit comments