← Back to team overview

yellow team mailing list archive

[Merge] lp:~frankban/lpsetup/steps into lp:lpsetup

 

Francesco Banconi has proposed merging lp:~frankban/lpsetup/steps into lp:lpsetup.

Requested reviews:
  Launchpad Yellow Squad (yellow)

For more details, see:
https://code.launchpad.net/~frankban/lpsetup/steps/+merge/98815

== Changes ==

lpsetup sub commands are able to execute only a subset of their internal functions. Now these functions composing a sub command are called "steps". Gary suggested that the previous name ("actions") could generate confusion since Python argparse has his own concept of actions.


== Tests ==

$ bin/test 
Running zope.testrunner.layer.UnitTests tests:
  Set up zope.testrunner.layer.UnitTests in 0.000 seconds.
  Ran 36 tests with 0 failures and 0 errors in 0.024 seconds.
Tearing down left over layers:
  Tear down zope.testrunner.layer.UnitTests in 0.000 seconds.

-- 
https://code.launchpad.net/~frankban/lpsetup/steps/+merge/98815
Your team Launchpad Yellow Squad is requested to review the proposed merge of lp:~frankban/lpsetup/steps into lp:lpsetup.
=== modified file 'lpsetup/__init__.py'
--- lpsetup/__init__.py	2012-03-16 11:03:51 +0000
+++ lpsetup/__init__.py	2012-03-22 11:09:20 +0000
@@ -9,7 +9,7 @@
     'get_version',
     ]
 
-VERSION = (0, 1, 1)
+VERSION = (0, 1, 2)
 
 
 def get_version():

=== modified file 'lpsetup/argparser.py'
--- lpsetup/argparser.py	2012-03-12 14:13:55 +0000
+++ lpsetup/argparser.py	2012-03-22 11:09:20 +0000
@@ -6,7 +6,7 @@
 
 __metaclass__ = type
 __all__ = [
-    'ActionsBasedSubCommand',
+    'StepsBasedSubCommand',
     'ArgumentParser',
     'BaseSubCommand',
     ]
@@ -311,25 +311,25 @@
         pass
 
 
-class ActionsBasedSubCommand(BaseSubCommand):
-    """A sub command that uses "actions" to handle its execution.
+class StepsBasedSubCommand(BaseSubCommand):
+    """A sub command that uses "steps" to handle its execution.
 
-    Actions are callables stored in the `actions` attribute, together
+    Steps are callables stored in the `steps` attribute, together
     with the arguments they expect. Those arguments are strings
     representing attributes of the argparse namespace::
 
         >>> trace = []
 
-        >>> def action1(foo):
-        ...     trace.append('action1 received ' + foo)
-
-        >>> def action2(foo, bar):
-        ...     trace.append('action2 received {0} and {1}'.format(foo, bar))
-
-        >>> class SubCommand(ActionsBasedSubCommand):
-        ...     actions = (
-        ...         (action1, 'foo'),
-        ...         (action2, 'foo', 'bar'),
+        >>> def step1(foo):
+        ...     trace.append('step1 received ' + foo)
+
+        >>> def step2(foo, bar):
+        ...     trace.append('step2 received {0} and {1}'.format(foo, bar))
+
+        >>> class SubCommand(StepsBasedSubCommand):
+        ...     steps = (
+        ...         (step1, 'foo'),
+        ...         (step2, 'foo', 'bar'),
         ...         )
         ...
         ...     def add_arguments(self, parser):
@@ -337,7 +337,7 @@
         ...         parser.add_argument('--foo')
         ...         parser.add_argument('--bar')
 
-    This class implements an handler method that executes actions in the
+    This class implements an handler method that executes steps in the
     order they are provided::
 
         >>> parser = ArgumentParser()
@@ -345,43 +345,42 @@
         >>> namespace = parser.parse_args('sub --foo eggs --bar spam'.split())
         >>> namespace.main(namespace)
         >>> trace
-        ['action1 received eggs', 'action2 received eggs and spam']
+        ['step1 received eggs', 'step2 received eggs and spam']
 
-    A special argument `-a` or `--actions` is automatically added to the
-    parser. It can be used to execute only one or a subset of actions::
+    A special argument `-s` or `--steps` is automatically added to the
+    parser. It can be used to execute only one or a subset of steps::
 
         >>> trace = []
 
-        >>> namespace = parser.parse_args('sub --foo eggs -a action1'.split())
+        >>> namespace = parser.parse_args('sub --foo eggs -s step1'.split())
         >>> namespace.main(namespace)
         >>> trace
-        ['action1 received eggs']
+        ['step1 received eggs']
 
-    A special argument `--skip-actions` is automatically added to the
-    parser. It can be used to skip one or more actions::
+    A special argument `--skip-steps` is automatically added to the
+    parser. It can be used to skip one or more steps::
 
         >>> trace = []
 
         >>> namespace = parser.parse_args(
-        ...     'sub --foo eggs --skip-actions action1'.split())
+        ...     'sub --foo eggs --skip-steps step1'.split())
         >>> namespace.main(namespace)
         >>> trace
-        ['action2 received eggs and None']
+        ['step2 received eggs and None']
 
-    The actions execution is stopped if an action raises
-    `subprocess.CalledProcessError`.
+    The steps execution is stopped if a step raises `CalledProcessError`.
     In that case, the error is returned by the handler.
 
         >>> trace = []
 
-        >>> def erroneous_action(foo):
+        >>> def erroneous_step(foo):
         ...     raise subprocess.CalledProcessError(1, 'command')
 
         >>> class SubCommandWithErrors(SubCommand):
-        ...     actions = (
-        ...         (action1, 'foo'),
-        ...         (erroneous_action, 'foo'),
-        ...         (action2, 'foo', 'bar'),
+        ...     steps = (
+        ...         (step1, 'foo'),
+        ...         (erroneous_step, 'foo'),
+        ...         (step2, 'foo', 'bar'),
         ...         )
 
         >>> parser = ArgumentParser()
@@ -391,66 +390,66 @@
         >>> str(error)
         "Command 'command' returned non-zero exit status 1"
 
-    The action `action2` is not executed::
+    The step `step2` is not executed::
 
         >>> trace
-        ['action1 received eggs']
+        ['step1 received eggs']
     """
 
-    actions = ()
+    steps = ()
 
     def __init__(self, *args, **kwargs):
-        super(ActionsBasedSubCommand, self).__init__(*args, **kwargs)
-        self._action_names = []
-        self._actions = {}
-        for action_args in self.actions:
-            action, args = action_args[0], action_args[1:]
-            action_name = self._get_action_name(action)
-            self._action_names.append(action_name)
-            self._actions[action_name] = (action, args)
-
-    def _get_action_name(self, action):
-        """Return the string representation of an action callable.
-
-        The name is retrieved using attributes lookup for `action_name`
+        super(StepsBasedSubCommand, self).__init__(*args, **kwargs)
+        self._step_names = []
+        self._steps = {}
+        for step_args in self.steps:
+            step, args = step_args[0], step_args[1:]
+            step_name = self._get_step_name(step)
+            self._step_names.append(step_name)
+            self._steps[step_name] = (step, args)
+
+    def _get_step_name(self, step):
+        """Return the string representation of a step callable.
+
+        The name is retrieved using attributes lookup for `step_name`
         and then `__name__`::
 
-            >>> def action1():
-            ...     pass
-            >>> action1.action_name = 'myaction'
-
-            >>> def action2():
-            ...     pass
-
-            >>> sub_command = ActionsBasedSubCommand('foo')
-            >>> sub_command._get_action_name(action1)
-            'myaction'
-            >>> sub_command._get_action_name(action2)
-            'action2'
+            >>> def step1():
+            ...     pass
+            >>> step1.step_name = 'mystep'
+
+            >>> def step2():
+            ...     pass
+
+            >>> sub_command = StepsBasedSubCommand('foo')
+            >>> sub_command._get_step_name(step1)
+            'mystep'
+            >>> sub_command._get_step_name(step2)
+            'step2'
         """
         try:
-            return action.action_name
+            return step.step_name
         except AttributeError:
-            return action.__name__
+            return step.__name__
 
     def add_arguments(self, parser):
-        super(ActionsBasedSubCommand, self).add_arguments(parser)
+        super(StepsBasedSubCommand, self).add_arguments(parser)
         parser.add_argument(
-            '-a', '--actions', nargs='+', choices=self._action_names,
+            '-s', '--steps', nargs='+', choices=self._step_names,
             help='Call one or more internal functions.')
         parser.add_argument(
-            '--skip-actions', nargs='+', choices=self._action_names,
+            '--skip-steps', nargs='+', choices=self._step_names,
             help='Skip one or more internal functions.')
 
     def handle(self, namespace):
-        skip_actions = namespace.skip_actions or []
-        action_names = filter(
-            lambda action_name: action_name not in skip_actions,
-            namespace.actions or self._action_names)
-        for action_name in action_names:
-            action, arg_names = self._actions[action_name]
+        skip_steps = namespace.skip_steps or []
+        step_names = filter(
+            lambda step_name: step_name not in skip_steps,
+            namespace.steps or self._step_names)
+        for step_name in step_names:
+            step, arg_names = self._steps[step_name]
             args = [getattr(namespace, i) for i in arg_names]
             try:
-                action(*args)
+                step(*args)
             except subprocess.CalledProcessError as err:
                 return err

=== modified file 'lpsetup/subcommands/install.py'
--- lpsetup/subcommands/install.py	2012-03-16 17:40:22 +0000
+++ lpsetup/subcommands/install.py	2012-03-22 11:09:20 +0000
@@ -211,10 +211,10 @@
         file_append(HOSTS_FILE, line)
 
 
-class SubCommand(argparser.ActionsBasedSubCommand):
+class SubCommand(argparser.StepsBasedSubCommand):
     """Install the Launchpad environment."""
 
-    actions = (
+    steps = (
         (initialize,
          'user', 'full_name', 'email', 'lpuser',
          'private_key', 'public_key', 'valid_ssh_keys', 'ssh_key_path',
@@ -283,7 +283,7 @@
                  'given user (see -u argument). '
                  '[DEFAULT={0}]'.format(CHECKOUT_DIR))
         parser.add_argument(
-            '-s', '--ssh-key-name', default=SSH_KEY_NAME,
+            '-S', '--ssh-key-name', default=SSH_KEY_NAME,
             help='{0} [DEFAULT={1}]'.format(
                 self.ssh_key_name_help, SSH_KEY_NAME))
         parser.add_argument(

=== modified file 'lpsetup/subcommands/lxcinstall.py'
--- lpsetup/subcommands/lxcinstall.py	2012-03-16 17:40:22 +0000
+++ lpsetup/subcommands/lxcinstall.py	2012-03-22 11:09:20 +0000
@@ -150,7 +150,7 @@
 class SubCommand(install.SubCommand):
     """Install the Launchpad environment inside an LXC."""
 
-    actions = (
+    steps = (
         (install.initialize,
          'user', 'full_name', 'email', 'lpuser', 'private_key',
          'public_key', 'valid_ssh_keys', 'dependencies_dir', 'directory'),

=== modified file 'lpsetup/subcommands/update.py'
--- lpsetup/subcommands/update.py	2012-03-16 17:40:22 +0000
+++ lpsetup/subcommands/update.py	2012-03-22 11:09:20 +0000
@@ -56,10 +56,10 @@
                 call(cmd, '--parent', dependencies_dir, '--target', branch)
 
 
-class SubCommand(argparser.ActionsBasedSubCommand):
+class SubCommand(argparser.StepsBasedSubCommand):
     """Update the Launchpad environment to latest version."""
 
-    actions = (
+    steps = (
         (update_launchpad,
          'user', 'valid_ssh_keys', 'dependencies_dir', 'directory', 'apt'),
         (link_sourcecode_in_branches,

=== modified file 'lpsetup/tests/examples.py'
--- lpsetup/tests/examples.py	2012-03-15 17:13:37 +0000
+++ lpsetup/tests/examples.py	2012-03-22 11:09:20 +0000
@@ -6,11 +6,11 @@
 
 __metaclass__ = type
 __all__ = [
-    'action1',
-    'action2',
-    'ActionsBasedSubCommand',
-    'ActionsBasedSubCommandWithErrors',
-    'bad_action',
+    'step1',
+    'step2',
+    'StepsBasedSubCommand',
+    'StepsBasedSubCommandWithErrors',
+    'bad_step',
     'SubCommand',
     ]
 
@@ -19,16 +19,16 @@
 from lpsetup import argparser
 
 
-def action1(foo):
-    print 'action1 received ' + foo
-
-
-def action2(foo, bar):
-    print 'action2 received {0} and {1}'.format(foo, bar)
-action2.action_name = 'myaction'
-
-
-def bad_action(foo):
+def step1(foo):
+    print 'step1 received ' + foo
+
+
+def step2(foo, bar):
+    print 'step2 received {0} and {1}'.format(foo, bar)
+step2.step_name = 'mystep'
+
+
+def bad_step(foo):
     raise subprocess.CalledProcessError(1, 'command')
 
 
@@ -45,25 +45,25 @@
         return namespace
 
 
-class ActionsBasedSubCommand(argparser.ActionsBasedSubCommand):
-    """An example action based sub command."""
+class StepsBasedSubCommand(argparser.StepsBasedSubCommand):
+    """An example steps based sub command."""
 
-    actions = (
-        (action1, 'foo'),
-        (action2, 'foo', 'bar'),
+    steps = (
+        (step1, 'foo'),
+        (step2, 'foo', 'bar'),
         )
 
     def add_arguments(self, parser):
-        super(ActionsBasedSubCommand, self).add_arguments(parser)
+        super(StepsBasedSubCommand, self).add_arguments(parser)
         parser.add_argument('--foo')
         parser.add_argument('--bar')
 
 
-class ActionsBasedSubCommandWithErrors(ActionsBasedSubCommand):
-    """An example action based sub command (containing a failing action)."""
+class StepsBasedSubCommandWithErrors(StepsBasedSubCommand):
+    """An example steps based sub command (containing a failing step)."""
 
-    actions = (
-        (action1, 'foo'),
-        (bad_action, 'foo'),
-        (action2, 'foo', 'bar'),
+    steps = (
+        (step1, 'foo'),
+        (bad_step, 'foo'),
+        (step2, 'foo', 'bar'),
         )

=== modified file 'lpsetup/tests/test_argparser.py'
--- lpsetup/tests/test_argparser.py	2012-03-15 17:13:37 +0000
+++ lpsetup/tests/test_argparser.py	2012-03-22 11:09:20 +0000
@@ -143,48 +143,48 @@
         self.assertIn(self.sub_command.help, help)
 
 
-class ActionsBasedSubCommandTest(SubCommandTestMixin, unittest.TestCase):
-
-    sub_command_class = examples.ActionsBasedSubCommand
-
-    def test_actions(self):
-        # Ensure actions are executed in the order they are provided.
+class StepsBasedSubCommandTest(SubCommandTestMixin, unittest.TestCase):
+
+    sub_command_class = examples.StepsBasedSubCommand
+
+    def test_steps(self):
+        # Ensure steps are executed in the order they are provided.
         with capture_output() as output:
             self.parse_and_call_main('--foo eggs --bar spam')
         self.check_output(
-            ['action1 received eggs', 'action2 received eggs and spam'],
+            ['step1 received eggs', 'step2 received eggs and spam'],
             output)
 
-    def test_action_flag(self):
-        # A special argument `-a` or `--actions` is automatically added to the
-        # parser. It can be used to execute only one or a subset of actions.
-        with capture_output() as output:
-            self.parse_and_call_main('--foo eggs -a action1')
-        self.check_output(['action1 received eggs'], output)
-
-    def test_skip_action(self):
-        # A special argument `--skip-actions` is automatically added to the
-        # parser. It can be used to skip one or more actions.
-        with capture_output() as output:
-            self.parse_and_call_main('--foo eggs --skip-actions action1')
-        self.check_output(['action2 received eggs and None'], output)
-
-    def test_action_name(self):
-        # Ensure the string representation of an action i correctly retrieved.
-        method = self.sub_command._get_action_name
-        self.assertEqual('action1', method(examples.action1))
-        self.assertEqual('myaction', method(examples.action2))
-
-
-class ActionsBasedSubCommandWithErrorsTest(
+    def test_step_flag(self):
+        # A special argument `-s` or `--steps` is automatically added to the
+        # parser. It can be used to execute only one or a subset of steps.
+        with capture_output() as output:
+            self.parse_and_call_main('--foo eggs -s step1')
+        self.check_output(['step1 received eggs'], output)
+
+    def test_skip_steps(self):
+        # A special argument `--skip-steps` is automatically added to the
+        # parser. It can be used to skip one or more steps.
+        with capture_output() as output:
+            self.parse_and_call_main('--foo eggs --skip-steps step1')
+        self.check_output(['step2 received eggs and None'], output)
+
+    def test_step_name(self):
+        # Ensure the string representation of a step is correctly retrieved.
+        method = self.sub_command._get_step_name
+        self.assertEqual('step1', method(examples.step1))
+        self.assertEqual('mystep', method(examples.step2))
+
+
+class StepsBasedSubCommandWithErrorsTest(
     SubCommandTestMixin, unittest.TestCase):
 
-    sub_command_class = examples.ActionsBasedSubCommandWithErrors
+    sub_command_class = examples.StepsBasedSubCommandWithErrors
 
-    def test_failing_action(self):
-        # Ensure the actions execution is stopped if an action raises
+    def test_failing_step(self):
+        # Ensure the steps execution is stopped if a step raises
         # `subprocess.CalledProcessError`.
         with capture_output() as output:
             error = self.parse_and_call_main('--foo eggs')
         self.assertEqual(1, error.returncode)
-        self.check_output(['action1 received eggs'], output)
+        self.check_output(['step1 received eggs'], output)