80 lines
2.7 KiB
Python
80 lines
2.7 KiB
Python
import os
|
|
import subprocess
|
|
import dotbot
|
|
import dotbot.util
|
|
|
|
|
|
class Shell(dotbot.Plugin):
|
|
'''
|
|
Run arbitrary shell commands.
|
|
'''
|
|
|
|
_directive = 'shell'
|
|
_has_shown_override_message = False
|
|
|
|
def can_handle(self, directive):
|
|
return directive == self._directive
|
|
|
|
def handle(self, directive, data):
|
|
if directive != self._directive:
|
|
raise ValueError('Shell cannot handle directive %s' %
|
|
directive)
|
|
return self._process_commands(data)
|
|
|
|
def _process_commands(self, data):
|
|
success = True
|
|
defaults = self._context.defaults().get('shell', {})
|
|
options = self._get_option_overrides()
|
|
for item in data:
|
|
stdin = defaults.get('stdin', False)
|
|
stdout = defaults.get('stdout', False)
|
|
stderr = defaults.get('stderr', False)
|
|
quiet = defaults.get('quiet', False)
|
|
if isinstance(item, dict):
|
|
cmd = item['command']
|
|
msg = item.get('description', None)
|
|
stdin = item.get('stdin', stdin)
|
|
stdout = item.get('stdout', stdout)
|
|
stderr = item.get('stderr', stderr)
|
|
quiet = item.get('quiet', quiet)
|
|
elif isinstance(item, list):
|
|
cmd = item[0]
|
|
msg = item[1] if len(item) > 1 else None
|
|
else:
|
|
cmd = item
|
|
msg = None
|
|
if msg is None:
|
|
self._log.lowinfo(cmd)
|
|
elif quiet:
|
|
self._log.lowinfo('%s' % msg)
|
|
else:
|
|
self._log.lowinfo('%s [%s]' % (msg, cmd))
|
|
stdout = options.get('stdout', stdout)
|
|
stderr = options.get('stderr', stderr)
|
|
ret = dotbot.util.shell_command(
|
|
cmd,
|
|
cwd=self._context.base_directory(),
|
|
enable_stdin=stdin,
|
|
enable_stdout=stdout,
|
|
enable_stderr=stderr
|
|
)
|
|
if ret != 0:
|
|
success = False
|
|
self._log.warning('Command [%s] failed' % cmd)
|
|
if success:
|
|
self._log.info('All commands have been executed')
|
|
else:
|
|
self._log.error('Some commands were not successfully executed')
|
|
return success
|
|
|
|
def _get_option_overrides(self):
|
|
ret = {}
|
|
options = self._context.options()
|
|
if options.verbose > 1:
|
|
ret['stderr'] = True
|
|
ret['stdout'] = True
|
|
if not self._has_shown_override_message:
|
|
self._log.debug("Shell: Found cli option to force show stderr and stdout.")
|
|
self._has_shown_override_message = True
|
|
return ret
|