aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'layman/overlays/source.py')
-rw-r--r--layman/overlays/source.py96
1 files changed, 63 insertions, 33 deletions
diff --git a/layman/overlays/source.py b/layman/overlays/source.py
index 8d41bf4..d6cffef 100644
--- a/layman/overlays/source.py
+++ b/layman/overlays/source.py
@@ -14,6 +14,7 @@
# Sebastian Pipping <sebastian@pipping.org>
import os
+import copy
import sys
import shutil
import subprocess
@@ -21,21 +22,26 @@ import subprocess
from layman.utils import path
+def _resolve_command(command):
+ if os.path.isabs(command):
+ if not os.path.exists(command):
+ raise Exception('Program "%s" not found' % command)
+ return ('File', command)
+ else:
+ kind = 'Command'
+ env_path = os.environ['PATH']
+ for d in env_path.split(os.pathsep):
+ f = os.path.join(d, command)
+ if os.path.exists(f):
+ return ('Command', f)
+ raise Exception('Cound not resolve command "%s" based on PATH "%s"' % (command, env_path))
+
+
def require_supported(binaries):
for command, mtype, package in binaries:
found = False
- if os.path.isabs(command):
- kind = 'Binary'
- found = os.path.exists(command)
- else:
- kind = 'Command'
- for d in os.environ['PATH'].split(os.pathsep):
- f = os.path.join(d, command)
- if os.path.exists(f):
- found = True
- break
-
- if not found:
+ kind, path = _resolve_command(command)
+ if not path:
raise Exception(kind + ' ' + command + ' seems to be missing!'
' Overlay type "' + mtype + '" not support'
'ed. Did you emerge ' + package + '?')
@@ -102,30 +108,54 @@ class OverlaySource(object):
def command(self):
return self.config['%s_command' % self.__class__.type_key]
- def cmd(self, command):
- '''Run a command.'''
+ def run_command(self, *args, **kwargs):
+ file_to_run = _resolve_command(self.command())[1]
+ args = (file_to_run, ) + args
+ assert('pwd' not in kwargs) # Bug detector
+
+ cwd = kwargs.get('cwd', None)
+ env = None
+ env_updates = None
+ if 'env' in kwargs:
+ # Build actual env from surrounding plus updates
+ env_updates = kwargs['env']
+ env = copy.copy(os.environ)
+ env.update(env_updates)
+
+ command_repr = ' '.join(args)
+ if env_updates:
+ command_repr = '%s %s' % (' '.join('%s=%s' % (k, v) for (k, v) in sorted(env_updates.items())), command_repr)
+ if cwd:
+ command_repr = '( cd %s && %s )' % (cwd, command_repr)
+
+ self.output.info('Running... # %s' % command_repr, 2)
+
+ if self.quiet:
+ input_source = subprocess.PIPE
+ output_target = open('/dev/null', 'w')
+ else:
+ # Re-use parent file descriptors
+ input_source = self.config['stdin']
+ output_target = self.config['stdout']
+
+ proc = subprocess.Popen(args,
+ stdin=input_source,
+ stdout=output_target,
+ stderr=self.config['stderr']t,
+ cwd=cwd,
+ env=env)
- self.output.info('Running command "' + command + '"...', 2)
+ if self.quiet:
+ # Make child non-interactive
+ proc.stdin.close()
- if hasattr(sys.stdout,'encoding'):
- enc = sys.stdout.encoding or sys.getfilesystemencoding()
- if enc:
- command = command.encode(enc)
+ result = proc.wait()
+
+ if self.quiet:
+ output_target.close()
+
+ return result
- if not self.quiet:
- cmd = subprocess.Popen([command], shell = True,
- stdout = self.config['stdout'],
- stderr = self.config['stderr'],
- close_fds = True)
- result = cmd.wait()
- return result
- else:
- cmd = subprocess.Popen([command], shell = True,
- stdout = subprocess.PIPE,
- stderr = subprocess.PIPE,
- close_fds = True)
- result = cmd.wait()
- return result
def to_xml_hook(self, repo_elem):
pass