diff options
Diffstat (limited to 'build_tools/l7/larch0/scripts/gen_repo')
-rwxr-xr-x | build_tools/l7/larch0/scripts/gen_repo | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/build_tools/l7/larch0/scripts/gen_repo b/build_tools/l7/larch0/scripts/gen_repo new file mode 100755 index 0000000..86e7b85 --- /dev/null +++ b/build_tools/l7/larch0/scripts/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) |