1import sys 2import re 3import os 4import subprocess 5import argparse 6 7import portage.dep as portage_dep 8 9template = """import info 10 11 12class subinfo(info.infoclass): 13 def setTargets(self): 14 self.versionInfo.setDefaultValues() 15 16 self.description = "%(appname)s" 17 18 def setDependencies(self): 19 self.runtimeDependencies["virtual/base"] = "default" 20%(qtdeps)s 21%(frameworksdeps)s 22%(kdeappsdeps)s 23%(otherdeps)s 24 25from Package.CMakePackageBase import * 26 27 28class Package(CMakePackageBase): 29 def __init__(self): 30 CMakePackageBase.__init__(self) 31""" 32 33def process(app, appname, portage, craft, indent): 34 print("%sProcessing %s" % (indent, app)) 35 ebuild = "%s-17.08.1.ebuild" % app 36 qtdeps = [] 37 frameworksdeps = [] 38 kdeappsdeps = [] 39 otherdeps = [] 40 qtre = re.compile("\$\(add_qt_dep ([^)]+)\)") 41 frameworksre = re.compile("\$\(add_frameworks_dep ([^)]+)\)") 42 kdeappsre = re.compile("\$\(add_kdeapps_dep ([^)]+)\)") 43 optionalre = re.compile("^[^\?]+\?") 44 45 with open(os.path.join(portage, app, ebuild), 'r') as ebuildfile: 46 allfile = ebuildfile.read() 47 dependencies = re.search("DEPEND=\"[^\"]*\"", allfile) 48 49 if dependencies: 50 deplines = dependencies.group(0).split("\n") 51 52 del deplines[0] # The first one is always spurious 53 del deplines[-1] # The last one is always spurious 54 55 for d in deplines: 56 depline = d.strip() 57 qtmatch = qtre.match(depline) 58 frameworksmatch = frameworksre.match(depline) 59 kdeappsmatch = kdeappsre.match(depline) 60 61 if qtmatch: 62 qtdeps.append(qtmatch.group(1)) 63 elif frameworksmatch: 64 frameworksdeps.append(frameworksmatch.group(1)) 65 elif kdeappsmatch: 66 appname = kdeappsmatch.group(1) 67 68 with subprocess.Popen(["find", os.path.join(craft, "kde", "applications"), "-name", appname], stdout=subprocess.PIPE) as find: 69 craftdep = find.stdout.read().decode("utf-8").strip() 70 71 if len(craftdep) == 0: 72 if not process(appname, appname, portage, craft, "%s\t" % indent): 73 print("%sCould not add application %s, skipping" % (indent, appname)) 74 75 return False 76 77 kdeappsdeps.append(appname) 78 elif optionalre.match(depline): 79 print("%sOptional dep %s" % (indent, depline)) 80 else: 81 if portage_dep.isvalidatom(depline): 82 packagename = portage_dep.dep_getkey(depline).split("/")[1] 83 84 # TODO be smart about these types of mappings 85 if packagename == "eigen": 86 packagename = "eigen3" 87 88 with subprocess.Popen(["find", craft, "-name", packagename], stdout=subprocess.PIPE) as find: 89 craftdep = find.stdout.read().decode("utf-8").strip() 90 91 if len(craftdep) > 0: 92 otherdeps.append(craftdep[len(craft):]) 93 else: 94 print("%sDependency %s not found, skipping" % (indent, packagename)) 95 return False 96 else: 97 print("%sGarbage: %s" % (indent,depline)) 98 99 fixedframeworks = [] 100 101 for f in frameworksdeps: 102 with subprocess.Popen(["find", craft, "-name", f], stdout=subprocess.PIPE) as find: 103 fixedframeworks.append(find.stdout.read().decode("utf-8").strip()[len(craft):]) 104 105 qtdepsstr = "\n".join([" self.runtimeDependencies[\"libs/qt5/%s\"] = \"default\"" % q for q in qtdeps]) 106 frameworksdepsstr = "\n".join([" self.runtimeDependencies[\"%s\"] = \"default\"" % f for f in fixedframeworks]) 107 kdeappsdepsstr = "\n".join([" self.runtimeDependencies[\"kde/applications/%s\"] = \"default\"" % k for k in kdeappsdeps]) 108 otherdepsstr = "\n".join([" self.runtimeDependencies[\"%s\"] = \"default\"" % o for o in otherdeps]) 109 recipe = template % { "appname" : appname, "qtdeps" : qtdepsstr, "frameworksdeps" : frameworksdepsstr, "otherdeps" : otherdepsstr } 110 outdir = os.path.join(craft, "kde", "applications", app) 111 112 os.mkdir(outdir) 113 114 with open(os.path.join(outdir, "%s.py" % app), 'w') as out: 115 out.write(recipe) 116 117 return True 118 119if __name__ == "__main__": 120 parser = argparse.ArgumentParser(description="Translate from portage ebuilds to craft recipes") 121 122 parser.add_argument("applist", help="List of applications to translate. Each line in this file is of the form <ebuild name> <application name>", type=argparse.FileType('r')) 123 parser.add_argument("craft", help="Location of the craft root") 124 parser.add_argument("--portage", help="Location of the portage ebuilds for KDE (defaults to /usr/portage/kde-apps)", default="/usr/portage/kde-apps") 125 126 options = parser.parse_args() 127 128 for l in options.applist: 129 app, appname = tuple(l.strip().split(" ")) 130 craft_dir = os.path.join(options.craft, "kde/applications/%s" % app) 131 portage_dir = os.path.join(options.portage, app) 132 133 if os.path.exists(craft_dir): 134 print("%s exists in craft, skipping" % app) 135 continue 136 137 if not os.path.exists(portage_dir): 138 print("%s does not exist in portage, skipping" % app) 139 continue 140 141 process(app, appname, options.portage, options.craft, "") 142