#!/usr/bin/env python2 # Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ import sys, os command = os.path.basename(sys.argv[0]) import string, getopt sys.path.insert(0, "/usr/lib/portage/pym") import portage from output import * class testpatterns: def __init__(self, package, ignore=[]): package = self.gen_package(package) self.fullpackage = portage.portdb.xmatch("bestmatch-visible", package) if not self.fullpackage: raise TypeError("Invalid package: %s\n" % package) self.category, self.pkgname, self.version, self.revision = portage.catpkgsplit(self.fullpackage) self.ebuild = self.find_ebuild() self.patterns = self.usetest_patterns(ignore=ignore) def make_testpatterns(self, flaglist): tplist = [] for n in range(2 ** len(flaglist)): testpattern = [] for count in range(len(flaglist)): if (n >> count) & 1 == 1: testpattern.append("-" + flaglist[count]) else: testpattern.append(" " + flaglist[count]) tplist.append(testpattern) return tplist def usetest_patterns(self, package=None, ignore=[]): if package is None: package = self.fullpackage mykey = portage.dep_expand(package, portage.portdb) flaglist = string.split(portage.portdb.aux_get(mykey, ["IUSE"])[0]) for i in ignore: while flaglist.count(i): flaglist.remove(i) tplist = self.make_testpatterns(flaglist) return tplist def gen_package(self, package=None): if package is None: package = self.fullpackage result = package if package[-7:] == ".ebuild": if not os.path.exists(package): result = None else: ebuild_path = os.path.abspath(package) pkg_dir = os.path.dirname(ebuild_path) cat = os.path.basename(os.path.normpath(pkg_dir + "/..")) mypv = os.path.basename(ebuild_path)[:-7] result = "=" + cat + "/" + mypv if result is None: raise TypeError("Invalid package: %s\n" % result) return result def find_ebuild(self, package=None): if package is not None: category, pkgname, version, revision = portage.catpkgsplit(package) else: category, pkgname, version, revision = self.category, self.pkgname, self.version, self.revision package = self.fullpackage portdir = string.split(portage.settings["PORTDIR"]) overlay = string.split(portage.settings["PORTDIR_OVERLAY"]) for d in portdir + overlay: if revision == "r0": cand = os.path.join(d, category, pkgname, (pkgname + "-" + version)) + ".ebuild" else: cand = os.path.join(d, category, pkgname, (pkgname + "-" + version + "-" + revision)) + ".ebuild" if os.path.exists(cand): return cand raise TypeError("ebuild not found: %s\n" % package) def usage(status=1): sys.stderr.write( "%s:\n" " %s [ %s ] ebuilds or atoms...\n\n" "%s:\n" " %s is a tester for ebuild in all USE flag patterns.\n" " It generates all patterns of USE flags from IUSE variables,\n" " and lets run emerge on each USE flag.\n\n" "%s:\n" " %s (%s): Don't use colors\n" " %s (%s): Don't stop if failed to build package\n" " %s (%s): Enable debug\n" " %s (%s): Keeps your world dependency using %s\n" " %s (%s): Lets run emerge with %s\n" " %s (%s): Keeps your environment using %s\n" " %s (%s): Prints test patterns\n" " %sIGN (%s=IGN): Ignore a flag specified by IGN (this option can set multiple)\n" " %s (%s): Cleans WORKDIR after each test\n" " %s (%s): Prints verbose message\n" " %s (%s): Show help message\n" % (white("Usage"), turquoise(command), green("options"), white("Description"), command, white("Options"), green("-n"), green("--nocolor"), green("-f"), green("--force"), green("-d"), green("--debug"), green("-o"), green("--oneshot"), "--oneshot", green("-O"), green("--nodeps"), "--nodeps", green("-B"), green("--buildpkgonly"), "--buildpkgonly", green("-p"), green("--pretend"), green("-i"), green("--ignore"), green("-c"), green("--clean"), green("-v"), green("--verbose"), green("-h"), green("--help")) ) sys.exit(status) def get_patterns(package, ignore=[]): try: return testpatterns(package, ignore) except TypeError, e: sys.stderr.write(str(e)) usage() except ValueError, errpkgs: sys.stderr.write('!!! The short ebuild name "' + package + '" is ambiguous. Please specify\n') sys.stderr.write("!!! one of the following fully-qualified ebuild names instead:\n\n") for i in errpkgs[0]: sys.stderr.write(" " + green(i) + "\n") sys.stderr.write("\n") sys.exit(1) def do_pretend(packages, ignore=[]): print green(" * ") + "Test patterns are:" for package in packages: tests = get_patterns(package, ignore) print " %s %s:" % (green("*"), turquoise(tests.fullpackage)) for each in tests.patterns: print ' %s "%s"' % (green("*"), string.join(each, " ")) print sys.exit(0) if __name__ == "__main__": if (not sys.stdout.isatty()) or (portage.settings["NOCOLOR"] in ["yes", "true"]): nocolor() args = sys.argv[1:] args.sort() try: options, packages = getopt.getopt(args, "oOBdnfpi:cvh", ["oneshot", "nodeps", "buildpkgonly", "debug", "nocolor", "force", "pretend", "ignore=", "clean", "verbose", "help"]) except getopt.error, e: usage() if not packages: usage(0) myopts = [] force = 0 clean = 0 pretend = 0 redirect = " &> /dev/null " ignore = [] for opt, val in options: if opt in ["-o", "--oneshot"]: myopts.append("--oneshot") elif opt in ["-O", "--nodeps"]: myopts.append("--nodeps") elif opt in ["-B", "--buildpkgonly"]: myopts.append("--buildpkgonly") elif opt in ["-d", "--debug"]: myopts.append("--debug") elif opt in ["-n", "--nocolor"]: nocolor() elif opt in ["-f", "--force"]: force = 1 elif opt in ["-p", "--pretend"]: pretend = 1 elif opt in ["-c", "--clean"]: clean = 1 elif opt in ["-v", "--verbose"]: redirect = '' elif opt in ["-i", "--ignore"]: ignore.append(val) elif opt in ["-h", "--help"]: usage(0) if pretend: do_pretend(packages, ignore) option = string.join(myopts, " ") for package in packages: tests = get_patterns(package, ignore) errlist = {} for each in tests.patterns: use = string.join(each, " ") line = 'USE="%s" /usr/bin/emerge %s %s %s' % (use, option, "=" + tests.fullpackage, redirect) print green(" * ") + "Now testing %s using '%s'..." % (turquoise(tests.fullpackage), green(use)) if not redirect: print green(" * ") + "Running: %s" % line res = os.system(line) if res == 0: print " %s USE='%s': %s" % (green("*"), green(use), white("Success!!!")) else: print " %s USE='%s': %s" % (green("*"), green(use), red("Failed!!!")) if not force: sys.exit(1) else: if errlist.has_key(tests.fullpackage): errlist[tests.fullpackage].append(use) else: errlist[tests.fullpackage] = [use] if each is not tests.patterns[-1]: print " %s continuing force..." % green("*") if clean: line = "/usr/sbin/ebuild %s clean" % tests.ebuild print green(" * ") + "Now cleaning..." if not redirect: print green(" * ") + "Running: %s" % line os.system(line) print else: print if force and errlist: print red(" * ") + "Failed patterns are:" for pkg in errlist.keys(): print " " + "%s:" % turquoise(pkg) for use in errlist[pkg]: print " USE='%s'" % green(use) print