summaryrefslogtreecommitdiffstats
path: root/build_tools/clarch/larch/run/gen_repo
diff options
context:
space:
mode:
Diffstat (limited to 'build_tools/clarch/larch/run/gen_repo')
-rwxr-xr-xbuild_tools/clarch/larch/run/gen_repo206
1 files changed, 206 insertions, 0 deletions
diff --git a/build_tools/clarch/larch/run/gen_repo b/build_tools/clarch/larch/run/gen_repo
new file mode 100755
index 0000000..86e7b85
--- /dev/null
+++ b/build_tools/clarch/larch/run/gen_repo
@@ -0,0 +1,206 @@
+#!/usr/bin/env python
+
+# gen_repo - build a repository db file from a set of packages
+#
+# Author: Michael Towers (gradgrind) <mt.42@web.de>
+#
+# This file is part of the larch project.
+#
+# larch is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# larch is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with larch; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+#----------------------------------------------------------------------------
+#
+# Version 1.5 // 7th July 2007
+
+import os
+import os.path
+import sys
+import tarfile
+from types import *
+import re
+from subprocess import check_call
+
+# to add a package:
+#check_call(["repo-add", dbfile, pkg, pkg, pkg, ...])
+
+# Regex to remove version comparison from package dependency
+onlyname = re.compile("([^=><]+).*")
+
+def create_db(dbname, packagesdir, dep_ignore_list):
+ os.chdir(packagesdir)
+ dbfile = dbname + ".db.tar.gz"
+ if os.path.exists(dbfile):
+ os.remove(dbfile)
+
+ # Get a list of packages
+ packages = filter(lambda s: s.endswith(".pkg.tar.gz"), os.listdir("."))
+ packages.sort()
+
+ # Use 'repo-add' to build the repo
+ check_call(["repo-add", dbfile] + packages)
+
+ # Make a dict for keeping track of dependencies
+ dep_dict = {}
+ for p in packages:
+ pkg_dict = get_pkg_info(p)
+ pkg_name = pkg_dict["pkgname"]
+ pkg_dbname = pkg_name + "-" + pkg_dict["pkgver"]
+ # Add dependency info to dependency dict
+ for d in pkg_dict["depend"]:
+ # But also need to cater for versioning!!!
+ # I will just ignore it here ...
+ dm = onlyname.match(d)
+ if not dm:
+ if d:
+ print "DEBUG: package %s, dependency = '%s'" % (pkg_name, d)
+ continue
+ d = dm.group(1)
+ if not dep_dict.has_key(d):
+ dep_dict[d] = [False]
+ dep_dict[d].append(pkg_name)
+ # Mark packages provided by this one
+ for p in (pkg_dict["provides"] + [pkg_name]):
+ if dep_dict.has_key(p):
+ dep_dict[p][0] = True
+ else:
+ dep_dict[p] = [True]
+ # Mark packages in ignore list
+ for p in dep_ignore_list:
+ if dep_dict.has_key(p):
+ dep_dict[p][0] = True
+
+ # Now display unsatisfied dependencies
+ # Should add the possibility of declaring a list of packages
+ # available (e.g. the base set, or all those on the live CD ..."
+ print "-------------\nUnsatisfied dependencies:"
+ for d, r in dep_dict.items():
+ if not r[0]:
+ print " ", d, "- needed by: ",
+ for p in r[1:]:
+ print p, " ",
+ print ""
+
+
+
+def get_pkg_info(pkg):
+ tf = tarfile.open(pkg, "r:gz")
+ pkginfo = tf.extractfile(".PKGINFO")
+ pkg_dict = {# the first ones go to 'desc'
+ "pkgname" : None,
+ "pkgver" : None,
+ # from here they are optional, and can occur more than once
+ "depend" : [],
+ "provides" : [],
+ }
+ while True:
+ l = pkginfo.readline().strip()
+ if not l: break
+ if l[0] == "#": continue
+ split3 = l.split(None, 2)
+ while len(split3) < 3: split3.append("")
+ key, eq, value = split3
+ if not pkg_dict.has_key(key): continue
+ val = pkg_dict[key]
+ if val == None:
+ pkg_dict[key] = value
+ continue
+ if not isinstance(val, ListType):
+ print "Unexpected situation ...\n key [oldvalue] <- newvalue"
+ print key, "[%s]" % val, "<-", value
+ sys.exit(1)
+ pkg_dict[key].append(value)
+ pkginfo.close()
+ return pkg_dict
+
+def cat(path):
+ """Python version of 'cat'"""
+ fp = open(path, "r")
+ op = ""
+ for l in fp:
+ op += l
+ fp.close()
+ return op
+
+def usage():
+ print """
+ gen_repo package-dir [repo-name] [-- ignore-list]
+
+ Generate a pacman db file for the packages in package-dir.
+
+ If repo-name is given, this will be used as the name for the repository,
+ otherwise the name of the directory containing the packages will be used.
+
+ All dependencies of the packages in the repository will be listed to
+ standard output, but a list of packages not to be included in this list
+ can be specified:
+ ignore-list should be either a file containing the names of packages
+ not to be listed as dependencies (separated by space or newline), or a
+ directory containing 'package directories', like /var/abs/base or
+ /var/lib/pacman/local
+ """
+ sys.exit(1)
+
+if __name__ == "__main__":
+
+ if len(sys.argv) < 2:
+ usage()
+ if os.getuid() != 0:
+ print "Must be root to run this"
+ sys.exit(1)
+ pkgdir = sys.argv[1]
+ if (len(sys.argv) == 2) or (sys.argv[2] == "--"):
+ dbname = os.path.basename(os.path.abspath(pkgdir))
+ i = 2
+ else:
+ dbname = sys.argv[2]
+ i = 3
+ if len(sys.argv) == i:
+ ignore_list = []
+ elif (len(sys.argv) == i+2) and (sys.argv[i] == "--"):
+ ignore_list = sys.argv[i+1]
+ else:
+ usage()
+ if not os.path.isdir(pkgdir):
+ print "\n1st argument must be a directory"
+ sys.exit(1)
+ print "\nCreating pacman database (%s.db.tar.gz) file in %s" % (dbname, pkgdir)
+
+ if ignore_list:
+ # Get list of packages to be ignored in dependency list
+ if os.path.isfile(ignore_list):
+ # A simple file containing the names of packages to ignore
+ # separated by space or newline.
+ ignore_list = cat(ignore_list).split()
+ elif os.path.isdir(ignore_list):
+ # A directory containing packages or package-directories (like in abs)
+ l = os.listdir(ignore_list)
+ # See if there are packages in this directory
+ lp = filter(lambda s: s.endswith(".pkg.tar.gz"), l)
+ if lp:
+ l = map(lambda s: s.replace(".pkg.tar.gz", ""), lp)
+ re1 = re.compile("(.+)-[^-]+?-[0-9]+")
+ ignore_list = []
+ for f in l:
+ m = re1.match(f)
+ if m:
+ ignore_list.append(m.group(1))
+ else:
+ # the directory contains just the package names (like abs)
+ ignore_list.append(m)
+ else:
+ print "!!! Invalid ignore-list"
+ usage()
+
+ create_db(dbname, pkgdir, ignore_list)