Refactor output and call
Each action has its own output from now on.
This commit is contained in:
parent
b703ed379e
commit
984f09d704
@ -8,3 +8,7 @@ repos:
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- repo: https://yourlabs.io/oss/shlax
|
||||
rev: master
|
||||
hooks:
|
||||
- id: shlaxfile-gitlabci
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
- id: shlaxfile-gitlabci
|
||||
name: Check for added large files
|
||||
name: Regenerate .gitlab-ci.yml
|
||||
description: Regenerate gitlabci
|
||||
entry: ./shlaxfile.py gitlabci
|
||||
entry: pip install -e . && ./shlaxfile.py gitlabci
|
||||
language: python
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
from .actions import *
|
||||
from .image import Image
|
||||
from .strategies import *
|
||||
from .proc import output, Proc
|
||||
from .proc import Proc
|
||||
from .targets import *
|
||||
from .shlaxfile import Shlaxfile
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import inspect
|
||||
import sys
|
||||
|
||||
from ..output import Output
|
||||
from ..exceptions import WrongResult
|
||||
|
||||
|
||||
class Action:
|
||||
parent = None
|
||||
@ -76,6 +79,22 @@ class Action:
|
||||
return getattr(a, name)
|
||||
raise AttributeError(name)
|
||||
|
||||
async def __call__(self, *args, **kwargs):
|
||||
print(f'{self}.__call__(*args, **kwargs) not implemented')
|
||||
async def call(self, *args, **kwargs):
|
||||
print(f'{self}.call(*args, **kwargs) not implemented')
|
||||
sys.exit(1)
|
||||
|
||||
def output_factory(self, *args, **kwargs):
|
||||
return Output(*args, kwargs)
|
||||
|
||||
async def __call__(self, *args, **kwargs):
|
||||
self.status = 'running'
|
||||
self.output = self.output_factory(*args, **kwargs)
|
||||
try:
|
||||
result = await self.call(*args, **kwargs)
|
||||
except WrongResult as e:
|
||||
print(e)
|
||||
self.status = 'fail'
|
||||
else:
|
||||
if self.status == 'running':
|
||||
self.status = 'success'
|
||||
return result
|
||||
|
||||
@ -50,7 +50,7 @@ class Commit(Action):
|
||||
if not self.tags:
|
||||
self.tags = ['latest']
|
||||
|
||||
async def __call__(self, *args, ctr=None, **kwargs):
|
||||
async def call(self, *args, ctr=None, **kwargs):
|
||||
self.sha = (await self.parent.parent.exec(
|
||||
'buildah',
|
||||
'commit',
|
||||
|
||||
@ -104,7 +104,7 @@ class Packages(Action):
|
||||
print(f'{self.container.name} | Waiting for update ...')
|
||||
await asyncio.sleep(1)
|
||||
|
||||
async def __call__(self, *args, **kwargs):
|
||||
async def call(self, *args, **kwargs):
|
||||
cached = getattr(self, '_pagkages_mgr', None)
|
||||
if cached:
|
||||
self.mgr = cached
|
||||
|
||||
@ -2,5 +2,5 @@ from .base import Action
|
||||
|
||||
|
||||
class Run(Action):
|
||||
async def __call__(self, *args, **kwargs):
|
||||
async def call(self, *args, **kwargs):
|
||||
return (await self.exec(*self.args, **self.kwargs))
|
||||
|
||||
@ -9,7 +9,7 @@ class Service(Action):
|
||||
self.names = names
|
||||
super().__init__()
|
||||
|
||||
async def __call__(self, *args, **kwargs):
|
||||
async def call(self, *args, **kwargs):
|
||||
return asyncio.gather(*[
|
||||
self.exec('systemctl', 'start', name, user='root')
|
||||
for name in self.names
|
||||
|
||||
@ -112,7 +112,7 @@ async def test(*args, **kwargs):
|
||||
|
||||
|
||||
class ConsoleScript(cli2.ConsoleScript):
|
||||
def __call__(self, *args, **kwargs):
|
||||
def call(self, *args, **kwargs):
|
||||
self.shlaxfile = None
|
||||
shlaxfile = sys.argv.pop(1) if len(sys.argv) > 1 else ''
|
||||
if os.path.exists(shlaxfile.split('::')[0]):
|
||||
|
||||
@ -4,7 +4,7 @@ from shlax import *
|
||||
|
||||
|
||||
class GitLabCIConfig(Script):
|
||||
async def __call__(self, *args, write=True, **kwargs):
|
||||
async def call(self, *args, write=True, **kwargs):
|
||||
await super().__call__(*args, **kwargs)
|
||||
self.kwargs = kwargs
|
||||
for name, definition in self.context.items():
|
||||
@ -17,5 +17,5 @@ class GitLabCIConfig(Script):
|
||||
|
||||
|
||||
class Job(Action):
|
||||
async def __call__(self, *args, **kwargs):
|
||||
async def call(self, *args, **kwargs):
|
||||
self.context[self.args[0]] = self.kwargs
|
||||
|
||||
76
shlax/output.py
Normal file
76
shlax/output.py
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
|
||||
class Output:
|
||||
colors = (
|
||||
'\x1b[1;36;45m',
|
||||
'\x1b[1;36;41m',
|
||||
'\x1b[1;36;40m',
|
||||
'\x1b[1;37;45m',
|
||||
'\x1b[1;32m',
|
||||
'\x1b[1;37;44m',
|
||||
)
|
||||
|
||||
def __init__(self, prefix=None):
|
||||
self.prefix = prefix
|
||||
self.prefixes = dict()
|
||||
self.prefix_length = 0
|
||||
|
||||
def call(self, line, prefix, highlight=True, flush=True):
|
||||
if prefix and prefix not in self.prefixes:
|
||||
self.prefixes[prefix] = (
|
||||
self.colors[len([*self.prefixes.keys()]) - 1]
|
||||
)
|
||||
if len(prefix) > self.prefix_length:
|
||||
self.prefix_length = len(prefix)
|
||||
|
||||
prefix_color = self.prefixes[prefix] if prefix else ''
|
||||
prefix_padding = '.' * (self.prefix_length - len(prefix) - 2) if prefix else ''
|
||||
if prefix_padding:
|
||||
prefix_padding = ' ' + prefix_padding + ' '
|
||||
|
||||
sys.stdout.buffer.write((
|
||||
(
|
||||
prefix_color
|
||||
+ prefix_padding
|
||||
+ prefix
|
||||
+ ' '
|
||||
+ Back.RESET
|
||||
+ Style.RESET_ALL
|
||||
+ Fore.LIGHTBLACK_EX
|
||||
+ '| '
|
||||
+ Style.RESET_ALL
|
||||
if prefix
|
||||
else ''
|
||||
)
|
||||
+ self.highlight(line, highlight)
|
||||
).encode('utf8'))
|
||||
|
||||
if flush:
|
||||
sys.stdout.flush()
|
||||
|
||||
def cmd(self, line, prefix):
|
||||
self(
|
||||
Fore.LIGHTBLACK_EX
|
||||
+ '+ '
|
||||
+ Style.RESET_ALL
|
||||
+ self.highlight(line, 'bash'),
|
||||
prefix,
|
||||
highlight=False
|
||||
)
|
||||
|
||||
def print(self, content):
|
||||
self(
|
||||
content,
|
||||
prefix=None,
|
||||
highlight=False
|
||||
)
|
||||
|
||||
def highlight(self, line, highlight=True):
|
||||
line = line.decode('utf8') if isinstance(line, bytes) else line
|
||||
if not highlight or (
|
||||
'\x1b[' in line
|
||||
or '\033[' in line
|
||||
or '\\e[' in line
|
||||
):
|
||||
return line
|
||||
return line
|
||||
@ -3,99 +3,12 @@ Asynchronous process execution wrapper.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from colorama import Fore, Back, Style
|
||||
import os
|
||||
import shlex
|
||||
import sys
|
||||
|
||||
from .exceptions import WrongResult
|
||||
import pygments
|
||||
from pygments import lexers
|
||||
from pygments.formatters import TerminalFormatter
|
||||
from pygments.formatters import Terminal256Formatter
|
||||
|
||||
|
||||
class Output:
|
||||
colors = (
|
||||
'\x1b[1;36;45m',
|
||||
'\x1b[1;36;41m',
|
||||
'\x1b[1;36;40m',
|
||||
'\x1b[1;37;45m',
|
||||
'\x1b[1;32m',
|
||||
'\x1b[1;37;44m',
|
||||
)
|
||||
def __init__(self):
|
||||
self.prefixes = dict()
|
||||
self.prefix_length = 0
|
||||
|
||||
def __call__(self, line, prefix, highlight=True, flush=True):
|
||||
if prefix and prefix not in self.prefixes:
|
||||
self.prefixes[prefix] = (
|
||||
self.colors[len([*self.prefixes.keys()]) - 1]
|
||||
)
|
||||
if len(prefix) > self.prefix_length:
|
||||
self.prefix_length = len(prefix)
|
||||
|
||||
prefix_color = self.prefixes[prefix] if prefix else ''
|
||||
prefix_padding = '.' * (self.prefix_length - len(prefix) - 2) if prefix else ''
|
||||
if prefix_padding:
|
||||
prefix_padding = ' ' + prefix_padding + ' '
|
||||
|
||||
sys.stdout.buffer.write((
|
||||
(
|
||||
prefix_color
|
||||
+ prefix_padding
|
||||
+ prefix
|
||||
+ ' '
|
||||
+ Back.RESET
|
||||
+ Style.RESET_ALL
|
||||
+ Fore.LIGHTBLACK_EX
|
||||
+ '| '
|
||||
+ Style.RESET_ALL
|
||||
if prefix
|
||||
else ''
|
||||
)
|
||||
+ self.highlight(line, highlight)
|
||||
).encode('utf8'))
|
||||
|
||||
if flush:
|
||||
sys.stdout.flush()
|
||||
|
||||
def cmd(self, line, prefix):
|
||||
self(
|
||||
Fore.LIGHTBLACK_EX
|
||||
+ '+ '
|
||||
+ Style.RESET_ALL
|
||||
+ self.highlight(line, 'bash'),
|
||||
prefix,
|
||||
highlight=False
|
||||
)
|
||||
|
||||
def print(self, content):
|
||||
self(
|
||||
content,
|
||||
prefix=None,
|
||||
highlight=False
|
||||
)
|
||||
|
||||
def highlight(self, line, highlight=True):
|
||||
line = line.decode('utf8') if isinstance(line, bytes) else line
|
||||
if not highlight or (
|
||||
'\x1b[' in line
|
||||
or '\033[' in line
|
||||
or '\\e[' in line
|
||||
):
|
||||
return line
|
||||
elif isinstance(highlight, str):
|
||||
lexer = lexers.get_lexer_by_name(highlight)
|
||||
else:
|
||||
lexer = lexers.get_lexer_by_name('python')
|
||||
formatter = Terminal256Formatter(
|
||||
style=os.getenv('PODCTL_STYLE', 'fruity'))
|
||||
return pygments.highlight(line, lexer, formatter)
|
||||
|
||||
|
||||
output = Output()
|
||||
from .output import Output
|
||||
|
||||
|
||||
class PrefixStreamProtocol(asyncio.subprocess.SubprocessStreamProtocol):
|
||||
@ -104,14 +17,13 @@ class PrefixStreamProtocol(asyncio.subprocess.SubprocessStreamProtocol):
|
||||
make asynchronous output readable.
|
||||
"""
|
||||
|
||||
def __init__(self, prefix, *args, **kwargs):
|
||||
self.debug = kwargs.get('debug', True)
|
||||
self.prefix = prefix
|
||||
def __init__(self, output, *args, **kwargs):
|
||||
self.output = output
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def pipe_data_received(self, fd, data):
|
||||
if (self.debug is True or 'out' in str(self.debug)) and fd in (1, 2):
|
||||
output(data, self.prefix, flush=False)
|
||||
self.output(data, flush=False)
|
||||
sys.stdout.flush()
|
||||
super().pipe_data_received(fd, data)
|
||||
|
||||
@ -142,8 +54,9 @@ class Proc:
|
||||
"""
|
||||
test = False
|
||||
|
||||
def __init__(self, *args, prefix=None, raises=True, debug=True):
|
||||
def __init__(self, *args, prefix=None, raises=True, debug=True, output=None):
|
||||
self.debug = debug if not self.test else False
|
||||
self.output = output or Output()
|
||||
self.cmd = ' '.join(args)
|
||||
self.args = args
|
||||
self.prefix = prefix
|
||||
|
||||
@ -4,7 +4,7 @@ from .script import Script
|
||||
|
||||
|
||||
class Async(Script):
|
||||
async def __call__(self, *args, **kwargs):
|
||||
async def call(self, *args, **kwargs):
|
||||
return asyncio.gather(*[
|
||||
procs.append(action(*args, **kwargs))
|
||||
for action in self.actions
|
||||
|
||||
@ -27,17 +27,9 @@ class Script(Action):
|
||||
super().__init__(**kwargs)
|
||||
self.actions = Actions(self, actions)
|
||||
|
||||
async def __call__(self, *args, **kwargs):
|
||||
async def call(self, *args, **kwargs):
|
||||
for action in self.actions:
|
||||
try:
|
||||
await action(*args, **kwargs)
|
||||
except WrongResult as e:
|
||||
print(e)
|
||||
action.status = 'fail'
|
||||
break
|
||||
else:
|
||||
if action.status == 'running':
|
||||
action.status = 'success'
|
||||
await action(*args, **kwargs)
|
||||
|
||||
def shargs(self, *args, **kwargs):
|
||||
user = kwargs.pop('user', None)
|
||||
|
||||
@ -8,7 +8,7 @@ import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
from ..proc import Proc, output
|
||||
from ..proc import Proc
|
||||
from ..image import Image
|
||||
from .localhost import Localhost
|
||||
|
||||
@ -88,12 +88,12 @@ class Buildah(Localhost):
|
||||
def __repr__(self):
|
||||
return f'Build'
|
||||
|
||||
async def __call__(self, *args, debug=False, **kwargs):
|
||||
async def call(self, *args, debug=False, **kwargs):
|
||||
if Proc.test or os.getuid() == 0 or self.parent.parent:
|
||||
self.ctr = (await self.exec('buildah', 'from', self.base, buildah=False)).out
|
||||
self.mnt = Path((await self.exec('buildah', 'mount', self.ctr, buildah=False)).out)
|
||||
|
||||
result = await super().__call__(*args, **kwargs)
|
||||
result = await super().call(*args, **kwargs)
|
||||
#await self.umounts()
|
||||
#await self.umount()
|
||||
await self.exec('buildah', 'rm', self.ctr, raises=False, buildah=False)
|
||||
@ -113,7 +113,7 @@ class Buildah(Localhost):
|
||||
cli.shlaxfile.path,
|
||||
cli.parser.command.name, # script name ?
|
||||
]
|
||||
output(' '.join(argv), 'EXECUTION', flush=True)
|
||||
self.output(' '.join(argv), 'EXECUTION', flush=True)
|
||||
|
||||
proc = await asyncio.create_subprocess_shell(
|
||||
shlex.join(argv),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user