diff --git a/libraries/entropyTools.py b/libraries/entropyTools.py index ec09a3580..0485a6c7d 100644 --- a/libraries/entropyTools.py +++ b/libraries/entropyTools.py @@ -113,6 +113,115 @@ def removePackageOperators(atom): atom = atom[1:] return atom +# Version compare function taken from portage_versions.py +# portage_versions.py -- core Portage functionality +# Copyright 1998-2006 Gentoo Foundation +def compareVersions(ver1, ver2, silent=1): + + if ver1 == ver2: + return 0 + mykey=ver1+":"+ver2 + try: + return vercmp_cache[mykey] + except KeyError: + pass + match1 = ver_regexp.match(ver1) + match2 = ver_regexp.match(ver2) + + # shortcut for cvs ebuilds (new style) + #if match1.group(1) and not match2.group(1): + # vercmp_cache[mykey] = 1 + # return 1 + #elif match2.group(1) and not match1.group(1): + # vercmp_cache[mykey] = -1 + # return -1 + + # building lists of the version parts before the suffix + # first part is simple + list1 = [int(match1.group(2))] + list2 = [int(match2.group(2))] + + # this part would greatly benefit from a fixed-length version pattern + if len(match1.group(3)) or len(match2.group(3)): + vlist1 = match1.group(3)[1:].split(".") + vlist2 = match2.group(3)[1:].split(".") + for i in range(0, max(len(vlist1), len(vlist2))): + # Implcit .0 is given a value of -1, so that 1.0.0 > 1.0, since it + # would be ambiguous if two versions that aren't literally equal + # are given the same value (in sorting, for example). + if len(vlist1) <= i or len(vlist1[i]) == 0: + list1.append(-1) + list2.append(int(vlist2[i])) + elif len(vlist2) <= i or len(vlist2[i]) == 0: + list1.append(int(vlist1[i])) + list2.append(-1) + # Let's make life easy and use integers unless we're forced to use floats + elif (vlist1[i][0] != "0" and vlist2[i][0] != "0"): + list1.append(int(vlist1[i])) + list2.append(int(vlist2[i])) + # now we have to use floats so 1.02 compares correctly against 1.1 + else: + list1.append(float("0."+vlist1[i])) + list2.append(float("0."+vlist2[i])) + + # and now the final letter + if len(match1.group(5)): + list1.append(ord(match1.group(5))) + if len(match2.group(5)): + list2.append(ord(match2.group(5))) + + for i in range(0, max(len(list1), len(list2))): + if len(list1) <= i: + return -1 + elif len(list2) <= i: + return 1 + elif list1[i] != list2[i]: + return list1[i] - list2[i] + + # main version is equal, so now compare the _suffix part + list1 = match1.group(6).split("_")[1:] + list2 = match2.group(6).split("_")[1:] + + for i in range(0, max(len(list1), len(list2))): + if len(list1) <= i: + s1 = ("p","0") + else: + s1 = suffix_regexp.match(list1[i]).groups() + if len(list2) <= i: + s2 = ("p","0") + else: + s2 = suffix_regexp.match(list2[i]).groups() + if s1[0] != s2[0]: + return suffix_value[s1[0]] - suffix_value[s2[0]] + if s1[1] != s2[1]: + # it's possible that the s(1|2)[1] == '' + # in such a case, fudge it. + try: r1 = int(s1[1]) + except ValueError: r1 = 0 + try: r2 = int(s2[1]) + except ValueError: r2 = 0 + return r1 - r2 + + # the suffix part is equal to, so finally check the revision + if match1.group(10): + r1 = int(match1.group(10)) + else: + r1 = 0 + if match2.group(10): + r2 = int(match2.group(10)) + else: + r2 = 0 + vercmp_cache[mykey] = r1 - r2 + return r1 - r2 + +def isnumber(x): + try: + t = int(x) + return True + except: + return False + + # Tool to run commands def spawnCommand(command, redirect = None): if redirect is not None: diff --git a/libraries/enzymeTools.py b/libraries/enzymeTools.py index ef5f2d10c..55f717a85 100644 --- a/libraries/enzymeTools.py +++ b/libraries/enzymeTools.py @@ -238,23 +238,25 @@ def build(atoms): atoms = atoms[0] else: atoms = "="+atoms[0] - print_info(green(" Sanity check on packages...")) - atomdeps, atomconflicts = calculateFullAtomsDependencies(atoms,enzymeRequestDeep) - for conflict in atomconflicts: - if getInstalledAtom(conflict) is not None: - # damn, it's installed - PackagesConflicting.append(conflict) - if PackagesConflicting != []: - print_info(red(" *")+" These are the conflicting packages:") - for i in PackagesConflicting: - print_warning(red(" *")+bold(" [CONFL] ")+i) - if (not enzymeRequestIgnoreConflicts): - print_error(red(" ***")+" Sorry, I can't continue. To force this, add --ignore-conflicts at your own risk.") - sys.exit(101) - else: - import time - print_warning((" ***")+" You are using --ignore-conflicts at your own risk.") - time.sleep(5) + + if (not enzymeRequestForceRepackage): + print_info(green(" Sanity check on packages...")) + atomdeps, atomconflicts = calculateFullAtomsDependencies(atoms,enzymeRequestDeep) + for conflict in atomconflicts: + if getInstalledAtom(conflict) is not None: + # damn, it's installed + PackagesConflicting.append(conflict) + if PackagesConflicting != []: + print_info(red(" *")+" These are the conflicting packages:") + for i in PackagesConflicting: + print_warning(red(" *")+bold(" [CONFL] ")+i) + if (not enzymeRequestIgnoreConflicts): + print_error(red(" ***")+" Sorry, I can't continue. To force this, add --ignore-conflicts at your own risk.") + sys.exit(101) + else: + import time + print_warning((" ***")+" You are using --ignore-conflicts at your own risk.") + time.sleep(5) else: toBeBuilt = validAtoms diff --git a/libraries/portageTools.py b/libraries/portageTools.py index bb8d4d520..e84c62185 100644 --- a/libraries/portageTools.py +++ b/libraries/portageTools.py @@ -187,7 +187,6 @@ def compareAtoms(atom1,atom2): from portage_versions import vercmp return vercmp(atom1,atom2) - # please always force =pkgcat/pkgname-ver if possible def getInstalledAtom(atom): rc = portage.db['/']['vartree'].dep_match(str(atom)) diff --git a/libraries/reagentTools.py b/libraries/reagentTools.py index 070527a23..937b40dda 100644 --- a/libraries/reagentTools.py +++ b/libraries/reagentTools.py @@ -32,7 +32,7 @@ import sys import string from portageTools import unpackTbz2, synthetizeRoughDependencies, getPackageRuntimeDependencies, dep_getkey, getThirdPartyMirrors -def generator(package, enzymeRequestBump = False): +def generator(package, enzymeRequestBump = False, dbconnection = None): # check if the package provided is valid validFile = False @@ -47,10 +47,16 @@ def generator(package, enzymeRequestBump = False): print_info(yellow(" * ")+red("Processing: ")+bold(packagename)+red(", please wait...")) etpData = extractPkgData(package) - # now import etpData inside the database - dbconn = databaseTools.etpDatabase(readOnly = False, noUpload = True) + if dbconnection is None: + dbconn = databaseTools.etpDatabase(readOnly = False, noUpload = True) + else: + dbconn = dbconnection + updated, revision = dbconn.handlePackage(etpData,enzymeRequestBump) - dbconn.closeDB() + + if dbconnection is None: + dbconn.commitChanges() + dbconn.closeDB() if (updated) and (revision != 0): print_info(green(" * ")+red("Package ")+bold(packagename)+red(" entry has been updated. Revision: ")+bold(str(revision))) @@ -83,6 +89,9 @@ def enzyme(options): # then exit gracefully sys.exit(0) + # open db connection + dbconn = databaseTools.etpDatabase(readOnly = False, noUpload = True) + counter = 0 etpCreated = 0 etpNotCreated = 0 @@ -91,13 +100,17 @@ def enzyme(options): tbz2name = tbz2.split("/")[len(tbz2.split("/"))-1] print_info(" ("+str(counter)+"/"+str(totalCounter)+") Processing "+tbz2name) tbz2path = etpConst['packagesstoredir']+"/"+tbz2 - rc = generator(tbz2path, enzymeRequestBump) + rc = generator(tbz2path, enzymeRequestBump, dbconn) if (rc): etpCreated += 1 os.system("mv "+tbz2path+" "+etpConst['packagessuploaddir']+"/ -f") else: etpNotCreated += 1 os.system("rm -rf "+tbz2path) + dbconn.commitChanges() + + dbconn.commitChanges() + dbconn.closeDB() print_info(green(" * ")+red("Statistics: ")+blue("Entries created/updated: ")+bold(str(etpCreated))+yellow(" - ")+darkblue("Entries discarded: ")+bold(str(etpNotCreated))) @@ -450,21 +463,51 @@ def smartgenerator(atom): pkgfilename = pkgfilepath.split("/")[len(pkgfilepath.split("/"))-1] pkgname = pkgfilename.split(".tbz2")[0] + # extra dependency check + extraDeps = [] + + pkgdependencies = dbconn.retrievePackageVar(atom,"dependencies").split() + for dep in pkgdependencies: + # remove unwanted dependencies + if (dep.find("sys-devel") == -1) \ + and (dep.find("dev-util") == -1) \ + and (dep.find("dev-lang") == -1) \ + and (dep.find("x11-libs") == -1) \ + and (dep.find("x11-proto") == -1): + extraDeps.append(dep_getkey(dep)) + + # expand dependencies + _extraDeps = [] + for dep in extraDeps: + depnames = dbconn.searchPackages(dep) + for depname in depnames: + _extraDeps.append(depname[0]) # get atom + + extraDeps = _extraDeps + + extraPackages = [] + # get their files + for dep in extraDeps: + depcontent = dbconn.retrievePackageVar(dep,"download") + extraPackages.append(depcontent.split("/")[len(depcontent.split("/"))-1]) + + pkgneededlibs = list(set(pkgneededlibs)) + extraPackages = list(set(extraPackages)) + + # now check - do a for cycle if (not os.path.isfile(etpConst['packagesbindir']+"/"+pkgfilename)): # I have to download it # FIXME: complete this + # do it when we have all the atoms that should be downloaded print "download needed: not yet implemented" - #print "DEBUG: "+pkgneededlibs - # create the working directory pkgtmpdir = etpConst['packagestmpdir']+"/"+pkgname #print "DEBUG: "+pkgtmpdir if os.path.isdir(pkgtmpdir): os.system("rm -rf "+pkgtmpdir) os.makedirs(pkgtmpdir) - os.makedirs(pkgtmpdir+"/libs") uncompressTarBz2(etpConst['packagesbindir']+"/"+pkgfilename,pkgtmpdir) binaryExecs = [] @@ -480,6 +523,11 @@ def smartgenerator(atom): binaryExecs.append(file) # check if file is executable + # now uncompress all the rest + for dep in extraPackages: + uncompressTarBz2(etpConst['packagesbindir']+"/"+dep,pkgtmpdir) + + #print "DEBUG: "+str(binaryExecs) librariesBlacklist = [] @@ -508,40 +556,32 @@ def smartgenerator(atom): _pkgneededlibs.append(lib) libdir = os.path.dirname(lib) #print lib - if not os.path.isdir(pkgtmpdir+"/libs/"+libdir): - os.makedirs(pkgtmpdir+"/libs/"+libdir) - os.system("cp -p "+lib+" "+pkgtmpdir+"/libs/"+libdir) + if not os.path.isdir(pkgtmpdir+libdir): + os.makedirs(pkgtmpdir+libdir) + os.system("cp -p "+lib+" "+pkgtmpdir+libdir) # ^^ libraries copied in place! now link! (with magic) pkgneededlibs = _pkgneededlibs # collect libraries in the directories - - for bin in binaryExecs: - # libs dir in in pkgtmpdir+/libs - # we are in pkgtmpdir+os.path.dirname(bin) - # calculate recursion level - bindir = pkgtmpdir+os.path.dirname(bin)+"/" - libsdir = pkgtmpdir+"/libs/" - bindirlevel = len(bindir.split("/")) - libsdirlevel = len(libsdir.split("/")) - recursion = bindirlevel-libsdirlevel+1 - #print str(recursion) - recursiontree = "" - for i in range(recursion): - recursiontree += "../" - #print recursiontree - for lib in pkgneededlibs: - os.system( - "cd "+bindir+";" - "ln -sf "+recursiontree+"libs"+lib+" ." - ) - + # FIXME: create .desktop files? # now create the bash script for each binaryExecs for bin in binaryExecs: bindirname = os.path.dirname(bin) + + # FIXME: add support for + # - Python + # - Perl bashScript = [] bashScript.append("#!/bin/sh\n") - bashScript.append('PATH="$PWD:$PWD/libs" LD_LIBRARY_PATH="$PWD'+bindirname+'" .'+bin+' "$@"\n') + bashScript.append( + 'export PATH=$PWD:$PWD/sbin:$PWD/bin:$PWD/usr/bin:$PWD/usr/sbin:$PWD/usr/X11R6/bin:$PWD/libexec:$PWD/usr/local/bin:$PWD/usr/local/sbin:$PATH\n' + 'export LD_LIBRARY_PATH=$PWD/lib:$PWD/usr/lib:$PWD/usr/qt/3/lib:$PWD/usr/kde/3.5/lib:$LD_LIBRARY_PATH\n' + 'export KDEDIRS=$PWD/usr/kde/3.5:$PWD/usr:$KDEDIRS\n' + 'export MANPATH=$PWD/share/man:$MANPATH\n' + 'export GUILE_LOAD_PATH=$PWD/share/:$GUILE_LOAD_PATH\n' + 'export SCHEME_LIBRARY_PATH=$PWD/share/slib:$SCHEME_LIBRARY_PATH\n' + '$PWD'+bin+' "$@"\n' + ) binname = bin.split("/")[len(bin.split("/"))-1] f = open(pkgtmpdir+"/"+binname,"w") f.writelines(bashScript) @@ -553,4 +593,6 @@ def smartgenerator(atom): # now compress in .tar.bz2 and place in etpConst['smartappsdir'] #print etpConst['smartappsdir']+"/"+pkgname+"-"+etpConst['currentarch']+".tar.bz2" #print pkgtmpdir+"/" - compressTarBz2(etpConst['smartappsdir']+"/"+pkgname+"-"+etpConst['currentarch']+".tar.bz2",pkgtmpdir+"/") \ No newline at end of file + compressTarBz2(etpConst['smartappsdir']+"/"+pkgname+"-"+etpConst['currentarch']+".tar.bz2",pkgtmpdir+"/") + + dbconn.closeDB() \ No newline at end of file