From 3afc739a1ed50ca4447a806e32756c6189d3ed24 Mon Sep 17 00:00:00 2001 From: jpic Date: Sat, 15 Feb 2020 16:09:44 +0100 Subject: [PATCH] Fix basic action outputs --- shlax/actions/base.py | 46 ++++++++++++++++++++++++++++++++---- shlax/contrib/gitlab.py | 16 +++++++++---- shlax/output.py | 52 ++++++++++++++++++++++++++--------------- tests/test_output.py | 4 ++-- 4 files changed, 87 insertions(+), 31 deletions(-) diff --git a/shlax/actions/base.py b/shlax/actions/base.py index 5494389..f8b63bc 100644 --- a/shlax/actions/base.py +++ b/shlax/actions/base.py @@ -8,8 +8,11 @@ from ..exceptions import WrongResult class Action: parent = None contextualize = [] - colorize = { - '[^ ]*([^:]*):': {1: 0}, + regexps = { + r'([\w]+):': '{cyan}\\1{gray}:{reset}', + r'(^|\n)( *)\- ': '\\1\\2{red}-{reset} ', + r'([^ =]+)=': '{blue}\\1{red}={reset} ', + r'=': '{blue}={reset} ', } def __init__(self, *args, **kwargs): @@ -50,6 +53,8 @@ class Action: def sibblings(self, f=None, **filters): + if not self.parent: + return [] return self.actions_filter( [a for a in self.parent.actions if a is not self], f, **filters @@ -87,23 +92,54 @@ class Action: sys.exit(1) def output_factory(self, *args, **kwargs): - kwargs.setdefault('regexps', self.colorize) + kwargs.setdefault('regexps', self.regexps) return Output(*args, **kwargs) async def __call__(self, *args, **kwargs): - self.status = 'running' self.output = self.output_factory(*args, **kwargs) + self.output_start() + self.status = 'running' try: result = await self.call(*args, **kwargs) except WrongResult as e: - print(e) + self.output_fail(e) self.status = 'fail' + result = e.proc.rc else: + self.output_success() if self.status == 'running': self.status = 'success' return result + def output_start(self): + self.output.start(self) + + def output_fail(self, exception=None): + self.output.fail(self, exception) + + def output_success(self): + self.output.success(self) + + def __repr__(self): + return ' '.join([type(self).__name__] + list(self.args) + [ + f'{k}={v}' + for k, v in self.kwargs.items() + ]) + + def colorized(self): + return ' '.join([ + self.output.colors['pink1'] + + type(self).__name__ + + self.output.colors['reset'] + ] + list(self.args) + [ + f'{self.output.colors["blue"]}{k}{self.output.colors["gray"]}={self.output.colors["green2"]}{v}' + for k, v in self.kwargs_output().items() + ] + [self.output.colors['reset']]) + def callable(self): async def cb(*a, **k): return await self(*a, **k) return cb + + def kwargs_output(self): + return self.kwargs diff --git a/shlax/contrib/gitlab.py b/shlax/contrib/gitlab.py index 39337a2..246b223 100644 --- a/shlax/contrib/gitlab.py +++ b/shlax/contrib/gitlab.py @@ -5,11 +5,11 @@ from shlax import * class GitLabCIConfig(Script): async def call(self, *args, write=True, **kwargs): + self.context['definition'] = kwargs await super().call(*args, **kwargs) - self.kwargs = kwargs - for name, definition in self.context.items(): - self.kwargs[name] = definition - output = yaml.dump(self.kwargs) + for name, definition in self.context['definition'].items(): + self.context['definition'][name] = definition + output = yaml.dump(self.context['definition']) self.output(output) if write: with open('.gitlab-ci.yml', 'w+') as f: @@ -18,4 +18,10 @@ class GitLabCIConfig(Script): class Job(Action): async def call(self, *args, **kwargs): - self.context[self.args[0]] = self.kwargs + self.context['definition'][self.args[0]] = self.kwargs + + def output_start(self): + pass + + def output_success(self): + pass diff --git a/shlax/output.py b/shlax/output.py index 7c3ddb4..0a57039 100644 --- a/shlax/output.py +++ b/shlax/output.py @@ -1,18 +1,12 @@ import re import sys +from .colors import colors + class Output: prefixes = dict() - colors = ( - '\x1b[1;36;45m', - '\x1b[1;36;41m', - '\x1b[1;36;40m', - '\x1b[1;37;45m', - '\x1b[1;32m', - '\x1b[1;37;44m', - '\u001b[30;1m', - ) + colors = colors def color(self, code=None): if not code: @@ -55,15 +49,19 @@ class Output: else '' ) + self.highlight(line, highlight) + + self.colors['reset'] ).encode('utf8')) if flush: + self.write(b'\n') self.flush() def cmd(self, line): self( self.colorize(251, '+ ') - + self.highlight(line, 'bash'), + + '\x1b[1;38;5;15;48;5;244m' + + self.highlight(line, 'bash') + + self.colors['reset'], highlight=False ) @@ -84,14 +82,30 @@ class Output: return line for regexp, colors in self.regexps.items(): - match = re.match(regexp, line) - if not match: - continue - - for group, color in colors.items(): - res = match.group(group) - if not res: - continue - line = line.replace(res, self.colorize(color, res)) + line = re.sub(regexp, colors.format(**self.colors), line) return line + + def start(self, action): + self(''.join([ + self.colors['orange'], + '[!] START ', + self.colors['reset'], + action.colorized(), + ])) + + def success(self, action): + self(''.join([ + self.colors['green'], + '[√] SUCCESS ', + self.colors['reset'], + action.colorized(), + ])) + + def fail(self, action, exception=None): + self(''.join([ + self.colors['red'], + '[x] FAIL ', + self.colors['reset'], + action.colorized(), + ])) diff --git a/tests/test_output.py b/tests/test_output.py index 8a6be51..5da9588 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -16,9 +16,9 @@ def write(): def test_output_regexps(write): output = Output( - regexps={'.*': {0: 0}}, + regexps={'^(.*)$': '{red}\\1'}, write=write, flush=lambda: None, ) output('foo') - assert write.output == output.colorize(0, 'foo') + assert write.output.strip() == output.colors['red'] + 'foo' + output.colors['reset']