Source code for dktasklib.commands
# -*- coding: utf-8 -*-
import os
import re
import invoke
from .executables import exe
from .utils import fmt
default_command_policy = dict(
negative_bool='omit', # omit False boolean parameters (or 'prefix')
list_join=',',
)
[docs]class Command(object):
def __init__(self, name, argspec="",
requirements=(),
policy=default_command_policy,
**optdefs):
self._args = (name, argspec, requirements, policy, optdefs)
self._initialized = False
def _initialize(self):
if self._initialized:
return
name, argspec, requirements, policy, optdefs = self._args
# handle any required params attached to the command, i.e. if the
# command is specified as foo = Command('foo -v', ...)
exename, reqparams = (name + ' ').split(' ', 1)
# make sure all requirements are present
exe.require(*requirements)
if os.path.isfile(exename): # if path to executable is given
self.cmd = exename # then use it
else:
self.cmd = exe.find(exename) # else search path
# fetch names of all argspec params
self.params = [p[1:-1] for p in re.findall(r'\{[^}]*\}', argspec)]
self.required_params = reqparams.strip()
self.argspec = argspec
self.policy = policy
self.optdefs = optdefs
self._initialized = True
def _kw_to_opts(self, kw):
res = ""
for k, v in kw.items():
# print 'k,v,res:', k, v, `res`
if k in self.params: # skip conversion of parameters to argspec
continue
res += ' '
flag = ('-' if len(k) == 1 else '--') + k.replace('_', '-')
if isinstance(v, bool):
if v:
res += flag
else:
if self.policy['negative_bool'] == 'prefix':
res += '--no' + flag
elif isinstance(v, (list, tuple)) and v:
res += flag + '=' + self.policy['list_join'].join(str(item) for item in v)
elif isinstance(v, basestring):
res += flag + '="%s"' % v
else:
res += flag + '=' + str(v)
return res
def __call__(self, ctx=None, *args, **kwargs):
self._initialize()
if ctx is not None and not isinstance(ctx, invoke.Context):
# we've been passed a real argument in position 0
args = (ctx,) + args
ctx = None
kwargs['opts'] = self._kw_to_opts(kwargs)
posargs = ' '.join(args)
if 'pos' in self.params:
kwargs['pos'] = posargs
fparams = fmt(self.argspec, kwargs)
if 'pos' not in self.params:
# if placement of positional args is not specified, then put at end
fparams += " " + posargs
if ctx is None:
ctx = invoke.Context()
cmd = '"%s"' % self.cmd if ' ' in self.cmd else self.cmd
cmd += ' ' + self.required_params + fparams
ctx.run(cmd)
return cmd
tree = Command('tree -I ".git|*.pyc|*.swp|dist|*.egg-info|_static|_build|_templates"')