]> TLD Linux GIT Repositories - TLD.git/blobdiff - pld-builder.new/PLD_Builder/deps.py
- from https://github.com/pld-linux/pld-builder.new
[TLD.git] / pld-builder.new / PLD_Builder / deps.py
diff --git a/pld-builder.new/PLD_Builder/deps.py b/pld-builder.new/PLD_Builder/deps.py
new file mode 100644 (file)
index 0000000..404b25c
--- /dev/null
@@ -0,0 +1,121 @@
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import string
+from chroot import *
+from util import *
+
+__all__ = ['compute_deps', 'remove_list']
+
+def compute_deps():
+    """Compute dependenecies between RPM installed on system.
+
+    Return dictionary from name of package to list of packages required by it.
+    Produce some warnings and progress information to stderr.
+    """
+    # pkg-name -> list of stuff returned by rpm -qR
+    rpm_req = {}
+    # --whatprovides ...
+    rpm_prov = {}
+    # list of required files
+    req_files = {}
+
+    def get_req():
+        msg("rpm-req... ")
+        f = chr_popen("rpm -qa --qf '@\n%{NAME}\n[%{REQUIRENAME}\n]'")
+        cur_pkg = None
+        while 1:
+            l = f.readline()
+            if l == "": break
+            l = string.strip(l)
+            if l == "@":
+                cur_pkg = string.strip(f.readline())
+                rpm_req[cur_pkg] = []
+                continue
+            rpm_req[cur_pkg].append(l)
+            if l[0] == '/':
+                req_files[l] = 1
+        f.close()
+        msg("done\n")
+
+    def add_provides(pkg, what):
+        if rpm_prov.has_key(what):
+            msg("[%s: %s, %s] " % (what, rpm_prov[what], pkg))
+        else:
+            rpm_prov[what] = pkg
+
+    def get_prov():
+        msg("rpm-prov... ")
+        f = chr_popen("rpm -qa --qf '@\n%{NAME}\n[%{PROVIDENAME}\n]'")
+        cur_pkg = None
+        while 1:
+            l = f.readline()
+            if l == "": break
+            l = string.strip(l)
+            if l == "@":
+                cur_pkg = string.strip(f.readline())
+                continue
+            add_provides(cur_pkg, l)
+            if l[0] == '/':
+                # already provided
+                del req_files[l]
+        f.close()
+        msg("done\n")
+
+    def get_prov_files():
+        msg("rpm-files... ")
+        f = chr_popen("rpm -qa --qf '@\n%{NAME}\n[%{FILENAMES}\n]'")
+        cur_pkg = None
+        while 1:
+            l = f.readline()
+            if l == "": break
+            l = string.strip(l)
+            if l == "@":
+                cur_pkg = string.strip(f.readline())
+                continue
+            if req_files.has_key(l):
+                add_provides(cur_pkg, l)
+        f.close()
+        msg("done\n")
+
+    def compute():
+        msg("computing deps... ")
+        for pkg, reqs in rpm_req.items():
+            pkg_reqs = []
+            for req in reqs:
+                if req[0:7] == "rpmlib(": continue
+                if rpm_prov.has_key(req):
+                    if rpm_prov[req] not in pkg_reqs:
+                        pkg_reqs.append(rpm_prov[req])
+                else:
+                    msg("[%s: %s] " % (pkg, req))
+            requires[pkg] = pkg_reqs
+        msg("done\n")
+
+    # map from pkg-name to list of pkg-names required by it
+    # this is result
+    requires = {}
+
+    get_req()
+    get_prov()
+    get_prov_files()
+    compute()
+    return requires
+
+def remove_list(req, need):
+    """List of packages scheduled for removal.
+
+    Given dependency information and list of needed packages compute list
+    of packages that don't need to be present.
+    """
+    need_m = {}
+    def close(n):
+        if need_m.has_key(n): return
+        need_m[n] = 1
+        if not req.has_key(n): return
+        for k in req[n]:
+            close(k)
+    for n in need: close(n)
+    rm = []
+    for p in req.keys():
+        if not need_m.has_key(p): rm.append(p)
+    return rm