Giuseppe Lavagetto has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/347573 )

Change subject: Properly handle inserting menu items with an explicit index
......................................................................


Properly handle inserting menu items with an explicit index

Instead of doing awkward tricks, just make Menu.items a dictionary, and
simplify most of the handling of menu items accordingly.

Change-Id: I9528d0c3248868ae5bad8d5a0bc37fbdecf83030
---
M switchdc/menu.py
M switchdc/switch.py
2 files changed, 33 insertions(+), 39 deletions(-)

Approvals:
  Giuseppe Lavagetto: Looks good to me, approved
  jenkins-bot: Verified
  Volans: Looks good to me, but someone else must approve



diff --git a/switchdc/menu.py b/switchdc/menu.py
index ccf8c26..1f10f12 100644
--- a/switchdc/menu.py
+++ b/switchdc/menu.py
@@ -4,6 +4,7 @@
 
 class Menu(object):
     """Menu class."""
+    DEFAULT_FIRST_ITEM = 1
 
     def __init__(self, title, parent=None):
         """Menu constructor
@@ -14,7 +15,7 @@
         """
         self.title = title
         self.parent = parent
-        self.items = []
+        self.items = {}
 
     @property
     def status(self):
@@ -22,15 +23,22 @@
         completed, total = Menu.calculate_status(self)
         return '{completed}/{total}'.format(completed=completed, total=total)
 
-    def append(self, item):
+    def append(self, item, idx=None):
         """Append an item or a submenu to this menu.
 
         Arguments:
         item -- the item to append
+        idx  -- optional the index at which this item will be found in the menu
         """
+        if idx is None:
+            if self.items:
+                idx = sorted(self.items.keys())[-1] + 1
+            else:
+                idx = self.DEFAULT_FIRST_ITEM
+
         if type(item) == Menu:
             item.parent = self
-        self.items.append(item)
+        self.items[idx] = item
 
     def run(self):
         """For menu run is equivalent to show."""
@@ -39,13 +47,10 @@
     def show(self):
         """Print the menu to stdout."""
         print(self.title)
-        if self.parent is None:
-            offset = 0
-        else:
-            offset = 1
 
-        for i, item in enumerate(self.items):
-            print(' {i: >2} [{status}] {title}'.format(i=i + offset, 
title=item.title, status=item.status))
+        for idx in sorted(self.items.keys()):
+            item = self.items[idx]
+            print(' {i: >2} [{status}] {title}'.format(i=idx, 
title=item.title, status=item.status))
 
         if self.parent is not None:
             print('  b - Back to parent menu')
@@ -61,7 +66,7 @@
         """
         completed = 0
         total = 0
-        for item in menu.items:
+        for item in menu.items.values():
             item_type = type(item)
             if item_type == Menu:
                 sub_completed, sub_total = Menu.calculate_status(item)
diff --git a/switchdc/switch.py b/switchdc/switch.py
index aff5f2d..c72da3d 100644
--- a/switchdc/switch.py
+++ b/switchdc/switch.py
@@ -39,13 +39,8 @@
             print('Invalid answer')
             continue
 
-        if menu.parent is None:
-            offset = 0
-        else:
-            offset = 1
-
-        if index >= offset and index < len(menu.items) + offset:
-            item = menu.items[index - offset]
+        if index in menu.items.keys():
+            item = menu.items[index]
             if type(item) == Menu:
                 menu = item
             elif type(item) == Item:
@@ -79,8 +74,6 @@
     dc_to   -- the name of the datacenter to migrate to
     """
     menu = Menu('Datacenter switchover automation')
-    stage = '00'
-    submenu = Menu('Stage 00')
 
     for module_file in sorted(glob.glob(os.path.join(
             os.path.dirname(os.path.abspath(__file__)), 'stages', 
't[0-9][0-9]_*.py'))):
@@ -88,17 +81,13 @@
         module_name = os.path.basename(module_file)[:-3]
         module_stage = module_name[1:3]
         module = 
importlib.import_module('switchdc.stages.{module_name}'.format(module_name=module_name))
+        stage = int(module_stage)
 
-        if module_stage != stage:
-            if submenu is not None:
-                menu.append(submenu)
-            stage = module_stage
-            submenu = Menu('Stage {stage}'.format(stage=stage))
+        if stage not in menu.items:
+            submenu = Menu('Stage {stage}'.format(stage=module_stage))
+            menu.append(submenu, stage)
 
         submenu.append(Item(module.__name__, module.__title__, module.execute, 
args=[dc_from, dc_to]))
-    else:
-        if submenu is not None:
-            menu.append(submenu)
 
     return menu
 
@@ -122,28 +111,28 @@
     rc = 1
     if args.task is not None:
         # Run a single task in non-interactive mode
-        # We can't know if the items list counts from 0 or 1,
-        # so let's just cycle through all menus
-        for submenu in menu.items:
-            for item in submenu.items:
+        stage = int(args.task[1:3])
+        try:
+            submenu = menu.items[stage]
+            for item in submenu.items.values():
                 if item.name.split('.')[-1] == args.task:
                     rc = item.run()
                     break
-        else:
-            print("Unable to find task '{task}'".format(task=args.task))
-
+            else:
+                print("Unable to find task '{task}'".format(task=args.task))
+        except KeyError:
+            print("Unable to find stage '{stage}'".format(stage=stage))
     elif args.stage is not None:
         # Run all tasks in a stage in non-interactive mode
         stage = int(args.stage)
-        if 0 < stage <= len(menu.items):
-            for item in menu.items[stage - 1].items:
+        if stage not in menu.items:
+            print("Unable to find stage '{stage}'".format(stage=args.stage))
+        else:
+            for item in menu.items[stage].items.values():
                 rc = item.run()
                 if rc != 0:
                     print "Task {name}: {title} failed, aborting 
execution".format(name=item.name, title=item.title)
                     break
-        else:
-            print("Unable to find stage '{stage}'".format(stage=args.stage))
-
     else:
         rc = run(menu, args.dc_from, args.dc_to)  # Run the interactive menu
 

-- 
To view, visit https://gerrit.wikimedia.org/r/347573
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I9528d0c3248868ae5bad8d5a0bc37fbdecf83030
Gerrit-PatchSet: 5
Gerrit-Project: operations/switchdc
Gerrit-Branch: master
Gerrit-Owner: Giuseppe Lavagetto <[email protected]>
Gerrit-Reviewer: Giuseppe Lavagetto <[email protected]>
Gerrit-Reviewer: Volans <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to