From 14b7ca062d96ab6b44f1b2bd192649db36ae6263 Mon Sep 17 00:00:00 2001 From: Chris Larson Date: Tue, 12 Oct 2010 19:05:19 -0700 Subject: oe.process: pull some common bits over Also update gitver to use the subprocess wrappers Signed-off-by: Chris Larson --- classes/gitver.bbclass | 28 ++++++------------ classes/utils.bbclass | 53 +++++++++------------------------- lib/oe/process.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 60 deletions(-) create mode 100644 lib/oe/process.py diff --git a/classes/gitver.bbclass b/classes/gitver.bbclass index 445067ec80..b67a017dcd 100644 --- a/classes/gitver.bbclass +++ b/classes/gitver.bbclass @@ -9,35 +9,23 @@ GITVER = "${@get_git_pv('${S}', d)}" def get_git_pv(path, d, tagadjust=None): - from subprocess import Popen, PIPE import os from bb import error from bb.parse import mark_dependency + import oe.process gitdir = os.path.abspath(os.path.join(d.getVar("S", True), ".git")) - env = { "GIT_DIR": gitdir } - - def popen(cmd, **kwargs): - kwargs["stderr"] = PIPE - kwargs["stdout"] = PIPE - kwargs["env"] = env + def git(cmd): try: - pipe = Popen(cmd, **kwargs) - except OSError, e: - #error("Execution of %s failed: %s" % (cmd, e)) - return - - (stdout, stderr) = pipe.communicate(None) - if pipe.returncode != 0: - #error("Execution of %s failed: %s" % (cmd, stderr)) - return - return stdout.rstrip() + return oe_run(d, ["git"] + cmd, cwd=gitdir).rstrip() + except oe.process.CmdError, exc: + bb.fatal(str(exc)) # Force the recipe to be reparsed so the version gets bumped # if the active branch is switched, or if the branch changes. mark_dependency(d, os.path.join(gitdir, "HEAD")) - ref = popen(["git", "symbolic-ref", "HEAD"]) + ref = git(["symbolic-ref", "HEAD"]) if ref: reffile = os.path.join(gitdir, ref) if os.path.exists(reffile): @@ -54,9 +42,9 @@ def get_git_pv(path, d, tagadjust=None): if os.path.exists(tagdir): mark_dependency(d, tagdir) - ver = popen(["git", "describe", "--tags"], cwd=path) + ver = git(["describe", "--tags"]) if not ver: - ver = popen(["git", "rev-parse", "--short", "HEAD"], cwd=path) + ver = git(["rev-parse", "--short", "HEAD"]) if ver: return "0.0-%s" % ver else: diff --git a/classes/utils.bbclass b/classes/utils.bbclass index f7d6996090..82beeb964e 100644 --- a/classes/utils.bbclass +++ b/classes/utils.bbclass @@ -57,50 +57,23 @@ def is_machine_specific(d): if any(urldata.localpath.startswith(mp + "/") for mp in machinepaths): return True -def subprocess_setup(): - import signal - # Python installs a SIGPIPE handler by default. This is usually not what - # non-Python subprocesses expect. - signal.signal(signal.SIGPIPE, signal.SIG_DFL) +def oe_popen_env(d): + env = d.getVar("__oe_popen_env", False) + if env is None: + env = {} + for v in d.keys(): + if d.getVarFlag(v, "export"): + env[v] = d.getVar(v, True) or "" + d.setVar("__oe_popen_env", env) + return env def oe_run(d, cmd, **kwargs): - """Convenience function to run a command and return its output, raising an - exception when the command fails""" - from subprocess import PIPE - - options = { - "stdout": PIPE, - "stderr": PIPE, - "shell": True, - } - options.update(kwargs) - pipe = oe_popen(d, cmd, **options) - stdout, stderr = pipe.communicate() - if pipe.returncode != 0: - raise RuntimeError("Execution of '%s' failed with '%s':\n%s" % - (cmd, pipe.returncode, stderr)) - return stdout + kwargs["env"] = oe_popen_env(d) + return oe.process.run(cmd, **kwargs) def oe_popen(d, cmd, **kwargs): - """ Convenience function to call out processes with our exported - variables in the environment. - """ - from subprocess import Popen - - if kwargs.get("env") is None: - env = d.getVar("__oe_popen_env", False) - if env is None: - env = {} - for v in d.keys(): - if d.getVarFlag(v, "export"): - env[v] = d.getVar(v, True) or "" - d.setVar("__oe_popen_env", env) - kwargs["env"] = env - - kwargs["close_fds"] = True - kwargs["preexec_fn"] = subprocess_setup - - return Popen(cmd, **kwargs) + kwargs["env"] = oe_popen_env(d) + return oe.process.popen(cmd, **kwargs) def oe_system(d, cmd, **kwargs): """ Popen based version of os.system. """ diff --git a/lib/oe/process.py b/lib/oe/process.py new file mode 100644 index 0000000000..179e0d4548 --- /dev/null +++ b/lib/oe/process.py @@ -0,0 +1,77 @@ +import subprocess +import signal + +def subprocess_setup(): + # Python installs a SIGPIPE handler by default. This is usually not what + # non-Python subprocesses expect. + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + +class CmdError(RuntimeError): + def __init__(self, command): + self.command = command + + def __str__(self): + if not isinstance(self.command, basestring): + cmd = subprocess.list2cmdline(self.command) + else: + cmd = self.command + + return "Execution of '%s' failed" % cmd + +class NotFoundError(CmdError): + def __str__(self): + return CmdError.__str__(self) + ": command not found" + +class ExecutionError(CmdError): + def __init__(self, command, exitcode, stdout = None, stderr = None): + CmdError.__init__(self, command) + self.exitcode = exitcode + self.stdout = stdout + self.stderr = stderr + + def __str__(self): + message = "" + if self.stderr: + message += self.stderr + if self.stdout: + message += self.stdout + if message: + message = ":\n" + message + return (CmdError.__str__(self) + + " with exit code %s" % self.exitcode + message) + +def run(cmd, **kwargs): + """Convenience function to run a command and return its output, raising an + exception when the command fails""" + from subprocess import PIPE, STDOUT + + options = { + "stdout": PIPE, + "stderr": STDOUT, + "shell": False, + } + if isinstance(cmd, basestring): + options["shell"] = True + options.update(kwargs) + try: + pipe = popen(cmd, **options) + except OSError, exc: + if exc.errno == 2: + raise NotFoundError(cmd) + else: + raise + stdout, stderr = pipe.communicate() + if pipe.returncode != 0: + raise ExecutionError(cmd, pipe.returncode, stdout, stderr) + return stdout + +def popen(cmd, **kwargs): + """ Convenience function to call out processes with our exported + variables in the environment. + """ + from subprocess import Popen + + kwargs["close_fds"] = True + kwargs["preexec_fn"] = subprocess_setup + + return Popen(cmd, **kwargs) -- cgit 1.2.3-korg