File: dh_qmldeps

package info (click to toggle)
pkg-kde-tools 0.20.0
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 916 kB
  • sloc: perl: 4,238; python: 686; ansic: 628; sh: 441; makefile: 5
file content (176 lines) | stat: -rwxr-xr-x 5,710 bytes parent folder | download
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2023 Sandro Knauß <hefee@debian.org>
# SPDX-License-Identifier: LGPL-2.0-or-later

#INTROSPECTABLE: CONFIG-FILES pkgfile(qmlfiles) path(debian/qmldeps.overrides) path(debian/qmldeps.optional)

import logging
import os
import pathlib
import subprocess
import sys
import typing

from debian.debian_support import DpkgArchTable

PKGKDE_GETQMLDEPENDS = "pkgkde-getqmldepends"

sys.path.insert(0,'/usr/share/pkg-kde-tools')
parent_path = pathlib.Path(__file__).parent.absolute()
if parent_path not in ("/usr/bin", "/bin"):
    sys.path.insert(0, str(parent_path))
    PKGKDE_GETQMLDEPENDS = parent_path/"pkgkde-getqmldepends"

from pythonlib import qmldeps

logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: %(message)s')

log = logging.getLogger()
log.setLevel(logging.INFO)

def qmlfiles_args(pkg_name: str) -> list[str | pathlib.Path]:
    qmlfiles_path = pathlib.Path(f"debian/{pkg_name}.qmlfiles")
    ret = []
    multiarch = qmldeps.deb_host_multiarch()

    replace_args = {
            "${DEB_HOST_MULTIARCH}" : lambda x: multiarch,
            "${QMLDEPS_AUTODETECT_MODULES}": autodetect_modules,
            "${QMLDEPS_AUTODETECT_FILES}": autodetect_files,
            "${QMLDEPS_AUTODETECT_SOURCE_FILES}": autodetect_source_files,
    }

    if qmlfiles_path.exists():
        content = qmlfiles_path.read_text()
        args = content.split()
        for arg in args:
            for test_arg,func in replace_args.items():
                if test_arg == arg:
                    arg = func(pkg_name)
                elif test_arg in arg:
                    arg = arg.replace(test_arg, func(pkg_name))

            if "*" in arg:
                ret.extend(pathlib.Path().glob(arg))
            elif type(arg) == list:
                ret.extend(arg)
            else:
                ret.append(arg)
    return ret

def qt_version_from_files(files: list[str|pathlib.Path]) -> typing.Optional[str]:
    qt_version = None
    for path in files:
        if qt_version:
            break
        if not isinstance(path, pathlib.Path):
            continue
        if not qt_version:
            for p, ver in qt_versions.items():
                if p in path.parts:
                    qt_version = ver
                    break
    return qt_version

def autodetect_modules(pkg_name: str) -> list[pathlib.Path]:
    """returns a list of all qml module paths shipped within a binary package."""
    return list(p.parent for p in pathlib.Path(f"debian/{pkg_name}").glob("**/qmldir"))

def autodetect_files(pkg_name: str) -> list[pathlib.Path]:
    """returns a list of all qml files shipped within a binnry package."""
    return list(pathlib.Path(f"debian/{pkg_name}").glob("**/*.qml"))

def autodetect_source_files(pkg_name: str) -> list[pathlib.Path]:
    """returns a list of all qml modules that are shipped within the source package and all binary packages.
       This function is mostly usefull for a single binary package mode.
       pkg_name is not used. It needs the same arguments than the other autodetect functions."""
    return list(pathlib.Path(".").glob("**/*.qml"))


qt_configs = qmldeps.get_config()
qt_versions = {i.qt_name: k for k,i in qt_configs.items()}
control = qmldeps.DebianControl(pathlib.Path("debian/control"))
single_pkg = control.isSinglePackage()

failed = False

getqmldepends_glob_args = sys.argv[1:]

arch_any = "-a" in getqmldepends_glob_args
arch_all = "-i" in getqmldepends_glob_args

try:
    host_arch = os.environ["DEB_HOST_ARCH"]
except KeyError:
    host_arch = subprocess.check_output(["dpkg-architecture", "-qDEB_HOST_ARCH"]).strip().decode()

archtable = DpkgArchTable.load_arch_table()

if not arch_any and not arch_all:
    arch_any = True
    arch_all = True

for pkg_name, pkg in control.packages.items():
    archs =  pkg.get("Architecture", "").split()

    skip = True
    if archs == []:
        skip = False
    elif arch_all and "all" in archs:
        skip = False
    elif arch_any and any(archtable.matches_architecture(host_arch, arch) for arch in archs):
        skip = False

    if skip:
        continue

    for qt_version, config_qt in qt_configs.items():
        var_name = config_qt.substvar_name("Depends")
        var = f"${{{var_name}}}"
        for field in ("Depends", "Recommends", "Suggests"):
            if var in pkg.get(field, ""):
                break
        else:
            continue
        break
    else:
        qt_version = None

    extra_args = qmlfiles_args(pkg_name)

    if not extra_args:
        if root_path := autodetect_modules(pkg_name):
            extra_args = ["-rootPath"] + root_path

    if not extra_args:
        files = autodetect_files(pkg_name)
        if single_pkg and not files:
            files = autodetect_source_files(pkg_name)

        if files:
            extra_args = ["-qmlFiles"] + files

    if extra_args:
        if not qt_version:
            qt_version = qt_version_from_files(extra_args)
        cmd = [PKGKDE_GETQMLDEPENDS]
        cmd.extend(getqmldepends_glob_args)

        cmd.extend(["-p", pkg_name])
        if qt_version:
            cmd.extend(["--qt", qt_version])

        cmd.append("--")
        cmd.extend(extra_args)

        log.info(f"Execute {' '.join(str(i) for i in cmd)}")
        try:
            subprocess.check_call(cmd)
        except subprocess.CalledProcessError as e:
            log.error(f"{PKGKDE_GETQMLDEPENDS} failed with {e.returncode}.")
            failed = True
    elif qt_version or single_pkg:
        log.error(f"{pkg_name}: No automatic qml files found for package you need to add the files by hand to debian/{pkg_name}.qmlfiles")

if failed:
    sys.exit(1)