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()) |