diff --git a/shlax/actions/base.py b/shlax/actions/base.py index e6f56f5..6c1ecde 100644 --- a/shlax/actions/base.py +++ b/shlax/actions/base.py @@ -104,6 +104,8 @@ class Action: return Output(*args, **kwargs) async def __call__(self, *args, **kwargs): + self.call_args = args + self.call_kwargs = kwargs self.output = self.output_factory(*args, **kwargs) self.output_start() self.status = 'running' diff --git a/shlax/contrib/gitlab.py b/shlax/contrib/gitlab.py index 1b7c0a8..e3b8891 100644 --- a/shlax/contrib/gitlab.py +++ b/shlax/contrib/gitlab.py @@ -6,7 +6,8 @@ from shlax import * class GitLabCIConfig(Script): async def call(self, *args, write=True, **kwargs): output = yaml.dump(self.kwargs) - self.output(output) + if kwargs['debug'] is True: + self.output(output) if write: with open('.gitlab-ci.yml', 'w+') as f: f.write(output) diff --git a/shlax/output.py b/shlax/output.py index 2ca97f0..8ae6a4b 100644 --- a/shlax/output.py +++ b/shlax/output.py @@ -17,7 +17,7 @@ class Output: def colorize(self, code, content): return self.color(code) + content + self.color() - def __init__(self, prefix=None, regexps=None, debug=True, write=None, flush=None): + def __init__(self, prefix=None, regexps=None, debug=False, write=None, flush=None): self.prefix = prefix self.debug = debug self.prefix_length = 0 diff --git a/shlax/proc.py b/shlax/proc.py index f701031..cacc54a 100644 --- a/shlax/proc.py +++ b/shlax/proc.py @@ -54,7 +54,7 @@ class Proc: """ test = False - def __init__(self, *args, prefix=None, raises=True, debug=True, output=None): + def __init__(self, *args, prefix=None, raises=True, debug=None, output=None): self.debug = debug if not self.test else False self.output = output or Output() self.cmd = ' '.join(args) diff --git a/shlax/strategies/script.py b/shlax/strategies/script.py index 282f1fc..c2c6a7b 100644 --- a/shlax/strategies/script.py +++ b/shlax/strategies/script.py @@ -31,54 +31,3 @@ class Script(Action): async def call(self, *args, **kwargs): for action in self.actions: await action(*args, **kwargs) - - def shargs(self, *args, **kwargs): - user = kwargs.pop('user', None) - kwargs['debug'] = True - args = [str(arg) for arg in args if args is not None] - - if args and ' ' in args[0]: - if len(args) == 1: - args = ['sh', '-euc', args[0]] - else: - args = ['sh', '-euc'] + list(args) - - if user == 'root': - args = ['sudo'] + args - elif user: - args = ['sudo', '-u', user] + args - - if self.parent: - return self.parent.shargs(*args, **kwargs) - else: - return args, kwargs - - async def exec(self, *args, **kwargs): - args, kwargs = self.shargs(*args, **kwargs) - proc = await Proc(*args, **kwargs)() - if kwargs.get('wait', True): - await proc.wait() - return proc - - async def rexec(self, *args, **kwargs): - kwargs['user'] = 'root' - return await self.exec(*args, **kwargs) - - async def env(self, name): - return (await self.exec('echo $' + name)).out - - async def which(self, *cmd): - """ - Return the first path to the cmd in the container. - - If cmd argument is a list then it will try all commands. - """ - for path in (await self.env('PATH')).split(':'): - for c in cmd: - p = os.path.join(self.root, path[1:], c) - if os.path.exists(p): - return p[len(str(self.root)):] - - async def copy(self, *args): - args = ['cp', '-ra'] + list(args) - return await self.exec(*args) diff --git a/shlax/targets/buildah.py b/shlax/targets/buildah.py index 0a0b4f4..fc6205a 100644 --- a/shlax/targets/buildah.py +++ b/shlax/targets/buildah.py @@ -86,12 +86,16 @@ class Buildah(Localhost): if os.path.exists(p): return p[len(str(self.mnt)):] - @property - def _compatible(self): - return Proc.test or os.getuid() == 0 or getattr(self.parent, 'parent', None) + def is_wrapper(self): + return ( + Proc.test + or os.getuid() == 0 + or getattr(self.parent, 'parent', None) + ) + async def call(self, *args, **kwargs): - if self._compatible: + if not self.is_wrapper(): 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) @@ -103,13 +107,13 @@ class Buildah(Localhost): argv = [ 'buildah', 'unshare', sys.argv[0], # current script location + cli.shlaxfile.path, # current shlaxfile location ] if debug is True: argv.append('-d') - elif isinstance(debug, str): + elif isinstance(debug, str) and debug: argv.append('-d=' + debug) argv += [ - cli.shlaxfile.path, cli.parser.command.name, # script name ? ] self.output(' '.join(argv), 'EXECUTION', flush=True) @@ -158,7 +162,7 @@ class Buildah(Localhost): await self.exec('podman', 'push', f'{self.image.repository}:{tag}', buildah=False) async def clean(self, *args, **kwargs): - if not self._compatible: + if self.is_wrapper(): return for src, dst in self.mounts.items(): diff --git a/shlax/targets/localhost.py b/shlax/targets/localhost.py index 42dabdc..d945fce 100644 --- a/shlax/targets/localhost.py +++ b/shlax/targets/localhost.py @@ -7,3 +7,54 @@ from ..strategies.script import Script class Localhost(Script): root = '/' + + def shargs(self, *args, **kwargs): + user = kwargs.pop('user', None) + args = [str(arg) for arg in args if args is not None] + + if args and ' ' in args[0]: + if len(args) == 1: + args = ['sh', '-euc', args[0]] + else: + args = ['sh', '-euc'] + list(args) + + if user == 'root': + args = ['sudo'] + args + elif user: + args = ['sudo', '-u', user] + args + + if self.parent: + return self.parent.shargs(*args, **kwargs) + else: + return args, kwargs + + async def exec(self, *args, **kwargs): + kwargs.setdefault('debug', self.call_kwargs.get('debug', False)) + args, kwargs = self.shargs(*args, **kwargs) + proc = await Proc(*args, **kwargs)() + if kwargs.get('wait', True): + await proc.wait() + return proc + + async def rexec(self, *args, **kwargs): + kwargs['user'] = 'root' + return await self.exec(*args, **kwargs) + + async def env(self, name): + return (await self.exec('echo $' + name)).out + + async def which(self, *cmd): + """ + Return the first path to the cmd in the container. + + If cmd argument is a list then it will try all commands. + """ + for path in (await self.env('PATH')).split(':'): + for c in cmd: + p = os.path.join(self.root, path[1:], c) + if os.path.exists(p): + return p[len(str(self.root)):] + + async def copy(self, *args): + args = ['cp', '-ra'] + list(args) + return await self.exec(*args)