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: end-of-file-fixer
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
|
- repo: https://yourlabs.io/oss/shlax
|
||||||
|
rev: master
|
||||||
|
hooks:
|
||||||
|
- id: shlaxfile-gitlabci
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
- id: shlaxfile-gitlabci
|
- id: shlaxfile-gitlabci
|
||||||
name: Check for added large files
|
name: Regenerate .gitlab-ci.yml
|
||||||
description: Regenerate gitlabci
|
description: Regenerate gitlabci
|
||||||
entry: ./shlaxfile.py gitlabci
|
entry: pip install -e . && ./shlaxfile.py gitlabci
|
||||||
language: python
|
language: python
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
from .actions import *
|
from .actions import *
|
||||||
from .image import Image
|
from .image import Image
|
||||||
from .strategies import *
|
from .strategies import *
|
||||||
from .proc import output, Proc
|
from .proc import Proc
|
||||||
from .targets import *
|
from .targets import *
|
||||||
from .shlaxfile import Shlaxfile
|
from .shlaxfile import Shlaxfile
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
import inspect
|
import inspect
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from ..output import Output
|
||||||
|
from ..exceptions import WrongResult
|
||||||
|
|
||||||
|
|
||||||
class Action:
|
class Action:
|
||||||
parent = None
|
parent = None
|
||||||
@ -76,6 +79,22 @@ class Action:
|
|||||||
return getattr(a, name)
|
return getattr(a, name)
|
||||||
raise AttributeError(name)
|
raise AttributeError(name)
|
||||||
|
|
||||||
async def __call__(self, *args, **kwargs):
|
async def call(self, *args, **kwargs):
|
||||||
print(f'{self}.__call__(*args, **kwargs) not implemented')
|
print(f'{self}.call(*args, **kwargs) not implemented')
|
||||||
sys.exit(1)
|
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:
|
if not self.tags:
|
||||||
self.tags = ['latest']
|
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(
|
self.sha = (await self.parent.parent.exec(
|
||||||
'buildah',
|
'buildah',
|
||||||
'commit',
|
'commit',
|
||||||
|
|||||||
@ -104,7 +104,7 @@ class Packages(Action):
|
|||||||
print(f'{self.container.name} | Waiting for update ...')
|
print(f'{self.container.name} | Waiting for update ...')
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
async def __call__(self, *args, **kwargs):
|
async def call(self, *args, **kwargs):
|
||||||
cached = getattr(self, '_pagkages_mgr', None)
|
cached = getattr(self, '_pagkages_mgr', None)
|
||||||
if cached:
|
if cached:
|
||||||
self.mgr = cached
|
self.mgr = cached
|
||||||
|
|||||||
@ -2,5 +2,5 @@ from .base import Action
|
|||||||
|
|
||||||
|
|
||||||
class Run(Action):
|
class Run(Action):
|
||||||
async def __call__(self, *args, **kwargs):
|
async def call(self, *args, **kwargs):
|
||||||
return (await self.exec(*self.args, **self.kwargs))
|
return (await self.exec(*self.args, **self.kwargs))
|
||||||
|
|||||||
@ -9,7 +9,7 @@ class Service(Action):
|
|||||||
self.names = names
|
self.names = names
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
async def __call__(self, *args, **kwargs):
|
async def call(self, *args, **kwargs):
|
||||||
return asyncio.gather(*[
|
return asyncio.gather(*[
|
||||||
self.exec('systemctl', 'start', name, user='root')
|
self.exec('systemctl', 'start', name, user='root')
|
||||||
for name in self.names
|
for name in self.names
|
||||||
|
|||||||
@ -112,7 +112,7 @@ async def test(*args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
class ConsoleScript(cli2.ConsoleScript):
|
class ConsoleScript(cli2.ConsoleScript):
|
||||||
def __call__(self, *args, **kwargs):
|
def call(self, *args, **kwargs):
|
||||||
self.shlaxfile = None
|
self.shlaxfile = None
|
||||||
shlaxfile = sys.argv.pop(1) if len(sys.argv) > 1 else ''
|
shlaxfile = sys.argv.pop(1) if len(sys.argv) > 1 else ''
|
||||||
if os.path.exists(shlaxfile.split('::')[0]):
|
if os.path.exists(shlaxfile.split('::')[0]):
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from shlax import *
|
|||||||
|
|
||||||
|
|
||||||
class GitLabCIConfig(Script):
|
class GitLabCIConfig(Script):
|
||||||
async def __call__(self, *args, write=True, **kwargs):
|
async def call(self, *args, write=True, **kwargs):
|
||||||
await super().__call__(*args, **kwargs)
|
await super().__call__(*args, **kwargs)
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
for name, definition in self.context.items():
|
for name, definition in self.context.items():
|
||||||
@ -17,5 +17,5 @@ class GitLabCIConfig(Script):
|
|||||||
|
|
||||||
|
|
||||||
class Job(Action):
|
class Job(Action):
|
||||||
async def __call__(self, *args, **kwargs):
|
async def call(self, *args, **kwargs):
|
||||||
self.context[self.args[0]] = self.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
|
import asyncio
|
||||||
from colorama import Fore, Back, Style
|
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .exceptions import WrongResult
|
from .exceptions import WrongResult
|
||||||
import pygments
|
from .output import Output
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
class PrefixStreamProtocol(asyncio.subprocess.SubprocessStreamProtocol):
|
class PrefixStreamProtocol(asyncio.subprocess.SubprocessStreamProtocol):
|
||||||
@ -104,14 +17,13 @@ class PrefixStreamProtocol(asyncio.subprocess.SubprocessStreamProtocol):
|
|||||||
make asynchronous output readable.
|
make asynchronous output readable.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, prefix, *args, **kwargs):
|
def __init__(self, output, *args, **kwargs):
|
||||||
self.debug = kwargs.get('debug', True)
|
self.output = output
|
||||||
self.prefix = prefix
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def pipe_data_received(self, fd, data):
|
def pipe_data_received(self, fd, data):
|
||||||
if (self.debug is True or 'out' in str(self.debug)) and fd in (1, 2):
|
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()
|
sys.stdout.flush()
|
||||||
super().pipe_data_received(fd, data)
|
super().pipe_data_received(fd, data)
|
||||||
|
|
||||||
@ -142,8 +54,9 @@ class Proc:
|
|||||||
"""
|
"""
|
||||||
test = False
|
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.debug = debug if not self.test else False
|
||||||
|
self.output = output or Output()
|
||||||
self.cmd = ' '.join(args)
|
self.cmd = ' '.join(args)
|
||||||
self.args = args
|
self.args = args
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from .script import Script
|
|||||||
|
|
||||||
|
|
||||||
class Async(Script):
|
class Async(Script):
|
||||||
async def __call__(self, *args, **kwargs):
|
async def call(self, *args, **kwargs):
|
||||||
return asyncio.gather(*[
|
return asyncio.gather(*[
|
||||||
procs.append(action(*args, **kwargs))
|
procs.append(action(*args, **kwargs))
|
||||||
for action in self.actions
|
for action in self.actions
|
||||||
|
|||||||
@ -27,17 +27,9 @@ class Script(Action):
|
|||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.actions = Actions(self, actions)
|
self.actions = Actions(self, actions)
|
||||||
|
|
||||||
async def __call__(self, *args, **kwargs):
|
async def call(self, *args, **kwargs):
|
||||||
for action in self.actions:
|
for action in self.actions:
|
||||||
try:
|
|
||||||
await action(*args, **kwargs)
|
await action(*args, **kwargs)
|
||||||
except WrongResult as e:
|
|
||||||
print(e)
|
|
||||||
action.status = 'fail'
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
if action.status == 'running':
|
|
||||||
action.status = 'success'
|
|
||||||
|
|
||||||
def shargs(self, *args, **kwargs):
|
def shargs(self, *args, **kwargs):
|
||||||
user = kwargs.pop('user', None)
|
user = kwargs.pop('user', None)
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
from ..proc import Proc, output
|
from ..proc import Proc
|
||||||
from ..image import Image
|
from ..image import Image
|
||||||
from .localhost import Localhost
|
from .localhost import Localhost
|
||||||
|
|
||||||
@ -88,12 +88,12 @@ class Buildah(Localhost):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'Build'
|
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:
|
if Proc.test or os.getuid() == 0 or self.parent.parent:
|
||||||
self.ctr = (await self.exec('buildah', 'from', self.base, buildah=False)).out
|
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)
|
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.umounts()
|
||||||
#await self.umount()
|
#await self.umount()
|
||||||
await self.exec('buildah', 'rm', self.ctr, raises=False, buildah=False)
|
await self.exec('buildah', 'rm', self.ctr, raises=False, buildah=False)
|
||||||
@ -113,7 +113,7 @@ class Buildah(Localhost):
|
|||||||
cli.shlaxfile.path,
|
cli.shlaxfile.path,
|
||||||
cli.parser.command.name, # script name ?
|
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(
|
proc = await asyncio.create_subprocess_shell(
|
||||||
shlex.join(argv),
|
shlex.join(argv),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user