Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement --show-action command line argument #392

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions doit/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import inspect
from pathlib import PurePath
from threading import Thread
from typing import Union
import pdb

from .exceptions import InvalidTask, TaskFailed, TaskError
Expand All @@ -27,6 +28,9 @@ class BaseAction(object):
# must implement:
# def execute(self, out=None, err=None)

# must implement:
# def title(self)

@staticmethod
def _prepare_kwargs(task, func, args, kwargs):
"""
Expand Down Expand Up @@ -153,6 +157,15 @@ def action(self):
kwargs = self._prepare_kwargs(self.task, ref, args, kw)
return ref(*args, **kwargs)

def title(self) -> Union[str, TaskError]:
try:
action = self.expand_action()
except Exception as exc:
return TaskError(
"CmdAction Error creating command string", exc)
assert isinstance(action, str)
return action


def _print_process_output(self, process, input_, capture, realtime):
"""Reads 'input_' until process is terminated.
Expand Down Expand Up @@ -396,6 +409,9 @@ def __init__(self, py_callable, args=None, kwargs=None, task=None):
msg = "%r kwargs must be a 'dict'. got '%s'"
raise InvalidTask(msg % (self.task, self.kwargs))

def title(self) -> str:
return f"{self.py_callable.__name__}(*{self.args}, **{self._prepare_kwargs()})"


def _prepare_kwargs(self):
return BaseAction._prepare_kwargs(self.task, self.py_callable,
Expand Down
8 changes: 7 additions & 1 deletion doit/reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def __init__(self, outstream, options):
self.failures = []
self.runtime_errors = []
self.failure_verbosity = options.get('failure_verbosity', 0)
self.show_action = options.get('show_action', False)
self.outstream = outstream

def write(self, text):
Expand All @@ -42,6 +43,11 @@ def execute_task(self, task):
if task.actions and (task.name[0] != '_'):
self.write('. %s\n' % task.title())

def execute_action(self, action):
"""called before executing each action"""
if self.show_action:
self.write(' + %s\n' % action.title())

def add_failure(self, task, exception):
"""called when execution finishes with a failure"""
result = {'task': task, 'exception':exception}
Expand Down Expand Up @@ -137,7 +143,7 @@ def _just_pass(self, *args):
"""over-write base to do nothing"""
pass

get_status = execute_task = add_failure = add_success \
get_status = execute_task = execute_action = add_failure = add_success \
= skip_uptodate = skip_ignore = teardown_task = complete_run \
= _just_pass

Expand Down
4 changes: 2 additions & 2 deletions doit/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def execute_task(self, task):

# finally execute it!
self.reporter.execute_task(task)
return task.execute(self.stream)
return task.execute(self.stream, self.reporter)


def process_task_result(self, node, catched_excp):
Expand Down Expand Up @@ -227,7 +227,7 @@ def teardown(self):
"""run teardown from all tasks"""
for task in reversed(self.teardown_list):
self.reporter.teardown_task(task)
catched = task.execute_teardown(self.stream)
catched = task.execute_teardown(self.stream, self.reporter)
if catched:
msg = "ERROR: task '%s' teardown action" % task.name
error = SetupError(msg, catched)
Expand Down
11 changes: 8 additions & 3 deletions doit/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@

from .cmdparse import CmdOption, TaskParse
from .exceptions import CatchedException, InvalidTask
from .action import create_action, PythonAction
from .action import create_action, BaseAction, PythonAction
from .dependency import UptodateCalculator
from .reporter import ConsoleReporter


def first_line(doc):
Expand Down Expand Up @@ -449,27 +450,31 @@ def save_extra_values(self):
def overwrite_verbosity(self, stream):
self.verbosity = stream.effective_verbosity(self.verbosity)

def execute(self, stream):
def execute(self, stream, reporter=None):
"""Executes the task.
@return failure: see CmdAction.execute
"""
self.executed = True
self.init_options()
task_stdout, task_stderr = stream._get_out_err(self.verbosity)
for action in self.actions:
if isinstance(action, BaseAction) and isinstance(reporter, ConsoleReporter):
reporter.execute_action(action)
action_return = action.execute(task_stdout, task_stderr)
if isinstance(action_return, CatchedException):
return action_return
self.result = action.result
self.values.update(action.values)


def execute_teardown(self, stream):
def execute_teardown(self, stream, reporter=None):
"""Executes task's teardown
@return failure: see CmdAction.execute
"""
task_stdout, task_stderr = stream._get_out_err(self.verbosity)
for action in self.teardown:
if isinstance(action, BaseAction) and isinstance(reporter, ConsoleReporter):
reporter.execute_action(action)
action_return = action.execute(task_stdout, task_stderr)
if isinstance(action_return, CatchedException):
return action_return
Expand Down
10 changes: 10 additions & 0 deletions tests/test_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ def test_values(self):
my_action.execute()
assert {} == my_action.values

def test_title(self):
cmd = "%s 1 2" % PROGRAM
my_action = action.CmdAction(cmd)
assert cmd == my_action.title()


class TestCmdActionParams(object):
def test_invalid_param_stdout(self):
Expand Down Expand Up @@ -596,6 +601,11 @@ def vvv(): return {'x': 5, 'y':10}
my_action.execute()
assert {'x': 5, 'y':10} == my_action.values

def test_title(self):
my_action = action.PythonAction(self._func_par,args=(2,2),
kwargs={'par3':25})
assert "_func_par(*(2, 2), **{'par3': 25})" == my_action.title()


class TestPythonVerbosity(object):
def write_stderr(self):
Expand Down
18 changes: 18 additions & 0 deletions tests/test_reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
from io import StringIO

from doit import reporter
from doit.action import BaseAction
from doit.task import Stream, Task
from doit.exceptions import CatchedException

import pytest


class TestConsoleReporter(object):

Expand All @@ -28,6 +31,21 @@ def do_nothing():pass
rep.execute_task(t1)
assert ". with_action\n" == rep.outstream.getvalue()

@pytest.mark.parametrize(
"options,expected",
[
({}, ""),
({"show_action": True}, " + action_title\n"),
({"show_action": False}, ""),
],
)
def test_executeAction(self, options, expected):
rep = reporter.ConsoleReporter(StringIO(), options)
a1 = BaseAction()
a1.title = lambda: "action_title"
rep.execute_action(a1)
assert expected == rep.outstream.getvalue()

def test_executeTask_unicode(self):
rep = reporter.ConsoleReporter(StringIO(), {})
def do_nothing():pass
Expand Down
21 changes: 21 additions & 0 deletions tests/test_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from doit.exceptions import TaskError
from doit.exceptions import CatchedException
from doit import action
from doit import reporter
from doit import task
from doit.task import Stream

Expand Down Expand Up @@ -392,6 +393,26 @@ def my_raise():
assert isinstance(got, CatchedException)


def py_fn(x):
pass

@pytest.mark.parametrize(
"t",
[
task.Task("t1", [(py_fn, [1]), (py_fn, [2])]),
task.Task("t1", [], teardown=[(py_fn, [1]), (py_fn, [2])]),
],
)
@pytest.mark.parametrize(
"show_action,expected",
[(False, ""), (True, " + py_fn(*[1], **{})\n + py_fn(*[2], **{})\n")],
)
def test_show_action(t, show_action, expected):
rep = reporter.ConsoleReporter(StringIO(), {"show_action": show_action})
t.execute(Stream(0), rep)
t.execute_teardown(Stream(0), rep)
assert expected == rep.outstream.getvalue()

class TestTaskClean(object):

@pytest.fixture
Expand Down