From 08e953608917faf1c120c40d4e53ebcd937cf131 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Tue, 3 Apr 2012 16:22:40 +0200 Subject: [PATCH] Automatically determine prerequires dependencies for scriptlets. --- python/pakfire/builder.py | 30 ++++++++++++++++++++++++++++- python/pakfire/constants.py | 7 +++++++ python/pakfire/packages/make.py | 9 +++++++++ python/pakfire/packages/packager.py | 12 +++++++++++- tools/Makefile | 1 + tools/find-prerequires | 20 +++++++++++++++++++ 6 files changed, 77 insertions(+), 2 deletions(-) create mode 100755 tools/find-prerequires diff --git a/python/pakfire/builder.py b/python/pakfire/builder.py index 81fe54888..40218bf56 100644 --- a/python/pakfire/builder.py +++ b/python/pakfire/builder.py @@ -955,6 +955,12 @@ class Builder(object): return environ def do(self, command, shell=True, personality=None, cwd=None, *args, **kwargs): + try: + logger = kwargs["logger"] + except KeyError: + logger = logging.getLogger("pakfire") + kwargs["logger"] = logger + # Environment variables log.debug("Environment:") for k, v in sorted(self.environ.items()): @@ -977,12 +983,26 @@ class Builder(object): personality=personality, shell=False, env=self.environ, - logger=logging.getLogger("pakfire"), cwd=cwd, *args, **kwargs ) + def run_script(self, script, *args): + if not script.startswith("/"): + script = os.path.join(SCRIPT_DIR, script) + + assert os.path.exists(script), "Script we should run does not exist: %s" % script + + cmd = [script,] + for arg in args: + cmd.append(arg) + cmd = " ".join(cmd) + + # Returns the output of the command, but the output won't get + # logged. + return self.do(cmd, returnOutput=True, logger=None) + def create_icecream_toolchain(self): try: out = self.do("icecc --build-native 2>/dev/null", returnOutput=True, cwd="/tmp") @@ -1091,6 +1111,14 @@ class Builder(object): log.error(_("Extracting debuginfo did not complete with success. Aborting build.")) raise + def find_prerequires(self, scriptlet_file): + assert os.path.exists(scriptlet_file), "Scriptlet file does not exist: %s" % scriptlet_file + + res = self.run_script("find-prerequires", scriptlet_file) + prerequires = set(res.splitlines()) + + return prerequires + def cleanup(self): if os.path.exists(self.buildroot): util.rm(self.buildroot) diff --git a/python/pakfire/constants.py b/python/pakfire/constants.py index e3fe8cd0f..9d4f34a2a 100644 --- a/python/pakfire/constants.py +++ b/python/pakfire/constants.py @@ -201,6 +201,13 @@ SCRIPTS = ( "posttransup", ) +SCRIPTS_PREREQUIRES = ( + "prein", + "postin", + "preup", + "postup", +) + LDCONFIG = "/sbin/ldconfig" CONFIG_FILE_SUFFIX_NEW = ".paknew" diff --git a/python/pakfire/packages/make.py b/python/pakfire/packages/make.py index 95e992776..46c0ec8e4 100644 --- a/python/pakfire/packages/make.py +++ b/python/pakfire/packages/make.py @@ -441,6 +441,15 @@ class MakefilePackage(MakefileBase): self._dependencies[key], self.lexer.get_var("filter_%s" % key) ) + def update_prerequires(self, prerequires): + if not prerequires: + return + + _prerequires = self._dependencies.get("prerequires", []) + _prerequires = set(_prerequires + prerequires) + + self._dependencies["prerequires"] = list(prerequires) + @staticmethod def filter_deps(deps, filters): if not filters: diff --git a/python/pakfire/packages/packager.py b/python/pakfire/packages/packager.py index 386a5ddf3..53879d1e5 100644 --- a/python/pakfire/packages/packager.py +++ b/python/pakfire/packages/packager.py @@ -425,6 +425,9 @@ class BinaryPackager(Packager): def create_scriptlets(self): scriptlets = [] + # Collect all prerequires for the scriptlets. + prerequires = [] + for scriptlet_name in SCRIPTS: scriptlet = self.pkg.get_scriptlet(scriptlet_name) @@ -463,12 +466,19 @@ class BinaryPackager(Packager): s.close() + if scriptlet_name in SCRIPTS_PREREQUIRES: + # Shell scripts require a shell to be executed. + prerequires.append("/bin/sh") + + prerequires += self.builder.find_prerequires(scriptlet_file) + else: raise Exception, "Unknown scriptlet language: %s" % scriptlet["lang"] scriptlets.append((scriptlet_name, scriptlet_file)) - # XXX scan for script dependencies + # Cleanup prerequires. + self.pkg.update_prerequires(prerequires) return scriptlets diff --git a/tools/Makefile b/tools/Makefile index 4448b69f5..d7cbf709a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -20,6 +20,7 @@ SCRIPTS_SHELL = \ compress-man-pages \ extract-debuginfo \ find-common \ + find-prerequires \ find-provides \ find-requires \ pakfire-multicall.py \ diff --git a/tools/find-prerequires b/tools/find-prerequires new file mode 100755 index 000000000..d4b39d093 --- /dev/null +++ b/tools/find-prerequires @@ -0,0 +1,20 @@ +#!/bin/bash + +if [ -z "${1}" ]; then + echo >&2 "No input file passed!" + exit 1 +fi + +prereqs=$(bash --rpm-requires < ${1} | sort | uniq | sed -e 's/^bash(//' -e 's/)$//' -e 's/^executable(//' -e 's/)$//') +[ -z "${prereqs}" ] && exit 0 + +for prereq in ${prereqs}; do + case "${prereq}" in + /*) + echo ${prereq} + ;; + *) + which ${prereq} 2>/dev/null + ;; + esac +done | sort | uniq -- 2.39.5