Example #1
0
 def _call_objs(self, contextualized):
     # Setup
     pre_body, post_body = Mock(), Mock()
     t1 = Task(pre_body, contextualized=contextualized)
     t2 = Task(post_body, contextualized=contextualized)
     t3 = Task(Mock(),
         pre=[call(t1, 5, foo='bar')],
         post=[call(t2, 7, biz='baz')],
     )
     c = Collection(t1=t1, t2=t2, t3=t3)
     e = Executor(collection=c)
     e.execute('t3')
     # Pre-task asserts
     args, kwargs = pre_body.call_args
     eq_(kwargs, {'foo': 'bar'})
     if contextualized:
         assert isinstance(args[0], Context)
         eq_(args[1], 5)
     else:
         eq_(args, (5,))
     # Post-task asserts
     args, kwargs = post_body.call_args
     eq_(kwargs, {'biz': 'baz'})
     if contextualized:
         assert isinstance(args[0], Context)
         eq_(args[1], 7)
     else:
         eq_(args, (7,))
Example #2
0
 def _call_objs(self, contextualized):
     # Setup
     pre_body, post_body = Mock(), Mock()
     t1 = Task(pre_body, contextualized=contextualized)
     t2 = Task(post_body, contextualized=contextualized)
     t3 = Task(
         Mock(),
         pre=[call(t1, 5, foo='bar')],
         post=[call(t2, 7, biz='baz')],
     )
     c = Collection(t1=t1, t2=t2, t3=t3)
     e = Executor(collection=c)
     e.execute('t3')
     # Pre-task asserts
     args, kwargs = pre_body.call_args
     eq_(kwargs, {'foo': 'bar'})
     if contextualized:
         assert isinstance(args[0], Context)
         eq_(args[1], 5)
     else:
         eq_(args, (5, ))
     # Post-task asserts
     args, kwargs = post_body.call_args
     eq_(kwargs, {'biz': 'baz'})
     if contextualized:
         assert isinstance(args[0], Context)
         eq_(args[1], 7)
     else:
         eq_(args, (7, ))
Example #3
0
class Executor_(Spec):
    def setup(self):
        self.task1 = Task(Mock())
        self.task2 = Task(Mock(), pre=['task1'])
        self.task3 = Task(Mock(), pre=['task1'])
        coll = Collection()
        coll.add_task(self.task1, name='task1')
        coll.add_task(self.task2, name='task2')
        coll.add_task(self.task3, name='task3')
        self.executor = Executor(coll)
        self.coll = coll

    def base_case(self):
        self.executor.execute('task1')
        assert self.task1.body.called

    def kwargs(self):
        k = {'foo': 'bar'}
        self.executor.execute(name='task1', kwargs=k)
        self.task1.body.assert_called_once_with(**k)

    def pre_tasks(self):
        self.executor.execute(name='task2')
        eq_(self.task1.body.call_count, 1)

    def enabled_deduping(self):
        self.executor.execute(name='task2')
        self.executor.execute(name='task3')
        eq_(self.task1.body.call_count, 1)

    def disabled_deduping(self):
        self.executor.execute(name='task2', dedupe=False)
        self.executor.execute(name='task3', dedupe=False)
        eq_(self.task1.body.call_count, 2)
Example #4
0
 def default_tasks_called_when_no_tasks_specified(self):
     # NOTE: when no tasks AND no default, Program will print global
     # help. We just won't do anything at all, which is fine for now.
     task = Task(Mock('default-task'))
     coll = Collection()
     coll.add_task(task, name='mytask', default=True)
     executor = Executor(collection=coll)
     executor.execute()
     task.body.assert_called_with()
Example #5
0
 def calls_default_to_empty_args_always(self):
     pre_body, post_body = Mock(), Mock()
     t1 = Task(pre_body)
     t2 = Task(post_body)
     t3 = Task(Mock(), pre=[t1], post=[t2])
     e = Executor(collection=Collection(t1=t1, t2=t2, t3=t3))
     e.execute(('t3', {'something': 'meh'}))
     for body in (pre_body, post_body):
         eq_(body.call_args, tuple())
Example #6
0
 def default_tasks_called_when_no_tasks_specified(self):
     # NOTE: when no tasks AND no default, Program will print global
     # help. We just won't do anything at all, which is fine for now.
     task = Task(Mock('default-task'))
     coll = Collection()
     coll.add_task(task, name='mytask', default=True)
     executor = Executor(collection=coll)
     executor.execute()
     task.body.assert_called_with()
Example #7
0
 def calls_default_to_empty_args_always(self):
     pre_body, post_body = Mock(), Mock()
     t1 = Task(pre_body)
     t2 = Task(post_body)
     t3 = Task(Mock(), pre=[t1], post=[t2])
     e = Executor(collection=Collection(t1=t1, t2=t2, t3=t3))
     e.execute(('t3', {'something': 'meh'}))
     for body in (pre_body, post_body):
         eq_(body.call_args, tuple())
Example #8
0
 def deduping_treats_different_calls_to_same_task_differently(self):
     body = Mock()
     t1 = Task(body)
     pre = [call(t1, 5), call(t1, 7), call(t1, 5)]
     t2 = Task(Mock(), pre=pre)
     c = Collection(t1=t1, t2=t2)
     e = Executor(collection=c)
     e.execute('t2')
     # Does not call the second t1(5)
     body.assert_has_calls([mock_call(5), mock_call(7)])
Example #9
0
 def deduping_treats_different_calls_to_same_task_differently(self):
     body = Mock()
     t1 = Task(body)
     pre = [call(t1, 5), call(t1, 7), call(t1, 5)]
     t2 = Task(Mock(), pre=pre)
     c = Collection(t1=t1, t2=t2)
     e = Executor(collection=c)
     e.execute('t2')
     # Does not call the second t1(5)
     body.assert_has_calls([mock_call(5), mock_call(7)])
Example #10
0
def execute_cleanup_tasks(ctx, cleanup_tasks, dry_run=False):
    """Execute several cleanup tasks as part of the cleanup.

    :param ctx:             Context object for the tasks.
    :param cleanup_tasks:   Collection of cleanup tasks (as Collection).
    :param dry_run:         Indicates dry-run mode (bool)
    """
    executor = Executor(cleanup_tasks, ctx.config)
    for cleanup_task in cleanup_tasks.tasks:
        print("CLEANUP TASK: %s" % cleanup_task)
        executor.execute((cleanup_task, dict(dry_run=dry_run)))
Example #11
0
def execute_cleanup_tasks(ctx, cleanup_tasks, dry_run=False):
    """Execute several cleanup tasks as part of the cleanup.

    REQUIRES: ``clean(ctx, dry_run=False)`` signature in cleanup tasks.

    :param ctx:             Context object for the tasks.
    :param cleanup_tasks:   Collection of cleanup tasks (as Collection).
    :param dry_run:         Indicates dry-run mode (bool)
    """
    executor = Executor(cleanup_tasks, ctx.config)
    for cleanup_task in cleanup_tasks.tasks:
        print("CLEANUP TASK: %s" % cleanup_task)
        executor.execute((cleanup_task, dict(dry_run=dry_run)))
Example #12
0
 def hands_task_specific_configuration_to_context(self):
     @ctask
     def mytask(ctx):
         eq_(ctx['my.config.key'], 'value')
     @ctask
     def othertask(ctx):
         eq_(ctx['my.config.key'], 'othervalue')
     inner1 = Collection('inner1', mytask)
     inner1.configure({'my.config.key': 'value'})
     inner2 = Collection('inner2', othertask)
     inner2.configure({'my.config.key': 'othervalue'})
     c = Collection(inner1, inner2)
     e = Executor(collection=c, context=Context())
     e.execute('inner1.mytask', 'inner2.othertask')
Example #13
0
def execute_cleanup_tasks(ctx, cleanup_tasks, dry_run=False):
    """Execute several cleanup tasks as part of the cleanup.

    REQUIRES: ``clean(ctx, dry_run=False)`` signature in cleanup tasks.

    :param ctx:             Context object for the tasks.
    :param cleanup_tasks:   Collection of cleanup tasks (as Collection).
    :param dry_run:         Indicates dry-run mode (bool)
    """
    # pylint: disable=redefined-outer-name
    executor = Executor(cleanup_tasks, ctx.config)
    for cleanup_task in cleanup_tasks.tasks:
        print("CLEANUP TASK: %s" % cleanup_task)
        executor.execute((cleanup_task, dict(dry_run=dry_run)))
Example #14
0
 def hands_task_specific_configuration_to_context(self):
     @ctask
     def mytask(ctx):
         eq_(ctx.my_key, 'value')
     @ctask
     def othertask(ctx):
         eq_(ctx.my_key, 'othervalue')
     inner1 = Collection('inner1', mytask)
     inner1.configure({'my_key': 'value'})
     inner2 = Collection('inner2', othertask)
     inner2.configure({'my_key': 'othervalue'})
     c = Collection(inner1, inner2)
     e = Executor(collection=c)
     e.execute('inner1.mytask', 'inner2.othertask')
Example #15
0
 def hands_collection_configuration_to_context(self):
     @ctask
     def mytask(ctx):
         eq_(ctx['my.config.key'], 'value')
     c = Collection(mytask)
     c.configure({'my.config.key': 'value'})
     Executor(collection=c, context=Context()).execute('mytask')
Example #16
0
def invoke_execute(context, command_name, **kwargs):
    """
    执行Invoke Task的帮助函数
    """
    results = Executor(namespace, config=context.config).execute((command_name, kwargs))
    target_task = context.root_namespace[command_name]
    return results[target_task]
Example #17
0
def invoke_execute(context, command_name, **kwargs):
    """
    Helper function to make invoke-tasks execution easier.
    """
    results = Executor(namespace, config=context.config).execute((command_name, kwargs))
    target_task = context.root_namespace[command_name]
    return results[target_task]
Example #18
0
 def run(self):
     """Override Process method"""
     self.configure_logging()
     from tasks import ns
     rc = 1
     try:
         with self._std_streams as (out, err):
             self._task_kwargs.update({'stdout': out, 'stderr': err})
             _result = Executor(ns).execute(
                 (self._task_name, self._task_kwargs))
         # result: {<Task 'task_to_build_doc'>: 0}
         rc = list(_result.values())[0]
     except Exception as e:
         self._root_logger.error('Task %s failed with traceback:\n' %
                                 self._task_name + traceback.format_exc())
     finally:
         exit(0) if rc is None else exit(rc)
Example #19
0
 def setup(self):
     self.task1 = Task(Mock(return_value=7))
     self.task2 = Task(Mock(return_value=10), pre=['task1'])
     self.task3 = Task(Mock(), pre=['task1'])
     coll = Collection()
     coll.add_task(self.task1, name='task1')
     coll.add_task(self.task2, name='task2')
     coll.add_task(self.task3, name='task3')
     self.executor = Executor(collection=coll, context=Context())
Example #20
0
def unit_test(ctx, version="3", setup=False):  # pylint: disable=redefined-outer-name
    """ Run unit tests for the desired python version """
    if setup:
        Executor(ns).execute(("setup", {
            "version": version,
            "skip_lock": True
        }))
    ctx.run(
        "pipenv run pytest --cov-report term-missing --cov=pycodeflow tests/")
Example #21
0
 def setup(self):
     self.task1 = Task(Mock())
     self.task2 = Task(Mock(), pre=['task1'])
     self.task3 = Task(Mock(), pre=['task1'])
     coll = Collection()
     coll.add_task(self.task1, name='task1')
     coll.add_task(self.task2, name='task2')
     coll.add_task(self.task3, name='task3')
     self.executor = Executor(coll)
     self.coll = coll
Example #22
0
 def subcollection_config_works_with_default_tasks(self):
     @ctask(default=True)
     def mytask(ctx):
         eq_(ctx['my.config.key'], 'value')
     # Sets up a task "known as" sub.mytask which may be called as just
     # 'sub' due to being default.
     sub = Collection('sub', mytask=mytask)
     sub.configure({'my.config.key': 'value'})
     main = Collection(sub=sub)
     # Execute via collection default 'task' name.
     Executor(collection=main, context=Context()).execute('sub')
Example #23
0
def execute_cleanup_tasks(ctx, cleanup_tasks):
    """Execute several cleanup tasks as part of the cleanup.

    :param ctx:             Context object for the tasks.
    :param cleanup_tasks:   Collection of cleanup tasks (as Collection).
    """
    # pylint: disable=redefined-outer-name
    executor = Executor(cleanup_tasks, ctx.config)
    failure_count = 0
    for cleanup_task in cleanup_tasks.tasks:
        try:
            print("CLEANUP TASK: %s" % cleanup_task)
            executor.execute(cleanup_task)
        except (Exit, Failure, UnexpectedExit) as e:
            print(e)
            print("FAILURE in CLEANUP TASK: %s (GRACEFULLY-IGNORED)" %
                  cleanup_task)
            failure_count += 1

    if failure_count:
        print("CLEANUP TASKS: %d failure(s) occured" % failure_count)
Example #24
0
 def setup(self):
     s = super(Executor_, self)
     s.setup()
     self.task1 = Task(Mock(return_value=7))
     self.task2 = Task(Mock(return_value=10), pre=[self.task1])
     self.task3 = Task(Mock(), pre=[self.task1])
     self.task4 = Task(Mock(return_value=15), post=[self.task1])
     coll = Collection()
     coll.add_task(self.task1, name='task1')
     coll.add_task(self.task2, name='task2')
     coll.add_task(self.task3, name='task3')
     coll.add_task(self.task4, name='task4')
     self.executor = Executor(collection=coll)
Example #25
0
def execute_cleanup_tasks(ctx, cleanup_tasks, dry_run=False):
    """Execute several cleanup tasks as part of the cleanup.

    REQUIRES: ``clean(ctx, dry_run=False)`` signature in cleanup tasks.

    :param ctx:             Context object for the tasks.
    :param cleanup_tasks:   Collection of cleanup tasks (as Collection).
    :param dry_run:         Indicates dry-run mode (bool)
    """
    # pylint: disable=redefined-outer-name
    executor = Executor(cleanup_tasks, ctx.config)
    failure_count = 0
    for cleanup_task in cleanup_tasks.tasks:
        try:
            print("CLEANUP TASK: %s" % cleanup_task)
            executor.execute((cleanup_task, dict(dry_run=dry_run)))
        except (Exit, Failure, UnexpectedExit) as e:
            print("FAILURE in CLEANUP TASK: %s (GRACEFULLY-IGNORED)" % cleanup_task)
            failure_count += 1

    if failure_count:
        print("CLEANUP TASKS: %d failure(s) occured" % failure_count)
Example #26
0
def execute_cleanup_tasks(ctx, cleanup_tasks, dry_run=False):
    """Execute several cleanup tasks as part of the cleanup.

    REQUIRES: ``clean(ctx, dry_run=False)`` signature in cleanup tasks.

    :param ctx:             Context object for the tasks.
    :param cleanup_tasks:   Collection of cleanup tasks (as Collection).
    :param dry_run:         Indicates dry-run mode (bool)
    """
    # pylint: disable=redefined-outer-name
    executor = Executor(cleanup_tasks, ctx.config)
    failure_count = 0
    for cleanup_task in cleanup_tasks.tasks:
        try:
            print("CLEANUP TASK: %s" % cleanup_task)
            executor.execute((cleanup_task, dict(dry_run=dry_run)))
        except (Exit, Failure, UnexpectedExit) as e:
            print("FAILURE in CLEANUP TASK: %s (GRACEFULLY-IGNORED)" %
                  cleanup_task)
            failure_count += 1

    if failure_count:
        print("CLEANUP TASKS: %d failure(s) occured" % failure_count)
Example #27
0
    c.run(f"git stash push -q --keep-index")


@task
def stage_changes(c):
    """
    Stage the newly changed files only.
    Only works in a pre-commit context.
    """
    c.run(f"git add -u")


# Until invoke has proper support for prgramatic accsess
# see https://github.com/pyinvoke/invoke/issues/170 for details
namespace = Collection(stash_changes, stage_changes, format, check, test)
namespace.configure({"root_namespace": namespace})
executor = Executor(namespace)

try:
    executor.execute("stash_changes")  # will be deleted in post-commit on success
    executor.execute("format")
    executor.execute("check")
    executor.execute("test")
    executor.execute("stage_changes")
except UnexpectedExit:
    print("\n\n[ERROR]] Pre-commit hook failed, commit aborted!")
    print("[ERROR]] Working directory contains files potentially changed by pre-commit hook")
    print("[ERROR]] Unaltered changes can be found in latest stash: 'git stash list'")
    print("[ERROR]] Cleanup of he stashes may be needed after failure")
    exit(1)
Example #28
0
 def uses_blank_config_by_default(self):
     e = Executor(collection=Collection())
     assert isinstance(e.config, Config)
Example #29
0
 def allows_collection_and_config(self):
     coll = Collection()
     conf = Config()
     e = Executor(collection=coll, config=conf)
     assert e.collection is coll
     assert e.config is conf
Example #30
0
 def needs_collection_and_context(self):
     coll = Collection()
     cont = Context()
     e = Executor(collection=coll, context=cont)
     assert e.collection is coll
     assert e.context is cont