Gentoo Archives: gentoo-commits

From: Michael Palimaka <kensington@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/kde:master commit in: Documentation/maintainers/
Date: Thu, 28 Dec 2017 13:43:55
Message-Id: 1514468618.a050ce84b3cf99236a8d452c4688d5d5b69bc1ea.kensington@gentoo
1 commit: a050ce84b3cf99236a8d452c4688d5d5b69bc1ea
2 Author: Michael Palimaka <kensington <AT> gentoo <DOT> org>
3 AuthorDate: Thu Dec 28 13:42:59 2017 +0000
4 Commit: Michael Palimaka <kensington <AT> gentoo <DOT> org>
5 CommitDate: Thu Dec 28 13:43:38 2017 +0000
6 URL: https://gitweb.gentoo.org/proj/kde.git/commit/?id=a050ce84
7
8 Documentation: add script to compare CMakeLists and ebuild dependencies
9
10 Documentation/maintainers/cmake_ebuild_check.py | 146 ++++++++++++++++++++++++
11 1 file changed, 146 insertions(+)
12
13 diff --git a/Documentation/maintainers/cmake_ebuild_check.py b/Documentation/maintainers/cmake_ebuild_check.py
14 new file mode 100755
15 index 0000000000..27786cf4cb
16 --- /dev/null
17 +++ b/Documentation/maintainers/cmake_ebuild_check.py
18 @@ -0,0 +1,146 @@
19 +#!/usr/bin/env python3
20 +#
21 +# Copyright (c) 2017 Michael Palimaka <kensington@g.o>
22 +#
23 +# Permission is hereby granted, free of charge, to any person obtaining a copy
24 +# of this software and associated documentation files (the "Software"), to deal
25 +# in the Software without restriction, including without limitation the rights
26 +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 +# copies of the Software, and to permit persons to whom the Software is
28 +# furnished to do so, subject to the following conditions:
29 +#
30 +# The above copyright notice and this permission notice shall be included in
31 +# all copies or substantial portions of the Software.
32 +#
33 +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39 +# THE SOFTWARE.
40 +
41 +import argparse
42 +import os
43 +import sys
44 +import subprocess
45 +import cmake_dep_check as cdc
46 +import portage
47 +
48 +
49 +def qatom(atom):
50 + output = subprocess.check_output(['qatom', '--format', '%{CATEGORY}|%{PN}|%{PV}|%[PR]|%[SLOT]|%[pfx]|%[sfx]', atom])
51 + return output.decode('utf-8').split('|')
52 +
53 +
54 +def get_cmake_deps(ebuild, repo):
55 + cpv = qatom(ebuild)
56 + settings = portage.config(config_root='/')
57 +
58 + tmpdir = os.path.join(settings.get('PORTAGE_TMPDIR'), 'portage')
59 + tmp_path = os.path.join(tmpdir, cpv[0], cpv[1] + '-' + cpv[2])
60 + repo_path = portage.db['/']["vartree"].settings.repositories.treemap.get(repo)
61 + ebuild_path = os.path.join(repo_path, cpv[0], cpv[1], cpv[1] + '-' + cpv[2] + '.ebuild')
62 +
63 + subprocess.call(['ebuild', ebuild_path, 'clean', 'prepare'], stdout=subprocess.DEVNULL)
64 +
65 + deps = cdc.getDeps(os.path.join(tmp_path))
66 +
67 + subprocess.call(['ebuild', ebuild_path, 'clean'])
68 +
69 + return deps
70 +
71 +
72 +def get_ebuild_deps(ebuild):
73 + porttree = portage.db[portage.root]['porttree']
74 + depstr = porttree.dbapi.aux_get(ebuild, ['DEPEND', 'RDEPEND', 'PDEPEND'])
75 +
76 + depend = portage.dep.use_reduce(depstr[0], matchall=True, flat=True)
77 + rdepend = portage.dep.use_reduce(depstr[1], matchall=True, flat=True)
78 + pdepend = portage.dep.use_reduce(depstr[2], matchall=True, flat=True)
79 +
80 + all_depend = set(depend + rdepend + pdepend)
81 +
82 + return(all_depend)
83 +
84 +
85 +def get_ebuild_repo(ebuild):
86 + porttree = portage.db[portage.root]['porttree']
87 + repo = porttree.dbapi.aux_get(ebuild, ['repository'])
88 +
89 + return repo[0]
90 +
91 +
92 +def clean_dep(dep):
93 + if dep.startswith('!') or dep == '||':
94 + return False
95 +
96 + parts = qatom(dep)
97 + cp = parts[0] + '/' + parts[1]
98 +
99 + return cp
100 +
101 +
102 +def main():
103 + parser = argparse.ArgumentParser(description='Compare CMakeLists.txt and ebuild dependencies')
104 + parser.add_argument('ebuild', help='app-foo/bar-1.2.3', nargs=1)
105 + parser.add_argument('--possible-bogus-ebuild', dest='bogusebuild', action='store_const', const=True, help='Show dependencies that appear in CMakeLists.txt but not the ebuild')
106 +
107 + args = parser.parse_args()
108 +
109 + ebuild = args.ebuild[0]
110 +
111 + ebuild_deps = get_ebuild_deps(ebuild)
112 + cmake_deps = get_cmake_deps(ebuild, get_ebuild_repo(ebuild))
113 +
114 + cmake_deps_merged = []
115 +
116 + for cmake, deps in cmake_deps.items():
117 + for dep in deps:
118 + if dep.startswith('ERROR'):
119 + print(dep)
120 + continue
121 + if len(dep) == 0:
122 + continue
123 + clean = clean_dep(dep)
124 + if clean:
125 + cmake_deps_merged.append(clean)
126 +
127 + ebuild_deps_clean = []
128 +
129 + for dep in ebuild_deps:
130 + clean = clean_dep(dep)
131 + if clean:
132 + ebuild_deps_clean.append(clean)
133 +
134 + missing_cmake = []
135 + missing_ebuild = []
136 +
137 + for dep in cmake_deps_merged:
138 + if dep not in ebuild_deps_clean:
139 + missing_ebuild.append(dep)
140 +
141 + for dep in ebuild_deps_clean:
142 + if dep not in cmake_deps_merged:
143 + missing_cmake.append(dep)
144 +
145 + missing_cmake = sorted(set(missing_cmake))
146 + missing_ebuild = sorted(set(missing_ebuild))
147 +
148 + if len(missing_ebuild) > 0:
149 + print('DEPENDENCIES IN CMAKELISTS BUT NOT EBUILD:')
150 + print('==========================================')
151 + for dep in missing_ebuild:
152 + print(dep)
153 + else:
154 + print('Did not find any dependencies in CMakeLists that do not appear in the ebuild')
155 +
156 + if len(missing_cmake) > 0 and args.bogusebuild is True:
157 + print('DEPENDENCIES IN EBUILD BUT NOT IN CMAKELISTS:')
158 + print('=============================================')
159 + for dep in missing_cmake:
160 + print(dep)
161 +
162 +
163 +if __name__ == '__main__':
164 + sys.exit(main())