File: portage2craft.py

package info (click to toggle)
kde-dev-scripts 4%3A18.08.0-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 3,496 kB
  • sloc: perl: 15,466; lisp: 5,627; sh: 4,157; python: 3,892; ruby: 2,158; makefile: 16; sed: 9
file content (141 lines) | stat: -rw-r--r-- 5,654 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import sys
import re
import os
import subprocess
import argparse

import portage.dep as portage_dep

template = """import info


class subinfo(info.infoclass):
    def setTargets(self):
        self.versionInfo.setDefaultValues()

        self.description = "%(appname)s"

    def setDependencies(self):
        self.runtimeDependencies["virtual/base"] = "default"
%(qtdeps)s
%(frameworksdeps)s
%(kdeappsdeps)s
%(otherdeps)s

from Package.CMakePackageBase import *


class Package(CMakePackageBase):
    def __init__(self):
        CMakePackageBase.__init__(self)
"""

def process(app, appname, portage, craft, indent):
    print("%sProcessing %s" % (indent, app))
    ebuild = "%s-17.08.1.ebuild" % app
    qtdeps = []
    frameworksdeps = []
    kdeappsdeps = []
    otherdeps = []
    qtre = re.compile("\$\(add_qt_dep ([^)]+)\)")
    frameworksre = re.compile("\$\(add_frameworks_dep ([^)]+)\)")
    kdeappsre = re.compile("\$\(add_kdeapps_dep ([^)]+)\)")
    optionalre = re.compile("^[^\?]+\?")

    with open(os.path.join(portage, app, ebuild), 'r') as ebuildfile:
        allfile = ebuildfile.read()
        dependencies = re.search("DEPEND=\"[^\"]*\"", allfile)

        if dependencies:
            deplines = dependencies.group(0).split("\n")

            del deplines[0] # The first one is always spurious
            del deplines[-1] # The last one is always spurious

            for d in deplines:
                depline = d.strip()
                qtmatch = qtre.match(depline)
                frameworksmatch = frameworksre.match(depline)
                kdeappsmatch = kdeappsre.match(depline)

                if qtmatch:
                    qtdeps.append(qtmatch.group(1))
                elif frameworksmatch:
                    frameworksdeps.append(frameworksmatch.group(1))
                elif kdeappsmatch:
                    appname = kdeappsmatch.group(1)
                    
                    with subprocess.Popen(["find", os.path.join(craft, "kde", "applications"), "-name", appname], stdout=subprocess.PIPE) as find:
                        craftdep = find.stdout.read().decode("utf-8").strip()

                    if len(craftdep) == 0:
                        if not process(appname, appname, portage, craft, "%s\t" % indent):
                            print("%sCould not add application %s, skipping" % (indent, appname))

                            return False

                    kdeappsdeps.append(appname)
                elif optionalre.match(depline):
                    print("%sOptional dep %s" % (indent, depline))
                else:
                    if portage_dep.isvalidatom(depline):
                        packagename = portage_dep.dep_getkey(depline).split("/")[1]

                        # TODO be smart about these types of mappings
                        if packagename == "eigen":
                            packagename = "eigen3"

                        with subprocess.Popen(["find", craft, "-name", packagename], stdout=subprocess.PIPE) as find:
                            craftdep = find.stdout.read().decode("utf-8").strip()

                            if len(craftdep) > 0:
                                otherdeps.append(craftdep[len(craft):])
                            else:
                                print("%sDependency %s not found, skipping" % (indent, packagename))
                                return False
                    else:
                        print("%sGarbage: %s" % (indent,depline))

    fixedframeworks = []

    for f in frameworksdeps:
        with subprocess.Popen(["find", craft, "-name", f], stdout=subprocess.PIPE) as find:
            fixedframeworks.append(find.stdout.read().decode("utf-8").strip()[len(craft):])

    qtdepsstr = "\n".join(["        self.runtimeDependencies[\"libs/qt5/%s\"] = \"default\"" % q for q in qtdeps])
    frameworksdepsstr = "\n".join(["        self.runtimeDependencies[\"%s\"] = \"default\"" % f for f in fixedframeworks])
    kdeappsdepsstr = "\n".join(["        self.runtimeDependencies[\"kde/applications/%s\"] = \"default\"" % k for k in kdeappsdeps])
    otherdepsstr = "\n".join(["        self.runtimeDependencies[\"%s\"] = \"default\"" % o for o in otherdeps])
    recipe = template % { "appname" : appname, "qtdeps" : qtdepsstr, "frameworksdeps" : frameworksdepsstr, "otherdeps" : otherdepsstr }
    outdir = os.path.join(craft, "kde", "applications", app)

    os.mkdir(outdir)

    with open(os.path.join(outdir, "%s.py" % app), 'w') as out:
        out.write(recipe)

    return True

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Translate from portage ebuilds to craft recipes")

    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'))
    parser.add_argument("craft", help="Location of the craft root")
    parser.add_argument("--portage", help="Location of the portage ebuilds for KDE (defaults to /usr/portage/kde-apps)", default="/usr/portage/kde-apps")
    
    options = parser.parse_args()

    for l in options.applist:
        app, appname = tuple(l.strip().split(" "))
        craft_dir = os.path.join(options.craft, "kde/applications/%s" % app)
        portage_dir = os.path.join(options.portage, app)

        if os.path.exists(craft_dir):
            print("%s exists in craft, skipping" % app)
            continue

        if not os.path.exists(portage_dir):
            print("%s does not exist in portage, skipping" % app)
            continue

        process(app, appname, options.portage, options.craft, "")