1 |
commit: 3ec97d8f0cd427b7b9874b05f55d1aec5a1df8b0 |
2 |
Author: Matt Turner <mattst88 <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Feb 21 20:59:34 2022 +0000 |
4 |
Commit: Matt Turner <mattst88 <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon May 2 18:44:51 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=3ec97d8f |
7 |
|
8 |
repoman: Remove |
9 |
|
10 |
RepoMan sez: So long and thanks for all the fish! I'll be enjoying my |
11 |
retirement now. Haven't I done enough to deserve that? |
12 |
|
13 |
Bug: https://bugs.gentoo.org/835013 |
14 |
Signed-off-by: Matt Turner <mattst88 <AT> gentoo.org> |
15 |
|
16 |
.github/workflows/black.yml | 2 +- |
17 |
.gitignore | 2 - |
18 |
cnf/make.globals | 2 +- |
19 |
lib/_emerge/Package.py | 5 +- |
20 |
lib/_emerge/depgraph.py | 2 +- |
21 |
lib/portage/dbapi/__init__.py | 12 - |
22 |
lib/portage/dbapi/porttree.py | 6 +- |
23 |
.../test_lazy_import_portage_baseline.py | 2 +- |
24 |
lib/portage/tests/resolver/ResolverPlayground.py | 10 - |
25 |
man/ebuild.5 | 6 +- |
26 |
man/make.conf.5 | 8 +- |
27 |
man/portage.5 | 42 +- |
28 |
repoman/.repoman_not_installed | 0 |
29 |
repoman/MANIFEST.in | 4 - |
30 |
repoman/NEWS | 14 - |
31 |
repoman/README | 49 -- |
32 |
repoman/RELEASE-NOTES | 213 ------ |
33 |
repoman/TEST-NOTES | 45 -- |
34 |
repoman/bin/repoman | 56 -- |
35 |
repoman/cnf/linechecks/linechecks.yaml | 34 - |
36 |
repoman/cnf/metadata.xsd | 548 -------------- |
37 |
repoman/cnf/qa_data/qa_data.yaml | 139 ---- |
38 |
repoman/cnf/repository/linechecks.yaml | 248 ------ |
39 |
repoman/cnf/repository/qa_data.yaml | 163 ---- |
40 |
repoman/cnf/repository/repository.yaml | 76 -- |
41 |
repoman/lib/repoman/__init__.py | 103 --- |
42 |
repoman/lib/repoman/_portage.py | 26 - |
43 |
repoman/lib/repoman/_subprocess.py | 58 -- |
44 |
repoman/lib/repoman/actions.py | 828 --------------------- |
45 |
repoman/lib/repoman/argparser.py | 388 ---------- |
46 |
repoman/lib/repoman/check_missingslot.py | 39 - |
47 |
repoman/lib/repoman/checks/__init__.py | 0 |
48 |
repoman/lib/repoman/config.py | 172 ----- |
49 |
repoman/lib/repoman/copyrights.py | 143 ---- |
50 |
repoman/lib/repoman/errors.py | 21 - |
51 |
repoman/lib/repoman/gpg.py | 73 -- |
52 |
repoman/lib/repoman/main.py | 255 ------- |
53 |
repoman/lib/repoman/metadata.py | 89 --- |
54 |
repoman/lib/repoman/modules/__init__.py | 0 |
55 |
repoman/lib/repoman/modules/commit/__init__.py | 0 |
56 |
repoman/lib/repoman/modules/commit/manifest.py | 122 --- |
57 |
repoman/lib/repoman/modules/commit/repochecks.py | 44 -- |
58 |
repoman/lib/repoman/modules/linechecks/__init__.py | 0 |
59 |
.../modules/linechecks/assignment/__init__.py | 27 - |
60 |
.../modules/linechecks/assignment/assignment.py | 38 - |
61 |
repoman/lib/repoman/modules/linechecks/base.py | 115 --- |
62 |
repoman/lib/repoman/modules/linechecks/config.py | 149 ---- |
63 |
.../lib/repoman/modules/linechecks/controller.py | 164 ---- |
64 |
.../repoman/modules/linechecks/depend/__init__.py | 21 - |
65 |
.../repoman/modules/linechecks/depend/implicit.py | 38 - |
66 |
.../modules/linechecks/deprecated/__init__.py | 46 -- |
67 |
.../modules/linechecks/deprecated/deprecated.py | 35 - |
68 |
.../modules/linechecks/deprecated/inherit.py | 67 -- |
69 |
.../lib/repoman/modules/linechecks/do/__init__.py | 21 - |
70 |
repoman/lib/repoman/modules/linechecks/do/dosym.py | 20 - |
71 |
.../repoman/modules/linechecks/eapi/__init__.py | 51 -- |
72 |
.../lib/repoman/modules/linechecks/eapi/checks.py | 79 -- |
73 |
.../repoman/modules/linechecks/eapi/definition.py | 35 - |
74 |
.../repoman/modules/linechecks/emake/__init__.py | 27 - |
75 |
.../lib/repoman/modules/linechecks/emake/emake.py | 25 - |
76 |
.../modules/linechecks/gentoo_header/__init__.py | 21 - |
77 |
.../modules/linechecks/gentoo_header/header.py | 56 -- |
78 |
.../repoman/modules/linechecks/helpers/__init__.py | 21 - |
79 |
.../repoman/modules/linechecks/helpers/offset.py | 21 - |
80 |
.../repoman/modules/linechecks/nested/__init__.py | 21 - |
81 |
.../repoman/modules/linechecks/nested/nested.py | 14 - |
82 |
.../repoman/modules/linechecks/nested/nesteddie.py | 9 - |
83 |
.../repoman/modules/linechecks/patches/__init__.py | 21 - |
84 |
.../repoman/modules/linechecks/patches/patches.py | 22 - |
85 |
.../repoman/modules/linechecks/phases/__init__.py | 40 - |
86 |
.../lib/repoman/modules/linechecks/phases/phase.py | 188 ----- |
87 |
.../repoman/modules/linechecks/portage/__init__.py | 27 - |
88 |
.../repoman/modules/linechecks/portage/internal.py | 32 - |
89 |
.../repoman/modules/linechecks/quotes/__init__.py | 27 - |
90 |
.../repoman/modules/linechecks/quotes/quoteda.py | 15 - |
91 |
.../repoman/modules/linechecks/quotes/quotes.py | 92 --- |
92 |
.../lib/repoman/modules/linechecks/uri/__init__.py | 21 - |
93 |
repoman/lib/repoman/modules/linechecks/uri/uri.py | 30 - |
94 |
.../lib/repoman/modules/linechecks/use/__init__.py | 21 - |
95 |
.../repoman/modules/linechecks/use/builtwith.py | 9 - |
96 |
.../repoman/modules/linechecks/useless/__init__.py | 27 - |
97 |
.../lib/repoman/modules/linechecks/useless/cd.py | 24 - |
98 |
.../repoman/modules/linechecks/useless/dodoc.py | 17 - |
99 |
.../modules/linechecks/whitespace/__init__.py | 27 - |
100 |
.../repoman/modules/linechecks/whitespace/blank.py | 24 - |
101 |
.../modules/linechecks/whitespace/whitespace.py | 20 - |
102 |
.../modules/linechecks/workaround/__init__.py | 21 - |
103 |
.../modules/linechecks/workaround/workarounds.py | 11 - |
104 |
repoman/lib/repoman/modules/scan/__init__.py | 0 |
105 |
.../lib/repoman/modules/scan/depend/__init__.py | 43 -- |
106 |
.../repoman/modules/scan/depend/_depend_checks.py | 260 ------- |
107 |
.../lib/repoman/modules/scan/depend/_gen_arches.py | 67 -- |
108 |
repoman/lib/repoman/modules/scan/depend/profile.py | 427 ----------- |
109 |
.../repoman/modules/scan/directories/__init__.py | 53 -- |
110 |
.../lib/repoman/modules/scan/directories/files.py | 99 --- |
111 |
.../lib/repoman/modules/scan/directories/mtime.py | 30 - |
112 |
repoman/lib/repoman/modules/scan/eapi/__init__.py | 28 - |
113 |
repoman/lib/repoman/modules/scan/eapi/eapi.py | 50 -- |
114 |
.../lib/repoman/modules/scan/ebuild/__init__.py | 66 -- |
115 |
repoman/lib/repoman/modules/scan/ebuild/ebuild.py | 263 ------- |
116 |
.../lib/repoman/modules/scan/ebuild/multicheck.py | 62 -- |
117 |
.../lib/repoman/modules/scan/eclasses/__init__.py | 49 -- |
118 |
repoman/lib/repoman/modules/scan/eclasses/live.py | 77 -- |
119 |
repoman/lib/repoman/modules/scan/eclasses/ruby.py | 49 -- |
120 |
repoman/lib/repoman/modules/scan/fetch/__init__.py | 37 - |
121 |
repoman/lib/repoman/modules/scan/fetch/fetches.py | 205 ----- |
122 |
.../lib/repoman/modules/scan/keywords/__init__.py | 37 - |
123 |
.../lib/repoman/modules/scan/keywords/keywords.py | 179 ----- |
124 |
.../lib/repoman/modules/scan/manifest/__init__.py | 34 - |
125 |
.../lib/repoman/modules/scan/manifest/manifests.py | 56 -- |
126 |
.../lib/repoman/modules/scan/metadata/__init__.py | 89 --- |
127 |
.../repoman/modules/scan/metadata/description.py | 44 -- |
128 |
.../modules/scan/metadata/ebuild_metadata.py | 84 --- |
129 |
.../repoman/modules/scan/metadata/pkgmetadata.py | 221 ------ |
130 |
.../lib/repoman/modules/scan/metadata/restrict.py | 58 -- |
131 |
.../lib/repoman/modules/scan/metadata/use_flags.py | 103 --- |
132 |
repoman/lib/repoman/modules/scan/module.py | 127 ---- |
133 |
.../lib/repoman/modules/scan/options/__init__.py | 28 - |
134 |
.../lib/repoman/modules/scan/options/options.py | 27 - |
135 |
repoman/lib/repoman/modules/scan/scan.py | 67 -- |
136 |
repoman/lib/repoman/modules/scan/scanbase.py | 79 -- |
137 |
repoman/lib/repoman/modules/vcs/None/__init__.py | 32 - |
138 |
repoman/lib/repoman/modules/vcs/None/changes.py | 50 -- |
139 |
repoman/lib/repoman/modules/vcs/None/status.py | 52 -- |
140 |
repoman/lib/repoman/modules/vcs/__init__.py | 12 - |
141 |
repoman/lib/repoman/modules/vcs/bzr/__init__.py | 32 - |
142 |
repoman/lib/repoman/modules/vcs/bzr/changes.py | 77 -- |
143 |
repoman/lib/repoman/modules/vcs/bzr/status.py | 72 -- |
144 |
repoman/lib/repoman/modules/vcs/changes.py | 170 ----- |
145 |
repoman/lib/repoman/modules/vcs/cvs/__init__.py | 32 - |
146 |
repoman/lib/repoman/modules/vcs/cvs/changes.py | 134 ---- |
147 |
repoman/lib/repoman/modules/vcs/cvs/status.py | 134 ---- |
148 |
repoman/lib/repoman/modules/vcs/git/__init__.py | 32 - |
149 |
repoman/lib/repoman/modules/vcs/git/changes.py | 145 ---- |
150 |
repoman/lib/repoman/modules/vcs/git/status.py | 80 -- |
151 |
repoman/lib/repoman/modules/vcs/hg/__init__.py | 32 - |
152 |
repoman/lib/repoman/modules/vcs/hg/changes.py | 109 --- |
153 |
repoman/lib/repoman/modules/vcs/hg/status.py | 68 -- |
154 |
repoman/lib/repoman/modules/vcs/settings.py | 113 --- |
155 |
repoman/lib/repoman/modules/vcs/svn/__init__.py | 32 - |
156 |
repoman/lib/repoman/modules/vcs/svn/changes.py | 156 ---- |
157 |
repoman/lib/repoman/modules/vcs/svn/status.py | 151 ---- |
158 |
repoman/lib/repoman/modules/vcs/vcs.py | 145 ---- |
159 |
repoman/lib/repoman/profile.py | 94 --- |
160 |
repoman/lib/repoman/qa_data.py | 210 ------ |
161 |
repoman/lib/repoman/qa_tracker.py | 46 -- |
162 |
repoman/lib/repoman/repos.py | 377 ---------- |
163 |
repoman/lib/repoman/scanner.py | 484 ------------ |
164 |
.../06B3A311BD775C280D22A9305D90EA06352177F6.rev | 37 - |
165 |
.../8DEDA2CDED49C8809287B89D8812797DDF1DD192.rev | 37 - |
166 |
.../273B030399E7BEA66A9AD42216DE7CA17BA5D42E.key | Bin 2055 -> 0 bytes |
167 |
.../C99796FB85B0C3DF03314A11B5850C51167D6282.key | Bin 2055 -> 0 bytes |
168 |
repoman/lib/repoman/tests/.gnupg/pubring.kbx | Bin 2774 -> 0 bytes |
169 |
repoman/lib/repoman/tests/.gnupg/trustdb.gpg | Bin 1360 -> 0 bytes |
170 |
repoman/lib/repoman/tests/__init__.py | 328 -------- |
171 |
repoman/lib/repoman/tests/__test__.py | 0 |
172 |
repoman/lib/repoman/tests/changelog/__init__.py | 2 - |
173 |
repoman/lib/repoman/tests/changelog/__test__.py | 0 |
174 |
.../lib/repoman/tests/changelog/test_echangelog.py | 169 ----- |
175 |
repoman/lib/repoman/tests/commit/__init__.py | 2 - |
176 |
repoman/lib/repoman/tests/commit/__test__.py | 0 |
177 |
repoman/lib/repoman/tests/commit/test_commitmsg.py | 155 ---- |
178 |
repoman/lib/repoman/tests/runTests.py | 85 --- |
179 |
repoman/lib/repoman/tests/simple/__init__.py | 2 - |
180 |
repoman/lib/repoman/tests/simple/__test__.py | 0 |
181 |
repoman/lib/repoman/tests/simple/test_simple.py | 512 ------------- |
182 |
repoman/lib/repoman/utilities.py | 590 --------------- |
183 |
repoman/man/repoman.1 | 478 ------------ |
184 |
repoman/runtests | 189 ----- |
185 |
repoman/setup.py | 523 ------------- |
186 |
tox.ini | 3 +- |
187 |
171 files changed, 32 insertions(+), 15135 deletions(-) |
188 |
|
189 |
diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml |
190 |
index d3c3fa3e1..1d6f1378c 100644 |
191 |
--- a/.github/workflows/black.yml |
192 |
+++ b/.github/workflows/black.yml |
193 |
@@ -11,7 +11,7 @@ jobs: |
194 |
id: stragglers |
195 |
run: | |
196 |
echo "::set-output name=missed::$( |
197 |
- find bin repoman runtests -type f -not -name '*.py' -not -name '*.sh' | \ |
198 |
+ find bin runtests -type f -not -name '*.py' -not -name '*.sh' | \ |
199 |
xargs grep -l '#!/usr/bin/env python' | tr $'\n' ' ')" |
200 |
- uses: psf/black@stable |
201 |
with: |
202 |
|
203 |
diff --git a/.gitignore b/.gitignore |
204 |
index a9f772c4c..c04a22a0b 100644 |
205 |
--- a/.gitignore |
206 |
+++ b/.gitignore |
207 |
@@ -6,5 +6,3 @@ __pycache__/ |
208 |
/tags |
209 |
/.tox/ |
210 |
setup.cfg |
211 |
- |
212 |
-repoman/build |
213 |
|
214 |
diff --git a/cnf/make.globals b/cnf/make.globals |
215 |
index f42cffe8b..f951bb317 100644 |
216 |
--- a/cnf/make.globals |
217 |
+++ b/cnf/make.globals |
218 |
@@ -147,7 +147,7 @@ PORTAGE_ELOG_MAILURI="root" |
219 |
PORTAGE_ELOG_MAILSUBJECT="[portage] ebuild log for \${PACKAGE} on \${HOST}" |
220 |
PORTAGE_ELOG_MAILFROM="portage@localhost" |
221 |
|
222 |
-# Signing command used by repoman |
223 |
+# Signing command used by egencache |
224 |
PORTAGE_GPG_SIGNING_COMMAND="gpg --sign --digest-algo SHA256 --clearsign --yes --default-key \"\${PORTAGE_GPG_KEY}\" --homedir \"\${PORTAGE_GPG_DIR}\" \"\${FILE}\"" |
225 |
|
226 |
# btrfs.* attributes are irrelevant, see bug #527636. |
227 |
|
228 |
diff --git a/lib/_emerge/Package.py b/lib/_emerge/Package.py |
229 |
index db42d836e..a19904113 100644 |
230 |
--- a/lib/_emerge/Package.py |
231 |
+++ b/lib/_emerge/Package.py |
232 |
@@ -136,10 +136,7 @@ class Package(Task): |
233 |
# sync metadata with validated repo (may be UNKNOWN_REPO) |
234 |
self._metadata["repository"] = self.cpv.repo |
235 |
|
236 |
- if self.root_config.settings.local_config: |
237 |
- implicit_match = db._iuse_implicit_cnstr(self.cpv, self._metadata) |
238 |
- else: |
239 |
- implicit_match = db._repoman_iuse_implicit_cnstr(self.cpv, self._metadata) |
240 |
+ implicit_match = db._iuse_implicit_cnstr(self.cpv, self._metadata) |
241 |
self.iuse = self._iuse( |
242 |
self, self._metadata["IUSE"].split(), implicit_match, self.eapi |
243 |
) |
244 |
|
245 |
diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py |
246 |
index c3f872c43..79fa1f3df 100644 |
247 |
--- a/lib/_emerge/depgraph.py |
248 |
+++ b/lib/_emerge/depgraph.py |
249 |
@@ -9048,7 +9048,7 @@ class depgraph: |
250 |
): |
251 |
# Make sure that portage always has all of its |
252 |
# RDEPENDs installed first, but ignore uninstalls |
253 |
- # (these occur when new portage blocks older repoman). |
254 |
+ # (these occur when new portage blocks an older package version). |
255 |
return False |
256 |
selected_nodes.add(node) |
257 |
for child in mygraph.child_nodes(node, ignore_priority=ignore_priority): |
258 |
|
259 |
diff --git a/lib/portage/dbapi/__init__.py b/lib/portage/dbapi/__init__.py |
260 |
index 43c3283e8..f52329c90 100644 |
261 |
--- a/lib/portage/dbapi/__init__.py |
262 |
+++ b/lib/portage/dbapi/__init__.py |
263 |
@@ -219,18 +219,6 @@ class dbapi: |
264 |
|
265 |
yield cpv |
266 |
|
267 |
- def _repoman_iuse_implicit_cnstr(self, pkg, metadata): |
268 |
- """ |
269 |
- In repoman's version of _iuse_implicit_cnstr, account for modifications |
270 |
- of the self.settings reference between calls. |
271 |
- """ |
272 |
- eapi_attrs = _get_eapi_attrs(metadata["EAPI"]) |
273 |
- if eapi_attrs.iuse_effective: |
274 |
- iuse_implicit_match = lambda flag: self.settings._iuse_effective_match(flag) |
275 |
- else: |
276 |
- iuse_implicit_match = lambda flag: self.settings._iuse_implicit_match(flag) |
277 |
- return iuse_implicit_match |
278 |
- |
279 |
def _iuse_implicit_cnstr(self, pkg, metadata): |
280 |
""" |
281 |
Construct a callable that checks if a given USE flag should |
282 |
|
283 |
diff --git a/lib/portage/dbapi/porttree.py b/lib/portage/dbapi/porttree.py |
284 |
index 93f3fee2f..cd919ba31 100644 |
285 |
--- a/lib/portage/dbapi/porttree.py |
286 |
+++ b/lib/portage/dbapi/porttree.py |
287 |
@@ -359,9 +359,9 @@ class portdbapi(dbapi): |
288 |
|
289 |
def _set_porttrees(self, porttrees): |
290 |
""" |
291 |
- Consumers, such as repoman and emirrordist, may modify the porttrees |
292 |
- attribute in order to modify the effective set of repositories for |
293 |
- all portdbapi operations. |
294 |
+ Consumers, such as emirrordist, may modify the porttrees attribute in |
295 |
+ order to modify the effective set of repositories for all portdbapi |
296 |
+ operations. |
297 |
|
298 |
@param porttrees: list of repo locations, in ascending order by |
299 |
repo priority |
300 |
|
301 |
diff --git a/lib/portage/tests/lazyimport/test_lazy_import_portage_baseline.py b/lib/portage/tests/lazyimport/test_lazy_import_portage_baseline.py |
302 |
index cf239240c..8cc248db9 100644 |
303 |
--- a/lib/portage/tests/lazyimport/test_lazy_import_portage_baseline.py |
304 |
+++ b/lib/portage/tests/lazyimport/test_lazy_import_portage_baseline.py |
305 |
@@ -14,7 +14,7 @@ from _emerge.SpawnProcess import SpawnProcess |
306 |
|
307 |
class LazyImportPortageBaselineTestCase(TestCase): |
308 |
|
309 |
- _module_re = re.compile(r"^(portage|repoman|_emerge)\.") |
310 |
+ _module_re = re.compile(r"^(portage|_emerge)\.") |
311 |
|
312 |
_baseline_imports = frozenset( |
313 |
[ |
314 |
|
315 |
diff --git a/lib/portage/tests/resolver/ResolverPlayground.py b/lib/portage/tests/resolver/ResolverPlayground.py |
316 |
index 8811354b5..ec69ee068 100644 |
317 |
--- a/lib/portage/tests/resolver/ResolverPlayground.py |
318 |
+++ b/lib/portage/tests/resolver/ResolverPlayground.py |
319 |
@@ -35,11 +35,6 @@ from _emerge.DependencyArg import DependencyArg |
320 |
from _emerge.depgraph import backtrack_depgraph |
321 |
from _emerge.RootConfig import RootConfig |
322 |
|
323 |
-try: |
324 |
- from repoman.tests import cnf_path_repoman |
325 |
-except ImportError: |
326 |
- cnf_path_repoman = None |
327 |
- |
328 |
|
329 |
class ResolverPlayground: |
330 |
""" |
331 |
@@ -664,11 +659,6 @@ class ResolverPlayground: |
332 |
for line in lines: |
333 |
f.write("%s\n" % line) |
334 |
|
335 |
- if cnf_path_repoman is not None: |
336 |
- # Create /usr/share/repoman |
337 |
- repoman_share_dir = os.path.join(self.eroot, "usr", "share", "repoman") |
338 |
- os.symlink(cnf_path_repoman, repoman_share_dir) |
339 |
- |
340 |
def _create_world(self, world, world_sets): |
341 |
# Create /var/lib/portage/world |
342 |
var_lib_portage = os.path.join(self.eroot, "var", "lib", "portage") |
343 |
|
344 |
diff --git a/man/ebuild.5 b/man/ebuild.5 |
345 |
index 3a3982738..8402d667b 100644 |
346 |
--- a/man/ebuild.5 |
347 |
+++ b/man/ebuild.5 |
348 |
@@ -554,9 +554,9 @@ EAPI value then it will mask the package and refuse to perform any |
349 |
operations with it since this means that a newer version of portage |
350 |
needs to be installed first. For maximum backward compatiblity, a |
351 |
package should conform to the lowest possible EAPI. Note that anyone |
352 |
-who uses the \fBebuild\fR(1) and \fBrepoman\fR(1) commands with this |
353 |
-package will be required to have a version of portage that recognizes |
354 |
-the EAPI to which this package conforms. |
355 |
+who uses the \fBebuild\fR(1) command with this package will be |
356 |
+required to have a version of portage that recognizes the EAPI to |
357 |
+which this package conforms. |
358 |
.TP |
359 |
.B SRC_URI\fR = \fI"https://example.com/path/${P}.tar.gz" |
360 |
Contains a list of URIs for the required source files. It can contain |
361 |
|
362 |
diff --git a/man/make.conf.5 b/man/make.conf.5 |
363 |
index fc4a018c5..8c77eda2e 100644 |
364 |
--- a/man/make.conf.5 |
365 |
+++ b/man/make.conf.5 |
366 |
@@ -457,9 +457,9 @@ enabled by default. |
367 |
.TP |
368 |
.B digest |
369 |
Autogenerate digests for packages when running the |
370 |
-\fBemerge\fR(1), \fBebuild\fR(1), or \fBrepoman\fR(1) commands. If |
371 |
-the \fIassume\-digests\fR feature is also enabled then existing SRC_URI digests |
372 |
-will be reused whenever they are available. |
373 |
+\fBemerge\fR(1) or \fBebuild\fR(1) commands. If the |
374 |
+\fIassume\-digests\fR feature is also enabled then existing SRC_URI |
375 |
+digests will be reused whenever they are available. |
376 |
.TP |
377 |
.B distcc |
378 |
Enable portage support for the distcc package. |
379 |
@@ -1051,7 +1051,7 @@ when \fBsign\fR is in \fBFEATURES\fR. In order to sign commits with |
380 |
to be configured by \fI`git config user.signingkey key_id`\fR. |
381 |
.TP |
382 |
.B PORTAGE_GPG_SIGNING_COMMAND |
383 |
-The command used by \fBrepoman\fR(1) to sign manifests when \fBsign\fR is |
384 |
+The command used by \fBegencache\fR(1) to sign manifests when \fBsign\fR is |
385 |
in \fBFEATURES\fR. |
386 |
.TP |
387 |
\fBPORTAGE_GRPNAME\fR = \fI[group]\fR |
388 |
|
389 |
diff --git a/man/portage.5 b/man/portage.5 |
390 |
index 50f20454c..f42564664 100644 |
391 |
--- a/man/portage.5 |
392 |
+++ b/man/portage.5 |
393 |
@@ -944,14 +944,13 @@ Setting this attribute is generally not recommended since resulting changes |
394 |
in eclass inheritance may trigger performance issues due to invalidation |
395 |
of metadata cache. |
396 |
.br |
397 |
-When 'force = eclass\-overrides' attribute is not set, \fBegencache\fR(1), |
398 |
-\fBemirrordist\fR(1) and \fBrepoman\fR(1) ignore this attribute, |
399 |
-since operations performed by these tools are inherently |
400 |
-\fBnot\fR \fIsite\-specific\fR. |
401 |
+When 'force = eclass\-overrides' attribute is not set, \fBegencache\fR(1) |
402 |
+and \fBemirrordist\fR(1) ignore this attribute, since operations |
403 |
+performed by these tools are inherently \fBnot\fR \fIsite\-specific\fR. |
404 |
.TP |
405 |
.B force |
406 |
Specifies names of attributes, which should be forcefully respected by |
407 |
-\fBegencache\fR(1), \fBemirrordist\fR(1) and \fBrepoman\fR(1). |
408 |
+\fBegencache\fR(1) and \fBemirrordist\fR(1). |
409 |
.br |
410 |
Valid values: aliases, eclass\-overrides, masters |
411 |
.RE |
412 |
@@ -966,10 +965,9 @@ Setting this attribute is generally not recommended since resulting changes |
413 |
in eclass inheritance may trigger performance issues due to invalidation |
414 |
of metadata cache. |
415 |
.br |
416 |
-When 'force = aliases' attribute is not set, \fBegencache\fR(1), |
417 |
-\fBemirrordist\fR(1) and \fBrepoman\fR(1) ignore this attribute, |
418 |
-since operations performed by these tools are inherently |
419 |
-\fBnot\fR \fIsite\-specific\fR. |
420 |
+When 'force = aliases' attribute is not set, \fBegencache\fR(1) and |
421 |
+\fBemirrordist\fR(1) ignore this attribute, since operations performed by |
422 |
+these tools are inherently \fBnot\fR \fIsite\-specific\fR. |
423 |
.TP |
424 |
.B auto\-sync = yes|no|true|false |
425 |
This setting determines if the repo will be synced during "\fBemerge \-\-sync\fR" or |
426 |
@@ -990,14 +988,13 @@ Setting this attribute is generally not recommended since resulting changes |
427 |
in eclass inheritance may trigger performance issues due to invalidation |
428 |
of metadata cache. |
429 |
.br |
430 |
-When 'force = eclass\-overrides' attribute is not set, \fBegencache\fR(1), |
431 |
-\fBemirrordist\fR(1) and \fBrepoman\fR(1) ignore this attribute, |
432 |
-since operations performed by these tools are inherently |
433 |
-\fBnot\fR \fIsite\-specific\fR. |
434 |
+When 'force = eclass\-overrides' attribute is not set, \fBegencache\fR(1) |
435 |
+and \fBemirrordist\fR(1) ignore this attribute, since operations |
436 |
+performed by these tools are inherently \fBnot\fR \fIsite\-specific\fR. |
437 |
.TP |
438 |
.B force |
439 |
Specifies names of attributes, which should be forcefully respected by |
440 |
-\fBegencache\fR(1), \fBemirrordist\fR(1) and \fBrepoman\fR(1). |
441 |
+\fBegencache\fR(1) and \fBemirrordist\fR(1). |
442 |
.br |
443 |
Valid values: aliases, eclass\-overrides, masters |
444 |
.TP |
445 |
@@ -1011,10 +1008,9 @@ Setting this attribute is generally not recommended since resulting changes |
446 |
in eclass inheritance may trigger performance issues due to invalidation |
447 |
of metadata cache. |
448 |
.br |
449 |
-When 'force = masters' attribute is not set, \fBegencache\fR(1), |
450 |
-\fBemirrordist\fR(1) and \fBrepoman\fR(1) ignore this attribute, |
451 |
-since operations performed by these tools are inherently |
452 |
-\fBnot\fR \fIsite\-specific\fR. |
453 |
+When 'force = masters' attribute is not set, \fBegencache\fR(1) and |
454 |
+\fBemirrordist\fR(1) ignore this attribute, since operations performed by |
455 |
+these tools are inherently \fBnot\fR \fIsite\-specific\fR. |
456 |
.TP |
457 |
.B priority |
458 |
Specifies priority of given repository. |
459 |
@@ -1423,7 +1419,7 @@ Specifies information about the repository layout. |
460 |
\fISite-specific\fR overrides to \fBlayout.conf\fR settings may be specified in |
461 |
\fB/etc/portage/repos.conf\fR. |
462 |
Settings in \fBrepos.conf\fR take precedence over settings in |
463 |
-\fBlayout.conf\fR, except tools such as \fBrepoman\fR(1) and \fBegencache\fR(1) |
464 |
+\fBlayout.conf\fR, except tools such as \fBegencache\fR(1) |
465 |
ignore "aliases", "eclass-overrides" and "masters" attributes set in |
466 |
\fBrepos.conf\fR since their operations are inherently \fBnot\fR |
467 |
\fIsite\-specific\fR. |
468 |
@@ -1485,9 +1481,6 @@ here are not present in the Manifest, Portage will refetch all distfiles |
469 |
and update the respective entries to include them. Must be a subset |
470 |
of manifest\-hashes. If not specified, defaults to all manifest\-hashes. |
471 |
.TP |
472 |
-.BR update\-changelog " = [true|" false "]" |
473 |
-The default setting for repoman's --echangelog option. |
474 |
-.TP |
475 |
.BR cache\-formats " = [pms] [md5-dict]" |
476 |
The cache formats supported in the metadata tree. There is the old "pms" format |
477 |
and the newer/faster "md5-dict" format. Default is to detect dirs. |
478 |
@@ -1553,9 +1546,6 @@ use\-manifests = strict |
479 |
# customize the set of hashes generated for Manifest entries |
480 |
manifest\-hashes = SHA256 SHA512 WHIRLPOOL |
481 |
|
482 |
-# indicate that this repo enables repoman's --echangelog=y option automatically |
483 |
-update\-changelog = false |
484 |
- |
485 |
# indicate that this repo contains the md5-dict cache format, |
486 |
# which may be generated by egencache(1) |
487 |
cache\-formats = md5-dict |
488 |
@@ -1700,7 +1690,7 @@ package has been masked and WHO is doing the masking. |
489 |
.TP |
490 |
.BR profiles.desc |
491 |
List all the current stable and development profiles. If a profile is listed |
492 |
-here, then it will be checked by repoman. |
493 |
+here, then it will be checked by pkgcheck. |
494 |
.I Format: |
495 |
.nf |
496 |
\- comments begin with # (no inline comments) |
497 |
|
498 |
diff --git a/repoman/.repoman_not_installed b/repoman/.repoman_not_installed |
499 |
deleted file mode 100644 |
500 |
index e69de29bb..000000000 |
501 |
|
502 |
diff --git a/repoman/MANIFEST.in b/repoman/MANIFEST.in |
503 |
deleted file mode 100644 |
504 |
index d9ef2aee0..000000000 |
505 |
--- a/repoman/MANIFEST.in |
506 |
+++ /dev/null |
507 |
@@ -1,4 +0,0 @@ |
508 |
- |
509 |
-# for the tests |
510 |
-include cnf/metadata.xsd |
511 |
-include .repoman_not_installed |
512 |
|
513 |
diff --git a/repoman/NEWS b/repoman/NEWS |
514 |
deleted file mode 100644 |
515 |
index c8d22d024..000000000 |
516 |
--- a/repoman/NEWS |
517 |
+++ /dev/null |
518 |
@@ -1,14 +0,0 @@ |
519 |
-News (mainly features/major bug fixes) |
520 |
- |
521 |
-repoman 2.3.8 |
522 |
-===================== |
523 |
-- Support for plugin module systems, see |
524 |
- https://wiki.gentoo.org/wiki/Project:Portage/Repoman-Module-specs |
525 |
- |
526 |
-repoman 2.3.0 |
527 |
-===================== |
528 |
-- Final release |
529 |
- |
530 |
-repoman 2.3.0_rc1 |
531 |
-===================== |
532 |
-- First test release |
533 |
|
534 |
diff --git a/repoman/README b/repoman/README |
535 |
deleted file mode 100644 |
536 |
index f0976e841..000000000 |
537 |
--- a/repoman/README |
538 |
+++ /dev/null |
539 |
@@ -1,49 +0,0 @@ |
540 |
-About Portage |
541 |
-============= |
542 |
- |
543 |
-Portage is a package management system based on ports collections. The |
544 |
-Package Manager Specification Project (PMS) standardises and documents |
545 |
-the behaviour of Portage so that ebuild repositories can be used by other |
546 |
-package managers. |
547 |
- |
548 |
- |
549 |
-Dependencies |
550 |
-============ |
551 |
- |
552 |
-Python and Bash should be the only hard dependencies. Python 2.7 is the |
553 |
-minimum supported version. |
554 |
- |
555 |
- |
556 |
-Licensing and Legalese |
557 |
-======================= |
558 |
- |
559 |
-Portage is free software; you can redistribute it and/or |
560 |
-modify it under the terms of the GNU General Public License |
561 |
-version 2 as published by the Free Software Foundation. |
562 |
- |
563 |
-Portage is distributed in the hope that it will be useful, |
564 |
-but WITHOUT ANY WARRANTY; without even the implied warranty of |
565 |
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
566 |
-GNU General Public License for more details. |
567 |
- |
568 |
-You should have received a copy of the GNU General Public License |
569 |
-along with Portage; if not, write to the Free Software |
570 |
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
571 |
-02110-1301, USA. |
572 |
- |
573 |
- |
574 |
-More information |
575 |
-================ |
576 |
- |
577 |
--DEVELOPING contains some code guidelines. |
578 |
--LICENSE contains the GNU General Public License version 2. |
579 |
--NEWS contains new features/major bug fixes for each version. |
580 |
--RELEASE NOTES contains mainly upgrade information for each version. |
581 |
--TEST-NOTES contains Portage unit test information. |
582 |
- |
583 |
- |
584 |
-Links |
585 |
-===== |
586 |
-Gentoo project page: <https://wiki.gentoo.org/wiki/Project:Portage> |
587 |
-PMS: <https://dev.gentoo.org/~ulm/pms/head/pms.html> |
588 |
-PMS git repo: <https://gitweb.gentoo.org/proj/pms.git/> |
589 |
|
590 |
diff --git a/repoman/RELEASE-NOTES b/repoman/RELEASE-NOTES |
591 |
deleted file mode 100644 |
592 |
index df34803cc..000000000 |
593 |
--- a/repoman/RELEASE-NOTES |
594 |
+++ /dev/null |
595 |
@@ -1,213 +0,0 @@ |
596 |
-Release Notes; upgrade information mainly. |
597 |
-Features/major bugfixes are listed in NEWS |
598 |
- |
599 |
-repoman-3.0.3 |
600 |
-================================== |
601 |
-* Bug Fixes: |
602 |
- - Bug 608664 variable.phase check like pkgcheck VariableScopeCheck |
603 |
- - Bug 692486 Change message for preserve_old_lib |
604 |
- |
605 |
-repoman-3.0.2 |
606 |
-================================== |
607 |
-* Bug Fixes: |
608 |
- - Bug 748144 Make file.size fatal for files larger than 20 KiB |
609 |
- |
610 |
-repoman-3.0.1 |
611 |
-================================== |
612 |
-* Bug Fixes: |
613 |
- - Bug 737698 Update repoman for compatibility with portage-3.0.4. |
614 |
- |
615 |
-repoman-3.0.0 |
616 |
-================================== |
617 |
-* Bug Fixes: |
618 |
- - Bug 448462 Add --jobs and --load-average options which allow |
619 |
- dependency checks for multiple profiles to run in parallel. |
620 |
- |
621 |
-repoman-2.3.23 |
622 |
-================================== |
623 |
-* Bug Fixes: |
624 |
- - Bug 637824 Deprecate netsurf.eclass |
625 |
- |
626 |
-repoman-2.3.22 |
627 |
-================================== |
628 |
-* Bug Fixes: |
629 |
- - Bug 712106 only stage changes in index for commit mode |
630 |
- |
631 |
-repoman-2.3.21 |
632 |
-================================== |
633 |
-* Bug Fixes: |
634 |
- - Bug 712106 prevent spurious copyright header updates |
635 |
- |
636 |
- |
637 |
-repoman-2.3.20 |
638 |
-================================== |
639 |
-* Bug Fixes: |
640 |
- - Bug 541076 repoman commit: ignore unadded hidden files |
641 |
- - Bug 702100 repoman: support profiles/package.deprecated |
642 |
- |
643 |
- |
644 |
-repoman-2.3.19 |
645 |
-================================== |
646 |
-* Bug Fixes: |
647 |
- - Bug 667432 Rename DCO_SIGNED_OFF_BY config variable to SIGNED_OFF_BY. |
648 |
- - Bug 700456 Add --include-profiles=PROFILES |
649 |
- |
650 |
- |
651 |
-repoman-2.3.18 |
652 |
-================================== |
653 |
-* Bug Fixes: |
654 |
- - Bug 690786 Support metadata/layout.conf restrict-allowed |
655 |
- - Bug 699514 Detect dosym absolute paths starting with ${D}, ${ED} etc. |
656 |
- - Bug 699508 Fix unsafe string interpolation. |
657 |
- |
658 |
- |
659 |
-repoman-2.3.17 |
660 |
-================================== |
661 |
-* Bug Fixes: |
662 |
- - Bug 233589 Support PROPERTIES="live" |
663 |
- |
664 |
- |
665 |
-repoman-2.3.16 |
666 |
-================================== |
667 |
-* Bug Fixes: |
668 |
- - Bug 687420 Allow empty LICENSE in acct-* packages for GLEP 81 |
669 |
- |
670 |
- |
671 |
-repoman-2.3.15 |
672 |
-================================== |
673 |
-* Bug Fixes: |
674 |
- - Bug 688278 Accept 'Gentoo Foundation' copyright for old ebuilds |
675 |
- |
676 |
- |
677 |
-repoman-2.3.14 |
678 |
-================================== |
679 |
-* Bug Fixes: |
680 |
- - Bug 666330 Update for new copyright policy |
681 |
- |
682 |
- |
683 |
-repoman-2.3.13 |
684 |
-================================== |
685 |
-* Bug Fixes: |
686 |
- - Bug 686074 report error for unknown arguments |
687 |
- |
688 |
- |
689 |
-repoman-2.3.12 |
690 |
-================================== |
691 |
-* Bug Fixes: |
692 |
- - Bug 588752 fix exit code for manifest mode |
693 |
- |
694 |
- |
695 |
-repoman-2.3.11 |
696 |
-================================== |
697 |
-* Bug Fixes: |
698 |
- - Bug 666330 support new 'Gentoo Authors' copyright policy and |
699 |
- automatically apply the new policy when updating copyright headers. |
700 |
- Earlier versions of repoman will report an ebuild.badheader warning |
701 |
- for the new copyright headers. Users of earlier versions of repoman |
702 |
- should be advised to simply ignore the ebuild.badheader warning, or |
703 |
- else upgrade to the latest version of repoman. |
704 |
- |
705 |
- |
706 |
-repoman-2.3.10 |
707 |
-================================== |
708 |
-* Bug Fixes: |
709 |
- - Bug 649482 warn about = deps without revision |
710 |
- - Bug 660982 populate implicit IUSE for empty profile |
711 |
- |
712 |
- |
713 |
-repoman-2.3.8 |
714 |
-================================== |
715 |
-* The --experimental-repository-modules=<y|n> option enables a new |
716 |
- plugin modules system: |
717 |
- https://wiki.gentoo.org/wiki/Project:Portage/Repoman-Module-specs |
718 |
- |
719 |
- |
720 |
-repoman-2.3.7 |
721 |
-================================== |
722 |
-* Bug Fixes: |
723 |
- - Bug 552720 allow https for metadata.dtd URI |
724 |
- |
725 |
- |
726 |
-repoman-2.3.6 |
727 |
-================================== |
728 |
-* Bug Fixes: |
729 |
- - Bug 637460 Fix import paths for unit tests |
730 |
- |
731 |
- |
732 |
-repoman-2.3.5 |
733 |
-================================== |
734 |
-* Repository metadata/layout.conf supports manifest-required-hashes |
735 |
- attribute (default value is SHA512). |
736 |
- |
737 |
- |
738 |
-repoman-2.3.4 |
739 |
-================================== |
740 |
-* Support two new options: --bug (-b) and --closes (-c) |
741 |
- |
742 |
- |
743 |
-repoman-2.3.3 |
744 |
-================================== |
745 |
-* Bug Fixes: |
746 |
- - Bug 571546 Change how the tmp file for the commit msg is made |
747 |
-* flag URIs using http:// when https:// is available |
748 |
-* Add a check for relative dosym candidates |
749 |
-* Make all shebangs prefix friendly |
750 |
-* Mark ruby-2.0 as deprecated |
751 |
-* Detect inconsistent metadata.xml indentation |
752 |
-* Warn about dropped keywords only for latest in SLOT. |
753 |
- |
754 |
- |
755 |
-repoman-2.3.2 |
756 |
-================================== |
757 |
-* Bug Fixes: |
758 |
- - Bug 544938 add dev-qt/linguist-tools to RDEPEND.suspect set |
759 |
- - Bug 602002 make unused local USE flags an error |
760 |
- - Bug 533554 add HOMEPAGE.missingurischeme check |
761 |
- - Bug 610414 use regular expression to detect line continuations |
762 |
- - Bug 610954 Warn about stale CVS keywords in ebuild header |
763 |
- - Bug 611296 Don't update years in non-Gentoo copyright lines |
764 |
-* Add virtual/linuxtv-dvb-headers to RDEPEND.suspect set |
765 |
-* Add virtual/os-headers to RDEPEND.suspect set |
766 |
-* Add gentoo to remote-id type |
767 |
-* Define long for python3 Fixes: 006b168c1bb6 |
768 |
-* Commit footer improvements |
769 |
-* Check for empty files in filesdir |
770 |
-* Deprecate gpe.eclass, confutils.eclass |
771 |
- |
772 |
- |
773 |
-repoman-2.3.1 |
774 |
-================================== |
775 |
-* Bug Fixes: |
776 |
- - Bug 586864 skip QA checks in manifest mode |
777 |
- - Bug 591184 fix erroneous LICENSE.syntax |
778 |
- - use https to fetch metadata.xsd |
779 |
- - update links to https |
780 |
- - Make LIVEVCS.* checks fatal |
781 |
- - fix _depend_checks baddepsyntax accounting |
782 |
- - Fix commitmessage assignment not being done |
783 |
- - Add cat/pkg: substtution in the commitsgfile text |
784 |
- - Disable SRC_URI.mirror warnings when there is only 1 mirror |
785 |
- - Fix version output string to say Repoman, fix live versioning, |
786 |
- add portage version to --version output. |
787 |
- - Add repoman version to "Package manager:" commit footer |
788 |
- |
789 |
-repoman-2.3.0 |
790 |
-================================== |
791 |
-* Bug Fixes: |
792 |
- - Bug 584786 Add support for .git as a file when --separate-git-dir is used |
793 |
- - Bug 585864 fix missing vcs_files_to_cps repodir argument |
794 |
- - Bug 585388 fix KeyError during manifest generation |
795 |
-* New QA error: slot operator under '||' alternative |
796 |
- |
797 |
-repoman-2.3.0_rc1 |
798 |
-================================== |
799 |
-* Initial test release |
800 |
-* Bug Fixes: |
801 |
- - Bug 579460 Disable the $ID header check |
802 |
- - Bug 546010 Handle removed packages in vcs_files_to_cps |
803 |
- - Bug 581594 Fix commit 8e7971169c2 missing self in func() parameters |
804 |
- - Bug 581598 Add InvalidPackageName exception trap |
805 |
- - Bug 405017 Fix copyright update |
806 |
-* Includes the stage2 re-writes, the checks are now in a modular system |
807 |
- which is not yet fully plug-in capable. Becoming fully plug-in capable and |
808 |
- configurable is to be done in the stage3 rewites. |
809 |
|
810 |
diff --git a/repoman/TEST-NOTES b/repoman/TEST-NOTES |
811 |
deleted file mode 100644 |
812 |
index 8be5f9cf3..000000000 |
813 |
--- a/repoman/TEST-NOTES |
814 |
+++ /dev/null |
815 |
@@ -1,45 +0,0 @@ |
816 |
-UnitTests |
817 |
---------- |
818 |
- |
819 |
-Portage has some tests that use the unittest framework that ships with python (2.3-2.4ish) |
820 |
-Tests have a specific naming convention. |
821 |
- |
822 |
-in lib/portage/tests/ there is a runTest script that invokes lib/portage/tests/__init__.py |
823 |
- |
824 |
-This init looks at a hardcoded list of test dirs to search for tests. |
825 |
-If you add a new dir and don't see your new tests, make sure that the dir is in this list. |
826 |
- |
827 |
-On the subject of adding more directories; the layout is basically 1 directory per portage |
828 |
-file at this point (we have few files, and even fewer large files). Inside of the dir |
829 |
-you should have files of the form test_${function}.py. |
830 |
- |
831 |
-So if I was to write a vercmp test, and vercmp is in portage_versions. |
832 |
- |
833 |
-lib/portage/tests/portage_versions/test_vercmp.py |
834 |
- |
835 |
-would be the filename. |
836 |
- |
837 |
-The __init__.py file now does recursive tests, but you need to tell it so. For example, if |
838 |
-you had cache tests the dir format would be something like... |
839 |
- |
840 |
-lib/portage/tests/cache/flat_hash/test_foo.py |
841 |
- |
842 |
-and you would put "cache/flat_hash" into the testDirs variable in __init__.py. |
843 |
- |
844 |
- |
845 |
-Skipping |
846 |
--------- |
847 |
- |
848 |
-Please use the portage.tests.* classes as they support throwing a SkipException for |
849 |
-tests that are known to fail. Normally one uses testing to do Test Driven Development |
850 |
-(TDD); however we do not do that here. Therefore there are times when legitimate tests |
851 |
-exist but fail due to code in trunk. We would still like the suite to pass in some instances |
852 |
-because the suite is built around two things, testing functionality in the current code as |
853 |
-well as poking holes in the current code (isvalidatom is an example). So sometimes we desire |
854 |
-a test to point out that "this needs fixing" but it doesn't affect portage's overall |
855 |
-functionality. You should raise portage.tests.SkipException in that case. |
856 |
- |
857 |
-emerge |
858 |
------- |
859 |
- |
860 |
-The emerge namespace currently has 0 tests (and no runner) |
861 |
|
862 |
diff --git a/repoman/bin/repoman b/repoman/bin/repoman |
863 |
deleted file mode 100755 |
864 |
index beaf8147a..000000000 |
865 |
--- a/repoman/bin/repoman |
866 |
+++ /dev/null |
867 |
@@ -1,56 +0,0 @@ |
868 |
-#!/usr/bin/env python |
869 |
-# Copyright 1999-2021 Gentoo Authors |
870 |
-# Distributed under the terms of the GNU General Public License v2 |
871 |
- |
872 |
-"""Ebuild and tree health checks and maintenance utilities. |
873 |
-""" |
874 |
- |
875 |
-import sys |
876 |
-import errno |
877 |
- |
878 |
-# This block ensures that ^C interrupts are handled quietly. |
879 |
-try: |
880 |
- import signal |
881 |
- |
882 |
- def exithandler(signum, _frame): |
883 |
- signal.signal(signal.SIGINT, signal.SIG_IGN) |
884 |
- signal.signal(signal.SIGTERM, signal.SIG_IGN) |
885 |
- sys.exit(128 + signum) |
886 |
- |
887 |
- signal.signal(signal.SIGINT, exithandler) |
888 |
- signal.signal(signal.SIGTERM, exithandler) |
889 |
- signal.signal(signal.SIGPIPE, signal.SIG_DFL) |
890 |
- |
891 |
-except KeyboardInterrupt: |
892 |
- sys.exit(1) |
893 |
- |
894 |
-from os import path as osp |
895 |
- |
896 |
-here = osp.realpath(__file__) |
897 |
-if osp.isfile(osp.join(osp.dirname(osp.dirname(here)), ".repoman_not_installed")): |
898 |
- # Add the repoman subpkg |
899 |
- pym_path = osp.join(osp.dirname(osp.dirname(here)), "lib") |
900 |
- sys.path.insert(0, pym_path) |
901 |
- if osp.isfile( |
902 |
- osp.join(osp.dirname(osp.dirname(osp.dirname(here))), ".portage_not_installed") |
903 |
- ): |
904 |
- # Add the base portage pkg |
905 |
- pym_path = osp.join(osp.dirname(osp.dirname(osp.dirname(here))), "lib") |
906 |
- sys.path.insert(0, pym_path) |
907 |
- |
908 |
-import portage |
909 |
- |
910 |
-portage._internal_caller = True |
911 |
-from portage.util._eventloop.global_event_loop import global_event_loop |
912 |
-from repoman.main import repoman_main |
913 |
- |
914 |
-try: |
915 |
- sys.exit(repoman_main(sys.argv)) |
916 |
-except IOError as e: |
917 |
- if e.errno == errno.EACCES: |
918 |
- print("\nRepoman: Need user access") |
919 |
- sys.exit(1) |
920 |
- else: |
921 |
- raise |
922 |
-finally: |
923 |
- global_event_loop().close() |
924 |
|
925 |
diff --git a/repoman/cnf/linechecks/linechecks.yaml b/repoman/cnf/linechecks/linechecks.yaml |
926 |
deleted file mode 100644 |
927 |
index c6c72ab26..000000000 |
928 |
--- a/repoman/cnf/linechecks/linechecks.yaml |
929 |
+++ /dev/null |
930 |
@@ -1,34 +0,0 @@ |
931 |
---- |
932 |
-# linecheck_help.yaml |
933 |
- |
934 |
-# Repoman API version (do not edit) |
935 |
-version: 1 |
936 |
-# minimum |
937 |
-repoman_version: 2.3.3 |
938 |
- |
939 |
-# configuration file for the LineCheck plugins run via the multicheck |
940 |
-# scan module |
941 |
-errors: |
942 |
- COPYRIGHT_ERROR: 'Invalid Copyright' |
943 |
- LICENSE_ERROR: 'Invalid Gentoo/GPL License' |
944 |
- ID_HEADER_ERROR: 'Stale CVS header' |
945 |
- NO_BLANK_LINE_ERROR: 'Non-blank line after header' |
946 |
- LEADING_SPACES_ERROR: 'Ebuild contains leading spaces' |
947 |
- TRAILING_WHITESPACE_ERROR: 'Trailing whitespace error' |
948 |
- READONLY_ASSIGNMENT_ERROR: 'Ebuild contains assignment to read-only variable' |
949 |
- MISSING_QUOTES_ERROR: 'Unquoted Variable' |
950 |
- NESTED_DIE_ERROR: 'Ebuild calls die in a subshell' |
951 |
- PATCHES_ERROR: 'PATCHES is not a bash array' |
952 |
- REDUNDANT_CD_S_ERROR: 'Ebuild has redundant cd ${S} statement' |
953 |
- EMAKE_PARALLEL_DISABLED: 'Upstream parallel compilation bug (ebuild calls emake -j1)' |
954 |
- EMAKE_PARALLEL_DISABLED_VIA_MAKEOPTS: 'Upstream parallel compilation bug (MAKEOPTS=-j1)' |
955 |
- DEPRECATED_BINDNOW_FLAGS: 'Deprecated bindnow-flags call' |
956 |
- EAPI_DEFINED_AFTER_INHERIT: 'EAPI defined after inherit' |
957 |
- NO_AS_NEEDED: 'Upstream asneeded linking bug (no-as-needed)' |
958 |
- PRESERVE_OLD_LIB: 'Ebuild calls preserve_old_lib function reserved for system packages' |
959 |
- BUILT_WITH_USE: 'built_with_use' |
960 |
- NO_OFFSET_WITH_HELPERS: 'Helper function is used with D, ROOT, ED, EROOT or EPREFIX' |
961 |
- USEQ_ERROR: 'Ebuild calls deprecated useq function' |
962 |
- HASQ_ERROR: 'Ebuild calls deprecated hasq function' |
963 |
- URI_HTTPS: 'Ebuild uses http:// but should use https://' |
964 |
- |
965 |
|
966 |
diff --git a/repoman/cnf/metadata.xsd b/repoman/cnf/metadata.xsd |
967 |
deleted file mode 100644 |
968 |
index 33ff58eac..000000000 |
969 |
--- a/repoman/cnf/metadata.xsd |
970 |
+++ /dev/null |
971 |
@@ -1,548 +0,0 @@ |
972 |
-<?xml version='1.0' encoding='UTF-8'?> |
973 |
- |
974 |
-<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'> |
975 |
- <!-- top-level variants --> |
976 |
- <xs:element name='pkgmetadata' type='pkgMetadataType'> |
977 |
- <!-- note: restrict uniquity rules are simplified |
978 |
- the spec says: one for each matched package |
979 |
- we can only do: one for each restrict rule --> |
980 |
- <xs:unique name='longDescUniquityConstraint'> |
981 |
- <xs:selector xpath='longdescription'/> |
982 |
- <xs:field xpath='@lang'/> |
983 |
- <xs:field xpath='@restrict'/> |
984 |
- </xs:unique> |
985 |
- <xs:unique name='maintainerUniquityConstraint'> |
986 |
- <xs:selector xpath='maintainer'/> |
987 |
- <xs:field xpath='email'/> |
988 |
- <xs:field xpath='@restrict'/> |
989 |
- </xs:unique> |
990 |
- <xs:unique name='slotsUniquityConstraint'> |
991 |
- <xs:selector xpath='slots'/> |
992 |
- <xs:field xpath='@lang'/> |
993 |
- </xs:unique> |
994 |
- <xs:unique name='upstreamSingleConstraint'> |
995 |
- <xs:selector xpath='upstream'/> |
996 |
- <xs:field xpath='@fake-only-once'/> |
997 |
- </xs:unique> |
998 |
- <xs:unique name='useUniquityConstraint'> |
999 |
- <xs:selector xpath='use'/> |
1000 |
- <xs:field xpath='@lang'/> |
1001 |
- </xs:unique> |
1002 |
- </xs:element> |
1003 |
- <xs:element name='catmetadata' type='catMetadataType'> |
1004 |
- <xs:unique name='catLongDescUniquityConstraint'> |
1005 |
- <xs:selector xpath='longdescription'/> |
1006 |
- <xs:field xpath='@lang'/> |
1007 |
- </xs:unique> |
1008 |
- </xs:element> |
1009 |
- |
1010 |
- <!-- global elements --> |
1011 |
- <xs:complexType name='pkgMetadataType'> |
1012 |
- <xs:choice minOccurs='0' maxOccurs='unbounded'> |
1013 |
- <xs:element name='longdescription' type='longDescType'/> |
1014 |
- <xs:element name='maintainer' type='maintainerType'> |
1015 |
- <xs:unique name='maintainerDescUniquityConstraint'> |
1016 |
- <xs:selector xpath='description'/> |
1017 |
- <xs:field xpath='@lang'/> |
1018 |
- </xs:unique> |
1019 |
- </xs:element> |
1020 |
- <xs:element name='slots' type='slotsType'> |
1021 |
- <xs:unique name='slotUniquityConstraint'> |
1022 |
- <xs:selector xpath='slot'/> |
1023 |
- <xs:field xpath='@name'/> |
1024 |
- </xs:unique> |
1025 |
- <xs:unique name='subslotsSingleConstraint'> |
1026 |
- <xs:selector xpath='subslots'/> |
1027 |
- <xs:field xpath='@fake-only-once'/> |
1028 |
- </xs:unique> |
1029 |
- </xs:element> |
1030 |
- <xs:element name='upstream' type='upstreamType'> |
1031 |
- <xs:unique name='bugsToSingleConstraint'> |
1032 |
- <xs:selector xpath='bugs-to'/> |
1033 |
- <xs:field xpath='@fake-only-once'/> |
1034 |
- </xs:unique> |
1035 |
- <xs:unique name='changelogSingleConstraint'> |
1036 |
- <xs:selector xpath='changelog'/> |
1037 |
- <xs:field xpath='@fake-only-once'/> |
1038 |
- </xs:unique> |
1039 |
- <!-- prevent accidentally repeating the same remote --> |
1040 |
- <xs:unique name='upstreamRemoteIdRepetitionConstraint'> |
1041 |
- <xs:selector xpath='remote-id'/> |
1042 |
- <xs:field xpath='@type'/> |
1043 |
- <xs:field xpath='.'/> |
1044 |
- </xs:unique> |
1045 |
- <xs:unique name='upstreamDocUniquityConstraint'> |
1046 |
- <xs:selector xpath='doc'/> |
1047 |
- <xs:field xpath='@lang'/> |
1048 |
- </xs:unique> |
1049 |
- </xs:element> |
1050 |
- <xs:element name='use' type='useType'> |
1051 |
- <xs:unique name='flagUniquityConstraint'> |
1052 |
- <xs:selector xpath='flag'/> |
1053 |
- <xs:field xpath='@name'/> |
1054 |
- <xs:field xpath='@restrict'/> |
1055 |
- </xs:unique> |
1056 |
- </xs:element> |
1057 |
- </xs:choice> |
1058 |
- </xs:complexType> |
1059 |
- |
1060 |
- <xs:complexType name='catMetadataType'> |
1061 |
- <xs:choice minOccurs='0' maxOccurs='unbounded'> |
1062 |
- <xs:element name='longdescription' type='catLongDescType'/> |
1063 |
- </xs:choice> |
1064 |
- </xs:complexType> |
1065 |
- |
1066 |
- <!-- the huge <upstream/> structure --> |
1067 |
- <xs:complexType name='upstreamType'> |
1068 |
- <xs:choice minOccurs='0' maxOccurs='unbounded'> |
1069 |
- <xs:element name='maintainer' type='upstreamMaintainerType'> |
1070 |
- <xs:unique name='upstreamMaintainerUniquityConstraint'> |
1071 |
- <xs:selector xpath='maintainer'/> |
1072 |
- <xs:field xpath='name'/> |
1073 |
- </xs:unique> |
1074 |
- </xs:element> |
1075 |
- <xs:element name='changelog' type='urlOnceType'/> |
1076 |
- <xs:element name='doc' type='upstreamDocType'/> |
1077 |
- <xs:element name='bugs-to' type='urlOnceType'/> |
1078 |
- <xs:element name='remote-id' type='upstreamRemoteIdType'/> |
1079 |
- </xs:choice> |
1080 |
- <xs:attribute name='fake-only-once' |
1081 |
- fixed='there can be at most one <upstream/> element'/> |
1082 |
- </xs:complexType> |
1083 |
- |
1084 |
- <!-- maintainer in two variants --> |
1085 |
- <xs:complexType name='maintainerType'> |
1086 |
- <xs:all> |
1087 |
- <xs:element name='email' type='emailType' |
1088 |
- minOccurs='1'/> |
1089 |
- <xs:element name='name' type='xs:token' |
1090 |
- minOccurs='0'/> |
1091 |
- <xs:element name='description' type='maintainerDescType' |
1092 |
- minOccurs='0'/> |
1093 |
- </xs:all> |
1094 |
- <xs:attribute name='type' type='maintainerTypeAttrType' |
1095 |
- use='required'/> |
1096 |
- <xs:attribute name='restrict' type='restrictAttrType'/> |
1097 |
- </xs:complexType> |
1098 |
- |
1099 |
- <xs:simpleType name='maintainerTypeAttrType'> |
1100 |
- <xs:restriction base='xs:token'> |
1101 |
- <xs:enumeration value='person'/> |
1102 |
- <xs:enumeration value='project'/> |
1103 |
- </xs:restriction> |
1104 |
- </xs:simpleType> |
1105 |
- |
1106 |
- <xs:complexType name='upstreamMaintainerType'> |
1107 |
- <xs:all> |
1108 |
- <xs:element name='email' type='emailType' |
1109 |
- minOccurs='0'/> |
1110 |
- <xs:element name='name' type='xs:token' |
1111 |
- minOccurs='0'/> |
1112 |
- </xs:all> |
1113 |
- <xs:attribute name='status' type='upstreamMaintainerStatusAttrType' |
1114 |
- default='unknown'/> |
1115 |
- </xs:complexType> |
1116 |
- |
1117 |
- <xs:simpleType name='upstreamMaintainerStatusAttrType'> |
1118 |
- <xs:restriction base='xs:token'> |
1119 |
- <xs:enumeration value='active'/> |
1120 |
- <xs:enumeration value='inactive'/> |
1121 |
- <xs:enumeration value='unknown'/> |
1122 |
- </xs:restriction> |
1123 |
- </xs:simpleType> |
1124 |
- |
1125 |
- <xs:complexType name='maintainerDescType'> |
1126 |
- <xs:simpleContent> |
1127 |
- <xs:extension base="xs:token"> |
1128 |
- <xs:attribute name='lang' type='langAttrType' default='en'/> |
1129 |
- </xs:extension> |
1130 |
- </xs:simpleContent> |
1131 |
- </xs:complexType> |
1132 |
- |
1133 |
- <!-- long description --> |
1134 |
- <xs:complexType name='longDescType' mixed='true'> |
1135 |
- <xs:choice minOccurs='0' maxOccurs='unbounded'> |
1136 |
- <xs:element name='pkg' type='pkgType'/> |
1137 |
- <xs:element name='cat' type='catType'/> |
1138 |
- </xs:choice> |
1139 |
- <xs:attribute name='lang' type='langAttrType' default='en'/> |
1140 |
- <xs:attribute name='restrict' type='restrictAttrType'/> |
1141 |
- </xs:complexType> |
1142 |
- |
1143 |
- <xs:complexType name='catLongDescType' mixed='true'> |
1144 |
- <xs:choice minOccurs='0' maxOccurs='unbounded'> |
1145 |
- <xs:element name='pkg' type='pkgType'/> |
1146 |
- <xs:element name='cat' type='catType'/> |
1147 |
- </xs:choice> |
1148 |
- <xs:attribute name='lang' type='langAttrType' default='en'/> |
1149 |
- </xs:complexType> |
1150 |
- |
1151 |
- <!-- slots --> |
1152 |
- <xs:complexType name='slotsType'> |
1153 |
- <xs:choice minOccurs='0' maxOccurs='unbounded'> |
1154 |
- <xs:element name='slot' type='slotType'/> |
1155 |
- <xs:element name='subslots' type='tokenOnceType'/> |
1156 |
- </xs:choice> |
1157 |
- <xs:attribute name='lang' type='langAttrType' default='en'/> |
1158 |
- </xs:complexType> |
1159 |
- |
1160 |
- <xs:complexType name='slotType'> |
1161 |
- <xs:simpleContent> |
1162 |
- <xs:extension base="xs:token"> |
1163 |
- <xs:attribute name='name' type='slotNameAttrType' |
1164 |
- use='required'/> |
1165 |
- </xs:extension> |
1166 |
- </xs:simpleContent> |
1167 |
- </xs:complexType> |
1168 |
- |
1169 |
- <xs:simpleType name='slotNameAttrType'> |
1170 |
- <xs:restriction base='xs:token'> |
1171 |
- <!-- PMS 3.1.3 Slot Names + special value '*' --> |
1172 |
- <xs:pattern value="[A-Za-z0-9_][A-Za-z0-9+_.-]*|[*]"/> |
1173 |
- </xs:restriction> |
1174 |
- </xs:simpleType> |
1175 |
- |
1176 |
- <!-- use flags --> |
1177 |
- <xs:complexType name='useType'> |
1178 |
- <xs:choice minOccurs='0' maxOccurs='unbounded'> |
1179 |
- <xs:element name='flag' type='flagType'/> |
1180 |
- </xs:choice> |
1181 |
- <xs:attribute name='lang' type='langAttrType' default='en'/> |
1182 |
- </xs:complexType> |
1183 |
- |
1184 |
- <xs:complexType name='flagType' mixed='true'> |
1185 |
- <xs:choice minOccurs='0' maxOccurs='unbounded'> |
1186 |
- <xs:element name='cat' type='catType'/> |
1187 |
- <xs:element name='pkg' type='pkgType'/> |
1188 |
- </xs:choice> |
1189 |
- <xs:attribute name='name' type='flagNameAttrType' |
1190 |
- use='required'/> |
1191 |
- <xs:attribute name='restrict' type='restrictAttrType' |
1192 |
- default=''/> |
1193 |
- </xs:complexType> |
1194 |
- |
1195 |
- <xs:simpleType name='flagNameAttrType'> |
1196 |
- <xs:restriction base='xs:token'> |
1197 |
- <!-- PMS 3.1.4 USE Flag Names --> |
1198 |
- <xs:pattern value="[A-Za-z0-9][A-Za-z0-9+_@-]*"/> |
1199 |
- </xs:restriction> |
1200 |
- </xs:simpleType> |
1201 |
- |
1202 |
- <!-- upstream-specific types --> |
1203 |
- <xs:complexType name='upstreamDocType'> |
1204 |
- <xs:simpleContent> |
1205 |
- <xs:extension base="urlType"> |
1206 |
- <xs:attribute name='lang' type='langAttrType' default='en'/> |
1207 |
- </xs:extension> |
1208 |
- </xs:simpleContent> |
1209 |
- </xs:complexType> |
1210 |
- |
1211 |
- <xs:complexType name='upstreamRemoteIdType'> |
1212 |
- <xs:simpleContent> |
1213 |
- <xs:extension base="xs:token"> |
1214 |
- <xs:attribute name='type' type='upstreamRemoteIdTypeAttrType' |
1215 |
- use='required'/> |
1216 |
- </xs:extension> |
1217 |
- </xs:simpleContent> |
1218 |
- </xs:complexType> |
1219 |
- |
1220 |
- <xs:simpleType name='upstreamRemoteIdTypeAttrType'> |
1221 |
- <xs:restriction base='xs:token'> |
1222 |
- <xs:enumeration value='bitbucket'/> |
1223 |
- <xs:enumeration value='cpan'/> |
1224 |
- <xs:enumeration value='cpan-module'/> |
1225 |
- <xs:enumeration value='cpe'/> |
1226 |
- <xs:enumeration value='cran'/> |
1227 |
- <xs:enumeration value='ctan'/> |
1228 |
- <xs:enumeration value='freecode'/> |
1229 |
- <xs:enumeration value='freshmeat'/> |
1230 |
- <xs:enumeration value='gentoo'/> |
1231 |
- <xs:enumeration value='github'/> |
1232 |
- <xs:enumeration value='gitlab'/> |
1233 |
- <xs:enumeration value='gitorious'/> |
1234 |
- <xs:enumeration value='google-code'/> |
1235 |
- <xs:enumeration value='launchpad'/> |
1236 |
- <xs:enumeration value='pear'/> |
1237 |
- <xs:enumeration value='pecl'/> |
1238 |
- <xs:enumeration value='pypi'/> |
1239 |
- <xs:enumeration value='rubyforge'/> |
1240 |
- <xs:enumeration value='rubygems'/> |
1241 |
- <xs:enumeration value='sourceforge'/> |
1242 |
- <xs:enumeration value='sourceforge-jp'/> |
1243 |
- <xs:enumeration value='vim'/> |
1244 |
- </xs:restriction> |
1245 |
- </xs:simpleType> |
1246 |
- |
1247 |
- <!-- creepy mixed-text types --> |
1248 |
- <xs:simpleType name='catType'> |
1249 |
- <xs:restriction base='xs:token'> |
1250 |
- <!-- PMS 3.1.1 Category Names --> |
1251 |
- <xs:pattern value="[A-Za-z0-9_][A-Za-z0-9+_.-]*"/> |
1252 |
- </xs:restriction> |
1253 |
- </xs:simpleType> |
1254 |
- <xs:simpleType name='pkgType'> |
1255 |
- <xs:restriction base='xs:token'> |
1256 |
- <!-- PMS 3.1.1 Category Names + 3.1.2 Package Names --> |
1257 |
- <!-- note: this does not enforce the 'anything matching |
1258 |
- the version syntax' requirement --> |
1259 |
- <xs:pattern |
1260 |
- value="[A-Za-z0-9_][A-Za-z0-9+_.-]*/[A-Za-z0-9_][A-Za-z0-9+_-]*"/> |
1261 |
- </xs:restriction> |
1262 |
- </xs:simpleType> |
1263 |
- |
1264 |
- <!-- common attributes --> |
1265 |
- <xs:simpleType name='langAttrType'> |
1266 |
- <xs:restriction base='xs:token'> |
1267 |
- <!-- ISO 639-1 language codes --> |
1268 |
- <xs:enumeration value='aa'/> |
1269 |
- <xs:enumeration value='ab'/> |
1270 |
- <xs:enumeration value='ae'/> |
1271 |
- <xs:enumeration value='af'/> |
1272 |
- <xs:enumeration value='ak'/> |
1273 |
- <xs:enumeration value='am'/> |
1274 |
- <xs:enumeration value='an'/> |
1275 |
- <xs:enumeration value='ar'/> |
1276 |
- <xs:enumeration value='as'/> |
1277 |
- <xs:enumeration value='av'/> |
1278 |
- <xs:enumeration value='ay'/> |
1279 |
- <xs:enumeration value='az'/> |
1280 |
- <xs:enumeration value='ba'/> |
1281 |
- <xs:enumeration value='be'/> |
1282 |
- <xs:enumeration value='bg'/> |
1283 |
- <xs:enumeration value='bh'/> |
1284 |
- <xs:enumeration value='bi'/> |
1285 |
- <xs:enumeration value='bm'/> |
1286 |
- <xs:enumeration value='bn'/> |
1287 |
- <xs:enumeration value='bo'/> |
1288 |
- <xs:enumeration value='bo'/> |
1289 |
- <xs:enumeration value='br'/> |
1290 |
- <xs:enumeration value='bs'/> |
1291 |
- <xs:enumeration value='ca'/> |
1292 |
- <xs:enumeration value='ce'/> |
1293 |
- <xs:enumeration value='ch'/> |
1294 |
- <xs:enumeration value='co'/> |
1295 |
- <xs:enumeration value='cr'/> |
1296 |
- <xs:enumeration value='cs'/> |
1297 |
- <xs:enumeration value='cs'/> |
1298 |
- <xs:enumeration value='cu'/> |
1299 |
- <xs:enumeration value='cv'/> |
1300 |
- <xs:enumeration value='cy'/> |
1301 |
- <xs:enumeration value='cy'/> |
1302 |
- <xs:enumeration value='da'/> |
1303 |
- <xs:enumeration value='de'/> |
1304 |
- <xs:enumeration value='de'/> |
1305 |
- <xs:enumeration value='dv'/> |
1306 |
- <xs:enumeration value='dz'/> |
1307 |
- <xs:enumeration value='ee'/> |
1308 |
- <xs:enumeration value='el'/> |
1309 |
- <xs:enumeration value='el'/> |
1310 |
- <xs:enumeration value='en'/> |
1311 |
- <xs:enumeration value='eo'/> |
1312 |
- <xs:enumeration value='es'/> |
1313 |
- <xs:enumeration value='et'/> |
1314 |
- <xs:enumeration value='eu'/> |
1315 |
- <xs:enumeration value='eu'/> |
1316 |
- <xs:enumeration value='fa'/> |
1317 |
- <xs:enumeration value='fa'/> |
1318 |
- <xs:enumeration value='ff'/> |
1319 |
- <xs:enumeration value='fi'/> |
1320 |
- <xs:enumeration value='fj'/> |
1321 |
- <xs:enumeration value='fo'/> |
1322 |
- <xs:enumeration value='fr'/> |
1323 |
- <xs:enumeration value='fr'/> |
1324 |
- <xs:enumeration value='fy'/> |
1325 |
- <xs:enumeration value='ga'/> |
1326 |
- <xs:enumeration value='ga'/> |
1327 |
- <xs:enumeration value='Ga'/> |
1328 |
- <xs:enumeration value='gd'/> |
1329 |
- <xs:enumeration value='gl'/> |
1330 |
- <xs:enumeration value='gn'/> |
1331 |
- <xs:enumeration value='gu'/> |
1332 |
- <xs:enumeration value='gv'/> |
1333 |
- <xs:enumeration value='ha'/> |
1334 |
- <xs:enumeration value='he'/> |
1335 |
- <xs:enumeration value='hi'/> |
1336 |
- <xs:enumeration value='ho'/> |
1337 |
- <xs:enumeration value='hr'/> |
1338 |
- <xs:enumeration value='ht'/> |
1339 |
- <xs:enumeration value='hu'/> |
1340 |
- <xs:enumeration value='hy'/> |
1341 |
- <xs:enumeration value='hy'/> |
1342 |
- <xs:enumeration value='hz'/> |
1343 |
- <xs:enumeration value='ia'/> |
1344 |
- <xs:enumeration value='id'/> |
1345 |
- <xs:enumeration value='ie'/> |
1346 |
- <xs:enumeration value='ig'/> |
1347 |
- <xs:enumeration value='ii'/> |
1348 |
- <xs:enumeration value='ik'/> |
1349 |
- <xs:enumeration value='io'/> |
1350 |
- <xs:enumeration value='is'/> |
1351 |
- <xs:enumeration value='is'/> |
1352 |
- <xs:enumeration value='it'/> |
1353 |
- <xs:enumeration value='iu'/> |
1354 |
- <xs:enumeration value='ja'/> |
1355 |
- <xs:enumeration value='jv'/> |
1356 |
- <xs:enumeration value='ka'/> |
1357 |
- <xs:enumeration value='ka'/> |
1358 |
- <xs:enumeration value='kg'/> |
1359 |
- <xs:enumeration value='ki'/> |
1360 |
- <xs:enumeration value='kj'/> |
1361 |
- <xs:enumeration value='kk'/> |
1362 |
- <xs:enumeration value='kl'/> |
1363 |
- <xs:enumeration value='km'/> |
1364 |
- <xs:enumeration value='kn'/> |
1365 |
- <xs:enumeration value='ko'/> |
1366 |
- <xs:enumeration value='kr'/> |
1367 |
- <xs:enumeration value='ks'/> |
1368 |
- <xs:enumeration value='ku'/> |
1369 |
- <xs:enumeration value='kv'/> |
1370 |
- <xs:enumeration value='kw'/> |
1371 |
- <xs:enumeration value='ky'/> |
1372 |
- <xs:enumeration value='la'/> |
1373 |
- <xs:enumeration value='lb'/> |
1374 |
- <xs:enumeration value='lg'/> |
1375 |
- <xs:enumeration value='li'/> |
1376 |
- <xs:enumeration value='ln'/> |
1377 |
- <xs:enumeration value='lo'/> |
1378 |
- <xs:enumeration value='lt'/> |
1379 |
- <xs:enumeration value='lu'/> |
1380 |
- <xs:enumeration value='lv'/> |
1381 |
- <xs:enumeration value='mg'/> |
1382 |
- <xs:enumeration value='mh'/> |
1383 |
- <xs:enumeration value='mi'/> |
1384 |
- <xs:enumeration value='mi'/> |
1385 |
- <xs:enumeration value='mk'/> |
1386 |
- <xs:enumeration value='mk'/> |
1387 |
- <xs:enumeration value='ml'/> |
1388 |
- <xs:enumeration value='mn'/> |
1389 |
- <xs:enumeration value='mr'/> |
1390 |
- <xs:enumeration value='ms'/> |
1391 |
- <xs:enumeration value='ms'/> |
1392 |
- <xs:enumeration value='mt'/> |
1393 |
- <xs:enumeration value='my'/> |
1394 |
- <xs:enumeration value='my'/> |
1395 |
- <xs:enumeration value='na'/> |
1396 |
- <xs:enumeration value='nb'/> |
1397 |
- <xs:enumeration value='nd'/> |
1398 |
- <xs:enumeration value='ne'/> |
1399 |
- <xs:enumeration value='ng'/> |
1400 |
- <xs:enumeration value='nl'/> |
1401 |
- <xs:enumeration value='nl'/> |
1402 |
- <xs:enumeration value='nn'/> |
1403 |
- <xs:enumeration value='no'/> |
1404 |
- <xs:enumeration value='nr'/> |
1405 |
- <xs:enumeration value='nv'/> |
1406 |
- <xs:enumeration value='ny'/> |
1407 |
- <xs:enumeration value='oc'/> |
1408 |
- <xs:enumeration value='oj'/> |
1409 |
- <xs:enumeration value='om'/> |
1410 |
- <xs:enumeration value='or'/> |
1411 |
- <xs:enumeration value='os'/> |
1412 |
- <xs:enumeration value='pa'/> |
1413 |
- <xs:enumeration value='pi'/> |
1414 |
- <xs:enumeration value='pl'/> |
1415 |
- <xs:enumeration value='ps'/> |
1416 |
- <xs:enumeration value='pt'/> |
1417 |
- <xs:enumeration value='qu'/> |
1418 |
- <xs:enumeration value='rm'/> |
1419 |
- <xs:enumeration value='rn'/> |
1420 |
- <xs:enumeration value='ro'/> |
1421 |
- <xs:enumeration value='ro'/> |
1422 |
- <xs:enumeration value='ru'/> |
1423 |
- <xs:enumeration value='rw'/> |
1424 |
- <xs:enumeration value='sa'/> |
1425 |
- <xs:enumeration value='sc'/> |
1426 |
- <xs:enumeration value='sd'/> |
1427 |
- <xs:enumeration value='se'/> |
1428 |
- <xs:enumeration value='sg'/> |
1429 |
- <xs:enumeration value='si'/> |
1430 |
- <xs:enumeration value='sk'/> |
1431 |
- <xs:enumeration value='sk'/> |
1432 |
- <xs:enumeration value='sl'/> |
1433 |
- <xs:enumeration value='sm'/> |
1434 |
- <xs:enumeration value='sn'/> |
1435 |
- <xs:enumeration value='so'/> |
1436 |
- <xs:enumeration value='sq'/> |
1437 |
- <xs:enumeration value='sq'/> |
1438 |
- <xs:enumeration value='sr'/> |
1439 |
- <xs:enumeration value='ss'/> |
1440 |
- <xs:enumeration value='st'/> |
1441 |
- <xs:enumeration value='su'/> |
1442 |
- <xs:enumeration value='sv'/> |
1443 |
- <xs:enumeration value='sw'/> |
1444 |
- <xs:enumeration value='ta'/> |
1445 |
- <xs:enumeration value='te'/> |
1446 |
- <xs:enumeration value='tg'/> |
1447 |
- <xs:enumeration value='th'/> |
1448 |
- <xs:enumeration value='ti'/> |
1449 |
- <xs:enumeration value='tk'/> |
1450 |
- <xs:enumeration value='tl'/> |
1451 |
- <xs:enumeration value='tn'/> |
1452 |
- <xs:enumeration value='to'/> |
1453 |
- <xs:enumeration value='tr'/> |
1454 |
- <xs:enumeration value='ts'/> |
1455 |
- <xs:enumeration value='tt'/> |
1456 |
- <xs:enumeration value='tw'/> |
1457 |
- <xs:enumeration value='ty'/> |
1458 |
- <xs:enumeration value='ug'/> |
1459 |
- <xs:enumeration value='uk'/> |
1460 |
- <xs:enumeration value='ur'/> |
1461 |
- <xs:enumeration value='uz'/> |
1462 |
- <xs:enumeration value='ve'/> |
1463 |
- <xs:enumeration value='vi'/> |
1464 |
- <xs:enumeration value='vo'/> |
1465 |
- <xs:enumeration value='wa'/> |
1466 |
- <xs:enumeration value='wo'/> |
1467 |
- <xs:enumeration value='xh'/> |
1468 |
- <xs:enumeration value='yi'/> |
1469 |
- <xs:enumeration value='yo'/> |
1470 |
- <xs:enumeration value='za'/> |
1471 |
- <xs:enumeration value='zh'/> |
1472 |
- <xs:enumeration value='zh'/> |
1473 |
- <xs:enumeration value='zu'/> |
1474 |
- </xs:restriction> |
1475 |
- </xs:simpleType> |
1476 |
- |
1477 |
- <xs:simpleType name='restrictAttrType'> |
1478 |
- <xs:restriction base='xs:token'> |
1479 |
- <!-- simplified package dependency syntax --> |
1480 |
- <!-- note: 'pure' package atom is technically valid too |
1481 |
- but not really meaningful --> |
1482 |
- <xs:pattern |
1483 |
- value="(([<>]=?|[=~])[A-Za-z0-9_][A-Za-z0-9+_.-]*/[A-Za-z0-9_][A-Za-z0-9+_-]*-[0-9]+(\.[0-9]+)*[a-z]?((_alpha|_beta|_pre|_rc|_p)[0-9]*)*(-r[0-9]+)?\*?)?"/> |
1484 |
- </xs:restriction> |
1485 |
- </xs:simpleType> |
1486 |
- |
1487 |
- <!-- generic types --> |
1488 |
- <xs:simpleType name='emailType'> |
1489 |
- <xs:restriction base='xs:token'> |
1490 |
- <!-- minimal safe regex --> |
1491 |
- <xs:pattern value="[^@]+@[^.]+\..+"/> |
1492 |
- </xs:restriction> |
1493 |
- </xs:simpleType> |
1494 |
- |
1495 |
- <xs:complexType name='tokenOnceType'> |
1496 |
- <xs:simpleContent> |
1497 |
- <xs:extension base="xs:token"> |
1498 |
- <xs:attribute name='fake-only-once' |
1499 |
- fixed='there can be at most one element of this type'/> |
1500 |
- </xs:extension> |
1501 |
- </xs:simpleContent> |
1502 |
- </xs:complexType> |
1503 |
- |
1504 |
- <xs:simpleType name='urlType'> |
1505 |
- <xs:restriction base='xs:token'> |
1506 |
- <!-- TODO: something better? --> |
1507 |
- <xs:pattern value="(mailto:[^@]+@[^.]+\..+|https?://.+)"/> |
1508 |
- </xs:restriction> |
1509 |
- </xs:simpleType> |
1510 |
- |
1511 |
- <xs:complexType name='urlOnceType'> |
1512 |
- <xs:simpleContent> |
1513 |
- <xs:extension base="urlType"> |
1514 |
- <xs:attribute name='fake-only-once' |
1515 |
- fixed='there can be at most one element of this type'/> |
1516 |
- </xs:extension> |
1517 |
- </xs:simpleContent> |
1518 |
- </xs:complexType> |
1519 |
-</xs:schema> |
1520 |
|
1521 |
diff --git a/repoman/cnf/qa_data/qa_data.yaml b/repoman/cnf/qa_data/qa_data.yaml |
1522 |
deleted file mode 100644 |
1523 |
index 530c8c806..000000000 |
1524 |
--- a/repoman/cnf/qa_data/qa_data.yaml |
1525 |
+++ /dev/null |
1526 |
@@ -1,139 +0,0 @@ |
1527 |
---- |
1528 |
-# qa_help.yaml |
1529 |
- |
1530 |
-# configuration file for the LineCheck plugins run via the multicheck |
1531 |
-# scan module |
1532 |
- |
1533 |
-# Repoman API version (do not edit) |
1534 |
-version: 1 |
1535 |
-# minimum |
1536 |
-repoman_version: 2.3.3 |
1537 |
- |
1538 |
-# qahelp: Primary QA help messages to describe the errors or warnings |
1539 |
-# Dictionary |
1540 |
-qahelp: |
1541 |
- Entries: |
1542 |
- IO_error: "Attempting to commit, and an IO error was encountered access the Entries file" |
1543 |
- changelog: |
1544 |
- ebuildadded: "An ebuild was added but the ChangeLog was not modified" |
1545 |
- missing: "Missing ChangeLog files" |
1546 |
- notadded: "ChangeLogs that exist but have not been added to cvs" |
1547 |
- dependency: |
1548 |
- bad: "User-visible ebuilds with unsatisfied dependencies (matched against *visible* ebuilds)" |
1549 |
- badmasked: "Masked ebuilds with unsatisfied dependencies (matched against *all* ebuilds)" |
1550 |
- badindev: "User-visible ebuilds with unsatisfied dependencies (matched against *visible* ebuilds) in developing arch" |
1551 |
- badmaskedindev: "Masked ebuilds with unsatisfied dependencies (matched against *all* ebuilds) in developing arch" |
1552 |
- badinexp: "User-visible ebuilds with unsatisfied dependencies (matched against *visible* ebuilds) in experimental arch" |
1553 |
- badmaskedinexp: "Masked ebuilds with unsatisfied dependencies (matched against *all* ebuilds) in experimental arch" |
1554 |
- badtilde: "Uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)" |
1555 |
- deprecated: "Ebuild has a dependency that refers to a deprecated package" |
1556 |
- equalsversion: "Suspicious =-dependency with a specific version and no rev. Please either use ~ if any revision is acceptable, or append -r0 to silence the warning." |
1557 |
- missingslot: "RDEPEND matches more than one SLOT but does not specify a slot and/or use the := or :* slot operator" |
1558 |
- perlcore: "This ebuild directly depends on a package in perl-core; it should use the corresponding virtual instead." |
1559 |
- syntax: "Syntax error in dependency string (usually an extra/missing space/parenthesis)" |
1560 |
- unknown: "Ebuild has a dependency that refers to an unknown package (which may be valid if it is a blocker for a renamed/removed package, or is an alternative choice provided by an overlay)" |
1561 |
- badslotop: "RDEPEND contains ':=' slot operator under '||' dependency." |
1562 |
- DESCRIPTION: |
1563 |
- missing: "Ebuilds that have a missing or empty DESCRIPTION variable" |
1564 |
- toolong: "DESCRIPTION is over %d characters" |
1565 |
- digest: |
1566 |
- assumed: "Existing digest must be assumed correct (Package level only)" |
1567 |
- missing: "Some files listed in SRC_URI aren't referenced in the Manifest" |
1568 |
- unused: "Some files listed in the Manifest aren't referenced in SRC_URI" |
1569 |
- EAPI: |
1570 |
- definition: "EAPI definition does not conform to PMS section 7.3.1 (first non-comment, non-blank line)" |
1571 |
- deprecated: "Ebuilds that use features that are deprecated in the current EAPI" |
1572 |
- incompatible: "Ebuilds that use features that are only available with a different EAPI" |
1573 |
- unsupported: "Ebuilds that have an unsupported EAPI version (you must upgrade portage)" |
1574 |
- ebuild: |
1575 |
- absdosym: "This ebuild uses absolute target to dosym where relative symlink could be used instead" |
1576 |
- badheader: "This ebuild has a malformed header" |
1577 |
- invalidname: "Ebuild files with a non-parseable or syntactically incorrect name (or using 2.1 versioning extensions)" |
1578 |
- majorsyn: "This ebuild has a major syntax error that may cause the ebuild to fail partially or fully" |
1579 |
- minorsyn: "This ebuild has a minor syntax error that contravenes gentoo coding style" |
1580 |
- namenomatch: "Ebuild files that do not have the same name as their parent directory" |
1581 |
- notadded: "Ebuilds that exist but have not been added to the vcs" |
1582 |
- nesteddie: "Placing 'die' inside ( ) prints an error, but doesn't stop the ebuild." |
1583 |
- output: "A simple sourcing of the ebuild produces output; this breaks ebuild policy." |
1584 |
- patches: "PATCHES variable should be a bash array to ensure white space safety" |
1585 |
- syntax: "Error generating cache entry for ebuild; typically caused by ebuild syntax error or digest verification failure" |
1586 |
- file: |
1587 |
- executable: "Ebuilds, digests, metadata.xml, Manifest, and ChangeLog do not need the executable bit" |
1588 |
- size: "Files in the files directory must be under 20 KiB" |
1589 |
- empty: "Empty file in the files directory" |
1590 |
- name: "File/dir name must be composed of only the following chars: %s " |
1591 |
- UTF8: "File is not UTF8 compliant" |
1592 |
- HOMEPAGE: |
1593 |
- missing: "Ebuilds that have a missing or empty HOMEPAGE variable" |
1594 |
- virtual: "Virtuals that have a non-empty HOMEPAGE variable" |
1595 |
- missingurischeme: "HOMEPAGE is missing an URI scheme" |
1596 |
- inherit: |
1597 |
- deprecated: "Ebuild inherits a deprecated eclass" |
1598 |
- missing: "Ebuild uses functions from an eclass but does not inherit it" |
1599 |
- unused: "Ebuild inherits an eclass but does not use it" |
1600 |
- IUSE: |
1601 |
- invalid: "This ebuild has a variable in IUSE that is not in the use.desc or its metadata.xml file" |
1602 |
- missing: "This ebuild has a USE conditional which references a flag that is not listed in IUSE" |
1603 |
- rubydeprecated: "The ebuild has set a ruby interpreter in USE_RUBY, that is not available as a ruby target anymore" |
1604 |
- java: |
1605 |
- eclassesnotused: "With virtual/jdk in DEPEND you must inherit a java eclass" |
1606 |
- KEYWORDS: |
1607 |
- dropped: "Ebuilds that appear to have dropped KEYWORDS for some arch" |
1608 |
- invalid: "This ebuild contains KEYWORDS that are not listed in profiles/arch.list or for which no valid profile was found" |
1609 |
- missing: "Ebuilds that have a missing or empty KEYWORDS variable" |
1610 |
- stable: "Ebuilds that have been added directly with stable KEYWORDS" |
1611 |
- stupid: "Ebuilds that use KEYWORDS=-* instead of package.mask" |
1612 |
- unsorted: "Ebuilds that contain KEYWORDS which are not sorted alphabetically." |
1613 |
- LICENSE: |
1614 |
- deprecated: "This ebuild is listing a deprecated license." |
1615 |
- invalid: "This ebuild is listing a license that doesnt exist in portages license/ dir." |
1616 |
- missing: "Ebuilds that have a missing or empty LICENSE variable" |
1617 |
- syntax: "Syntax error in LICENSE (usually an extra/missing space/parenthesis)" |
1618 |
- virtual: "Virtuals that have a non-empty LICENSE variable" |
1619 |
- LIVEVCS: |
1620 |
- stable: "This ebuild is a live checkout from a VCS but has stable keywords." |
1621 |
- unmasked: "This ebuild is a live checkout from a VCS but has keywords and is not masked in the global package.mask." |
1622 |
- manifest: |
1623 |
- bad: "Manifest has missing or incorrect digests" |
1624 |
- metadata: |
1625 |
- bad: "Bad metadata.xml files" |
1626 |
- missing: "Missing metadata.xml files" |
1627 |
- warning: "Warnings in metadata.xml files" |
1628 |
- PDEPEND: |
1629 |
- suspect: "PDEPEND contains a package that usually only belongs in DEPEND." |
1630 |
- portage: |
1631 |
- internal: "The ebuild uses an internal Portage function or variable" |
1632 |
- PROPERTIES: |
1633 |
- syntax: "Syntax error in PROPERTIES (usually an extra/missing space/parenthesis)" |
1634 |
- RDEPEND: |
1635 |
- implicit: "RDEPEND is unset in the ebuild which triggers implicit RDEPEND=$DEPEND assignment (prior to EAPI 4)" |
1636 |
- suspect: "RDEPEND contains a package that usually only belongs in DEPEND." |
1637 |
- repo: |
1638 |
- eapi-banned: "The ebuild uses an EAPI which is banned by the repository's metadata/layout.conf settings" |
1639 |
- eapi-deprecated: "The ebuild uses an EAPI which is deprecated by the repository's metadata/layout.conf settings" |
1640 |
- RESTRICT: |
1641 |
- invalid: "This ebuild contains invalid RESTRICT values." |
1642 |
- syntax: "Syntax error in RESTRICT (usually an extra/missing space/parenthesis)" |
1643 |
- REQUIRED_USE: |
1644 |
- syntax: "Syntax error in REQUIRED_USE (usually an extra/missing space/parenthesis)" |
1645 |
- SLOT: |
1646 |
- invalid: "Ebuilds that have a missing or invalid SLOT variable value" |
1647 |
- SRC_URI: |
1648 |
- syntax: "Syntax error in SRC_URI (usually an extra/missing space/parenthesis)" |
1649 |
- mirror: "A uri listed in profiles/thirdpartymirrors is found in SRC_URI" |
1650 |
- upstream: |
1651 |
- workaround: "The ebuild works around an upstream bug, an upstream bug should be filed and tracked in bugs.gentoo.org" |
1652 |
- uri: |
1653 |
- https: "URI uses http:// but should use https://" |
1654 |
- usage: |
1655 |
- obsolete: "The ebuild makes use of an obsolete construct" |
1656 |
- variable: |
1657 |
- invalidchar: "A variable contains an invalid character that is not part of the ASCII character set" |
1658 |
- phase: "Variable referenced found within scope of incorrect ebuild phase as specified by PMS" |
1659 |
- readonly: "Assigning a readonly variable" |
1660 |
- usedwithhelpers: "Ebuild uses D, ROOT, BROOT, ED, EROOT or EPREFIX with helpers" |
1661 |
- virtual: |
1662 |
- suspect: "Ebuild contains a package that usually should be pulled via virtual/, not directly." |
1663 |
- wxwidgets: |
1664 |
- eclassnotused: "Ebuild DEPENDs on x11-libs/wxGTK without inheriting wxwidgets.eclass" |
1665 |
- |
1666 |
|
1667 |
diff --git a/repoman/cnf/repository/linechecks.yaml b/repoman/cnf/repository/linechecks.yaml |
1668 |
deleted file mode 100644 |
1669 |
index 528fdd99c..000000000 |
1670 |
--- a/repoman/cnf/repository/linechecks.yaml |
1671 |
+++ /dev/null |
1672 |
@@ -1,248 +0,0 @@ |
1673 |
---- |
1674 |
-# linecheck.yaml |
1675 |
- |
1676 |
-# configuration file for the LineCheck plugins run via the multicheck |
1677 |
-# scan module |
1678 |
-# no random drive-by commits please |
1679 |
-# Please obtain authorization from the portage team |
1680 |
-# |
1681 |
-# Overlay maintainers override/add/negate checks at your discression |
1682 |
-# but support for third party module will be limited to the plugin API |
1683 |
-# |
1684 |
- |
1685 |
-# Repoman API version (do not edit) |
1686 |
-version: 1 |
1687 |
-# minimum |
1688 |
-repoman_version: 2.3.3 |
1689 |
- |
1690 |
-eclass_export_functions: |
1691 |
- - ant-tasks |
1692 |
- - apache-2 |
1693 |
- - apache-module |
1694 |
- - aspell-dict |
1695 |
- - autotools-utils |
1696 |
- - base |
1697 |
- - bsdmk |
1698 |
- - cannadic |
1699 |
- - clutter |
1700 |
- - cmake-utils |
1701 |
- - db |
1702 |
- - distutils |
1703 |
- - elisp |
1704 |
- - embassy |
1705 |
- - emboss |
1706 |
- - emul-linux-x86 |
1707 |
- - enlightenment |
1708 |
- - font-ebdftopcf |
1709 |
- - font |
1710 |
- - fox |
1711 |
- - freebsd |
1712 |
- - freedict |
1713 |
- - games |
1714 |
- - games-ggz |
1715 |
- - games-mods |
1716 |
- - gdesklets |
1717 |
- - gems |
1718 |
- - gkrellm-plugin |
1719 |
- - gnatbuild |
1720 |
- - gnat |
1721 |
- - gnome2 |
1722 |
- - gnome-python-common |
1723 |
- - gnustep-base |
1724 |
- - go-mono |
1725 |
- - gpe |
1726 |
- - gst-plugins-bad |
1727 |
- - gst-plugins-base |
1728 |
- - gst-plugins-good |
1729 |
- - gst-plugins-ugly |
1730 |
- - gtk-sharp-module |
1731 |
- - haskell-cabal |
1732 |
- - horde |
1733 |
- - java-ant-2 |
1734 |
- - java-pkg-2 |
1735 |
- - java-pkg-simple |
1736 |
- - java-virtuals-2 |
1737 |
- - kde4-base |
1738 |
- - kde4-meta |
1739 |
- - kernel-2 |
1740 |
- - latex-package |
1741 |
- - linux-mod |
1742 |
- - mozlinguas |
1743 |
- - myspell |
1744 |
- - myspell-r2 |
1745 |
- - mysql |
1746 |
- - mysql-v2 |
1747 |
- - mythtv-plugins |
1748 |
- - oasis |
1749 |
- - obs-service |
1750 |
- - office-ext |
1751 |
- - perl-app |
1752 |
- - perl-module |
1753 |
- - php-ext-base-r1 |
1754 |
- - php-ext-pecl-r2 |
1755 |
- - php-ext-source-r2 |
1756 |
- - php-lib-r1 |
1757 |
- - php-pear-lib-r1 |
1758 |
- - php-pear-r1 |
1759 |
- - python-distutils-ng |
1760 |
- - python |
1761 |
- - qt4-build |
1762 |
- - qt4-r2 |
1763 |
- - rox-0install |
1764 |
- - rox |
1765 |
- - ruby |
1766 |
- - ruby-ng |
1767 |
- - scsh |
1768 |
- - selinux-policy-2 |
1769 |
- - sgml-catalog |
1770 |
- - stardict |
1771 |
- - sword-module |
1772 |
- - tetex-3 |
1773 |
- - tetex |
1774 |
- - texlive-module |
1775 |
- - toolchain-binutils |
1776 |
- - toolchain |
1777 |
- - twisted |
1778 |
- - vdr-plugin-2 |
1779 |
- - vdr-plugin |
1780 |
- - vim |
1781 |
- - vim-plugin |
1782 |
- - vim-spell |
1783 |
- - virtuoso |
1784 |
- - vmware |
1785 |
- - vmware-mod |
1786 |
- - waf-utils |
1787 |
- - webapp |
1788 |
- - xemacs-elisp |
1789 |
- - xemacs-packages |
1790 |
- - xfconf |
1791 |
- - x-modular |
1792 |
- - xorg-2 |
1793 |
- - zproduct |
1794 |
- |
1795 |
-eclass_info_experimental_inherit: |
1796 |
- autotools: |
1797 |
- funcs: |
1798 |
- - eaclocal |
1799 |
- - eautoconf |
1800 |
- - eautoheader |
1801 |
- - eautomake |
1802 |
- - eautoreconf |
1803 |
- - _elibtoolize |
1804 |
- - eautopoint |
1805 |
- comprehensive: true |
1806 |
- # Exempt eclasses: |
1807 |
- # git - An EGIT_BOOTSTRAP variable may be used to call one of |
1808 |
- # the autotools functions. |
1809 |
- # subversion - An ESVN_BOOTSTRAP variable may be used to call one of |
1810 |
- # the autotools functions. |
1811 |
- exempt_eclasses: |
1812 |
- - git |
1813 |
- - git-2 |
1814 |
- - subversion |
1815 |
- - autotools-utils |
1816 |
- eutils: |
1817 |
- funcs: |
1818 |
- - estack_push |
1819 |
- - estack_pop |
1820 |
- - eshopts_push |
1821 |
- - eshopts_pop |
1822 |
- - eumask_push |
1823 |
- - eumask_pop |
1824 |
- - epatch |
1825 |
- - epatch_user |
1826 |
- - emktemp |
1827 |
- - edos2unix |
1828 |
- - in_iuse |
1829 |
- - use_if_iuse |
1830 |
- - usex |
1831 |
- comprehensive: false |
1832 |
- flag-o-matic: |
1833 |
- funcs: |
1834 |
- - 'filter-(ld)?flags' |
1835 |
- - 'strip-flags' |
1836 |
- - 'strip-unsupported-flags' |
1837 |
- - 'append-((ld|c(pp|xx)?))?flags' |
1838 |
- - 'append-libs' |
1839 |
- comprehensive: false |
1840 |
- libtool: |
1841 |
- funcs: |
1842 |
- - elibtoolize |
1843 |
- comprehensive: true |
1844 |
- exempt_eclasses: |
1845 |
- - autotools |
1846 |
- multilib: |
1847 |
- funcs: |
1848 |
- - get_libdir |
1849 |
- # These are "eclasses are the whole ebuild" type thing. |
1850 |
- exempt_eclasses: |
1851 |
- - autotools |
1852 |
- - libtool |
1853 |
- - multilib-minimal |
1854 |
- comprehensive: false |
1855 |
- multiprocessing: |
1856 |
- funcs: |
1857 |
- - makeopts_jobs |
1858 |
- comprehensive: false |
1859 |
- prefix: |
1860 |
- funcs: |
1861 |
- - eprefixify |
1862 |
- comprehensive: true |
1863 |
- toolchain-funcs: |
1864 |
- funcs: |
1865 |
- - gen_usr_ldscript |
1866 |
- comprehensive: false |
1867 |
- user: |
1868 |
- funcs: |
1869 |
- - enewuser |
1870 |
- - enewgroup |
1871 |
- - egetent |
1872 |
- - egethome |
1873 |
- - egetshell |
1874 |
- - esethome |
1875 |
- comprehensive: true |
1876 |
- |
1877 |
-# non experimental_inherit |
1878 |
-eclass_info: |
1879 |
- autotools: |
1880 |
- funcs: |
1881 |
- - eaclocal |
1882 |
- - eautoconf |
1883 |
- - eautoheader |
1884 |
- - eautomake |
1885 |
- - eautoreconf |
1886 |
- - _elibtoolize |
1887 |
- - eautopoint |
1888 |
- comprehensive: true |
1889 |
- ignore_missing: true |
1890 |
- # Exempt eclasses: |
1891 |
- # git - An EGIT_BOOTSTRAP variable may be used to call one of |
1892 |
- # the autotools functions. |
1893 |
- # subversion - An ESVN_BOOTSTRAP variable may be used to call one of |
1894 |
- # the autotools functions. |
1895 |
- exempt_eclasses: |
1896 |
- - git |
1897 |
- - git-2 |
1898 |
- - subversion |
1899 |
- - autotools-utils |
1900 |
- prefix: |
1901 |
- funcs: |
1902 |
- - eprefixify |
1903 |
- comprehensive: true |
1904 |
- |
1905 |
-usex_supported_eapis: |
1906 |
- - "0" |
1907 |
- - "1" |
1908 |
- - "2" |
1909 |
- - "3" |
1910 |
- - "4" |
1911 |
- - "4-slot-abi" |
1912 |
- |
1913 |
-in_iuse_supported_eapis: |
1914 |
- - "0" |
1915 |
- - "1" |
1916 |
- - "2" |
1917 |
- - "3" |
1918 |
- - "4" |
1919 |
- - "4-slot-abi" |
1920 |
- - "5" |
1921 |
|
1922 |
diff --git a/repoman/cnf/repository/qa_data.yaml b/repoman/cnf/repository/qa_data.yaml |
1923 |
deleted file mode 100644 |
1924 |
index 2249000c3..000000000 |
1925 |
--- a/repoman/cnf/repository/qa_data.yaml |
1926 |
+++ /dev/null |
1927 |
@@ -1,163 +0,0 @@ |
1928 |
---- |
1929 |
-# This yaml syntax file holds various configuration data for |
1930 |
-# the Quality-Assurance checks performed. |
1931 |
- |
1932 |
-# no random drive-by commits please |
1933 |
-# Please obtain authorization from the portage team |
1934 |
-# |
1935 |
-# Overlay maintainers override/add/negate checks at your discression |
1936 |
-# but support for third party module will be limited to the plugin API |
1937 |
-# |
1938 |
- |
1939 |
-# Repoman API version (do not edit) |
1940 |
-version: 1 |
1941 |
-# minimum |
1942 |
-repoman_version: 2.3.3 |
1943 |
- |
1944 |
- |
1945 |
-allowed_filename_chars: "a-zA-Z0-9._-+:" |
1946 |
-max_description_length: 80 |
1947 |
- |
1948 |
-# missingvars check: Mandatory (non-defaulted) ebuild variables |
1949 |
-# list |
1950 |
-missingvars: |
1951 |
- - KEYWORDS |
1952 |
- - LICENSE |
1953 |
- - DESCRIPTION |
1954 |
- - HOMEPAGE |
1955 |
- |
1956 |
-# file.executable check, non executable files |
1957 |
-# list |
1958 |
-no_exec_files: |
1959 |
- - Manifest |
1960 |
- - ChangeLog |
1961 |
- - metadata.xml |
1962 |
- |
1963 |
-# qawarnings: Non-fatal warnings, |
1964 |
-# all values in here MUST have a corresponding qahelp entry |
1965 |
-# list |
1966 |
-qawarnings: |
1967 |
- - changelog.missing |
1968 |
- - changelog.notadded |
1969 |
- - dependency.unknown |
1970 |
- - dependency.badmasked |
1971 |
- - dependency.badindev |
1972 |
- - dependency.badmaskedindev |
1973 |
- - dependency.badtilde |
1974 |
- - dependency.deprecated |
1975 |
- - dependency.equalsversion |
1976 |
- - dependency.missingslot |
1977 |
- - dependency.perlcore |
1978 |
- - DESCRIPTION.toolong |
1979 |
- - digest.assumed |
1980 |
- - digest.unused |
1981 |
- - EAPI.deprecated |
1982 |
- - ebuild.notadded |
1983 |
- - ebuild.nesteddie |
1984 |
- - ebuild.absdosym |
1985 |
- - ebuild.minorsyn |
1986 |
- - ebuild.badheader |
1987 |
- - ebuild.patches |
1988 |
- - file.empty |
1989 |
- - HOMEPAGE.virtual |
1990 |
- - inherit.unused |
1991 |
- - inherit.deprecated |
1992 |
- - IUSE.rubydeprecated |
1993 |
- - java.eclassesnotused |
1994 |
- - KEYWORDS.dropped |
1995 |
- - KEYWORDS.stupid |
1996 |
- - KEYWORDS.missing |
1997 |
- - KEYWORDS.unsorted |
1998 |
- - LICENSE.deprecated |
1999 |
- - LICENSE.virtual |
2000 |
- - metadata.warning |
2001 |
- - PDEPEND.suspect |
2002 |
- - portage.internal |
2003 |
- - RDEPEND.implicit |
2004 |
- - RDEPEND.suspect |
2005 |
- - repo.eapi-deprecated |
2006 |
- - RESTRICT.invalid |
2007 |
- - usage.obsolete |
2008 |
- - upstream.workaround |
2009 |
- - uri.https |
2010 |
- - variable.phase |
2011 |
- - virtual.suspect |
2012 |
- - wxwidgets.eclassnotused |
2013 |
- |
2014 |
-# ruby_deprecated: Deprecated ruby targets |
2015 |
-# list |
2016 |
-ruby_deprecated: |
2017 |
- - ruby_targets_ruby18 |
2018 |
- - ruby_targets_ruby19 |
2019 |
- - ruby_targets_ruby20 |
2020 |
- |
2021 |
-# suspect_rdepend: Common build only Dependencies |
2022 |
-# not usually run time dependencies |
2023 |
-# list |
2024 |
-suspect_rdepend: |
2025 |
- - app-arch/cabextract |
2026 |
- - app-arch/rpm2targz |
2027 |
- - app-doc/doxygen |
2028 |
- - dev-lang/nasm |
2029 |
- - dev-lang/swig |
2030 |
- - dev-lang/yasm |
2031 |
- - dev-perl/extutils-pkgconfig |
2032 |
- - dev-qt/linguist-tools |
2033 |
- - dev-util/byacc |
2034 |
- - dev-util/cmake |
2035 |
- - dev-util/ftjam |
2036 |
- - dev-util/gperf |
2037 |
- - dev-util/gtk-doc |
2038 |
- - dev-util/gtk-doc-am |
2039 |
- - dev-util/intltool |
2040 |
- - dev-util/jam |
2041 |
- - dev-util/pkg-config-lite |
2042 |
- - dev-util/pkgconf |
2043 |
- - dev-util/pkgconfig |
2044 |
- - dev-util/pkgconfig-openbsd |
2045 |
- - dev-util/scons |
2046 |
- - dev-util/unifdef |
2047 |
- - dev-util/yacc |
2048 |
- - media-gfx/ebdftopcf |
2049 |
- - sys-apps/help2man |
2050 |
- - sys-devel/autoconf |
2051 |
- - sys-devel/automake |
2052 |
- - sys-devel/bin86 |
2053 |
- - sys-devel/bison |
2054 |
- - sys-devel/dev86 |
2055 |
- - sys-devel/flex |
2056 |
- - sys-devel/m4 |
2057 |
- - sys-devel/pmake |
2058 |
- - virtual/linux-sources |
2059 |
- - virtual/linuxtv-dvb-headers |
2060 |
- - virtual/os-headers |
2061 |
- - virtual/pkgconfig |
2062 |
- - x11-misc/bdftopcf |
2063 |
- - x11-misc/imake |
2064 |
- |
2065 |
-# suspect_virtual: Dependencies that should usually be made to the virtual |
2066 |
-# Not to the final target library |
2067 |
-# dictionary |
2068 |
-suspect_virtual: |
2069 |
- dev-libs/libusb: virtual/libusb |
2070 |
- dev-libs/libusb-compat: virtual/libusb |
2071 |
- dev-libs/libusbx: virtual/libusb |
2072 |
- dev-util/pkg-config-lite: virtual/pkgconfig |
2073 |
- dev-util/pkgconf: virtual/pkgconfig |
2074 |
- dev-util/pkgconfig: virtual/pkgconfig |
2075 |
- dev-util/pkgconfig-openbsd: virtual/pkgconfig |
2076 |
- |
2077 |
-# valid_restrict: ??? |
2078 |
-# list |
2079 |
-valid_restrict: |
2080 |
- - binchecks |
2081 |
- - bindist |
2082 |
- - fetch |
2083 |
- - installsources |
2084 |
- - mirror |
2085 |
- - preserve-libs |
2086 |
- - primaryuri |
2087 |
- - splitdebug |
2088 |
- - strip |
2089 |
- - test |
2090 |
- - userpriv |
2091 |
|
2092 |
diff --git a/repoman/cnf/repository/repository.yaml b/repoman/cnf/repository/repository.yaml |
2093 |
deleted file mode 100644 |
2094 |
index dbc1decaa..000000000 |
2095 |
--- a/repoman/cnf/repository/repository.yaml |
2096 |
+++ /dev/null |
2097 |
@@ -1,76 +0,0 @@ |
2098 |
---- |
2099 |
-# repository-modules.yaml |
2100 |
-# |
2101 |
-# This is the repository configuration file for repoman modules |
2102 |
-# |
2103 |
-# no random drive-by commits please |
2104 |
-# Please obtain authorization from the portage team |
2105 |
-# |
2106 |
-# Overlay maintainers override/add/negate checks at your discression |
2107 |
-# but support for third party module will be limited to the plugin API |
2108 |
-# |
2109 |
- |
2110 |
-# Repoman API version (do not edit) |
2111 |
-version: 1 |
2112 |
-# minimum |
2113 |
-repoman_version: 2.3.3 |
2114 |
- |
2115 |
-# NOTE: for non-gentoo repos, any custom modules added will need their |
2116 |
-# module names to the modules list in order for them to run. |
2117 |
- |
2118 |
-# These are the non-mandatory modules that can be disabled/enabled. |
2119 |
-# use -foo notation to disable, just like use flags |
2120 |
-# Add custom modules to enable them too |
2121 |
-scan_modules: |
2122 |
- description |
2123 |
- eapi |
2124 |
- ebuild_metadata |
2125 |
- fetches |
2126 |
- files |
2127 |
- keywords |
2128 |
- live |
2129 |
- manifests |
2130 |
- multicheck |
2131 |
- pkgmetadata |
2132 |
- profile |
2133 |
- restrict |
2134 |
- ruby |
2135 |
- |
2136 |
-linechecks_modules: |
2137 |
- assignment |
2138 |
- eapi3assignment |
2139 |
- implicitdepend |
2140 |
- hasq |
2141 |
- useq |
2142 |
- preservelib |
2143 |
- bindnow |
2144 |
- inherit |
2145 |
- dosym |
2146 |
- definition |
2147 |
- srcprepare |
2148 |
- eapi3deprecated |
2149 |
- pkgpretend |
2150 |
- eapi4incompatible |
2151 |
- eapi4gonevars |
2152 |
- paralleldisabled |
2153 |
- autodefault |
2154 |
- gentooheader |
2155 |
- nooffset |
2156 |
- nesteddie |
2157 |
- patches |
2158 |
- emakeparallel |
2159 |
- srccompileeconf |
2160 |
- srcunpackpatches |
2161 |
- pmsvariablerefphasescope |
2162 |
- portageinternal |
2163 |
- portageinternalvariableassignment |
2164 |
- quote |
2165 |
- quoteda |
2166 |
- httpsuri |
2167 |
- builtwith |
2168 |
- uselesscds |
2169 |
- uselessdodoc |
2170 |
- whitespace |
2171 |
- blankline |
2172 |
- noasneeded |
2173 |
- |
2174 |
|
2175 |
diff --git a/repoman/lib/repoman/__init__.py b/repoman/lib/repoman/__init__.py |
2176 |
deleted file mode 100644 |
2177 |
index b3690c07d..000000000 |
2178 |
--- a/repoman/lib/repoman/__init__.py |
2179 |
+++ /dev/null |
2180 |
@@ -1,103 +0,0 @@ |
2181 |
-import os.path |
2182 |
-import subprocess |
2183 |
-import sys |
2184 |
-import time |
2185 |
- |
2186 |
-try: |
2187 |
- import portage.const |
2188 |
- import portage.proxy as proxy |
2189 |
- from portage import _encodings, _shell_quote, _unicode_encode, _unicode_decode |
2190 |
- from portage.const import PORTAGE_BASE_PATH, BASH_BINARY |
2191 |
-except ImportError as e: |
2192 |
- sys.stderr.write("\n\n") |
2193 |
- sys.stderr.write( |
2194 |
- "!!! Failed to complete portage imports. There are internal modules for\n" |
2195 |
- ) |
2196 |
- sys.stderr.write( |
2197 |
- "!!! portage and failure here indicates that you have a problem with your\n" |
2198 |
- ) |
2199 |
- sys.stderr.write( |
2200 |
- "!!! installation of portage. Please try a rescue portage located in the ebuild\n" |
2201 |
- ) |
2202 |
- sys.stderr.write( |
2203 |
- "!!! repository under '/var/db/repos/gentoo/sys-apps/portage/files/' (default).\n" |
2204 |
- ) |
2205 |
- sys.stderr.write( |
2206 |
- "!!! There is a README.RESCUE file that details the steps required to perform\n" |
2207 |
- ) |
2208 |
- sys.stderr.write("!!! a recovery of portage.\n") |
2209 |
- sys.stderr.write(" " + str(e) + "\n\n") |
2210 |
- raise |
2211 |
- |
2212 |
- |
2213 |
-VERSION = "HEAD" |
2214 |
- |
2215 |
-REPOMAN_BASE_PATH = os.path.join( |
2216 |
- os.sep, os.sep.join(os.path.realpath(__file__.rstrip("co")).split(os.sep)[:-3]) |
2217 |
-) |
2218 |
- |
2219 |
-_not_installed = os.path.isfile( |
2220 |
- os.path.join(REPOMAN_BASE_PATH, ".repoman_not_installed") |
2221 |
-) |
2222 |
- |
2223 |
-if VERSION == "HEAD": |
2224 |
- |
2225 |
- class _LazyVersion(proxy.objectproxy.ObjectProxy): |
2226 |
- def _get_target(self): |
2227 |
- global VERSION |
2228 |
- if VERSION is not self: |
2229 |
- return VERSION |
2230 |
- if os.path.isdir(os.path.join(PORTAGE_BASE_PATH, ".git")): |
2231 |
- encoding = _encodings["fs"] |
2232 |
- cmd = [ |
2233 |
- BASH_BINARY, |
2234 |
- "-c", |
2235 |
- ( |
2236 |
- "cd %s ; git describe --match 'repoman-*' || exit $? ; " |
2237 |
- + 'if [ -n "`git diff-index --name-only --diff-filter=M HEAD`" ] ; ' |
2238 |
- + "then echo modified ; git rev-list --format=%%ct -n 1 HEAD ; fi ; " |
2239 |
- + "exit 0" |
2240 |
- ) |
2241 |
- % _shell_quote(PORTAGE_BASE_PATH), |
2242 |
- ] |
2243 |
- cmd = [ |
2244 |
- _unicode_encode(x, encoding=encoding, errors="strict") for x in cmd |
2245 |
- ] |
2246 |
- proc = subprocess.Popen( |
2247 |
- cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT |
2248 |
- ) |
2249 |
- output = _unicode_decode(proc.communicate()[0], encoding=encoding) |
2250 |
- status = proc.wait() |
2251 |
- if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK: |
2252 |
- output_lines = output.splitlines() |
2253 |
- if output_lines: |
2254 |
- version_split = output_lines[0].split("-") |
2255 |
- if len(version_split) > 1: |
2256 |
- VERSION = version_split[1] |
2257 |
- patchlevel = False |
2258 |
- if len(version_split) > 2: |
2259 |
- patchlevel = True |
2260 |
- VERSION = "%s_p%s" % (VERSION, version_split[2]) |
2261 |
- if len(output_lines) > 1 and output_lines[1] == "modified": |
2262 |
- head_timestamp = None |
2263 |
- if len(output_lines) > 3: |
2264 |
- try: |
2265 |
- head_timestamp = int(output_lines[3]) |
2266 |
- except ValueError: |
2267 |
- pass |
2268 |
- timestamp = int(time.time()) |
2269 |
- if ( |
2270 |
- head_timestamp is not None |
2271 |
- and timestamp > head_timestamp |
2272 |
- ): |
2273 |
- timestamp = timestamp - head_timestamp |
2274 |
- if not patchlevel: |
2275 |
- VERSION = "%s_p0" % (VERSION,) |
2276 |
- VERSION = "%s_p%d" % (VERSION, timestamp) |
2277 |
- return VERSION |
2278 |
- else: |
2279 |
- print("NO output lines :(") |
2280 |
- VERSION = "HEAD" |
2281 |
- return VERSION |
2282 |
- |
2283 |
- VERSION = _LazyVersion() |
2284 |
|
2285 |
diff --git a/repoman/lib/repoman/_portage.py b/repoman/lib/repoman/_portage.py |
2286 |
deleted file mode 100644 |
2287 |
index 01a2a4cf5..000000000 |
2288 |
--- a/repoman/lib/repoman/_portage.py |
2289 |
+++ /dev/null |
2290 |
@@ -1,26 +0,0 @@ |
2291 |
-"""repoman/_portage.py |
2292 |
-Central location for the portage import. |
2293 |
-There were problems when portage was imported by submodules |
2294 |
-due to the portage instance was somehow different that the |
2295 |
-initial portage import in main.py. The later portage imports |
2296 |
-did not contain the repo it was working on. That repo was my cvs tree |
2297 |
-and not listed in those subsequent portage imports. |
2298 |
- |
2299 |
-All modules should import portage from this one |
2300 |
- |
2301 |
-from repoman._portage import portage |
2302 |
- |
2303 |
-Then continue to import the remaining portage modules needed |
2304 |
-""" |
2305 |
- |
2306 |
-import sys |
2307 |
- |
2308 |
-from os import path as osp |
2309 |
- |
2310 |
-pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__)))) |
2311 |
-sys.path.insert(0, pym_path) |
2312 |
- |
2313 |
-import portage |
2314 |
- |
2315 |
-portage._internal_caller = True |
2316 |
-portage._disable_legacy_globals() |
2317 |
|
2318 |
diff --git a/repoman/lib/repoman/_subprocess.py b/repoman/lib/repoman/_subprocess.py |
2319 |
deleted file mode 100644 |
2320 |
index 08ee9e748..000000000 |
2321 |
--- a/repoman/lib/repoman/_subprocess.py |
2322 |
+++ /dev/null |
2323 |
@@ -1,58 +0,0 @@ |
2324 |
-# -*- coding:utf-8 -*- |
2325 |
- |
2326 |
- |
2327 |
-import codecs |
2328 |
-import subprocess |
2329 |
- |
2330 |
-# import our initialized portage instance |
2331 |
-from repoman._portage import portage |
2332 |
-from portage import _encodings, _unicode_encode |
2333 |
- |
2334 |
- |
2335 |
-def repoman_getstatusoutput(cmd): |
2336 |
- """ |
2337 |
- Implements an interface similar to getstatusoutput(), but with |
2338 |
- customized unicode handling (see bug #310789) and without the shell. |
2339 |
- """ |
2340 |
- args = portage.util.shlex_split(cmd) |
2341 |
- |
2342 |
- encoding = _encodings["fs"] |
2343 |
- args = [_unicode_encode(x, encoding=encoding, errors="strict") for x in args] |
2344 |
- proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
2345 |
- output = portage._unicode_decode( |
2346 |
- proc.communicate()[0], encoding=encoding, errors="strict" |
2347 |
- ) |
2348 |
- if output and output[-1] == "\n": |
2349 |
- # getstatusoutput strips one newline |
2350 |
- output = output[:-1] |
2351 |
- return (proc.wait(), output) |
2352 |
- |
2353 |
- |
2354 |
-class repoman_popen(portage.proxy.objectproxy.ObjectProxy): |
2355 |
- """ |
2356 |
- Implements an interface similar to os.popen(), but with customized |
2357 |
- unicode handling (see bug #310789) and without the shell. |
2358 |
- """ |
2359 |
- |
2360 |
- __slots__ = ("_proc", "_stdout") |
2361 |
- |
2362 |
- def __init__(self, cmd): |
2363 |
- args = portage.util.shlex_split(cmd) |
2364 |
- |
2365 |
- encoding = _encodings["fs"] |
2366 |
- args = [_unicode_encode(x, encoding=encoding, errors="strict") for x in args] |
2367 |
- proc = subprocess.Popen(args, stdout=subprocess.PIPE) |
2368 |
- object.__setattr__(self, "_proc", proc) |
2369 |
- object.__setattr__( |
2370 |
- self, "_stdout", codecs.getreader(encoding)(proc.stdout, "strict") |
2371 |
- ) |
2372 |
- |
2373 |
- def _get_target(self): |
2374 |
- return object.__getattribute__(self, "_stdout") |
2375 |
- |
2376 |
- __enter__ = _get_target |
2377 |
- |
2378 |
- def __exit__(self, exc_type, exc_value, traceback): |
2379 |
- proc = object.__getattribute__(self, "_proc") |
2380 |
- proc.wait() |
2381 |
- proc.stdout.close() |
2382 |
|
2383 |
diff --git a/repoman/lib/repoman/actions.py b/repoman/lib/repoman/actions.py |
2384 |
deleted file mode 100644 |
2385 |
index 920f0e97a..000000000 |
2386 |
--- a/repoman/lib/repoman/actions.py |
2387 |
+++ /dev/null |
2388 |
@@ -1,828 +0,0 @@ |
2389 |
-# -*- coding:utf-8 -*- |
2390 |
-# Copyright 1999-2021 Gentoo Authors |
2391 |
-# Distributed under the terms of the GNU General Public License v2 |
2392 |
- |
2393 |
-import errno |
2394 |
-import io |
2395 |
-import logging |
2396 |
-import platform |
2397 |
-import re |
2398 |
-import shutil |
2399 |
-import signal |
2400 |
-import sys |
2401 |
-import tempfile |
2402 |
-import time |
2403 |
-from itertools import chain |
2404 |
- |
2405 |
-try: |
2406 |
- from urllib.parse import parse_qs, urlsplit, urlunsplit |
2407 |
-except ImportError: |
2408 |
- from urlparse import parse_qs, urlsplit, urlunsplit |
2409 |
- |
2410 |
-from _emerge.UserQuery import UserQuery |
2411 |
- |
2412 |
-from repoman._portage import portage |
2413 |
-from portage import os |
2414 |
-from portage import _encodings |
2415 |
-from portage import _unicode_encode |
2416 |
-from portage.output import bold, create_color_func, green, red |
2417 |
-from portage.package.ebuild.digestgen import digestgen |
2418 |
-from portage.util import writemsg_level |
2419 |
- |
2420 |
-# pylint: disable=ungrouped-imports |
2421 |
-from repoman.copyrights import update_copyright |
2422 |
-from repoman.gpg import gpgsign, need_signature |
2423 |
-from repoman import utilities |
2424 |
-from repoman.modules.vcs.vcs import vcs_files_to_cps |
2425 |
-from repoman import VERSION |
2426 |
- |
2427 |
-bad = create_color_func("BAD") |
2428 |
- |
2429 |
- |
2430 |
-class Actions: |
2431 |
- """Handles post check result output and performs |
2432 |
- the various vcs activities for committing the results""" |
2433 |
- |
2434 |
- def __init__(self, repo_settings, options, scanner, vcs_settings): |
2435 |
- self.repo_settings = repo_settings |
2436 |
- self.options = options |
2437 |
- self.scanner = scanner |
2438 |
- self.vcs_settings = vcs_settings |
2439 |
- self.repoman_settings = repo_settings.repoman_settings |
2440 |
- self.suggest = { |
2441 |
- "ignore_masked": False, |
2442 |
- "include_dev": False, |
2443 |
- } |
2444 |
- if scanner.have["pmasked"] and not ( |
2445 |
- options.without_mask or options.ignore_masked |
2446 |
- ): |
2447 |
- self.suggest["ignore_masked"] = True |
2448 |
- if scanner.have["dev_keywords"] and not options.include_dev: |
2449 |
- self.suggest["include_dev"] = True |
2450 |
- |
2451 |
- def inform(self, can_force, result): |
2452 |
- """Inform the user of all the problems found""" |
2453 |
- if ( |
2454 |
- self.suggest["ignore_masked"] or self.suggest["include_dev"] |
2455 |
- ) and not self.options.quiet: |
2456 |
- self._suggest() |
2457 |
- if self.options.mode != "commit": |
2458 |
- self._non_commit(result) |
2459 |
- return False |
2460 |
- else: |
2461 |
- self._fail(result, can_force) |
2462 |
- if self.options.pretend: |
2463 |
- utilities.repoman_sez('"So, you want to play it safe. Good call."\n') |
2464 |
- return True |
2465 |
- |
2466 |
- def perform(self, qa_output): |
2467 |
- myautoadd = self._vcs_autoadd() |
2468 |
- |
2469 |
- self._vcs_deleted() |
2470 |
- |
2471 |
- changes = self.get_vcs_changed() |
2472 |
- |
2473 |
- mynew, mychanged, myremoved, no_expansion, expansion = changes |
2474 |
- |
2475 |
- # Manifests need to be regenerated after all other commits, so don't commit |
2476 |
- # them now even if they have changed. |
2477 |
- mymanifests = set() |
2478 |
- myupdates = set() |
2479 |
- for f in mychanged + mynew: |
2480 |
- if "Manifest" == os.path.basename(f): |
2481 |
- mymanifests.add(f) |
2482 |
- else: |
2483 |
- myupdates.add(f) |
2484 |
- myupdates.difference_update(myremoved) |
2485 |
- myupdates = list(myupdates) |
2486 |
- mymanifests = list(mymanifests) |
2487 |
- myheaders = [] |
2488 |
- |
2489 |
- commitmessage = self.options.commitmsg |
2490 |
- if self.options.commitmsgfile: |
2491 |
- try: |
2492 |
- f = io.open( |
2493 |
- _unicode_encode( |
2494 |
- self.options.commitmsgfile, |
2495 |
- encoding=_encodings["fs"], |
2496 |
- errors="strict", |
2497 |
- ), |
2498 |
- mode="r", |
2499 |
- encoding=_encodings["content"], |
2500 |
- errors="replace", |
2501 |
- ) |
2502 |
- commitmessage = f.read() |
2503 |
- f.close() |
2504 |
- del f |
2505 |
- except (IOError, OSError) as e: |
2506 |
- if e.errno == errno.ENOENT: |
2507 |
- portage.writemsg( |
2508 |
- "!!! File Not Found:" |
2509 |
- " --commitmsgfile='%s'\n" % self.options.commitmsgfile |
2510 |
- ) |
2511 |
- else: |
2512 |
- raise |
2513 |
- if commitmessage[:9].lower() in ("cat/pkg: ",): |
2514 |
- commitmessage = self.msg_prefix() + commitmessage[9:] |
2515 |
- |
2516 |
- if commitmessage is not None and commitmessage.strip(): |
2517 |
- res, expl = self.verify_commit_message(commitmessage) |
2518 |
- if not res: |
2519 |
- print(bad("RepoMan does not like your commit message:")) |
2520 |
- print(expl) |
2521 |
- if self.options.force: |
2522 |
- print("(but proceeding due to --force)") |
2523 |
- else: |
2524 |
- sys.exit(1) |
2525 |
- else: |
2526 |
- commitmessage = None |
2527 |
- msg_qa_output = qa_output |
2528 |
- initial_message = None |
2529 |
- while True: |
2530 |
- commitmessage = self.get_new_commit_message( |
2531 |
- msg_qa_output, commitmessage |
2532 |
- ) |
2533 |
- res, expl = self.verify_commit_message(commitmessage) |
2534 |
- if res: |
2535 |
- break |
2536 |
- else: |
2537 |
- full_expl = ( |
2538 |
- """Issues with the commit message were found. Please fix it or remove |
2539 |
-the whole commit message to abort. |
2540 |
- |
2541 |
-""" |
2542 |
- + expl |
2543 |
- ) |
2544 |
- msg_qa_output = [ |
2545 |
- " %s\n" % x for x in full_expl.splitlines() |
2546 |
- ] + qa_output |
2547 |
- |
2548 |
- commitmessage = commitmessage.rstrip() |
2549 |
- |
2550 |
- # Update copyright for new and changed files |
2551 |
- year = time.strftime("%Y", time.gmtime()) |
2552 |
- updated_copyright = [] |
2553 |
- for fn in chain(mynew, mychanged): |
2554 |
- if fn.endswith(".diff") or fn.endswith(".patch"): |
2555 |
- continue |
2556 |
- if update_copyright(fn, year, pretend=self.options.pretend): |
2557 |
- updated_copyright.append(fn) |
2558 |
- |
2559 |
- if updated_copyright and not ( |
2560 |
- self.options.pretend or self.repo_settings.repo_config.thin_manifest |
2561 |
- ): |
2562 |
- for cp in sorted(self._vcs_files_to_cps(iter(updated_copyright))): |
2563 |
- self._manifest_gen(cp) |
2564 |
- |
2565 |
- myupdates, broken_changelog_manifests = self.changelogs( |
2566 |
- myupdates, |
2567 |
- mymanifests, |
2568 |
- myremoved, |
2569 |
- mychanged, |
2570 |
- myautoadd, |
2571 |
- mynew, |
2572 |
- commitmessage, |
2573 |
- ) |
2574 |
- |
2575 |
- lines = commitmessage.splitlines() |
2576 |
- lastline = lines[-1] |
2577 |
- if len(lines) == 1 or re.match(r"^\S+:\s", lastline) is None: |
2578 |
- commitmessage += "\n" |
2579 |
- |
2580 |
- commit_footer = self.get_commit_footer() |
2581 |
- commitmessage += commit_footer |
2582 |
- |
2583 |
- print("* %s files being committed..." % green(str(len(myupdates))), end=" ") |
2584 |
- |
2585 |
- if not self.vcs_settings.needs_keyword_expansion: |
2586 |
- # With some VCS types there's never any keyword expansion, so |
2587 |
- # there's no need to regenerate manifests and all files will be |
2588 |
- # committed in one big commit at the end. |
2589 |
- logging.debug("VCS type doesn't need keyword expansion") |
2590 |
- print() |
2591 |
- elif not self.repo_settings.repo_config.thin_manifest: |
2592 |
- logging.debug("perform: Calling thick_manifest()") |
2593 |
- self.vcs_settings.changes.thick_manifest( |
2594 |
- myupdates, myheaders, no_expansion, expansion |
2595 |
- ) |
2596 |
- |
2597 |
- logging.info("myupdates: %s", myupdates) |
2598 |
- logging.info("myheaders: %s", myheaders) |
2599 |
- |
2600 |
- uq = UserQuery(self.options) |
2601 |
- if self.options.ask and uq.query("Commit changes?", True) != "Yes": |
2602 |
- print("* aborting commit.") |
2603 |
- sys.exit(128 + signal.SIGINT) |
2604 |
- |
2605 |
- # Handle the case where committed files have keywords which |
2606 |
- # will change and need a priming commit before the Manifest |
2607 |
- # can be committed. |
2608 |
- if (myupdates or myremoved) and myheaders: |
2609 |
- self.priming_commit(myupdates, myremoved, commitmessage) |
2610 |
- |
2611 |
- # When files are removed and re-added, the cvs server will put /Attic/ |
2612 |
- # inside the $Header path. This code detects the problem and corrects it |
2613 |
- # so that the Manifest will generate correctly. See bug #169500. |
2614 |
- # Use binary mode in order to avoid potential character encoding issues. |
2615 |
- self.vcs_settings.changes.clear_attic(myheaders) |
2616 |
- |
2617 |
- if self.scanner.repolevel == 1: |
2618 |
- utilities.repoman_sez( |
2619 |
- "\"You're rather crazy... " 'doing the entire repository."\n' |
2620 |
- ) |
2621 |
- |
2622 |
- self.vcs_settings.changes.digest_regen( |
2623 |
- myupdates, myremoved, mymanifests, self.scanner, broken_changelog_manifests |
2624 |
- ) |
2625 |
- |
2626 |
- if self.repo_settings.sign_manifests: |
2627 |
- self.sign_manifest(myupdates, myremoved, mymanifests) |
2628 |
- |
2629 |
- self.vcs_settings.changes.update_index(mymanifests, myupdates) |
2630 |
- |
2631 |
- self.add_manifest(mymanifests, myheaders, myupdates, myremoved, commitmessage) |
2632 |
- |
2633 |
- if self.options.quiet: |
2634 |
- return |
2635 |
- print() |
2636 |
- if self.vcs_settings.vcs: |
2637 |
- print("Commit complete.") |
2638 |
- else: |
2639 |
- print( |
2640 |
- "repoman was too scared" |
2641 |
- " by not seeing any familiar version control file" |
2642 |
- " that he forgot to commit anything" |
2643 |
- ) |
2644 |
- utilities.repoman_sez('"If everyone were like you, I\'d be out of business!"\n') |
2645 |
- return |
2646 |
- |
2647 |
- def _vcs_files_to_cps(self, vcs_file_iter): |
2648 |
- """ |
2649 |
- Iterate over the given modified file paths returned from the vcs, |
2650 |
- and return a frozenset containing category/pn strings for each |
2651 |
- modified package. |
2652 |
- |
2653 |
- @param vcs_file_iter: file paths from vcs module |
2654 |
- @type iter |
2655 |
- @rtype: frozenset |
2656 |
- @return: category/pn strings for each package. |
2657 |
- """ |
2658 |
- return vcs_files_to_cps( |
2659 |
- vcs_file_iter, |
2660 |
- self.repo_settings.repodir, |
2661 |
- self.scanner.repolevel, |
2662 |
- self.scanner.reposplit, |
2663 |
- self.scanner.categories, |
2664 |
- ) |
2665 |
- |
2666 |
- def _manifest_gen(self, cp): |
2667 |
- """ |
2668 |
- Generate manifest for a cp. |
2669 |
- |
2670 |
- @param cp: category/pn string |
2671 |
- @type str |
2672 |
- @rtype: bool |
2673 |
- @return: True if successful, False otherwise |
2674 |
- """ |
2675 |
- self.repoman_settings["O"] = os.path.join(self.repo_settings.repodir, cp) |
2676 |
- return bool( |
2677 |
- digestgen( |
2678 |
- mysettings=self.repoman_settings, myportdb=self.repo_settings.portdb |
2679 |
- ) |
2680 |
- ) |
2681 |
- |
2682 |
- def _suggest(self): |
2683 |
- print() |
2684 |
- if self.suggest["ignore_masked"]: |
2685 |
- print( |
2686 |
- bold( |
2687 |
- "Note: use --without-mask to check " |
2688 |
- "KEYWORDS on dependencies of masked packages" |
2689 |
- ) |
2690 |
- ) |
2691 |
- |
2692 |
- if self.suggest["include_dev"]: |
2693 |
- print( |
2694 |
- bold( |
2695 |
- "Note: use --include-dev (-d) to check " |
2696 |
- "dependencies for 'dev' profiles" |
2697 |
- ) |
2698 |
- ) |
2699 |
- print() |
2700 |
- |
2701 |
- def _non_commit(self, result): |
2702 |
- if result["full"]: |
2703 |
- print(bold('Note: type "repoman full" for a complete listing.')) |
2704 |
- if result["warn"] and not result["fail"]: |
2705 |
- if self.options.quiet: |
2706 |
- print(bold("Non-Fatal QA errors found")) |
2707 |
- else: |
2708 |
- utilities.repoman_sez( |
2709 |
- "\"You're only giving me a partial QA payment?\n" |
2710 |
- " I'll take it this time, but I'm not happy.\"" |
2711 |
- ) |
2712 |
- elif not result["fail"]: |
2713 |
- if self.options.quiet: |
2714 |
- print("No QA issues found") |
2715 |
- else: |
2716 |
- utilities.repoman_sez( |
2717 |
- '"If everyone were like you, I\'d be out of business!"' |
2718 |
- ) |
2719 |
- elif result["fail"]: |
2720 |
- print(bad("Please fix these important QA issues first.")) |
2721 |
- if not self.options.quiet: |
2722 |
- utilities.repoman_sez( |
2723 |
- '"Make your QA payment on time' |
2724 |
- " and you'll never see the likes of me.\"\n" |
2725 |
- ) |
2726 |
- |
2727 |
- def _fail(self, result, can_force): |
2728 |
- if ( |
2729 |
- result["fail"] |
2730 |
- and can_force |
2731 |
- and self.options.force |
2732 |
- and not self.options.pretend |
2733 |
- ): |
2734 |
- utilities.repoman_sez( |
2735 |
- ' "You want to commit even with these QA issues?\n' |
2736 |
- " I'll take it this time, but I'm not happy.\"\n" |
2737 |
- ) |
2738 |
- elif result["fail"]: |
2739 |
- if self.options.force and not can_force: |
2740 |
- print( |
2741 |
- bad( |
2742 |
- "The --force option has been disabled" |
2743 |
- " due to extraordinary issues." |
2744 |
- ) |
2745 |
- ) |
2746 |
- print(bad("Please fix these important QA issues first.")) |
2747 |
- utilities.repoman_sez( |
2748 |
- '"Make your QA payment on time' |
2749 |
- " and you'll never see the likes of me.\"\n" |
2750 |
- ) |
2751 |
- sys.exit(1) |
2752 |
- |
2753 |
- def _vcs_autoadd(self): |
2754 |
- myunadded = self.vcs_settings.changes.unadded |
2755 |
- myautoadd = [] |
2756 |
- if myunadded: |
2757 |
- for x in range(len(myunadded) - 1, -1, -1): |
2758 |
- xs = myunadded[x].split("/") |
2759 |
- if ( |
2760 |
- any(token.startswith(".") and token != "." for token in xs) |
2761 |
- or self.repo_settings.repo_config.find_invalid_path_char( |
2762 |
- myunadded[x] |
2763 |
- ) |
2764 |
- != -1 |
2765 |
- ): |
2766 |
- # The Manifest excludes this file, |
2767 |
- # so it's safe to ignore. |
2768 |
- del myunadded[x] |
2769 |
- elif xs[-1] == "files": |
2770 |
- print("!!! files dir is not added! Please correct this.") |
2771 |
- sys.exit(-1) |
2772 |
- elif xs[-1] == "Manifest": |
2773 |
- # It's a manifest... auto add |
2774 |
- myautoadd += [myunadded[x]] |
2775 |
- del myunadded[x] |
2776 |
- |
2777 |
- if myunadded: |
2778 |
- print( |
2779 |
- red( |
2780 |
- "!!! The following files are in your local tree" |
2781 |
- " but are not added to the master" |
2782 |
- ) |
2783 |
- ) |
2784 |
- print( |
2785 |
- red( |
2786 |
- "!!! tree. Please remove them from the local tree" |
2787 |
- " or add them to the master tree." |
2788 |
- ) |
2789 |
- ) |
2790 |
- for x in myunadded: |
2791 |
- print(" ", x) |
2792 |
- print() |
2793 |
- print() |
2794 |
- sys.exit(1) |
2795 |
- return myautoadd |
2796 |
- |
2797 |
- def _vcs_deleted(self): |
2798 |
- if self.vcs_settings.changes.has_deleted: |
2799 |
- print( |
2800 |
- red( |
2801 |
- "!!! The following files are removed manually" |
2802 |
- " from your local tree but are not" |
2803 |
- ) |
2804 |
- ) |
2805 |
- print( |
2806 |
- red( |
2807 |
- "!!! removed from the repository." |
2808 |
- ' Please remove them, using "%s remove [FILES]".' |
2809 |
- % self.vcs_settings.vcs |
2810 |
- ) |
2811 |
- ) |
2812 |
- for x in self.vcs_settings.changes.deleted: |
2813 |
- print(" ", x) |
2814 |
- print() |
2815 |
- print() |
2816 |
- sys.exit(1) |
2817 |
- |
2818 |
- def get_vcs_changed(self): |
2819 |
- """Holding function which calls the approriate VCS module for the data""" |
2820 |
- changes = self.vcs_settings.changes |
2821 |
- # re-run the scan to pick up a newly modified Manifest file |
2822 |
- logging.debug("RE-scanning for changes...") |
2823 |
- changes.scan() |
2824 |
- |
2825 |
- if not changes.has_changes: |
2826 |
- utilities.repoman_sez('"Doing nothing is not always good for QA."') |
2827 |
- print() |
2828 |
- print("(Didn't find any changed files...)") |
2829 |
- print() |
2830 |
- sys.exit(1) |
2831 |
- return ( |
2832 |
- changes.new, |
2833 |
- changes.changed, |
2834 |
- changes.removed, |
2835 |
- changes.no_expansion, |
2836 |
- changes.expansion, |
2837 |
- ) |
2838 |
- |
2839 |
- https_bugtrackers = frozenset( |
2840 |
- [ |
2841 |
- "bitbucket.org", |
2842 |
- "bugs.gentoo.org", |
2843 |
- "github.com", |
2844 |
- "gitlab.com", |
2845 |
- ] |
2846 |
- ) |
2847 |
- |
2848 |
- def get_commit_footer(self): |
2849 |
- portage_version = getattr(portage, "VERSION", None) |
2850 |
- gpg_key = self.repoman_settings.get("PORTAGE_GPG_KEY", "") |
2851 |
- signoff = self.repoman_settings.get("SIGNED_OFF_BY", "") |
2852 |
- report_options = [] |
2853 |
- if self.options.force: |
2854 |
- report_options.append("--force") |
2855 |
- if self.options.ignore_arches: |
2856 |
- report_options.append("--ignore-arches") |
2857 |
- if self.scanner.include_arches is not None: |
2858 |
- report_options.append( |
2859 |
- '--include-arches="%s"' % " ".join(sorted(self.scanner.include_arches)) |
2860 |
- ) |
2861 |
- if self.scanner.include_profiles is not None: |
2862 |
- report_options.append( |
2863 |
- '--include-profiles="%s"' |
2864 |
- % " ".join(sorted(self.scanner.include_profiles)) |
2865 |
- ) |
2866 |
- |
2867 |
- if portage_version is None: |
2868 |
- sys.stderr.write("Failed to insert portage version in message!\n") |
2869 |
- sys.stderr.flush() |
2870 |
- portage_version = "Unknown" |
2871 |
- |
2872 |
- # Common part of commit footer |
2873 |
- commit_footer = "" |
2874 |
- for tag, bug in chain( |
2875 |
- (("Bug", x) for x in self.options.bug), |
2876 |
- (("Closes", x) for x in self.options.closes), |
2877 |
- ): |
2878 |
- # case 1: pure number NNNNNN |
2879 |
- if bug.isdigit(): |
2880 |
- bug = "https://bugs.gentoo.org/%s" % (bug,) |
2881 |
- else: |
2882 |
- purl = urlsplit(bug) |
2883 |
- qs = parse_qs(purl.query) |
2884 |
- # case 2: long Gentoo bugzilla URL to shorten |
2885 |
- if ( |
2886 |
- purl.netloc == "bugs.gentoo.org" |
2887 |
- and purl.path == "/show_bug.cgi" |
2888 |
- and tuple(qs.keys()) == ("id",) |
2889 |
- ): |
2890 |
- bug = urlunsplit( |
2891 |
- ("https", purl.netloc, qs["id"][-1], "", purl.fragment) |
2892 |
- ) |
2893 |
- # case 3: bug tracker w/ http -> https |
2894 |
- elif purl.scheme == "http" and purl.netloc in self.https_bugtrackers: |
2895 |
- bug = urlunsplit(("https",) + purl[1:]) |
2896 |
- commit_footer += "\n%s: %s" % (tag, bug) |
2897 |
- |
2898 |
- # Use new footer only for git (see bug #438364). |
2899 |
- if self.vcs_settings.vcs in ["git"]: |
2900 |
- commit_footer += "\nPackage-Manager: Portage-%s, Repoman-%s" % ( |
2901 |
- portage.VERSION, |
2902 |
- VERSION, |
2903 |
- ) |
2904 |
- if report_options: |
2905 |
- commit_footer += "\nRepoMan-Options: " + " ".join(report_options) |
2906 |
- if self.repo_settings.sign_manifests: |
2907 |
- commit_footer += "\nManifest-Sign-Key: %s" % (gpg_key,) |
2908 |
- else: |
2909 |
- unameout = platform.system() + " " |
2910 |
- if platform.system() in ["Darwin", "SunOS"]: |
2911 |
- unameout += platform.processor() |
2912 |
- else: |
2913 |
- unameout += platform.machine() |
2914 |
- commit_footer += "\n(Portage version: %s/%s/%s" % ( |
2915 |
- portage_version, |
2916 |
- self.vcs_settings.vcs, |
2917 |
- unameout, |
2918 |
- ) |
2919 |
- if report_options: |
2920 |
- commit_footer += ", RepoMan options: " + " ".join(report_options) |
2921 |
- if self.repo_settings.sign_manifests: |
2922 |
- commit_footer += ", signed Manifest commit with key %s" % (gpg_key,) |
2923 |
- else: |
2924 |
- commit_footer += ", unsigned Manifest commit" |
2925 |
- commit_footer += ")" |
2926 |
- |
2927 |
- if signoff: |
2928 |
- commit_footer += "\nSigned-off-by: %s" % (signoff,) |
2929 |
- |
2930 |
- return commit_footer |
2931 |
- |
2932 |
- def changelogs( |
2933 |
- self, |
2934 |
- myupdates, |
2935 |
- mymanifests, |
2936 |
- myremoved, |
2937 |
- mychanged, |
2938 |
- myautoadd, |
2939 |
- mynew, |
2940 |
- changelog_msg, |
2941 |
- ): |
2942 |
- broken_changelog_manifests = [] |
2943 |
- if self.options.echangelog in ("y", "force"): |
2944 |
- logging.info("checking for unmodified ChangeLog files") |
2945 |
- committer_name = utilities.get_committer_name(env=self.repoman_settings) |
2946 |
- for x in sorted( |
2947 |
- vcs_files_to_cps( |
2948 |
- chain(myupdates, mymanifests, myremoved), |
2949 |
- self.repo_settings.repodir, |
2950 |
- self.scanner.repolevel, |
2951 |
- self.scanner.reposplit, |
2952 |
- self.scanner.categories, |
2953 |
- ) |
2954 |
- ): |
2955 |
- catdir, pkgdir = x.split("/") |
2956 |
- checkdir = self.repo_settings.repodir + "/" + x |
2957 |
- checkdir_relative = "" |
2958 |
- if self.scanner.repolevel < 3: |
2959 |
- checkdir_relative = os.path.join(pkgdir, checkdir_relative) |
2960 |
- if self.scanner.repolevel < 2: |
2961 |
- checkdir_relative = os.path.join(catdir, checkdir_relative) |
2962 |
- checkdir_relative = os.path.join(".", checkdir_relative) |
2963 |
- |
2964 |
- changelog_path = os.path.join(checkdir_relative, "ChangeLog") |
2965 |
- changelog_modified = changelog_path in self.scanner.changed.changelogs |
2966 |
- if changelog_modified and self.options.echangelog != "force": |
2967 |
- continue |
2968 |
- |
2969 |
- # get changes for this package |
2970 |
- cdrlen = len(checkdir_relative) |
2971 |
- check_relative = lambda e: e.startswith(checkdir_relative) |
2972 |
- split_relative = lambda e: e[cdrlen:] |
2973 |
- clnew = list(map(split_relative, filter(check_relative, mynew))) |
2974 |
- clremoved = list(map(split_relative, filter(check_relative, myremoved))) |
2975 |
- clchanged = list(map(split_relative, filter(check_relative, mychanged))) |
2976 |
- |
2977 |
- # Skip ChangeLog generation if only the Manifest was modified, |
2978 |
- # as discussed in bug #398009. |
2979 |
- nontrivial_cl_files = set() |
2980 |
- nontrivial_cl_files.update(clnew, clremoved, clchanged) |
2981 |
- nontrivial_cl_files.difference_update(["Manifest"]) |
2982 |
- if not nontrivial_cl_files and self.options.echangelog != "force": |
2983 |
- continue |
2984 |
- |
2985 |
- new_changelog = utilities.UpdateChangeLog( |
2986 |
- checkdir_relative, |
2987 |
- committer_name, |
2988 |
- changelog_msg, |
2989 |
- os.path.join(self.repo_settings.repodir, "skel.ChangeLog"), |
2990 |
- catdir, |
2991 |
- pkgdir, |
2992 |
- new=clnew, |
2993 |
- removed=clremoved, |
2994 |
- changed=clchanged, |
2995 |
- pretend=self.options.pretend, |
2996 |
- ) |
2997 |
- if new_changelog is None: |
2998 |
- writemsg_level( |
2999 |
- "!!! Updating the ChangeLog failed\n", |
3000 |
- level=logging.ERROR, |
3001 |
- noiselevel=-1, |
3002 |
- ) |
3003 |
- sys.exit(1) |
3004 |
- |
3005 |
- # if the ChangeLog was just created, add it to vcs |
3006 |
- if new_changelog: |
3007 |
- myautoadd.append(changelog_path) |
3008 |
- # myautoadd is appended to myupdates below |
3009 |
- else: |
3010 |
- myupdates.append(changelog_path) |
3011 |
- |
3012 |
- if self.options.ask and not self.options.pretend: |
3013 |
- # regenerate Manifest for modified ChangeLog (bug #420735) |
3014 |
- self.repoman_settings["O"] = checkdir |
3015 |
- digestgen( |
3016 |
- mysettings=self.repoman_settings, |
3017 |
- myportdb=self.repo_settings.portdb, |
3018 |
- ) |
3019 |
- else: |
3020 |
- broken_changelog_manifests.append(x) |
3021 |
- |
3022 |
- if myautoadd: |
3023 |
- print(">>> Auto-Adding missing Manifest/ChangeLog file(s)...") |
3024 |
- self.vcs_settings.changes.add_items(myautoadd) |
3025 |
- myupdates += myautoadd |
3026 |
- return myupdates, broken_changelog_manifests |
3027 |
- |
3028 |
- def add_manifest(self, mymanifests, myheaders, myupdates, myremoved, commitmessage): |
3029 |
- myfiles = mymanifests[:] |
3030 |
- # If there are no header (SVN/CVS keywords) changes in |
3031 |
- # the files, this Manifest commit must include the |
3032 |
- # other (yet uncommitted) files. |
3033 |
- if not myheaders: |
3034 |
- myfiles += myupdates |
3035 |
- myfiles += myremoved |
3036 |
- myfiles.sort() |
3037 |
- |
3038 |
- commitmessagedir = tempfile.mkdtemp(".repoman.msg") |
3039 |
- commitmessagefile = os.path.join(commitmessagedir, "COMMIT_EDITMSG") |
3040 |
- with open(commitmessagefile, "wb") as mymsg: |
3041 |
- mymsg.write(_unicode_encode(commitmessage)) |
3042 |
- |
3043 |
- retval = self.vcs_settings.changes.commit(myfiles, commitmessagefile) |
3044 |
- # cleanup the commit message before possibly exiting |
3045 |
- try: |
3046 |
- shutil.rmtree(commitmessagedir) |
3047 |
- except OSError: |
3048 |
- pass |
3049 |
- if retval != os.EX_OK: |
3050 |
- writemsg_level( |
3051 |
- "!!! Exiting on %s (shell) " |
3052 |
- "error code: %s\n" % (self.vcs_settings.vcs, retval), |
3053 |
- level=logging.ERROR, |
3054 |
- noiselevel=-1, |
3055 |
- ) |
3056 |
- sys.exit(retval) |
3057 |
- |
3058 |
- def priming_commit(self, myupdates, myremoved, commitmessage): |
3059 |
- myfiles = myupdates + myremoved |
3060 |
- commitmessagedir = tempfile.mkdtemp(".repoman.msg") |
3061 |
- commitmessagefile = os.path.join(commitmessagedir, "COMMIT_EDITMSG") |
3062 |
- with open(commitmessagefile, "wb") as mymsg: |
3063 |
- mymsg.write(_unicode_encode(commitmessage)) |
3064 |
- |
3065 |
- separator = "-" * 78 |
3066 |
- |
3067 |
- print() |
3068 |
- print(green("Using commit message:")) |
3069 |
- print(green(separator)) |
3070 |
- print(commitmessage) |
3071 |
- print(green(separator)) |
3072 |
- print() |
3073 |
- |
3074 |
- # Having a leading ./ prefix on file paths can trigger a bug in |
3075 |
- # the cvs server when committing files to multiple directories, |
3076 |
- # so strip the prefix. |
3077 |
- myfiles = [f.lstrip("./") for f in myfiles] |
3078 |
- |
3079 |
- retval = self.vcs_settings.changes.commit(myfiles, commitmessagefile) |
3080 |
- # cleanup the commit message before possibly exiting |
3081 |
- try: |
3082 |
- shutil.rmtree(commitmessagedir) |
3083 |
- except OSError: |
3084 |
- pass |
3085 |
- if retval != os.EX_OK: |
3086 |
- writemsg_level( |
3087 |
- "!!! Exiting on %s (shell) " |
3088 |
- "error code: %s\n" % (self.vcs_settings.vcs, retval), |
3089 |
- level=logging.ERROR, |
3090 |
- noiselevel=-1, |
3091 |
- ) |
3092 |
- sys.exit(retval) |
3093 |
- |
3094 |
- def sign_manifest(self, myupdates, myremoved, mymanifests): |
3095 |
- try: |
3096 |
- for x in sorted( |
3097 |
- vcs_files_to_cps( |
3098 |
- chain(myupdates, myremoved, mymanifests), |
3099 |
- self.scanner.repo_settings.repodir, |
3100 |
- self.scanner.repolevel, |
3101 |
- self.scanner.reposplit, |
3102 |
- self.scanner.categories, |
3103 |
- ) |
3104 |
- ): |
3105 |
- self.repoman_settings["O"] = os.path.join(self.repo_settings.repodir, x) |
3106 |
- manifest_path = os.path.join(self.repoman_settings["O"], "Manifest") |
3107 |
- if not need_signature(manifest_path): |
3108 |
- continue |
3109 |
- gpgsign(manifest_path, self.repoman_settings, self.options) |
3110 |
- except portage.exception.PortageException as e: |
3111 |
- portage.writemsg("!!! %s\n" % str(e)) |
3112 |
- portage.writemsg("!!! Disabled FEATURES='sign'\n") |
3113 |
- self.repo_settings.sign_manifests = False |
3114 |
- |
3115 |
- def msg_prefix(self): |
3116 |
- prefix = "" |
3117 |
- if self.scanner.repolevel > 1: |
3118 |
- prefix = "/".join(self.scanner.reposplit[1:]) + ": " |
3119 |
- return prefix |
3120 |
- |
3121 |
- def get_new_commit_message(self, qa_output, old_message=None): |
3122 |
- msg_prefix = old_message or self.msg_prefix() |
3123 |
- try: |
3124 |
- editor = os.environ.get("EDITOR") |
3125 |
- if editor and utilities.editor_is_executable(editor): |
3126 |
- commitmessage = utilities.get_commit_message_with_editor( |
3127 |
- editor, message=qa_output, prefix=msg_prefix |
3128 |
- ) |
3129 |
- else: |
3130 |
- print( |
3131 |
- "EDITOR is unset or invalid. Please set EDITOR to your preferred editor." |
3132 |
- ) |
3133 |
- print(bad("* no EDITOR found for commit message, aborting commit.")) |
3134 |
- sys.exit(1) |
3135 |
- except KeyboardInterrupt: |
3136 |
- logging.fatal("Interrupted; exiting...") |
3137 |
- sys.exit(1) |
3138 |
- if ( |
3139 |
- not commitmessage |
3140 |
- or not commitmessage.strip() |
3141 |
- or commitmessage.strip() == msg_prefix |
3142 |
- ): |
3143 |
- print("* no commit message? aborting commit.") |
3144 |
- sys.exit(1) |
3145 |
- return commitmessage |
3146 |
- |
3147 |
- @staticmethod |
3148 |
- def verify_commit_message(msg): |
3149 |
- """ |
3150 |
- Check whether the message roughly complies with GLEP66. Returns |
3151 |
- (True, None) if it does, (False, <explanation>) if it does not. |
3152 |
- """ |
3153 |
- |
3154 |
- problems = [] |
3155 |
- paras = msg.strip().split("\n\n") |
3156 |
- summary = paras.pop(0) |
3157 |
- |
3158 |
- if ":" not in summary: |
3159 |
- problems.append( |
3160 |
- 'summary line must start with a logical unit name, e.g. "cat/pkg:"' |
3161 |
- ) |
3162 |
- if "\n" in summary.strip(): |
3163 |
- problems.append( |
3164 |
- "commit message must start with a *single* line of summary, followed by empty line" |
3165 |
- ) |
3166 |
- # accept 69 overall or unit+50, in case of very long package names |
3167 |
- elif len(summary.strip()) > 69 and len(summary.split(":", 1)[-1]) > 50: |
3168 |
- problems.append("summary line is too long (max 69 characters)") |
3169 |
- |
3170 |
- multiple_footers = False |
3171 |
- gentoo_bug_used = False |
3172 |
- bug_closes_without_url = False |
3173 |
- body_too_long = False |
3174 |
- |
3175 |
- footer_re = re.compile(r"^[\w-]+:") |
3176 |
- |
3177 |
- found_footer = False |
3178 |
- for p in paras: |
3179 |
- lines = p.splitlines() |
3180 |
- # if all lines look like footer material, we assume it's footer |
3181 |
- # else, we assume it's body text |
3182 |
- if all(footer_re.match(l) for l in lines if l.strip()): |
3183 |
- # multiple footer-like blocks? |
3184 |
- if found_footer: |
3185 |
- multiple_footers = True |
3186 |
- found_footer = True |
3187 |
- for l in lines: |
3188 |
- if l.startswith("Gentoo-Bug"): |
3189 |
- gentoo_bug_used = True |
3190 |
- elif l.startswith("Bug:") or l.startswith("Closes:"): |
3191 |
- if "http://" not in l and "https://" not in l: |
3192 |
- bug_closes_without_url = True |
3193 |
- else: |
3194 |
- for l in lines: |
3195 |
- # we recommend wrapping at 72 but accept up to 80; |
3196 |
- # do not complain if we have single word (usually |
3197 |
- # it means very long URL) |
3198 |
- if len(l.strip()) > 80 and len(l.split()) > 1: |
3199 |
- body_too_long = True |
3200 |
- |
3201 |
- if multiple_footers: |
3202 |
- problems.append( |
3203 |
- "multiple footer-style blocks found, please combine them into one" |
3204 |
- ) |
3205 |
- if gentoo_bug_used: |
3206 |
- problems.append( |
3207 |
- "please replace Gentoo-Bug with GLEP 66-compliant Bug/Closes" |
3208 |
- ) |
3209 |
- if bug_closes_without_url: |
3210 |
- problems.append("Bug/Closes footers require full URL") |
3211 |
- if body_too_long: |
3212 |
- problems.append("body lines should be wrapped at 72 (max 80) characters") |
3213 |
- |
3214 |
- if problems: |
3215 |
- return (False, "\n".join("- %s" % x for x in problems)) |
3216 |
- return (True, None) |
3217 |
|
3218 |
diff --git a/repoman/lib/repoman/argparser.py b/repoman/lib/repoman/argparser.py |
3219 |
deleted file mode 100644 |
3220 |
index 019c7381b..000000000 |
3221 |
--- a/repoman/lib/repoman/argparser.py |
3222 |
+++ /dev/null |
3223 |
@@ -1,388 +0,0 @@ |
3224 |
-# repoman: Argument parser |
3225 |
-# Copyright 2007-2021 Gentoo Authors |
3226 |
-# Distributed under the terms of the GNU General Public License v2 |
3227 |
- |
3228 |
-"""This module contains functions used in Repoman to parse CLI arguments.""" |
3229 |
- |
3230 |
-import argparse |
3231 |
-import logging |
3232 |
- |
3233 |
-# import our initialized portage instance |
3234 |
-from repoman._portage import portage |
3235 |
- |
3236 |
-from portage import _unicode_decode |
3237 |
-from portage import util |
3238 |
- |
3239 |
- |
3240 |
-def parse_args(argv, repoman_default_opts): |
3241 |
- """Use a customized optionParser to parse command line arguments for repoman |
3242 |
- Args: |
3243 |
- argv - a sequence of command line arguments |
3244 |
- Returns: |
3245 |
- (opts, args), just like a call to parser.parse_args() |
3246 |
- """ |
3247 |
- |
3248 |
- argv = portage._decode_argv(argv) |
3249 |
- |
3250 |
- modes = { |
3251 |
- "commit": "Run a scan then commit changes", |
3252 |
- "ci": "Run a scan then commit changes", |
3253 |
- "fix": "Fix simple QA issues (stray digests, missing digests)", |
3254 |
- "full": "Scan directory tree and print all issues (not a summary)", |
3255 |
- "help": "Show this screen", |
3256 |
- "manifest": "Generate a Manifest (fetches files if necessary)", |
3257 |
- "manifest-check": "Check Manifests for missing or incorrect digests", |
3258 |
- "scan": "Scan directory tree for QA issues", |
3259 |
- } |
3260 |
- |
3261 |
- output_choices = { |
3262 |
- "default": "The normal output format", |
3263 |
- "column": "Columnar output suitable for use with grep", |
3264 |
- } |
3265 |
- |
3266 |
- mode_keys = list(modes) |
3267 |
- mode_keys.sort() |
3268 |
- |
3269 |
- output_keys = sorted(output_choices) |
3270 |
- |
3271 |
- parser = argparse.ArgumentParser( |
3272 |
- usage="repoman [options] [mode]", |
3273 |
- description="Modes: %s" % " | ".join(mode_keys), |
3274 |
- epilog="For more help consult the man page.", |
3275 |
- ) |
3276 |
- |
3277 |
- parser.add_argument( |
3278 |
- "-a", |
3279 |
- "--ask", |
3280 |
- dest="ask", |
3281 |
- action="store_true", |
3282 |
- default=False, |
3283 |
- help="Request a confirmation before commiting", |
3284 |
- ) |
3285 |
- |
3286 |
- parser.add_argument( |
3287 |
- "-b", |
3288 |
- "--bug", |
3289 |
- dest="bug", |
3290 |
- action="append", |
3291 |
- metavar="<BUG-NO|BUG-URL>", |
3292 |
- default=[], |
3293 |
- help=( |
3294 |
- "Mention a Gentoo or upstream bug in the commit footer; " |
3295 |
- "takes either Gentoo bug number or full bug URL" |
3296 |
- ), |
3297 |
- ) |
3298 |
- |
3299 |
- parser.add_argument( |
3300 |
- "-c", |
3301 |
- "--closes", |
3302 |
- dest="closes", |
3303 |
- action="append", |
3304 |
- metavar="<PR-NO|PR-URL>", |
3305 |
- default=[], |
3306 |
- help=( |
3307 |
- "Adds a Closes footer to close GitHub pull request (or compatible); " |
3308 |
- "takes either GitHub PR number or full PR URL" |
3309 |
- ), |
3310 |
- ) |
3311 |
- |
3312 |
- parser.add_argument( |
3313 |
- "-m", |
3314 |
- "--commitmsg", |
3315 |
- dest="commitmsg", |
3316 |
- help="specify a commit message on the command line", |
3317 |
- ) |
3318 |
- |
3319 |
- parser.add_argument( |
3320 |
- "-M", |
3321 |
- "--commitmsgfile", |
3322 |
- dest="commitmsgfile", |
3323 |
- help="specify a path to a file that contains a commit message", |
3324 |
- ) |
3325 |
- |
3326 |
- parser.add_argument( |
3327 |
- "--digest", |
3328 |
- choices=("y", "n"), |
3329 |
- metavar="<y|n>", |
3330 |
- help="Automatically update Manifest digests for modified files", |
3331 |
- ) |
3332 |
- |
3333 |
- parser.add_argument( |
3334 |
- "-p", |
3335 |
- "--pretend", |
3336 |
- dest="pretend", |
3337 |
- default=False, |
3338 |
- action="store_true", |
3339 |
- help="don't commit or fix anything; just show what would be done", |
3340 |
- ) |
3341 |
- |
3342 |
- parser.add_argument( |
3343 |
- "-q", |
3344 |
- "--quiet", |
3345 |
- dest="quiet", |
3346 |
- action="count", |
3347 |
- default=0, |
3348 |
- help="do not print unnecessary messages", |
3349 |
- ) |
3350 |
- |
3351 |
- parser.add_argument( |
3352 |
- "--echangelog", |
3353 |
- choices=("y", "n", "force"), |
3354 |
- metavar="<y|n|force>", |
3355 |
- help=( |
3356 |
- "for commit mode, call echangelog if ChangeLog is unmodified (or " |
3357 |
- "regardless of modification if 'force' is specified)" |
3358 |
- ), |
3359 |
- ) |
3360 |
- |
3361 |
- parser.add_argument( |
3362 |
- "--experimental-inherit", |
3363 |
- choices=("y", "n"), |
3364 |
- metavar="<y|n>", |
3365 |
- default="n", |
3366 |
- help=( |
3367 |
- "Enable experimental inherit.missing checks which may misbehave" |
3368 |
- " when the internal eclass database becomes outdated" |
3369 |
- ), |
3370 |
- ) |
3371 |
- |
3372 |
- parser.add_argument( |
3373 |
- "--experimental-repository-modules", |
3374 |
- choices=("y", "n"), |
3375 |
- metavar="<y|n>", |
3376 |
- default="n", |
3377 |
- help="Enable experimental repository modules", |
3378 |
- ) |
3379 |
- |
3380 |
- parser.add_argument( |
3381 |
- "-f", |
3382 |
- "--force", |
3383 |
- dest="force", |
3384 |
- action="store_true", |
3385 |
- default=False, |
3386 |
- help="Commit with QA violations", |
3387 |
- ) |
3388 |
- |
3389 |
- parser.add_argument( |
3390 |
- "-S", |
3391 |
- "--straight-to-stable", |
3392 |
- dest="straight_to_stable", |
3393 |
- default=False, |
3394 |
- action="store_true", |
3395 |
- help="Allow committing straight to stable", |
3396 |
- ) |
3397 |
- |
3398 |
- parser.add_argument( |
3399 |
- "--vcs", dest="vcs", help="Force using specific VCS instead of autodetection" |
3400 |
- ) |
3401 |
- |
3402 |
- parser.add_argument( |
3403 |
- "-v", |
3404 |
- "--verbose", |
3405 |
- dest="verbosity", |
3406 |
- action="count", |
3407 |
- help="be very verbose in output", |
3408 |
- default=0, |
3409 |
- ) |
3410 |
- |
3411 |
- parser.add_argument( |
3412 |
- "-V", "--version", dest="version", action="store_true", help="show version info" |
3413 |
- ) |
3414 |
- |
3415 |
- parser.add_argument( |
3416 |
- "-x", |
3417 |
- "--xmlparse", |
3418 |
- dest="xml_parse", |
3419 |
- action="store_true", |
3420 |
- default=False, |
3421 |
- help="forces the metadata.xml parse check to be carried out", |
3422 |
- ) |
3423 |
- |
3424 |
- parser.add_argument( |
3425 |
- "--if-modified", |
3426 |
- choices=("y", "n"), |
3427 |
- default="n", |
3428 |
- metavar="<y|n>", |
3429 |
- help="only check packages that have uncommitted modifications", |
3430 |
- ) |
3431 |
- |
3432 |
- parser.add_argument( |
3433 |
- "-i", |
3434 |
- "--ignore-arches", |
3435 |
- dest="ignore_arches", |
3436 |
- action="store_true", |
3437 |
- default=False, |
3438 |
- help="ignore arch-specific failures (where arch != host)", |
3439 |
- ) |
3440 |
- |
3441 |
- parser.add_argument( |
3442 |
- "--ignore-default-opts", |
3443 |
- action="store_true", |
3444 |
- help="do not use the REPOMAN_DEFAULT_OPTS environment variable", |
3445 |
- ) |
3446 |
- |
3447 |
- parser.add_argument( |
3448 |
- "-I", |
3449 |
- "--ignore-masked", |
3450 |
- dest="ignore_masked", |
3451 |
- action="store_true", |
3452 |
- default=False, |
3453 |
- help="ignore masked packages (not allowed with commit mode)", |
3454 |
- ) |
3455 |
- |
3456 |
- parser.add_argument( |
3457 |
- "--include-arches", |
3458 |
- dest="include_arches", |
3459 |
- metavar="ARCHES", |
3460 |
- action="append", |
3461 |
- help=( |
3462 |
- "A space separated list of arches used to " |
3463 |
- "filter the selection of profiles for dependency checks" |
3464 |
- ), |
3465 |
- ) |
3466 |
- |
3467 |
- parser.add_argument( |
3468 |
- "--include-profiles", |
3469 |
- dest="include_profiles", |
3470 |
- metavar="PROFILES", |
3471 |
- action="append", |
3472 |
- help=( |
3473 |
- "A space separated list of profiles used to " |
3474 |
- "define the selection of profiles for dependency checks" |
3475 |
- ), |
3476 |
- ) |
3477 |
- |
3478 |
- parser.add_argument( |
3479 |
- "-d", |
3480 |
- "--include-dev", |
3481 |
- dest="include_dev", |
3482 |
- action="store_true", |
3483 |
- default=False, |
3484 |
- help="include dev profiles in dependency checks", |
3485 |
- ) |
3486 |
- |
3487 |
- parser.add_argument( |
3488 |
- "-e", |
3489 |
- "--include-exp-profiles", |
3490 |
- choices=("y", "n"), |
3491 |
- metavar="<y|n>", |
3492 |
- default=False, |
3493 |
- help="include exp profiles in dependency checks", |
3494 |
- ) |
3495 |
- |
3496 |
- parser.add_argument( |
3497 |
- "--unmatched-removal", |
3498 |
- dest="unmatched_removal", |
3499 |
- action="store_true", |
3500 |
- default=False, |
3501 |
- help=( |
3502 |
- "enable strict checking of package.mask and package.unmask files" |
3503 |
- " for unmatched removal atoms" |
3504 |
- ), |
3505 |
- ) |
3506 |
- |
3507 |
- parser.add_argument( |
3508 |
- "--without-mask", |
3509 |
- dest="without_mask", |
3510 |
- action="store_true", |
3511 |
- default=False, |
3512 |
- help=( |
3513 |
- "behave as if no package.mask entries exist" |
3514 |
- " (not allowed with commit mode)" |
3515 |
- ), |
3516 |
- ) |
3517 |
- |
3518 |
- parser.add_argument( |
3519 |
- "--output-style", |
3520 |
- dest="output_style", |
3521 |
- choices=output_keys, |
3522 |
- help="select output type", |
3523 |
- default="default", |
3524 |
- ) |
3525 |
- |
3526 |
- parser.add_argument( |
3527 |
- "-j", |
3528 |
- "--jobs", |
3529 |
- dest="jobs", |
3530 |
- action="store", |
3531 |
- type=int, |
3532 |
- default=1, |
3533 |
- help="Specifies the number of jobs (processes) to run simultaneously.", |
3534 |
- ) |
3535 |
- |
3536 |
- parser.add_argument( |
3537 |
- "-l", |
3538 |
- "--load-average", |
3539 |
- dest="load_average", |
3540 |
- action="store", |
3541 |
- type=float, |
3542 |
- default=None, |
3543 |
- help="Specifies that no new jobs (processes) should be started if there are others " |
3544 |
- "jobs running and the load average is at least load (a floating-point number).", |
3545 |
- ) |
3546 |
- |
3547 |
- parser.add_argument( |
3548 |
- "--mode", |
3549 |
- dest="mode", |
3550 |
- choices=mode_keys, |
3551 |
- help="specify which mode repoman will run in (default=full)", |
3552 |
- ) |
3553 |
- |
3554 |
- # Modes help is included earlier, in the parser description. |
3555 |
- parser.add_argument( |
3556 |
- "mode_positional", |
3557 |
- nargs="?", |
3558 |
- metavar="mode", |
3559 |
- choices=mode_keys, |
3560 |
- help=argparse.SUPPRESS, |
3561 |
- ) |
3562 |
- |
3563 |
- opts = parser.parse_args(argv[1:]) |
3564 |
- |
3565 |
- if not opts.ignore_default_opts: |
3566 |
- default_opts = util.shlex_split(repoman_default_opts) |
3567 |
- if default_opts: |
3568 |
- opts = parser.parse_args(default_opts + argv[1:]) |
3569 |
- |
3570 |
- args = [] |
3571 |
- if opts.mode is not None: |
3572 |
- args.append(opts.mode) |
3573 |
- if opts.mode_positional is not None: |
3574 |
- args.append(opts.mode_positional) |
3575 |
- |
3576 |
- if len(set(args)) > 1: |
3577 |
- parser.error("multiple modes specified: %s" % " ".join(args)) |
3578 |
- |
3579 |
- opts.mode = args[0] if args else None |
3580 |
- |
3581 |
- if opts.mode == "help": |
3582 |
- parser.print_help() |
3583 |
- parser.exit() |
3584 |
- |
3585 |
- if not opts.mode: |
3586 |
- opts.mode = "full" |
3587 |
- |
3588 |
- if opts.mode == "ci": |
3589 |
- opts.mode = "commit" # backwards compat shortcut |
3590 |
- |
3591 |
- # Use verbosity and quiet options to appropriately fiddle with the loglevel |
3592 |
- for val in range(opts.verbosity): |
3593 |
- logger = logging.getLogger() |
3594 |
- logger.setLevel(logger.getEffectiveLevel() - 10) |
3595 |
- |
3596 |
- for val in range(opts.quiet): |
3597 |
- logger = logging.getLogger() |
3598 |
- logger.setLevel(logger.getEffectiveLevel() + 10) |
3599 |
- |
3600 |
- if opts.mode == "commit" and opts.commitmsg: |
3601 |
- opts.commitmsg = _unicode_decode(opts.commitmsg) |
3602 |
- |
3603 |
- if opts.mode == "commit" and not (opts.force or opts.pretend): |
3604 |
- if opts.ignore_masked: |
3605 |
- opts.ignore_masked = False |
3606 |
- logging.warn("Commit mode automatically disables --ignore-masked") |
3607 |
- if opts.without_mask: |
3608 |
- opts.without_mask = False |
3609 |
- logging.warn("Commit mode automatically disables --without-mask") |
3610 |
- |
3611 |
- return (opts, args) |
3612 |
|
3613 |
diff --git a/repoman/lib/repoman/check_missingslot.py b/repoman/lib/repoman/check_missingslot.py |
3614 |
deleted file mode 100644 |
3615 |
index 4d2d7676b..000000000 |
3616 |
--- a/repoman/lib/repoman/check_missingslot.py |
3617 |
+++ /dev/null |
3618 |
@@ -1,39 +0,0 @@ |
3619 |
-# -*- coding:utf-8 -*- |
3620 |
-# repoman: missing slot check |
3621 |
-# Copyright 2014 Gentoo Foundation |
3622 |
-# Distributed under the terms of the GNU General Public License v2 |
3623 |
- |
3624 |
-"""This module contains the check used to find missing slot values |
3625 |
-in dependencies.""" |
3626 |
- |
3627 |
-from portage.eapi import eapi_has_slot_operator |
3628 |
- |
3629 |
- |
3630 |
-def check_missingslot(atom, mytype, eapi, portdb, qatracker, relative_path, my_aux): |
3631 |
- # If no slot or slot operator is specified in RDEP... |
3632 |
- if ( |
3633 |
- not atom.blocker |
3634 |
- and not atom.slot |
3635 |
- and not atom.slot_operator |
3636 |
- and mytype == "RDEPEND" |
3637 |
- and eapi_has_slot_operator(eapi) |
3638 |
- ): |
3639 |
- # Check whether it doesn't match more than one. |
3640 |
- atom_matches = portdb.xmatch("match-all", atom) |
3641 |
- dep_slots = frozenset( |
3642 |
- portdb.aux_get(cpv, ["SLOT"])[0].split("/")[0] for cpv in atom_matches |
3643 |
- ) |
3644 |
- |
3645 |
- if len(dep_slots) > 1: |
3646 |
- # See if it is a DEPEND as well. It's a very simple & dumb |
3647 |
- # check but should suffice for catching it. |
3648 |
- depend = my_aux["DEPEND"].split() |
3649 |
- if atom not in depend: |
3650 |
- return |
3651 |
- |
3652 |
- qatracker.add_error( |
3653 |
- "dependency.missingslot", |
3654 |
- relative_path |
3655 |
- + ": %s: '%s' matches more than one slot, please specify an explicit slot and/or use the := or :* slot operator" |
3656 |
- % (mytype, atom), |
3657 |
- ) |
3658 |
|
3659 |
diff --git a/repoman/lib/repoman/checks/__init__.py b/repoman/lib/repoman/checks/__init__.py |
3660 |
deleted file mode 100644 |
3661 |
index e69de29bb..000000000 |
3662 |
|
3663 |
diff --git a/repoman/lib/repoman/config.py b/repoman/lib/repoman/config.py |
3664 |
deleted file mode 100644 |
3665 |
index 621143de4..000000000 |
3666 |
--- a/repoman/lib/repoman/config.py |
3667 |
+++ /dev/null |
3668 |
@@ -1,172 +0,0 @@ |
3669 |
-# -*- coding:utf-8 -*- |
3670 |
- |
3671 |
-import copy |
3672 |
-import itertools |
3673 |
-import json |
3674 |
-import os |
3675 |
-import stat |
3676 |
- |
3677 |
-try: |
3678 |
- import yaml |
3679 |
-except ImportError: |
3680 |
- yaml = None |
3681 |
- |
3682 |
- |
3683 |
-class ConfigError(Exception): |
3684 |
- """Raised when a config file fails to load""" |
3685 |
- |
3686 |
- pass |
3687 |
- |
3688 |
- |
3689 |
-def merge_config(base, head): |
3690 |
- """ |
3691 |
- Merge two JSON or YAML documents into a single object. Arrays are |
3692 |
- merged by extension. If dissimilar types are encountered, then the |
3693 |
- head value overwrites the base value. |
3694 |
- """ |
3695 |
- |
3696 |
- if isinstance(head, dict): |
3697 |
- if not isinstance(base, dict): |
3698 |
- return copy.deepcopy(head) |
3699 |
- |
3700 |
- result = {} |
3701 |
- for k in itertools.chain(head, base): |
3702 |
- try: |
3703 |
- result[k] = merge_config(base[k], head[k]) |
3704 |
- except KeyError: |
3705 |
- try: |
3706 |
- result[k] = copy.deepcopy(head[k]) |
3707 |
- except KeyError: |
3708 |
- result[k] = copy.deepcopy(base[k]) |
3709 |
- |
3710 |
- elif isinstance(head, list): |
3711 |
- result = [] |
3712 |
- if not isinstance(base, list): |
3713 |
- result.extend(copy.deepcopy(x) for x in head) |
3714 |
- else: |
3715 |
- if any(isinstance(x, (dict, list)) for x in itertools.chain(head, base)): |
3716 |
- # merge items with identical indexes |
3717 |
- for x, y in zip(base, head): |
3718 |
- if isinstance(x, (dict, list)): |
3719 |
- result.append(merge_config(x, y)) |
3720 |
- else: |
3721 |
- # head overwrites base (preserving index) |
3722 |
- result.append(copy.deepcopy(y)) |
3723 |
- # copy remaining items from the longer list |
3724 |
- if len(base) != len(head): |
3725 |
- if len(base) > len(head): |
3726 |
- result.extend(copy.deepcopy(x) for x in base[len(head) :]) |
3727 |
- else: |
3728 |
- result.extend(copy.deepcopy(x) for x in head[len(base) :]) |
3729 |
- else: |
3730 |
- result.extend(copy.deepcopy(x) for x in base) |
3731 |
- result.extend(copy.deepcopy(x) for x in head) |
3732 |
- |
3733 |
- else: |
3734 |
- result = copy.deepcopy(head) |
3735 |
- |
3736 |
- return result |
3737 |
- |
3738 |
- |
3739 |
-def _yaml_load(filename): |
3740 |
- """ |
3741 |
- Load filename as YAML and return a dict. Raise ConfigError if |
3742 |
- it fails to load. |
3743 |
- """ |
3744 |
- if yaml is None: |
3745 |
- raise ImportError("Please install pyyaml in order to read yaml files") |
3746 |
- |
3747 |
- with open(filename, "rt") as f: |
3748 |
- try: |
3749 |
- return yaml.safe_load(f) |
3750 |
- except yaml.parser.ParserError as e: |
3751 |
- raise ConfigError("{}: {}".format(filename, e)) |
3752 |
- |
3753 |
- |
3754 |
-def _json_load(filename): |
3755 |
- """ |
3756 |
- Load filename as JSON and return a dict. Raise ConfigError if |
3757 |
- it fails to load. |
3758 |
- """ |
3759 |
- with open(filename, "rt") as f: |
3760 |
- try: |
3761 |
- return json.load(f) # nosec |
3762 |
- except ValueError as e: |
3763 |
- raise ConfigError("{}: {}".format(filename, e)) |
3764 |
- |
3765 |
- |
3766 |
-def iter_files(files_dirs): |
3767 |
- """ |
3768 |
- Iterate over nested file paths in lexical order. |
3769 |
- """ |
3770 |
- stack = list(reversed(files_dirs)) |
3771 |
- while stack: |
3772 |
- location = stack.pop() |
3773 |
- try: |
3774 |
- st = os.stat(location) |
3775 |
- except FileNotFoundError: |
3776 |
- continue |
3777 |
- |
3778 |
- if stat.S_ISDIR(st.st_mode): |
3779 |
- stack.extend( |
3780 |
- os.path.join(location, x) |
3781 |
- for x in sorted(os.listdir(location), reverse=True) |
3782 |
- ) |
3783 |
- |
3784 |
- elif stat.S_ISREG(st.st_mode): |
3785 |
- yield location |
3786 |
- |
3787 |
- |
3788 |
-def load_config(conf_dirs, file_extensions=None, valid_versions=None): |
3789 |
- """ |
3790 |
- Load JSON and/or YAML files from a directories, and merge them together |
3791 |
- into a single object. |
3792 |
- |
3793 |
- @param conf_dirs: ordered iterable of directories to load the config from |
3794 |
- @param file_extensions: Optional list of file extension types to load |
3795 |
- @param valid_versions: list of compatible file versions allowed |
3796 |
- @returns: the stacked config |
3797 |
- """ |
3798 |
- |
3799 |
- result = {} |
3800 |
- for filename in iter_files(conf_dirs): |
3801 |
- if file_extensions is not None and not filename.endswith(file_extensions): |
3802 |
- continue |
3803 |
- |
3804 |
- loaders = [] |
3805 |
- extension = filename.rsplit(".", 1)[1] |
3806 |
- if extension in ["json"]: |
3807 |
- loaders.append(_json_load) |
3808 |
- elif extension in ["yml", "yaml"]: |
3809 |
- loaders.append(_yaml_load) |
3810 |
- |
3811 |
- config = None |
3812 |
- exception = None |
3813 |
- for loader in loaders: |
3814 |
- try: |
3815 |
- config = loader(filename) or {} |
3816 |
- except ConfigError as e: |
3817 |
- exception = e |
3818 |
- else: |
3819 |
- break |
3820 |
- |
3821 |
- if config is None: |
3822 |
- print("Repoman.config.load_config(), Error loading file: %s" % filename) |
3823 |
- print(" Aborting...") |
3824 |
- raise exception |
3825 |
- |
3826 |
- if config: |
3827 |
- if config["version"] not in valid_versions: |
3828 |
- raise ConfigError( |
3829 |
- "Invalid file version: %s in: %s\nPlease upgrade to " |
3830 |
- ">=app-portage/repoman-%s, current valid API versions: %s" |
3831 |
- % ( |
3832 |
- config["version"], |
3833 |
- filename, |
3834 |
- config["repoman_version"], |
3835 |
- valid_versions, |
3836 |
- ) |
3837 |
- ) |
3838 |
- result = merge_config(result, config) |
3839 |
- |
3840 |
- return result |
3841 |
|
3842 |
diff --git a/repoman/lib/repoman/copyrights.py b/repoman/lib/repoman/copyrights.py |
3843 |
deleted file mode 100644 |
3844 |
index 199f5efbf..000000000 |
3845 |
--- a/repoman/lib/repoman/copyrights.py |
3846 |
+++ /dev/null |
3847 |
@@ -1,143 +0,0 @@ |
3848 |
-# -*- coding:utf-8 -*- |
3849 |
- |
3850 |
- |
3851 |
-import difflib |
3852 |
-import io |
3853 |
-import re |
3854 |
-from tempfile import mkstemp |
3855 |
- |
3856 |
-from portage import _encodings |
3857 |
-from portage import _unicode_decode |
3858 |
-from portage import _unicode_encode |
3859 |
-from portage import os |
3860 |
-from portage import shutil |
3861 |
-from portage import util |
3862 |
- |
3863 |
- |
3864 |
-_copyright_re1 = re.compile( |
3865 |
- rb"^(# Copyright \d\d\d\d)-\d\d\d\d( Gentoo (Foundation|Authors))\b" |
3866 |
-) |
3867 |
-_copyright_re2 = re.compile( |
3868 |
- rb"^(# Copyright )(\d\d\d\d)( Gentoo (Foundation|Authors))\b" |
3869 |
-) |
3870 |
- |
3871 |
- |
3872 |
-class _copyright_repl: |
3873 |
- __slots__ = ("year",) |
3874 |
- |
3875 |
- def __init__(self, year): |
3876 |
- self.year = year |
3877 |
- |
3878 |
- def __call__(self, matchobj): |
3879 |
- if matchobj.group(2) == self.year: |
3880 |
- return matchobj.group(0) |
3881 |
- else: |
3882 |
- return ( |
3883 |
- matchobj.group(1) |
3884 |
- + matchobj.group(2) |
3885 |
- + b"-" |
3886 |
- + self.year |
3887 |
- + b" Gentoo Authors" |
3888 |
- ) |
3889 |
- |
3890 |
- |
3891 |
-def update_copyright_year(year, line): |
3892 |
- """ |
3893 |
- These two regexes are taken from echangelog |
3894 |
- update_copyright(), except that we don't hardcode |
3895 |
- 1999 here (in order to be more generic). |
3896 |
- """ |
3897 |
- is_bytes = isinstance(line, bytes) |
3898 |
- if is_bytes: |
3899 |
- if not line.startswith(b"# Copyright "): |
3900 |
- return line |
3901 |
- else: |
3902 |
- if not line.startswith("# Copyright "): |
3903 |
- return line |
3904 |
- |
3905 |
- year = _unicode_encode(year) |
3906 |
- line = _unicode_encode(line) |
3907 |
- |
3908 |
- line = _copyright_re1.sub(rb"\1-" + year + b" Gentoo Authors", line) |
3909 |
- line = _copyright_re2.sub(_copyright_repl(year), line) |
3910 |
- if not is_bytes: |
3911 |
- line = _unicode_decode(line) |
3912 |
- return line |
3913 |
- |
3914 |
- |
3915 |
-def update_copyright(fn_path, year, pretend=False): |
3916 |
- """ |
3917 |
- Check file for a Copyright statement, and update its year. The |
3918 |
- patterns used for replacing copyrights are taken from echangelog. |
3919 |
- Only the first lines of each file that start with a hash ('#') are |
3920 |
- considered, until a line is found that doesn't start with a hash. |
3921 |
- Files are read and written in binary mode, so that this function |
3922 |
- will work correctly with files encoded in any character set, as |
3923 |
- long as the copyright statements consist of plain ASCII. |
3924 |
- |
3925 |
- @param fn_path: file path |
3926 |
- @type str |
3927 |
- @param year: current year |
3928 |
- @type str |
3929 |
- @param pretend: pretend mode |
3930 |
- @type bool |
3931 |
- @rtype: bool |
3932 |
- @return: True if copyright update was needed, False otherwise |
3933 |
- """ |
3934 |
- |
3935 |
- try: |
3936 |
- fn_hdl = io.open( |
3937 |
- _unicode_encode(fn_path, encoding=_encodings["fs"], errors="strict"), |
3938 |
- mode="rb", |
3939 |
- ) |
3940 |
- except EnvironmentError: |
3941 |
- return |
3942 |
- |
3943 |
- orig_header = [] |
3944 |
- new_header = [] |
3945 |
- |
3946 |
- for line in fn_hdl: |
3947 |
- line_strip = line.strip() |
3948 |
- orig_header.append(line) |
3949 |
- if not line_strip or line_strip[:1] != b"#": |
3950 |
- new_header.append(line) |
3951 |
- break |
3952 |
- |
3953 |
- line = update_copyright_year(year, line) |
3954 |
- new_header.append(line) |
3955 |
- |
3956 |
- difflines = 0 |
3957 |
- for diffline in difflib.unified_diff( |
3958 |
- [_unicode_decode(diffline) for diffline in orig_header], |
3959 |
- [_unicode_decode(diffline) for diffline in new_header], |
3960 |
- fromfile=fn_path, |
3961 |
- tofile=fn_path, |
3962 |
- n=0, |
3963 |
- ): |
3964 |
- util.writemsg_stdout(diffline, noiselevel=-1) |
3965 |
- difflines += 1 |
3966 |
- util.writemsg_stdout("\n", noiselevel=-1) |
3967 |
- |
3968 |
- # unified diff has three lines to start with |
3969 |
- if difflines > 3 and not pretend: |
3970 |
- # write new file with changed header |
3971 |
- f, fnnew_path = mkstemp() |
3972 |
- f = io.open(f, mode="wb") |
3973 |
- for line in new_header: |
3974 |
- f.write(line) |
3975 |
- for line in fn_hdl: |
3976 |
- f.write(line) |
3977 |
- f.close() |
3978 |
- try: |
3979 |
- fn_stat = os.stat(fn_path) |
3980 |
- except OSError: |
3981 |
- fn_stat = None |
3982 |
- |
3983 |
- shutil.move(fnnew_path, fn_path) |
3984 |
- |
3985 |
- if fn_stat is None: |
3986 |
- util.apply_permissions(fn_path, mode=0o644) |
3987 |
- else: |
3988 |
- util.apply_stat_permissions(fn_path, fn_stat) |
3989 |
- fn_hdl.close() |
3990 |
- return difflines > 3 |
3991 |
|
3992 |
diff --git a/repoman/lib/repoman/errors.py b/repoman/lib/repoman/errors.py |
3993 |
deleted file mode 100644 |
3994 |
index c3ee92d37..000000000 |
3995 |
--- a/repoman/lib/repoman/errors.py |
3996 |
+++ /dev/null |
3997 |
@@ -1,21 +0,0 @@ |
3998 |
-# -*- coding:utf-8 -*- |
3999 |
- |
4000 |
-import sys |
4001 |
- |
4002 |
- |
4003 |
-def warn(txt): |
4004 |
- print("repoman: " + txt) |
4005 |
- |
4006 |
- |
4007 |
-def err(txt): |
4008 |
- warn(txt) |
4009 |
- sys.exit(1) |
4010 |
- |
4011 |
- |
4012 |
-def caterror(catdir, repodir): |
4013 |
- err( |
4014 |
- "%s is not an official category." |
4015 |
- " Skipping QA checks in this directory.\n" |
4016 |
- "Please ensure that you add %s to %s/profiles/categories\n" |
4017 |
- "if it is a new category." % (catdir, catdir, repodir) |
4018 |
- ) |
4019 |
|
4020 |
diff --git a/repoman/lib/repoman/gpg.py b/repoman/lib/repoman/gpg.py |
4021 |
deleted file mode 100644 |
4022 |
index 10e884e52..000000000 |
4023 |
--- a/repoman/lib/repoman/gpg.py |
4024 |
+++ /dev/null |
4025 |
@@ -1,73 +0,0 @@ |
4026 |
-# -*- coding:utf-8 -*- |
4027 |
- |
4028 |
-import errno |
4029 |
-import logging |
4030 |
-import subprocess |
4031 |
- |
4032 |
-import portage |
4033 |
-from portage import os |
4034 |
-from portage import _encodings |
4035 |
-from portage import _unicode_encode |
4036 |
-from portage.exception import MissingParameter |
4037 |
- |
4038 |
- |
4039 |
-# Setup the GPG commands |
4040 |
-def gpgsign(filename, repoman_settings, options): |
4041 |
- gpgcmd = repoman_settings.get("PORTAGE_GPG_SIGNING_COMMAND") |
4042 |
- if gpgcmd in [None, ""]: |
4043 |
- raise MissingParameter( |
4044 |
- "PORTAGE_GPG_SIGNING_COMMAND is unset!" " Is make.globals missing?" |
4045 |
- ) |
4046 |
- if "${PORTAGE_GPG_KEY}" in gpgcmd and "PORTAGE_GPG_KEY" not in repoman_settings: |
4047 |
- raise MissingParameter("PORTAGE_GPG_KEY is unset!") |
4048 |
- if "${PORTAGE_GPG_DIR}" in gpgcmd: |
4049 |
- if "PORTAGE_GPG_DIR" not in repoman_settings: |
4050 |
- repoman_settings["PORTAGE_GPG_DIR"] = os.path.expanduser("~/.gnupg") |
4051 |
- logging.info( |
4052 |
- "Automatically setting PORTAGE_GPG_DIR to '%s'" |
4053 |
- % repoman_settings["PORTAGE_GPG_DIR"] |
4054 |
- ) |
4055 |
- else: |
4056 |
- repoman_settings["PORTAGE_GPG_DIR"] = os.path.expanduser( |
4057 |
- repoman_settings["PORTAGE_GPG_DIR"] |
4058 |
- ) |
4059 |
- if not os.access(repoman_settings["PORTAGE_GPG_DIR"], os.X_OK): |
4060 |
- raise portage.exception.InvalidLocation( |
4061 |
- "Unable to access directory: PORTAGE_GPG_DIR='%s'" |
4062 |
- % repoman_settings["PORTAGE_GPG_DIR"] |
4063 |
- ) |
4064 |
- gpgvars = {"FILE": filename} |
4065 |
- for k in ("PORTAGE_GPG_DIR", "PORTAGE_GPG_KEY"): |
4066 |
- v = repoman_settings.get(k) |
4067 |
- if v is not None: |
4068 |
- gpgvars[k] = v |
4069 |
- gpgcmd = portage.util.varexpand(gpgcmd, mydict=gpgvars) |
4070 |
- if options.pretend: |
4071 |
- print("(" + gpgcmd + ")") |
4072 |
- else: |
4073 |
- # Encode unicode manually for bug #310789. |
4074 |
- gpgcmd = portage.util.shlex_split(gpgcmd) |
4075 |
- |
4076 |
- gpgcmd = [ |
4077 |
- _unicode_encode(arg, encoding=_encodings["fs"], errors="strict") |
4078 |
- for arg in gpgcmd |
4079 |
- ] |
4080 |
- rValue = subprocess.call(gpgcmd) |
4081 |
- if rValue == os.EX_OK: |
4082 |
- os.rename(filename + ".asc", filename) |
4083 |
- else: |
4084 |
- raise portage.exception.PortageException( |
4085 |
- "!!! gpg exited with '" + str(rValue) + "' status" |
4086 |
- ) |
4087 |
- |
4088 |
- |
4089 |
-def need_signature(filename): |
4090 |
- try: |
4091 |
- with open( |
4092 |
- _unicode_encode(filename, encoding=_encodings["fs"], errors="strict"), "rb" |
4093 |
- ) as f: |
4094 |
- return b"BEGIN PGP SIGNED MESSAGE" not in f.readline() |
4095 |
- except IOError as e: |
4096 |
- if e.errno in (errno.ENOENT, errno.ESTALE): |
4097 |
- return False |
4098 |
- raise |
4099 |
|
4100 |
diff --git a/repoman/lib/repoman/main.py b/repoman/lib/repoman/main.py |
4101 |
deleted file mode 100755 |
4102 |
index 1cfe86e8d..000000000 |
4103 |
--- a/repoman/lib/repoman/main.py |
4104 |
+++ /dev/null |
4105 |
@@ -1,255 +0,0 @@ |
4106 |
-#!/usr/bin/env python |
4107 |
-# -*- coding:utf-8 -*- |
4108 |
-# Copyright 1999-2021 Gentoo Authors |
4109 |
-# Distributed under the terms of the GNU General Public License v2 |
4110 |
- |
4111 |
-import collections |
4112 |
-import io |
4113 |
-import logging |
4114 |
-import sys |
4115 |
- |
4116 |
-# import our centrally initialized portage instance |
4117 |
-from repoman._portage import portage |
4118 |
- |
4119 |
-portage._internal_caller = True |
4120 |
-portage._disable_legacy_globals() |
4121 |
- |
4122 |
- |
4123 |
-from portage import os |
4124 |
-import portage.checksum |
4125 |
-import portage.const |
4126 |
-import portage.repository.config |
4127 |
-from portage.output import create_color_func, nocolor |
4128 |
-from portage.output import ConsoleStyleFile, StyleWriter |
4129 |
-from portage.util import formatter |
4130 |
-from portage.util.futures.extendedfutures import ( |
4131 |
- ExtendedFuture, |
4132 |
-) |
4133 |
- |
4134 |
-# pylint: disable=ungrouped-imports |
4135 |
-from repoman.actions import Actions |
4136 |
-from repoman.argparser import parse_args |
4137 |
-from repoman.qa_data import QAData |
4138 |
-from repoman.qa_data import format_qa_output, format_qa_output_column |
4139 |
-from repoman.repos import RepoSettings |
4140 |
-from repoman.scanner import Scanner |
4141 |
-from repoman import utilities |
4142 |
-from repoman.modules.vcs.settings import VCSSettings |
4143 |
-from repoman import VERSION |
4144 |
- |
4145 |
- |
4146 |
-bad = create_color_func("BAD") |
4147 |
- |
4148 |
-# A sane umask is needed for files that portage creates. |
4149 |
-os.umask(0o22) |
4150 |
- |
4151 |
-LOGLEVEL = logging.WARNING |
4152 |
-portage.util.initialize_logger(LOGLEVEL) |
4153 |
- |
4154 |
-VALID_VERSIONS = [ |
4155 |
- 1, |
4156 |
-] |
4157 |
- |
4158 |
-_repoman_main_vars = collections.namedtuple( |
4159 |
- "_repoman_main_vars", |
4160 |
- ( |
4161 |
- "can_force", |
4162 |
- "exitcode", |
4163 |
- "options", |
4164 |
- "qadata", |
4165 |
- "repo_settings", |
4166 |
- "scanner", |
4167 |
- "vcs_settings", |
4168 |
- ), |
4169 |
-) |
4170 |
- |
4171 |
- |
4172 |
-def repoman_main(argv): |
4173 |
- repoman_vars = _repoman_init(argv) |
4174 |
- if repoman_vars.exitcode is not None: |
4175 |
- return repoman_vars.exitcode |
4176 |
- result = _repoman_scan(*repoman_vars) |
4177 |
- return _handle_result(*repoman_vars, result) |
4178 |
- |
4179 |
- |
4180 |
-def _repoman_init(argv): |
4181 |
- config_root = os.environ.get("PORTAGE_CONFIGROOT") |
4182 |
- repoman_settings = portage.config(config_root=config_root, local_config=False) |
4183 |
- repoman_settings.valid_versions = VALID_VERSIONS |
4184 |
- |
4185 |
- if ( |
4186 |
- repoman_settings.get("NOCOLOR", "").lower() in ("yes", "true") |
4187 |
- or repoman_settings.get("TERM") == "dumb" |
4188 |
- or not sys.stdout.isatty() |
4189 |
- ): |
4190 |
- nocolor() |
4191 |
- |
4192 |
- options, arguments = parse_args( |
4193 |
- argv, repoman_settings.get("REPOMAN_DEFAULT_OPTS", "") |
4194 |
- ) |
4195 |
- |
4196 |
- if options.version: |
4197 |
- print("Repoman", VERSION, "(portage-%s)" % portage.VERSION) |
4198 |
- return _repoman_main_vars(None, 0, None, None, None, None, None) |
4199 |
- |
4200 |
- logger = logging.getLogger() |
4201 |
- |
4202 |
- if options.verbosity > 0: |
4203 |
- logger.setLevel(LOGLEVEL - 10 * options.verbosity) |
4204 |
- else: |
4205 |
- logger.setLevel(LOGLEVEL) |
4206 |
- |
4207 |
- # Set this to False when an extraordinary issue (generally |
4208 |
- # something other than a QA issue) makes it impossible to |
4209 |
- # commit (like if Manifest generation fails). |
4210 |
- can_force = ExtendedFuture(True) |
4211 |
- repo_settings, vcs_settings, scanner, qadata = _create_scanner( |
4212 |
- options, can_force, config_root, repoman_settings |
4213 |
- ) |
4214 |
- return _repoman_main_vars( |
4215 |
- can_force, None, options, qadata, repo_settings, scanner, vcs_settings |
4216 |
- ) |
4217 |
- |
4218 |
- |
4219 |
-def _create_scanner(options, can_force, config_root, repoman_settings): |
4220 |
- |
4221 |
- portdir, portdir_overlay, mydir = utilities.FindPortdir(repoman_settings) |
4222 |
- if portdir is None: |
4223 |
- return (None, None, None, None) |
4224 |
- |
4225 |
- myreporoot = os.path.basename(portdir_overlay) |
4226 |
- myreporoot += mydir[len(portdir_overlay) :] |
4227 |
- |
4228 |
- # avoid a circular parameter repo_settings |
4229 |
- vcs_settings = VCSSettings(options, repoman_settings) |
4230 |
- qadata = QAData() |
4231 |
- |
4232 |
- logging.debug("repoman_main: RepoSettings init") |
4233 |
- repo_settings = RepoSettings( |
4234 |
- config_root, |
4235 |
- portdir, |
4236 |
- portdir_overlay, |
4237 |
- repoman_settings, |
4238 |
- vcs_settings, |
4239 |
- options, |
4240 |
- qadata, |
4241 |
- ) |
4242 |
- repoman_settings = repo_settings.repoman_settings |
4243 |
- repoman_settings.valid_versions = VALID_VERSIONS |
4244 |
- |
4245 |
- # Now set repo_settings |
4246 |
- vcs_settings.repo_settings = repo_settings |
4247 |
- # set QATracker qacats, qawarnings |
4248 |
- vcs_settings.qatracker.qacats = repo_settings.qadata.qacats |
4249 |
- vcs_settings.qatracker.qawarnings = repo_settings.qadata.qawarnings |
4250 |
- logging.debug("repoman_main: vcs_settings done") |
4251 |
- logging.debug("repoman_main: qadata: %s", repo_settings.qadata) |
4252 |
- |
4253 |
- if "digest" in repoman_settings.features and options.digest != "n": |
4254 |
- options.digest = "y" |
4255 |
- |
4256 |
- logging.debug("vcs: %s" % (vcs_settings.vcs,)) |
4257 |
- logging.debug("repo config: %s" % (repo_settings.repo_config,)) |
4258 |
- logging.debug("options: %s" % (options,)) |
4259 |
- |
4260 |
- # It's confusing if these warnings are displayed without the user |
4261 |
- # being told which profile they come from, so disable them. |
4262 |
- env = os.environ.copy() |
4263 |
- env["FEATURES"] = env.get("FEATURES", "") + " -unknown-features-warn" |
4264 |
- |
4265 |
- # Perform the main checks |
4266 |
- scanner = Scanner( |
4267 |
- repo_settings, myreporoot, config_root, options, vcs_settings, mydir, env |
4268 |
- ) |
4269 |
- return repo_settings, vcs_settings, scanner, qadata |
4270 |
- |
4271 |
- |
4272 |
-def _repoman_scan( |
4273 |
- can_force, exitcode, options, qadata, repo_settings, scanner, vcs_settings |
4274 |
-): |
4275 |
- scanner.scan_pkgs(can_force) |
4276 |
- |
4277 |
- if options.if_modified == "y" and len(scanner.effective_scanlist) < 1: |
4278 |
- logging.warning( |
4279 |
- "--if-modified is enabled, but no modified packages were found!" |
4280 |
- ) |
4281 |
- |
4282 |
- result = { |
4283 |
- # fail will be true if we have failed in at least one non-warning category |
4284 |
- "fail": 0, |
4285 |
- # warn will be true if we tripped any warnings |
4286 |
- "warn": 0, |
4287 |
- # full will be true if we should print a "repoman full" informational message |
4288 |
- "full": options.mode != "full", |
4289 |
- } |
4290 |
- |
4291 |
- for x in qadata.qacats: |
4292 |
- if x not in vcs_settings.qatracker.fails: |
4293 |
- continue |
4294 |
- result["warn"] = 1 |
4295 |
- if x not in qadata.qawarnings: |
4296 |
- result["fail"] = 1 |
4297 |
- |
4298 |
- if result["fail"] or ( |
4299 |
- result["warn"] and not (options.quiet or options.mode == "scan") |
4300 |
- ): |
4301 |
- result["full"] = 0 |
4302 |
- |
4303 |
- return result |
4304 |
- |
4305 |
- |
4306 |
-def _handle_result( |
4307 |
- can_force, exitcode, options, qadata, repo_settings, scanner, vcs_settings, result |
4308 |
-): |
4309 |
- commitmessage = None |
4310 |
- if options.commitmsg: |
4311 |
- commitmessage = options.commitmsg |
4312 |
- elif options.commitmsgfile: |
4313 |
- # we don't need the actual text of the commit message here |
4314 |
- # the filename will do for the next code block |
4315 |
- commitmessage = options.commitmsgfile |
4316 |
- |
4317 |
- # Save QA output so that it can be conveniently displayed |
4318 |
- # in $EDITOR while the user creates a commit message. |
4319 |
- # Otherwise, the user would not be able to see this output |
4320 |
- # once the editor has taken over the screen. |
4321 |
- qa_output = io.StringIO() |
4322 |
- style_file = ConsoleStyleFile(sys.stdout) |
4323 |
- if options.mode == "commit" and (not commitmessage or not commitmessage.strip()): |
4324 |
- style_file.write_listener = qa_output |
4325 |
- console_writer = StyleWriter(file=style_file, maxcol=9999) |
4326 |
- console_writer.style_listener = style_file.new_styles |
4327 |
- |
4328 |
- f = formatter.AbstractFormatter(console_writer) |
4329 |
- |
4330 |
- format_outputs = {"column": format_qa_output_column, "default": format_qa_output} |
4331 |
- |
4332 |
- format_output = format_outputs.get(options.output_style, format_outputs["default"]) |
4333 |
- format_output( |
4334 |
- f, |
4335 |
- vcs_settings.qatracker.fails, |
4336 |
- result["full"], |
4337 |
- result["fail"], |
4338 |
- options, |
4339 |
- qadata.qawarnings, |
4340 |
- ) |
4341 |
- |
4342 |
- style_file.flush() |
4343 |
- del console_writer, f, style_file |
4344 |
- |
4345 |
- # early out for manifest generation |
4346 |
- if options.mode == "manifest": |
4347 |
- return 1 if result["fail"] else 0 |
4348 |
- |
4349 |
- qa_output = qa_output.getvalue() |
4350 |
- qa_output = qa_output.splitlines(True) |
4351 |
- |
4352 |
- # output the results |
4353 |
- actions = Actions(repo_settings, options, scanner, vcs_settings) |
4354 |
- if actions.inform(can_force.get(), result): |
4355 |
- # perform any other actions |
4356 |
- actions.perform(qa_output) |
4357 |
- elif result["fail"]: |
4358 |
- return 1 |
4359 |
- |
4360 |
- return 0 |
4361 |
|
4362 |
diff --git a/repoman/lib/repoman/metadata.py b/repoman/lib/repoman/metadata.py |
4363 |
deleted file mode 100644 |
4364 |
index 5dc44b119..000000000 |
4365 |
--- a/repoman/lib/repoman/metadata.py |
4366 |
+++ /dev/null |
4367 |
@@ -1,89 +0,0 @@ |
4368 |
-# -*- coding:utf-8 -*- |
4369 |
- |
4370 |
-import errno |
4371 |
-import logging |
4372 |
-import time |
4373 |
- |
4374 |
-# import our initialized portage instance |
4375 |
-from repoman._portage import portage |
4376 |
- |
4377 |
-from portage import os |
4378 |
-from portage.output import green |
4379 |
-from portage.package.ebuild.fetch import fetch |
4380 |
- |
4381 |
- |
4382 |
-# Note: This URI is hardcoded in all metadata.xml files. We can't |
4383 |
-# change it without updating all the xml files in the tree. |
4384 |
-metadata_dtd_uri = "https://www.gentoo.org/dtd/metadata.dtd" |
4385 |
-metadata_xsd_uri = "https://www.gentoo.org/xml-schema/metadata.xsd" |
4386 |
-# force refetch if the local copy creation time is older than this |
4387 |
-metadata_xsd_ctime_interval = 60 * 60 * 24 * 7 # 7 days |
4388 |
- |
4389 |
- |
4390 |
-def fetch_metadata_xsd(metadata_xsd, repoman_settings): |
4391 |
- """ |
4392 |
- Fetch metadata.xsd if it doesn't exist or the ctime is older than |
4393 |
- metadata_xsd_ctime_interval. |
4394 |
- @rtype: bool |
4395 |
- @return: True if successful, otherwise False |
4396 |
- """ |
4397 |
- |
4398 |
- must_fetch = True |
4399 |
- metadata_xsd_st = None |
4400 |
- current_time = int(time.time()) |
4401 |
- try: |
4402 |
- metadata_xsd_st = os.stat(metadata_xsd) |
4403 |
- except EnvironmentError as e: |
4404 |
- if e.errno not in (errno.ENOENT, errno.ESTALE): |
4405 |
- raise |
4406 |
- del e |
4407 |
- else: |
4408 |
- # Trigger fetch if metadata.xsd mtime is old or clock is wrong. |
4409 |
- if abs(current_time - metadata_xsd_st.st_ctime) < metadata_xsd_ctime_interval: |
4410 |
- must_fetch = False |
4411 |
- |
4412 |
- if must_fetch: |
4413 |
- print() |
4414 |
- print( |
4415 |
- "%s the local copy of metadata.xsd " |
4416 |
- "needs to be refetched, doing that now" % green("***") |
4417 |
- ) |
4418 |
- print() |
4419 |
- |
4420 |
- if not fetch([metadata_xsd_uri], repoman_settings, force=1, try_mirrors=0): |
4421 |
- logging.error("failed to fetch metadata.xsd from '%s'" % metadata_xsd_uri) |
4422 |
- return False |
4423 |
- |
4424 |
- try: |
4425 |
- portage.util.apply_secpass_permissions( |
4426 |
- metadata_xsd, gid=portage.data.portage_gid, mode=0o664, mask=0o2 |
4427 |
- ) |
4428 |
- except portage.exception.PortageException: |
4429 |
- pass |
4430 |
- |
4431 |
- return True |
4432 |
- |
4433 |
- |
4434 |
-def get_metadata_xsd(repo_settings): |
4435 |
- """Locate and or fetch the metadata.xsd file |
4436 |
- |
4437 |
- @param repo_settings: RepoSettings instance |
4438 |
- @returns: path to the metadata.xsd file |
4439 |
- """ |
4440 |
- metadata_xsd = None |
4441 |
- paths = list(repo_settings.repo_config.eclass_db.porttrees) |
4442 |
- paths.reverse() |
4443 |
- # add the test copy |
4444 |
- paths.append("/usr/lib/portage/cnf/") |
4445 |
- for path in paths: |
4446 |
- path = os.path.join(path, "metadata/xml-schema/metadata.xsd") |
4447 |
- if os.path.exists(path): |
4448 |
- metadata_xsd = path |
4449 |
- break |
4450 |
- if metadata_xsd is None: |
4451 |
- metadata_xsd = os.path.join( |
4452 |
- repo_settings.repoman_settings["DISTDIR"], "metadata.xsd" |
4453 |
- ) |
4454 |
- |
4455 |
- fetch_metadata_xsd(metadata_xsd, repo_settings.repoman_settings) |
4456 |
- return metadata_xsd |
4457 |
|
4458 |
diff --git a/repoman/lib/repoman/modules/__init__.py b/repoman/lib/repoman/modules/__init__.py |
4459 |
deleted file mode 100644 |
4460 |
index e69de29bb..000000000 |
4461 |
|
4462 |
diff --git a/repoman/lib/repoman/modules/commit/__init__.py b/repoman/lib/repoman/modules/commit/__init__.py |
4463 |
deleted file mode 100644 |
4464 |
index e69de29bb..000000000 |
4465 |
|
4466 |
diff --git a/repoman/lib/repoman/modules/commit/manifest.py b/repoman/lib/repoman/modules/commit/manifest.py |
4467 |
deleted file mode 100644 |
4468 |
index e282ad406..000000000 |
4469 |
--- a/repoman/lib/repoman/modules/commit/manifest.py |
4470 |
+++ /dev/null |
4471 |
@@ -1,122 +0,0 @@ |
4472 |
-# -*- coding:utf-8 -*- |
4473 |
- |
4474 |
-import logging |
4475 |
- |
4476 |
-# import our initialized portage instance |
4477 |
-from repoman._portage import portage |
4478 |
- |
4479 |
-from portage import os |
4480 |
-from portage.package.ebuild.digestgen import digestgen |
4481 |
-from portage.util import writemsg_level |
4482 |
- |
4483 |
- |
4484 |
-class Manifest: |
4485 |
- """Creates as well as checks pkg Manifest entries/files""" |
4486 |
- |
4487 |
- def __init__(self, **kwargs): |
4488 |
- """Class init |
4489 |
- |
4490 |
- @param options: the run time cli options |
4491 |
- @param portdb: portdb instance |
4492 |
- @param repo_settings: repository settings instance |
4493 |
- """ |
4494 |
- self.options = kwargs.get("options") |
4495 |
- self.portdb = kwargs.get("portdb") |
4496 |
- self.repoman_settings = kwargs.get("repo_settings").repoman_settings |
4497 |
- self.generated_manifest = False |
4498 |
- |
4499 |
- def update_manifest(self, checkdir): |
4500 |
- """Perform a manifest generation for the pkg |
4501 |
- |
4502 |
- @param checkdir: the current package directory |
4503 |
- @rtype: bool |
4504 |
- @return: True if successful, False otherwise |
4505 |
- """ |
4506 |
- self.generated_manifest = False |
4507 |
- failed = False |
4508 |
- self.auto_assumed = set() |
4509 |
- fetchlist_dict = portage.FetchlistDict( |
4510 |
- checkdir, self.repoman_settings, self.portdb |
4511 |
- ) |
4512 |
- if self.options.mode == "manifest" and self.options.force: |
4513 |
- self._discard_dist_digests(checkdir, fetchlist_dict) |
4514 |
- self.repoman_settings["O"] = checkdir |
4515 |
- try: |
4516 |
- self.generated_manifest = digestgen( |
4517 |
- mysettings=self.repoman_settings, myportdb=self.portdb |
4518 |
- ) |
4519 |
- except portage.exception.PermissionDenied as e: |
4520 |
- self.generated_manifest = False |
4521 |
- writemsg_level( |
4522 |
- "!!! Permission denied: '%s'\n" % (e,), |
4523 |
- level=logging.ERROR, |
4524 |
- noiselevel=-1, |
4525 |
- ) |
4526 |
- |
4527 |
- if not self.generated_manifest: |
4528 |
- writemsg_level( |
4529 |
- "!!! Unable to generate manifest for '%s'.\n" % (checkdir,), |
4530 |
- level=logging.ERROR, |
4531 |
- noiselevel=-1, |
4532 |
- ) |
4533 |
- failed = True |
4534 |
- |
4535 |
- if self.options.mode == "manifest": |
4536 |
- if ( |
4537 |
- not failed |
4538 |
- and self.options.force |
4539 |
- and self.auto_assumed |
4540 |
- and "assume-digests" in self.repoman_settings.features |
4541 |
- ): |
4542 |
- # Show which digests were assumed despite the --force option |
4543 |
- # being given. This output will already have been shown by |
4544 |
- # digestgen() if assume-digests is not enabled, so only show |
4545 |
- # it here if assume-digests is enabled. |
4546 |
- pkgs = list(fetchlist_dict) |
4547 |
- pkgs.sort() |
4548 |
- portage.writemsg_stdout( |
4549 |
- " digest.assumed %s" |
4550 |
- % portage.output.colorize( |
4551 |
- "WARN", str(len(self.auto_assumed)).rjust(18) |
4552 |
- ) |
4553 |
- + "\n" |
4554 |
- ) |
4555 |
- for cpv in pkgs: |
4556 |
- fetchmap = fetchlist_dict[cpv] |
4557 |
- pf = portage.catsplit(cpv)[1] |
4558 |
- for distfile in sorted(fetchmap): |
4559 |
- if distfile in self.auto_assumed: |
4560 |
- portage.writemsg_stdout(" %s::%s\n" % (pf, distfile)) |
4561 |
- return not failed |
4562 |
- |
4563 |
- def _discard_dist_digests(self, checkdir, fetchlist_dict): |
4564 |
- """Discard DIST digests for files that exist in DISTDIR |
4565 |
- |
4566 |
- This method is intended to be called prior to digestgen, only for |
4567 |
- manifest mode with the --force option, in order to discard DIST |
4568 |
- digests that we intend to update. This is necessary because |
4569 |
- digestgen never replaces existing digests, since otherwise it |
4570 |
- would be too easy for ebuild developers to accidentally corrupt |
4571 |
- existing DIST digests. |
4572 |
- |
4573 |
- @param checkdir: the directory to generate the Manifest in |
4574 |
- @param fetchlist_dict: dictionary of files to fetch and/or include |
4575 |
- in the manifest |
4576 |
- """ |
4577 |
- portage._doebuild_manifest_exempt_depend += 1 |
4578 |
- try: |
4579 |
- distdir = self.repoman_settings["DISTDIR"] |
4580 |
- mf = self.repoman_settings.repositories.get_repo_for_location( |
4581 |
- os.path.dirname(os.path.dirname(checkdir)) |
4582 |
- ) |
4583 |
- mf = mf.load_manifest(checkdir, distdir, fetchlist_dict=fetchlist_dict) |
4584 |
- mf.create(requiredDistfiles=None, assumeDistHashesAlways=True) |
4585 |
- for distfiles in fetchlist_dict.values(): |
4586 |
- for distfile in distfiles: |
4587 |
- if os.path.isfile(os.path.join(distdir, distfile)): |
4588 |
- mf.fhashdict["DIST"].pop(distfile, None) |
4589 |
- else: |
4590 |
- self.auto_assumed.add(distfile) |
4591 |
- mf.write() |
4592 |
- finally: |
4593 |
- portage._doebuild_manifest_exempt_depend -= 1 |
4594 |
|
4595 |
diff --git a/repoman/lib/repoman/modules/commit/repochecks.py b/repoman/lib/repoman/modules/commit/repochecks.py |
4596 |
deleted file mode 100644 |
4597 |
index 32466021e..000000000 |
4598 |
--- a/repoman/lib/repoman/modules/commit/repochecks.py |
4599 |
+++ /dev/null |
4600 |
@@ -1,44 +0,0 @@ |
4601 |
-# -*- coding:utf-8 -*- |
4602 |
- |
4603 |
-from portage.output import red |
4604 |
- |
4605 |
-from repoman.errors import err |
4606 |
- |
4607 |
- |
4608 |
-def commit_check(repolevel, reposplit): |
4609 |
- # Check if it's in $PORTDIR/$CATEGORY/$PN , otherwise bail if commiting. |
4610 |
- # Reason for this is if they're trying to commit in just $FILESDIR/*, |
4611 |
- # the Manifest needs updating. |
4612 |
- # This check ensures that repoman knows where it is, |
4613 |
- # and the manifest recommit is at least possible. |
4614 |
- if repolevel not in [1, 2, 3]: |
4615 |
- print( |
4616 |
- red("***") |
4617 |
- + ( |
4618 |
- " Commit attempts *must* be from within a vcs checkout," |
4619 |
- " category, or package directory." |
4620 |
- ) |
4621 |
- ) |
4622 |
- print( |
4623 |
- red("***") |
4624 |
- + ( |
4625 |
- " Attempting to commit from a packages files directory" |
4626 |
- " will be blocked for instance." |
4627 |
- ) |
4628 |
- ) |
4629 |
- print( |
4630 |
- red("***") |
4631 |
- + ( |
4632 |
- " This is intended behaviour," |
4633 |
- " to ensure the manifest is recommitted for a package." |
4634 |
- ) |
4635 |
- ) |
4636 |
- print(red("***")) |
4637 |
- err( |
4638 |
- "Unable to identify level we're commiting from for %s" % "/".join(reposplit) |
4639 |
- ) |
4640 |
- |
4641 |
- |
4642 |
-def conflict_check(vcs_settings, options): |
4643 |
- if vcs_settings.vcs: |
4644 |
- conflicts = vcs_settings.status.detect_conflicts(options) |
4645 |
|
4646 |
diff --git a/repoman/lib/repoman/modules/linechecks/__init__.py b/repoman/lib/repoman/modules/linechecks/__init__.py |
4647 |
deleted file mode 100644 |
4648 |
index e69de29bb..000000000 |
4649 |
|
4650 |
diff --git a/repoman/lib/repoman/modules/linechecks/assignment/__init__.py b/repoman/lib/repoman/modules/linechecks/assignment/__init__.py |
4651 |
deleted file mode 100644 |
4652 |
index df2844cf5..000000000 |
4653 |
--- a/repoman/lib/repoman/modules/linechecks/assignment/__init__.py |
4654 |
+++ /dev/null |
4655 |
@@ -1,27 +0,0 @@ |
4656 |
-# Copyright 2015-2021 Gentoo Authors |
4657 |
-# Distributed under the terms of the GNU General Public License v2 |
4658 |
- |
4659 |
-doc = """Assignment plug-in module for repoman LineChecks. |
4660 |
-Performs assignments checks on ebuilds.""" |
4661 |
-__doc__ = doc[:] |
4662 |
- |
4663 |
- |
4664 |
-module_spec = { |
4665 |
- "name": "assignment", |
4666 |
- "description": doc, |
4667 |
- "provides": { |
4668 |
- "assignment-check": { |
4669 |
- "name": "assignment", |
4670 |
- "sourcefile": "assignment", |
4671 |
- "class": "EbuildAssignment", |
4672 |
- "description": doc, |
4673 |
- }, |
4674 |
- "eapi3-check": { |
4675 |
- "name": "eapi3assignment", |
4676 |
- "sourcefile": "assignment", |
4677 |
- "class": "Eapi3EbuildAssignment", |
4678 |
- "description": doc, |
4679 |
- }, |
4680 |
- }, |
4681 |
- "version": 1, |
4682 |
-} |
4683 |
|
4684 |
diff --git a/repoman/lib/repoman/modules/linechecks/assignment/assignment.py b/repoman/lib/repoman/modules/linechecks/assignment/assignment.py |
4685 |
deleted file mode 100644 |
4686 |
index 2fbdef7ae..000000000 |
4687 |
--- a/repoman/lib/repoman/modules/linechecks/assignment/assignment.py |
4688 |
+++ /dev/null |
4689 |
@@ -1,38 +0,0 @@ |
4690 |
-import re |
4691 |
- |
4692 |
-from portage.eapi import eapi_supports_prefix, eapi_has_broot |
4693 |
-from repoman.modules.linechecks.base import LineCheck |
4694 |
- |
4695 |
- |
4696 |
-class EbuildAssignment(LineCheck): |
4697 |
- """Ensure ebuilds don't assign to readonly variables.""" |
4698 |
- |
4699 |
- repoman_check_name = "variable.readonly" |
4700 |
- read_only_vars = "A|CATEGORY|P|P[VNRF]|PVR|D|WORKDIR|FILESDIR|FEATURES|USE" |
4701 |
- readonly_assignment = re.compile(r"^\s*(export\s+)?(%s)=" % read_only_vars) |
4702 |
- |
4703 |
- def check(self, num, line): |
4704 |
- match = self.readonly_assignment.match(line) |
4705 |
- e = None |
4706 |
- if match is not None: |
4707 |
- e = self.errors["READONLY_ASSIGNMENT_ERROR"] |
4708 |
- return e |
4709 |
- |
4710 |
- |
4711 |
-class Eapi3EbuildAssignment(EbuildAssignment): |
4712 |
- """Ensure ebuilds don't assign to readonly EAPI 3-introduced variables.""" |
4713 |
- |
4714 |
- read_only_vars = "ED|EPREFIX|EROOT" |
4715 |
- readonly_assignment = re.compile(r"\s*(export\s+)?(%s)=" % read_only_vars) |
4716 |
- |
4717 |
- def check_eapi(self, eapi): |
4718 |
- return eapi_supports_prefix(eapi) |
4719 |
- |
4720 |
- |
4721 |
-class Eapi7EbuildAssignment(EbuildAssignment): |
4722 |
- """Ensure ebuilds don't assign to readonly EAPI 7-introduced variables.""" |
4723 |
- |
4724 |
- readonly_assignment = re.compile(r"\s*(export\s+)?BROOT=") |
4725 |
- |
4726 |
- def check_eapi(self, eapi): |
4727 |
- return eapi_has_broot(eapi) |
4728 |
|
4729 |
diff --git a/repoman/lib/repoman/modules/linechecks/base.py b/repoman/lib/repoman/modules/linechecks/base.py |
4730 |
deleted file mode 100644 |
4731 |
index 851057940..000000000 |
4732 |
--- a/repoman/lib/repoman/modules/linechecks/base.py |
4733 |
+++ /dev/null |
4734 |
@@ -1,115 +0,0 @@ |
4735 |
-import logging |
4736 |
-import re |
4737 |
- |
4738 |
- |
4739 |
-class LineCheck: |
4740 |
- """Run a check on a line of an ebuild.""" |
4741 |
- |
4742 |
- """A regular expression to determine whether to ignore the line""" |
4743 |
- ignore_line = False |
4744 |
- """True if lines containing nothing more than comments with optional |
4745 |
- leading whitespace should be ignored""" |
4746 |
- ignore_comment = True |
4747 |
- |
4748 |
- def __init__(self, errors): |
4749 |
- self.errors = errors |
4750 |
- |
4751 |
- def new(self, pkg): |
4752 |
- pass |
4753 |
- |
4754 |
- def check_eapi(self, eapi): |
4755 |
- """Returns if check should be run in the given EAPI (default: True)""" |
4756 |
- return True |
4757 |
- |
4758 |
- def check(self, num, line): |
4759 |
- """Run the check on line and return error if there is one""" |
4760 |
- if self.re.match(line): |
4761 |
- return self.errors[self.error] |
4762 |
- |
4763 |
- def end(self): |
4764 |
- pass |
4765 |
- |
4766 |
- |
4767 |
-class InheritEclass(LineCheck): |
4768 |
- """ |
4769 |
- Base class for checking for missing inherits, as well as excess inherits. |
4770 |
- |
4771 |
- Args: |
4772 |
- eclass: Set to the name of your eclass. |
4773 |
- funcs: A tuple of functions that this eclass provides. |
4774 |
- comprehensive: Is the list of functions complete? |
4775 |
- exempt_eclasses: If these eclasses are inherited, disable the missing |
4776 |
- inherit check. |
4777 |
- """ |
4778 |
- |
4779 |
- def __init__( |
4780 |
- self, |
4781 |
- eclass, |
4782 |
- eclass_eapi_functions, |
4783 |
- errors, |
4784 |
- funcs=None, |
4785 |
- comprehensive=False, |
4786 |
- exempt_eclasses=None, |
4787 |
- ignore_missing=False, |
4788 |
- **kwargs |
4789 |
- ): |
4790 |
- self._eclass = eclass |
4791 |
- self._comprehensive = comprehensive |
4792 |
- self._exempt_eclasses = exempt_eclasses |
4793 |
- self._ignore_missing = ignore_missing |
4794 |
- self.errors = errors |
4795 |
- inherit_re = eclass |
4796 |
- self._eclass_eapi_functions = eclass_eapi_functions |
4797 |
- self._inherit_re = re.compile( |
4798 |
- r"^(\s*|.*[|&]\s*)\binherit\s(.*\s)?%s(\s|$)" % inherit_re |
4799 |
- ) |
4800 |
- # Match when the function is preceded only by leading whitespace, a |
4801 |
- # shell operator such as (, {, |, ||, or &&, or optional variable |
4802 |
- # setting(s). This prevents false positives in things like elog |
4803 |
- # messages, as reported in bug #413285. |
4804 |
- logging.debug("InheritEclass, eclass: %s, funcs: %s", eclass, funcs) |
4805 |
- self._func_re = re.compile( |
4806 |
- r"(^|[|&{(])\s*(\w+=.*)?\b(" + r"|".join(funcs) + r")\b" |
4807 |
- ) |
4808 |
- |
4809 |
- def new(self, pkg): |
4810 |
- self.repoman_check_name = "inherit.missing" |
4811 |
- # We can't use pkg.inherited because that tells us all the eclasses that |
4812 |
- # have been inherited and not just the ones we inherit directly. |
4813 |
- self._inherit = False |
4814 |
- self._func_call = False |
4815 |
- if self._exempt_eclasses is not None: |
4816 |
- inherited = pkg.inherited |
4817 |
- self._disabled = any(x in inherited for x in self._exempt_eclasses) |
4818 |
- else: |
4819 |
- self._disabled = False |
4820 |
- self._eapi = pkg.eapi |
4821 |
- |
4822 |
- def check(self, num, line): |
4823 |
- if not self._inherit: |
4824 |
- self._inherit = self._inherit_re.match(line) |
4825 |
- if not self._inherit: |
4826 |
- if self._disabled or self._ignore_missing: |
4827 |
- return |
4828 |
- s = self._func_re.search(line) |
4829 |
- if s is not None: |
4830 |
- func_name = s.group(3) |
4831 |
- eapi_func = self._eclass_eapi_functions.get(func_name) |
4832 |
- if eapi_func is None or not eapi_func(self._eapi): |
4833 |
- self._func_call = True |
4834 |
- return '%s.eclass not inherited, but "%s" called' % ( |
4835 |
- self._eclass, |
4836 |
- func_name, |
4837 |
- ) |
4838 |
- elif not self._func_call: |
4839 |
- self._func_call = self._func_re.search(line) |
4840 |
- |
4841 |
- def end(self): |
4842 |
- if ( |
4843 |
- not self._disabled |
4844 |
- and self._comprehensive |
4845 |
- and self._inherit |
4846 |
- and not self._func_call |
4847 |
- ): |
4848 |
- self.repoman_check_name = "inherit.unused" |
4849 |
- yield "no function called from %s.eclass; please drop" % self._eclass |
4850 |
|
4851 |
diff --git a/repoman/lib/repoman/modules/linechecks/config.py b/repoman/lib/repoman/modules/linechecks/config.py |
4852 |
deleted file mode 100644 |
4853 |
index e4275f5cc..000000000 |
4854 |
--- a/repoman/lib/repoman/modules/linechecks/config.py |
4855 |
+++ /dev/null |
4856 |
@@ -1,149 +0,0 @@ |
4857 |
-# -*- coding:utf-8 -*- |
4858 |
-# repoman: Checks |
4859 |
-# Copyright 2007-2017 Gentoo Foundation |
4860 |
-# Distributed under the terms of the GNU General Public License v2 |
4861 |
- |
4862 |
-"""This module contains functions used in Repoman to ascertain the quality |
4863 |
-and correctness of an ebuild.""" |
4864 |
- |
4865 |
-import collections |
4866 |
-import logging |
4867 |
-import os |
4868 |
-from copy import deepcopy |
4869 |
- |
4870 |
-from repoman._portage import portage |
4871 |
-from repoman.config import load_config |
4872 |
-from repoman import _not_installed |
4873 |
- |
4874 |
-# Avoid a circular import issue in py2.7 |
4875 |
-portage.proxy.lazyimport.lazyimport( |
4876 |
- globals(), |
4877 |
- "portage.util:stack_lists", |
4878 |
-) |
4879 |
- |
4880 |
- |
4881 |
-def merge(dict1, dict2): |
4882 |
- """Return a new dictionary by merging two dictionaries recursively.""" |
4883 |
- |
4884 |
- result = deepcopy(dict1) |
4885 |
- |
4886 |
- for key, value in dict2.items(): |
4887 |
- if isinstance(value, collections.Mapping): |
4888 |
- result[key] = merge(result.get(key, {}), value) |
4889 |
- else: |
4890 |
- result[key] = deepcopy(dict2[key]) |
4891 |
- |
4892 |
- return result |
4893 |
- |
4894 |
- |
4895 |
-class LineChecksConfig: |
4896 |
- """Holds our LineChecks configuration data and operation functions""" |
4897 |
- |
4898 |
- def __init__(self, repo_settings): |
4899 |
- """Class init |
4900 |
- |
4901 |
- @param repo_settings: RepoSettings instance |
4902 |
- @param configpaths: ordered list of filepaths to load |
4903 |
- """ |
4904 |
- self.repo_settings = repo_settings |
4905 |
- self.infopaths = None |
4906 |
- self.info_config = None |
4907 |
- self._config = None |
4908 |
- self.usex_supported_eapis = None |
4909 |
- self.in_iuse_supported_eapis = None |
4910 |
- self.get_libdir_supported_eapis = None |
4911 |
- self.eclass_eapi_functions = {} |
4912 |
- self.eclass_export_functions = None |
4913 |
- self.eclass_info = {} |
4914 |
- self.eclass_info_experimental_inherit = {} |
4915 |
- self.errors = {} |
4916 |
- self.set_infopaths() |
4917 |
- self.load_checks_info() |
4918 |
- |
4919 |
- def set_infopaths(self): |
4920 |
- if _not_installed: |
4921 |
- cnfdir = os.path.realpath( |
4922 |
- os.path.join( |
4923 |
- os.path.dirname( |
4924 |
- os.path.dirname( |
4925 |
- os.path.dirname(os.path.dirname(os.path.dirname(__file__))) |
4926 |
- ) |
4927 |
- ), |
4928 |
- "cnf/linechecks", |
4929 |
- ) |
4930 |
- ) |
4931 |
- else: |
4932 |
- cnfdir = os.path.join( |
4933 |
- portage.const.EPREFIX or "/", "usr/share/repoman/linechecks" |
4934 |
- ) |
4935 |
- repomanpaths = [os.path.join(cnfdir, _file_) for _file_ in os.listdir(cnfdir)] |
4936 |
- logging.debug("LineChecksConfig; repomanpaths: %s", repomanpaths) |
4937 |
- repopaths = [ |
4938 |
- os.path.join(path, "linechecks.yaml") |
4939 |
- for path in self.repo_settings.masters_list |
4940 |
- ] |
4941 |
- self.infopaths = repomanpaths + repopaths |
4942 |
- logging.debug("LineChecksConfig; configpaths: %s", self.infopaths) |
4943 |
- |
4944 |
- def load_checks_info(self, infopaths=None): |
4945 |
- """load the config files in order |
4946 |
- |
4947 |
- @param infopaths: ordered list of filepaths to load |
4948 |
- """ |
4949 |
- if infopaths: |
4950 |
- self.infopaths = infopaths |
4951 |
- elif not self.infopaths: |
4952 |
- logging.error("LineChecksConfig; Error: No linechecks.yaml files defined") |
4953 |
- |
4954 |
- configs = load_config( |
4955 |
- self.infopaths, "yaml", self.repo_settings.repoman_settings.valid_versions |
4956 |
- ) |
4957 |
- if configs == {}: |
4958 |
- logging.error( |
4959 |
- "LineChecksConfig: Failed to load a valid 'linechecks.yaml' file at paths: %s", |
4960 |
- self.infopaths, |
4961 |
- ) |
4962 |
- return False |
4963 |
- logging.debug("LineChecksConfig: linechecks.yaml configs: %s", configs) |
4964 |
- self.info_config = configs |
4965 |
- |
4966 |
- self.errors = self.info_config["errors"] |
4967 |
- self.usex_supported_eapis = self.info_config.get("usex_supported_eapis", []) |
4968 |
- self.in_iuse_supported_eapis = self.info_config.get( |
4969 |
- "in_iuse_supported_eapis", [] |
4970 |
- ) |
4971 |
- self.eclass_info_experimental_inherit = self.info_config.get( |
4972 |
- "eclass_info_experimental_inherit", [] |
4973 |
- ) |
4974 |
- self.get_libdir_supported_eapis = self.in_iuse_supported_eapis |
4975 |
- self.eclass_eapi_functions = { |
4976 |
- "usex": lambda eapi: eapi not in self.usex_supported_eapis, |
4977 |
- "in_iuse": lambda eapi: eapi not in self.in_iuse_supported_eapis, |
4978 |
- "get_libdir": lambda eapi: eapi not in self.get_libdir_supported_eapis, |
4979 |
- } |
4980 |
- |
4981 |
- # eclasses that export ${ECLASS}_src_(compile|configure|install) |
4982 |
- self.eclass_export_functions = self.info_config.get( |
4983 |
- "eclass_export_functions", [] |
4984 |
- ) |
4985 |
- |
4986 |
- self.eclass_info_experimental_inherit = self.info_config.get( |
4987 |
- "eclass_info_experimental_inherit", {} |
4988 |
- ) |
4989 |
- # These are "eclasses are the whole ebuild" type thing. |
4990 |
- try: |
4991 |
- self.eclass_info_experimental_inherit["eutils"][ |
4992 |
- "exempt_eclasses" |
4993 |
- ] = self.eclass_export_functions |
4994 |
- except KeyError: |
4995 |
- pass |
4996 |
- try: |
4997 |
- self.eclass_info_experimental_inherit["multilib"][ |
4998 |
- "exempt_eclasses" |
4999 |
- ] = self.eclass_export_functions + [ |
5000 |
- "autotools", |
5001 |
- "libtool", |
5002 |
- "multilib-minimal", |
5003 |
- ] |
5004 |
- except KeyError: |
5005 |
- pass |
5006 |
|
5007 |
diff --git a/repoman/lib/repoman/modules/linechecks/controller.py b/repoman/lib/repoman/modules/linechecks/controller.py |
5008 |
deleted file mode 100644 |
5009 |
index f4cfe2aca..000000000 |
5010 |
--- a/repoman/lib/repoman/modules/linechecks/controller.py |
5011 |
+++ /dev/null |
5012 |
@@ -1,164 +0,0 @@ |
5013 |
-import logging |
5014 |
-import operator |
5015 |
-import os |
5016 |
-import re |
5017 |
- |
5018 |
-from repoman.modules.linechecks.base import InheritEclass |
5019 |
-from repoman.modules.linechecks.config import LineChecksConfig |
5020 |
-from repoman._portage import portage |
5021 |
- |
5022 |
-# Avoid a circular import issue in py2.7 |
5023 |
-portage.proxy.lazyimport.lazyimport( |
5024 |
- globals(), |
5025 |
- "portage.module:Modules", |
5026 |
-) |
5027 |
- |
5028 |
-MODULES_PATH = os.path.dirname(__file__) |
5029 |
-# initial development debug info |
5030 |
-logging.debug("LineChecks module path: %s", MODULES_PATH) |
5031 |
- |
5032 |
- |
5033 |
-class LineCheckController: |
5034 |
- """Initializes and runs the LineCheck checks""" |
5035 |
- |
5036 |
- def __init__(self, repo_settings, linechecks): |
5037 |
- """Class init |
5038 |
- |
5039 |
- @param repo_settings: RepoSettings instance |
5040 |
- """ |
5041 |
- self.repo_settings = repo_settings |
5042 |
- self.linechecks = linechecks |
5043 |
- self.config = LineChecksConfig(repo_settings) |
5044 |
- |
5045 |
- self.controller = Modules( |
5046 |
- path=MODULES_PATH, namepath="repoman.modules.linechecks" |
5047 |
- ) |
5048 |
- logging.debug( |
5049 |
- "LineCheckController; module_names: %s", self.controller.module_names |
5050 |
- ) |
5051 |
- |
5052 |
- self._constant_checks = None |
5053 |
- |
5054 |
- self._here_doc_re = re.compile(r".*<<[-]?(\w+)\s*(>\s*\S+\s*)?$") |
5055 |
- self._ignore_comment_re = re.compile(r"^\s*#") |
5056 |
- self._continuation_re = re.compile(r"(\\)*$") |
5057 |
- |
5058 |
- def checks_init(self, experimental_inherit=False): |
5059 |
- """Initialize the main variables |
5060 |
- |
5061 |
- @param experimental_inherit boolean |
5062 |
- """ |
5063 |
- if not experimental_inherit: |
5064 |
- # Emulate the old eprefixify.defined and inherit.autotools checks. |
5065 |
- self._eclass_info = self.config.eclass_info |
5066 |
- else: |
5067 |
- self._eclass_info = self.config.eclass_info_experimental_inherit |
5068 |
- |
5069 |
- self._constant_checks = [] |
5070 |
- logging.debug("LineCheckController; modules: %s", self.linechecks) |
5071 |
- # Add in the pluggable modules |
5072 |
- for mod in self.linechecks: |
5073 |
- mod_class = self.controller.get_class(mod) |
5074 |
- logging.debug( |
5075 |
- "LineCheckController; module_name: %s, class: %s", |
5076 |
- mod, |
5077 |
- mod_class.__name__, |
5078 |
- ) |
5079 |
- self._constant_checks.append(mod_class(self.config.errors)) |
5080 |
- # Add in the InheritEclass checks |
5081 |
- logging.debug( |
5082 |
- "LineCheckController; eclass_info.items(): %s", |
5083 |
- list(self.config.eclass_info), |
5084 |
- ) |
5085 |
- for k, kwargs in self.config.eclass_info.items(): |
5086 |
- logging.debug("LineCheckController; k: %s, kwargs: %s", k, kwargs) |
5087 |
- self._constant_checks.append( |
5088 |
- InheritEclass( |
5089 |
- k, self.config.eclass_eapi_functions, self.config.errors, **kwargs |
5090 |
- ) |
5091 |
- ) |
5092 |
- |
5093 |
- def run_checks(self, contents, pkg): |
5094 |
- """Run the configured linechecks |
5095 |
- |
5096 |
- @param contents: the ebuild contents to check |
5097 |
- @param pkg: the package being checked |
5098 |
- """ |
5099 |
- if self._constant_checks is None: |
5100 |
- self.checks_init() |
5101 |
- checks = self._constant_checks |
5102 |
- here_doc_delim = None |
5103 |
- multiline = None |
5104 |
- |
5105 |
- for lc in checks: |
5106 |
- lc.new(pkg) |
5107 |
- |
5108 |
- multinum = 0 |
5109 |
- for num, line in enumerate(contents): |
5110 |
- |
5111 |
- # Check if we're inside a here-document. |
5112 |
- if here_doc_delim is not None: |
5113 |
- if here_doc_delim.match(line): |
5114 |
- here_doc_delim = None |
5115 |
- if here_doc_delim is None: |
5116 |
- here_doc = self._here_doc_re.match(line) |
5117 |
- if here_doc is not None: |
5118 |
- here_doc_delim = re.compile(r"^\s*%s$" % here_doc.group(1)) |
5119 |
- if here_doc_delim is not None: |
5120 |
- continue |
5121 |
- |
5122 |
- # Unroll multiline escaped strings so that we can check things: |
5123 |
- # inherit foo bar \ |
5124 |
- # moo \ |
5125 |
- # cow |
5126 |
- # This will merge these lines like so: |
5127 |
- # inherit foo bar moo cow |
5128 |
- # A line ending with an even number of backslashes does not count, |
5129 |
- # because the last backslash is escaped. Therefore, search for an |
5130 |
- # odd number of backslashes. |
5131 |
- line_escaped = ( |
5132 |
- operator.sub(*self._continuation_re.search(line).span()) % 2 == 1 |
5133 |
- ) |
5134 |
- if multiline: |
5135 |
- # Chop off the \ and \n bytes from the previous line. |
5136 |
- multiline = multiline[:-2] + line |
5137 |
- if not line_escaped: |
5138 |
- line = multiline |
5139 |
- num = multinum |
5140 |
- multiline = None |
5141 |
- else: |
5142 |
- continue |
5143 |
- else: |
5144 |
- if line_escaped: |
5145 |
- multinum = num |
5146 |
- multiline = line |
5147 |
- continue |
5148 |
- |
5149 |
- if not line.endswith("#nowarn\n"): |
5150 |
- # Finally we have a full line to parse. |
5151 |
- is_comment = self._ignore_comment_re.match(line) is not None |
5152 |
- for lc in checks: |
5153 |
- if is_comment and lc.ignore_comment: |
5154 |
- continue |
5155 |
- if lc.check_eapi(pkg.eapi): |
5156 |
- ignore = lc.ignore_line |
5157 |
- if not ignore or not ignore.match(line): |
5158 |
- errors = lc.check(num, line) |
5159 |
- if errors: |
5160 |
- if isinstance(errors, (tuple, list)): |
5161 |
- for error in errors: |
5162 |
- yield lc.repoman_check_name, "line %d: %s" % ( |
5163 |
- num + 1, |
5164 |
- error, |
5165 |
- ) |
5166 |
- else: |
5167 |
- yield lc.repoman_check_name, "line %d: %s" % ( |
5168 |
- num + 1, |
5169 |
- errors, |
5170 |
- ) |
5171 |
- |
5172 |
- for lc in checks: |
5173 |
- i = lc.end() |
5174 |
- if i is not None: |
5175 |
- for e in i: |
5176 |
- yield lc.repoman_check_name, e |
5177 |
|
5178 |
diff --git a/repoman/lib/repoman/modules/linechecks/depend/__init__.py b/repoman/lib/repoman/modules/linechecks/depend/__init__.py |
5179 |
deleted file mode 100644 |
5180 |
index 7fe35f968..000000000 |
5181 |
--- a/repoman/lib/repoman/modules/linechecks/depend/__init__.py |
5182 |
+++ /dev/null |
5183 |
@@ -1,21 +0,0 @@ |
5184 |
-# Copyright 2015-2021 Gentoo Authors |
5185 |
-# Distributed under the terms of the GNU General Public License v2 |
5186 |
- |
5187 |
-doc = """Depend plug-in module for repoman LineChecks. |
5188 |
-Performs dependency checks on ebuilds.""" |
5189 |
-__doc__ = doc[:] |
5190 |
- |
5191 |
- |
5192 |
-module_spec = { |
5193 |
- "name": "depend", |
5194 |
- "description": doc, |
5195 |
- "provides": { |
5196 |
- "implicit-check": { |
5197 |
- "name": "implicitdepend", |
5198 |
- "sourcefile": "implicit", |
5199 |
- "class": "ImplicitRuntimeDeps", |
5200 |
- "description": doc, |
5201 |
- }, |
5202 |
- }, |
5203 |
- "version": 1, |
5204 |
-} |
5205 |
|
5206 |
diff --git a/repoman/lib/repoman/modules/linechecks/depend/implicit.py b/repoman/lib/repoman/modules/linechecks/depend/implicit.py |
5207 |
deleted file mode 100644 |
5208 |
index 5f4c06618..000000000 |
5209 |
--- a/repoman/lib/repoman/modules/linechecks/depend/implicit.py |
5210 |
+++ /dev/null |
5211 |
@@ -1,38 +0,0 @@ |
5212 |
-import re |
5213 |
- |
5214 |
-from portage.eapi import eapi_has_implicit_rdepend |
5215 |
-from repoman.modules.linechecks.base import LineCheck |
5216 |
- |
5217 |
- |
5218 |
-class ImplicitRuntimeDeps(LineCheck): |
5219 |
- """ |
5220 |
- Detect the case where DEPEND is set and RDEPEND is unset in the ebuild, |
5221 |
- since this triggers implicit RDEPEND=$DEPEND assignment (prior to EAPI 4). |
5222 |
- """ |
5223 |
- |
5224 |
- repoman_check_name = "RDEPEND.implicit" |
5225 |
- _assignment_re = re.compile(r"^\s*(R?DEPEND)\+?=") |
5226 |
- |
5227 |
- def new(self, pkg): |
5228 |
- self._rdepend = False |
5229 |
- self._depend = False |
5230 |
- |
5231 |
- def check_eapi(self, eapi): |
5232 |
- # Beginning with EAPI 4, there is no |
5233 |
- # implicit RDEPEND=$DEPEND assignment |
5234 |
- # to be concerned with. |
5235 |
- return eapi_has_implicit_rdepend(eapi) |
5236 |
- |
5237 |
- def check(self, num, line): |
5238 |
- if not self._rdepend: |
5239 |
- m = self._assignment_re.match(line) |
5240 |
- if m is None: |
5241 |
- pass |
5242 |
- elif m.group(1) == "RDEPEND": |
5243 |
- self._rdepend = True |
5244 |
- elif m.group(1) == "DEPEND": |
5245 |
- self._depend = True |
5246 |
- |
5247 |
- def end(self): |
5248 |
- if self._depend and not self._rdepend: |
5249 |
- yield "RDEPEND is not explicitly assigned" |
5250 |
|
5251 |
diff --git a/repoman/lib/repoman/modules/linechecks/deprecated/__init__.py b/repoman/lib/repoman/modules/linechecks/deprecated/__init__.py |
5252 |
deleted file mode 100644 |
5253 |
index 593bc1d3f..000000000 |
5254 |
--- a/repoman/lib/repoman/modules/linechecks/deprecated/__init__.py |
5255 |
+++ /dev/null |
5256 |
@@ -1,46 +0,0 @@ |
5257 |
-# Copyright 2015-2021 Gentoo Authors |
5258 |
-# Distributed under the terms of the GNU General Public License v2 |
5259 |
- |
5260 |
-doc = """Deprecated plug-in module for repoman LineChecks. |
5261 |
-Performs miscelaneous deprecation checks on ebuilds not covered by |
5262 |
-specialty modules.""" |
5263 |
-__doc__ = doc[:] |
5264 |
- |
5265 |
- |
5266 |
-module_spec = { |
5267 |
- "name": "deprecated", |
5268 |
- "description": doc, |
5269 |
- "provides": { |
5270 |
- "useq-check": { |
5271 |
- "name": "useq", |
5272 |
- "sourcefile": "deprecated", |
5273 |
- "class": "DeprecatedUseq", |
5274 |
- "description": doc, |
5275 |
- }, |
5276 |
- "hasq-check": { |
5277 |
- "name": "hasq", |
5278 |
- "sourcefile": "deprecated", |
5279 |
- "class": "DeprecatedHasq", |
5280 |
- "description": doc, |
5281 |
- }, |
5282 |
- "preserve-check": { |
5283 |
- "name": "preservelib", |
5284 |
- "sourcefile": "deprecated", |
5285 |
- "class": "PreserveOldLib", |
5286 |
- "description": doc, |
5287 |
- }, |
5288 |
- "bindnow-check": { |
5289 |
- "name": "bindnow", |
5290 |
- "sourcefile": "deprecated", |
5291 |
- "class": "DeprecatedBindnowFlags", |
5292 |
- "description": doc, |
5293 |
- }, |
5294 |
- "inherit-check": { |
5295 |
- "name": "inherit", |
5296 |
- "sourcefile": "inherit", |
5297 |
- "class": "InheritDeprecated", |
5298 |
- "description": doc, |
5299 |
- }, |
5300 |
- }, |
5301 |
- "version": 1, |
5302 |
-} |
5303 |
|
5304 |
diff --git a/repoman/lib/repoman/modules/linechecks/deprecated/deprecated.py b/repoman/lib/repoman/modules/linechecks/deprecated/deprecated.py |
5305 |
deleted file mode 100644 |
5306 |
index abf7dbf42..000000000 |
5307 |
--- a/repoman/lib/repoman/modules/linechecks/deprecated/deprecated.py |
5308 |
+++ /dev/null |
5309 |
@@ -1,35 +0,0 @@ |
5310 |
-import re # pylint: disable=unused-import |
5311 |
- |
5312 |
-from repoman.modules.linechecks.base import LineCheck |
5313 |
- |
5314 |
- |
5315 |
-class DeprecatedUseq(LineCheck): |
5316 |
- """Checks for use of the deprecated useq function""" |
5317 |
- |
5318 |
- repoman_check_name = "ebuild.minorsyn" |
5319 |
- re = re.compile(r"(^|.*\b)useq\b") |
5320 |
- error = "USEQ_ERROR" |
5321 |
- |
5322 |
- |
5323 |
-class DeprecatedHasq(LineCheck): |
5324 |
- """Checks for use of the deprecated hasq function""" |
5325 |
- |
5326 |
- repoman_check_name = "ebuild.minorsyn" |
5327 |
- re = re.compile(r"(^|.*\b)hasq\b") |
5328 |
- error = "HASQ_ERROR" |
5329 |
- |
5330 |
- |
5331 |
-class PreserveOldLib(LineCheck): |
5332 |
- """Check for calls to the preserve_old_lib function reserved for system packages.""" |
5333 |
- |
5334 |
- repoman_check_name = "ebuild.minorsyn" |
5335 |
- re = re.compile(r".*preserve_old_lib") |
5336 |
- error = "PRESERVE_OLD_LIB" |
5337 |
- |
5338 |
- |
5339 |
-class DeprecatedBindnowFlags(LineCheck): |
5340 |
- """Check for calls to the deprecated bindnow-flags function.""" |
5341 |
- |
5342 |
- repoman_check_name = "ebuild.minorsyn" |
5343 |
- re = re.compile(r".*\$\(bindnow-flags\)") |
5344 |
- error = "DEPRECATED_BINDNOW_FLAGS" |
5345 |
|
5346 |
diff --git a/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py b/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py |
5347 |
deleted file mode 100644 |
5348 |
index 7d7f66d5d..000000000 |
5349 |
--- a/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py |
5350 |
+++ /dev/null |
5351 |
@@ -1,67 +0,0 @@ |
5352 |
-import re |
5353 |
- |
5354 |
-from repoman.modules.linechecks.base import LineCheck |
5355 |
- |
5356 |
- |
5357 |
-class InheritDeprecated(LineCheck): |
5358 |
- """Check if ebuild directly or indirectly inherits a deprecated eclass.""" |
5359 |
- |
5360 |
- repoman_check_name = "inherit.deprecated" |
5361 |
- |
5362 |
- # deprecated eclass : new eclass (False if no new eclass) |
5363 |
- deprecated_eclasses = { |
5364 |
- "autotools-multilib": "multilib-minimal", |
5365 |
- "autotools-utils": False, |
5366 |
- "base": False, |
5367 |
- "bash-completion": "bash-completion-r1", |
5368 |
- "boost-utils": False, |
5369 |
- "clutter": "gnome2", |
5370 |
- "cmake-utils": "cmake", |
5371 |
- "confutils": False, |
5372 |
- "distutils": "distutils-r1", |
5373 |
- "epatch": "(eapply since EAPI 6)", |
5374 |
- "fdo-mime": "xdg-utils", |
5375 |
- "games": False, |
5376 |
- "gems": "ruby-fakegem", |
5377 |
- "git-2": "git-r3", |
5378 |
- "gpe": False, |
5379 |
- "gst-plugins-bad": "gstreamer", |
5380 |
- "gst-plugins-base": "gstreamer", |
5381 |
- "gst-plugins-good": "gstreamer", |
5382 |
- "gst-plugins-ugly": "gstreamer", |
5383 |
- "gst-plugins10": "gstreamer", |
5384 |
- "ltprune": False, |
5385 |
- "mono": "mono-env", |
5386 |
- "python": "python-r1 / python-single-r1 / python-any-r1", |
5387 |
- "ruby": "ruby-ng", |
5388 |
- "user": "GLEP 81", |
5389 |
- "versionator": "eapi7-ver (built-in since EAPI 7)", |
5390 |
- "x-modular": "xorg-2", |
5391 |
- "xfconf": False, |
5392 |
- } |
5393 |
- |
5394 |
- _inherit_re = re.compile(r"^\s*inherit\s(.*)$") |
5395 |
- |
5396 |
- def check(self, num, line): |
5397 |
- direct_inherits = None |
5398 |
- m = self._inherit_re.match(line) |
5399 |
- if m is not None: |
5400 |
- direct_inherits = m.group(1) |
5401 |
- if direct_inherits: |
5402 |
- direct_inherits = direct_inherits.split() |
5403 |
- |
5404 |
- if not direct_inherits: |
5405 |
- return |
5406 |
- |
5407 |
- errors = [] |
5408 |
- for eclass in direct_inherits: |
5409 |
- replacement = self.deprecated_eclasses.get(eclass) |
5410 |
- if replacement is None: |
5411 |
- pass |
5412 |
- elif replacement is False: |
5413 |
- errors.append("please migrate from " "'%s' (no replacement)" % eclass) |
5414 |
- else: |
5415 |
- errors.append( |
5416 |
- "please migrate from " "'%s' to '%s'" % (eclass, replacement) |
5417 |
- ) |
5418 |
- return errors |
5419 |
|
5420 |
diff --git a/repoman/lib/repoman/modules/linechecks/do/__init__.py b/repoman/lib/repoman/modules/linechecks/do/__init__.py |
5421 |
deleted file mode 100644 |
5422 |
index 597b961e7..000000000 |
5423 |
--- a/repoman/lib/repoman/modules/linechecks/do/__init__.py |
5424 |
+++ /dev/null |
5425 |
@@ -1,21 +0,0 @@ |
5426 |
-# Copyright 2015-2021 Gentoo Authors |
5427 |
-# Distributed under the terms of the GNU General Public License v2 |
5428 |
- |
5429 |
-doc = """Do plug-in module for repoman LineChecks. |
5430 |
-Performs do* checks on ebuilds.""" |
5431 |
-__doc__ = doc[:] |
5432 |
- |
5433 |
- |
5434 |
-module_spec = { |
5435 |
- "name": "do", |
5436 |
- "description": doc, |
5437 |
- "provides": { |
5438 |
- "nonrelative-check": { |
5439 |
- "name": "dosym", |
5440 |
- "sourcefile": "dosym", |
5441 |
- "class": "EbuildNonRelativeDosym", |
5442 |
- "description": doc, |
5443 |
- }, |
5444 |
- }, |
5445 |
- "version": 1, |
5446 |
-} |
5447 |
|
5448 |
diff --git a/repoman/lib/repoman/modules/linechecks/do/dosym.py b/repoman/lib/repoman/modules/linechecks/do/dosym.py |
5449 |
deleted file mode 100644 |
5450 |
index 2276b3315..000000000 |
5451 |
--- a/repoman/lib/repoman/modules/linechecks/do/dosym.py |
5452 |
+++ /dev/null |
5453 |
@@ -1,20 +0,0 @@ |
5454 |
-import re |
5455 |
- |
5456 |
-from repoman.modules.linechecks.base import LineCheck |
5457 |
- |
5458 |
- |
5459 |
-class EbuildNonRelativeDosym(LineCheck): |
5460 |
- """Check ebuild for dosym using absolute paths instead of relative.""" |
5461 |
- |
5462 |
- repoman_check_name = "ebuild.absdosym" |
5463 |
- variables = ("D", "ED", "ROOT", "EROOT", "BROOT") |
5464 |
- regex = re.compile( |
5465 |
- r'^\s*dosym\s+(["\']?((\$(%s)\W|\${(%s)(%%/)?})|/(bin|etc|lib|opt|sbin|srv|usr|var))\S*)' |
5466 |
- % ("|".join(variables), "|".join(variables)), |
5467 |
- getattr(re, "ASCII", 0), |
5468 |
- ) |
5469 |
- |
5470 |
- def check(self, num, line): |
5471 |
- match = self.regex.match(line) |
5472 |
- if match: |
5473 |
- return "dosym '%s'... could use relative path" % match.group(1) |
5474 |
|
5475 |
diff --git a/repoman/lib/repoman/modules/linechecks/eapi/__init__.py b/repoman/lib/repoman/modules/linechecks/eapi/__init__.py |
5476 |
deleted file mode 100644 |
5477 |
index 68e6b722a..000000000 |
5478 |
--- a/repoman/lib/repoman/modules/linechecks/eapi/__init__.py |
5479 |
+++ /dev/null |
5480 |
@@ -1,51 +0,0 @@ |
5481 |
-# Copyright 2015-2021 Gentoo Authors |
5482 |
-# Distributed under the terms of the GNU General Public License v2 |
5483 |
- |
5484 |
-doc = """Eapi plug-in module for repoman LineChecks. |
5485 |
-Performs eapi dependant checks on ebuilds.""" |
5486 |
-__doc__ = doc[:] |
5487 |
- |
5488 |
- |
5489 |
-module_spec = { |
5490 |
- "name": "eapi", |
5491 |
- "description": doc, |
5492 |
- "provides": { |
5493 |
- "definition-check": { |
5494 |
- "name": "definition", |
5495 |
- "sourcefile": "definition", |
5496 |
- "class": "EapiDefinition", |
5497 |
- "description": doc, |
5498 |
- }, |
5499 |
- "srcprepare-check": { |
5500 |
- "name": "srcprepare", |
5501 |
- "sourcefile": "checks", |
5502 |
- "class": "UndefinedSrcPrepareSrcConfigurePhases", |
5503 |
- "description": doc, |
5504 |
- }, |
5505 |
- "eapi3deprecated-check": { |
5506 |
- "name": "eapi3deprecated", |
5507 |
- "sourcefile": "checks", |
5508 |
- "class": "Eapi3DeprecatedFuncs", |
5509 |
- "description": doc, |
5510 |
- }, |
5511 |
- "pkgpretend-check": { |
5512 |
- "name": "pkgpretend", |
5513 |
- "sourcefile": "checks", |
5514 |
- "class": "UndefinedPkgPretendPhase", |
5515 |
- "description": doc, |
5516 |
- }, |
5517 |
- "eapi4incompatible-check": { |
5518 |
- "name": "eapi4incompatible", |
5519 |
- "sourcefile": "checks", |
5520 |
- "class": "Eapi4IncompatibleFuncs", |
5521 |
- "description": doc, |
5522 |
- }, |
5523 |
- "eapi4gonevars-check": { |
5524 |
- "name": "eapi4gonevars", |
5525 |
- "sourcefile": "checks", |
5526 |
- "class": "Eapi4GoneVars", |
5527 |
- "description": doc, |
5528 |
- }, |
5529 |
- }, |
5530 |
- "version": 1, |
5531 |
-} |
5532 |
|
5533 |
diff --git a/repoman/lib/repoman/modules/linechecks/eapi/checks.py b/repoman/lib/repoman/modules/linechecks/eapi/checks.py |
5534 |
deleted file mode 100644 |
5535 |
index 64bb509a7..000000000 |
5536 |
--- a/repoman/lib/repoman/modules/linechecks/eapi/checks.py |
5537 |
+++ /dev/null |
5538 |
@@ -1,79 +0,0 @@ |
5539 |
-import re |
5540 |
- |
5541 |
-from portage.eapi import ( |
5542 |
- eapi_has_src_prepare_and_src_configure, |
5543 |
- eapi_has_dosed_dohard, |
5544 |
- eapi_exports_AA, |
5545 |
- eapi_has_pkg_pretend, |
5546 |
-) |
5547 |
-from repoman.modules.linechecks.base import LineCheck |
5548 |
- |
5549 |
- |
5550 |
-# EAPI <2 checks |
5551 |
-class UndefinedSrcPrepareSrcConfigurePhases(LineCheck): |
5552 |
- repoman_check_name = "EAPI.incompatible" |
5553 |
- src_configprepare_re = re.compile(r"\s*(src_configure|src_prepare)\s*\(\)") |
5554 |
- |
5555 |
- def check_eapi(self, eapi): |
5556 |
- return not eapi_has_src_prepare_and_src_configure(eapi) |
5557 |
- |
5558 |
- def check(self, num, line): |
5559 |
- m = self.src_configprepare_re.match(line) |
5560 |
- if m is not None: |
5561 |
- return ("'%s'" % m.group(1)) + " phase is not defined in EAPI < 2" |
5562 |
- |
5563 |
- |
5564 |
-# EAPI-3 checks |
5565 |
-class Eapi3DeprecatedFuncs(LineCheck): |
5566 |
- repoman_check_name = "EAPI.deprecated" |
5567 |
- deprecated_commands_re = re.compile(r"^\s*(check_license)\b") |
5568 |
- |
5569 |
- def check_eapi(self, eapi): |
5570 |
- return eapi not in ("0", "1", "2") |
5571 |
- |
5572 |
- def check(self, num, line): |
5573 |
- m = self.deprecated_commands_re.match(line) |
5574 |
- if m is not None: |
5575 |
- return ("'%s'" % m.group(1)) + " has been deprecated in EAPI=3" |
5576 |
- |
5577 |
- |
5578 |
-# EAPI <4 checks |
5579 |
-class UndefinedPkgPretendPhase(LineCheck): |
5580 |
- repoman_check_name = "EAPI.incompatible" |
5581 |
- pkg_pretend_re = re.compile(r"\s*(pkg_pretend)\s*\(\)") |
5582 |
- |
5583 |
- def check_eapi(self, eapi): |
5584 |
- return not eapi_has_pkg_pretend(eapi) |
5585 |
- |
5586 |
- def check(self, num, line): |
5587 |
- m = self.pkg_pretend_re.match(line) |
5588 |
- if m is not None: |
5589 |
- return ("'%s'" % m.group(1)) + " phase is not defined in EAPI < 4" |
5590 |
- |
5591 |
- |
5592 |
-# EAPI-4 checks |
5593 |
-class Eapi4IncompatibleFuncs(LineCheck): |
5594 |
- repoman_check_name = "EAPI.incompatible" |
5595 |
- banned_commands_re = re.compile(r"^\s*(dosed|dohard)") |
5596 |
- |
5597 |
- def check_eapi(self, eapi): |
5598 |
- return not eapi_has_dosed_dohard(eapi) |
5599 |
- |
5600 |
- def check(self, num, line): |
5601 |
- m = self.banned_commands_re.match(line) |
5602 |
- if m is not None: |
5603 |
- return ("'%s'" % m.group(1)) + " has been banned in EAPI=4" |
5604 |
- |
5605 |
- |
5606 |
-class Eapi4GoneVars(LineCheck): |
5607 |
- repoman_check_name = "EAPI.incompatible" |
5608 |
- undefined_vars_re = re.compile(r".*\$(\{(AA|KV|EMERGE_FROM)\}|(AA|KV|EMERGE_FROM))") |
5609 |
- |
5610 |
- def check_eapi(self, eapi): |
5611 |
- # AA, KV, and EMERGE_FROM should not be referenced in EAPI 4 or later. |
5612 |
- return not eapi_exports_AA(eapi) |
5613 |
- |
5614 |
- def check(self, num, line): |
5615 |
- m = self.undefined_vars_re.match(line) |
5616 |
- if m is not None: |
5617 |
- return ("variable '$%s'" % m.group(1)) + " is gone in EAPI=4" |
5618 |
|
5619 |
diff --git a/repoman/lib/repoman/modules/linechecks/eapi/definition.py b/repoman/lib/repoman/modules/linechecks/eapi/definition.py |
5620 |
deleted file mode 100644 |
5621 |
index 964fa4ea3..000000000 |
5622 |
--- a/repoman/lib/repoman/modules/linechecks/eapi/definition.py |
5623 |
+++ /dev/null |
5624 |
@@ -1,35 +0,0 @@ |
5625 |
-from repoman.modules.linechecks.base import LineCheck |
5626 |
-from repoman._portage import portage |
5627 |
- |
5628 |
- |
5629 |
-class EapiDefinition(LineCheck): |
5630 |
- """ |
5631 |
- Check that EAPI assignment conforms to PMS section 7.3.1 |
5632 |
- (first non-comment, non-blank line). |
5633 |
- """ |
5634 |
- |
5635 |
- repoman_check_name = "EAPI.definition" |
5636 |
- ignore_comment = True |
5637 |
- _eapi_re = portage._pms_eapi_re |
5638 |
- |
5639 |
- def new(self, pkg): |
5640 |
- self._cached_eapi = pkg.eapi |
5641 |
- self._parsed_eapi = None |
5642 |
- self._eapi_line_num = None |
5643 |
- |
5644 |
- def check(self, num, line): |
5645 |
- if self._eapi_line_num is None and line.strip(): |
5646 |
- self._eapi_line_num = num + 1 |
5647 |
- m = self._eapi_re.match(line) |
5648 |
- if m is not None: |
5649 |
- self._parsed_eapi = m.group(2) |
5650 |
- |
5651 |
- def end(self): |
5652 |
- if self._parsed_eapi is None: |
5653 |
- if self._cached_eapi != "0": |
5654 |
- yield "valid EAPI assignment must occur on or before line: %s" % self._eapi_line_num |
5655 |
- elif self._parsed_eapi != self._cached_eapi: |
5656 |
- yield ( |
5657 |
- "bash returned EAPI '%s' which does not match " |
5658 |
- "assignment on line: %s" % (self._cached_eapi, self._eapi_line_num) |
5659 |
- ) |
5660 |
|
5661 |
diff --git a/repoman/lib/repoman/modules/linechecks/emake/__init__.py b/repoman/lib/repoman/modules/linechecks/emake/__init__.py |
5662 |
deleted file mode 100644 |
5663 |
index 9a2c54915..000000000 |
5664 |
--- a/repoman/lib/repoman/modules/linechecks/emake/__init__.py |
5665 |
+++ /dev/null |
5666 |
@@ -1,27 +0,0 @@ |
5667 |
-# Copyright 2015-2021 Gentoo Authors |
5668 |
-# Distributed under the terms of the GNU General Public License v2 |
5669 |
- |
5670 |
-doc = """Emake plug-in module for repoman LineChecks. |
5671 |
-Performs emake checks on ebuilds.""" |
5672 |
-__doc__ = doc[:] |
5673 |
- |
5674 |
- |
5675 |
-module_spec = { |
5676 |
- "name": "do", |
5677 |
- "description": doc, |
5678 |
- "provides": { |
5679 |
- "paralleldisabled-check": { |
5680 |
- "name": "paralleldisabled", |
5681 |
- "sourcefile": "emake", |
5682 |
- "class": "EMakeParallelDisabledViaMAKEOPTS", |
5683 |
- "description": doc, |
5684 |
- }, |
5685 |
- "autodefault-check": { |
5686 |
- "name": "autodefault", |
5687 |
- "sourcefile": "emake", |
5688 |
- "class": "WantAutoDefaultValue", |
5689 |
- "description": doc, |
5690 |
- }, |
5691 |
- }, |
5692 |
- "version": 1, |
5693 |
-} |
5694 |
|
5695 |
diff --git a/repoman/lib/repoman/modules/linechecks/emake/emake.py b/repoman/lib/repoman/modules/linechecks/emake/emake.py |
5696 |
deleted file mode 100644 |
5697 |
index 3bb7fc35b..000000000 |
5698 |
--- a/repoman/lib/repoman/modules/linechecks/emake/emake.py |
5699 |
+++ /dev/null |
5700 |
@@ -1,25 +0,0 @@ |
5701 |
-import re |
5702 |
- |
5703 |
-from repoman.modules.linechecks.base import LineCheck |
5704 |
- |
5705 |
- |
5706 |
-class EMakeParallelDisabledViaMAKEOPTS(LineCheck): |
5707 |
- """Check for MAKEOPTS=-j1 that disables parallelization.""" |
5708 |
- |
5709 |
- repoman_check_name = "upstream.workaround" |
5710 |
- re = re.compile(r'^\s*MAKEOPTS=(\'|")?.*-j\s*1\b') |
5711 |
- error = "EMAKE_PARALLEL_DISABLED_VIA_MAKEOPTS" |
5712 |
- |
5713 |
- |
5714 |
-class WantAutoDefaultValue(LineCheck): |
5715 |
- """Check setting WANT_AUTO* to latest (default value).""" |
5716 |
- |
5717 |
- repoman_check_name = "ebuild.minorsyn" |
5718 |
- _re = re.compile(r'^WANT_AUTO(CONF|MAKE)=(\'|")?latest') |
5719 |
- |
5720 |
- def check(self, num, line): |
5721 |
- m = self._re.match(line) |
5722 |
- if m is not None: |
5723 |
- return ( |
5724 |
- "WANT_AUTO" + m.group(1) + ' redundantly set to default value "latest"' |
5725 |
- ) |
5726 |
|
5727 |
diff --git a/repoman/lib/repoman/modules/linechecks/gentoo_header/__init__.py b/repoman/lib/repoman/modules/linechecks/gentoo_header/__init__.py |
5728 |
deleted file mode 100644 |
5729 |
index 565b43ec2..000000000 |
5730 |
--- a/repoman/lib/repoman/modules/linechecks/gentoo_header/__init__.py |
5731 |
+++ /dev/null |
5732 |
@@ -1,21 +0,0 @@ |
5733 |
-# Copyright 2015-2021 Gentoo Authors |
5734 |
-# Distributed under the terms of the GNU General Public License v2 |
5735 |
- |
5736 |
-doc = """Gentoo-header plug-in module for repoman LineChecks. |
5737 |
-Performs header checks on ebuilds.""" |
5738 |
-__doc__ = doc[:] |
5739 |
- |
5740 |
- |
5741 |
-module_spec = { |
5742 |
- "name": "do", |
5743 |
- "description": doc, |
5744 |
- "provides": { |
5745 |
- "header-check": { |
5746 |
- "name": "gentooheader", |
5747 |
- "sourcefile": "header", |
5748 |
- "class": "EbuildHeader", |
5749 |
- "description": doc, |
5750 |
- }, |
5751 |
- }, |
5752 |
- "version": 1, |
5753 |
-} |
5754 |
|
5755 |
diff --git a/repoman/lib/repoman/modules/linechecks/gentoo_header/header.py b/repoman/lib/repoman/modules/linechecks/gentoo_header/header.py |
5756 |
deleted file mode 100644 |
5757 |
index 7ef77ae44..000000000 |
5758 |
--- a/repoman/lib/repoman/modules/linechecks/gentoo_header/header.py |
5759 |
+++ /dev/null |
5760 |
@@ -1,56 +0,0 @@ |
5761 |
-import re |
5762 |
-import time |
5763 |
- |
5764 |
-from repoman.modules.linechecks.base import LineCheck |
5765 |
- |
5766 |
- |
5767 |
-class EbuildHeader(LineCheck): |
5768 |
- """Ensure ebuilds have proper headers |
5769 |
- Copyright header errors |
5770 |
- CVS header errors |
5771 |
- License header errors |
5772 |
- |
5773 |
- Args: |
5774 |
- modification_year - Year the ebuild was last modified |
5775 |
- """ |
5776 |
- |
5777 |
- repoman_check_name = "ebuild.badheader" |
5778 |
- |
5779 |
- gentoo_copyright = r"^# Copyright ((1999|2\d\d\d)-)?(?P<year2>%s) (?P<author>.*)$" |
5780 |
- gentoo_license = ( |
5781 |
- "# Distributed under the terms" " of the GNU General Public License v2" |
5782 |
- ) |
5783 |
- id_header_re = re.compile(r".*\$(Id|Header)(:.*)?\$.*") |
5784 |
- blank_line_re = re.compile(r"^$") |
5785 |
- ignore_comment = False |
5786 |
- |
5787 |
- def new(self, pkg): |
5788 |
- if pkg.mtime is None: |
5789 |
- self.modification_year = r"2\d\d\d" |
5790 |
- else: |
5791 |
- self.modification_year = str(time.gmtime(pkg.mtime)[0]) |
5792 |
- self.gentoo_copyright_re = re.compile( |
5793 |
- self.gentoo_copyright % self.modification_year |
5794 |
- ) |
5795 |
- |
5796 |
- def check(self, num, line): |
5797 |
- if num > 2: |
5798 |
- return |
5799 |
- elif num == 0: |
5800 |
- match = self.gentoo_copyright_re.match(line) |
5801 |
- if match is None: |
5802 |
- return self.errors["COPYRIGHT_ERROR"] |
5803 |
- if not ( |
5804 |
- match.group("author") == "Gentoo Authors" |
5805 |
- or ( |
5806 |
- int(match.group("year2")) < 2019 |
5807 |
- and match.group("author") == "Gentoo Foundation" |
5808 |
- ) |
5809 |
- ): |
5810 |
- return self.errors["COPYRIGHT_ERROR"] |
5811 |
- elif num == 1 and line.rstrip("\n") != self.gentoo_license: |
5812 |
- return self.errors["LICENSE_ERROR"] |
5813 |
- elif num == 2 and self.id_header_re.match(line): |
5814 |
- return self.errors["ID_HEADER_ERROR"] |
5815 |
- elif num == 2 and not self.blank_line_re.match(line): |
5816 |
- return self.errors["NO_BLANK_LINE_ERROR"] |
5817 |
|
5818 |
diff --git a/repoman/lib/repoman/modules/linechecks/helpers/__init__.py b/repoman/lib/repoman/modules/linechecks/helpers/__init__.py |
5819 |
deleted file mode 100644 |
5820 |
index b65b454f1..000000000 |
5821 |
--- a/repoman/lib/repoman/modules/linechecks/helpers/__init__.py |
5822 |
+++ /dev/null |
5823 |
@@ -1,21 +0,0 @@ |
5824 |
-# Copyright 2015-2021 Gentoo Authors |
5825 |
-# Distributed under the terms of the GNU General Public License v2 |
5826 |
- |
5827 |
-doc = """Helpers plug-in module for repoman LineChecks. |
5828 |
-Performs variable helpers checks on ebuilds.""" |
5829 |
-__doc__ = doc[:] |
5830 |
- |
5831 |
- |
5832 |
-module_spec = { |
5833 |
- "name": "do", |
5834 |
- "description": doc, |
5835 |
- "provides": { |
5836 |
- "nooffset-check": { |
5837 |
- "name": "nooffset", |
5838 |
- "sourcefile": "offset", |
5839 |
- "class": "NoOffsetWithHelpers", |
5840 |
- "description": doc, |
5841 |
- }, |
5842 |
- }, |
5843 |
- "version": 1, |
5844 |
-} |
5845 |
|
5846 |
diff --git a/repoman/lib/repoman/modules/linechecks/helpers/offset.py b/repoman/lib/repoman/modules/linechecks/helpers/offset.py |
5847 |
deleted file mode 100644 |
5848 |
index 72ece48d5..000000000 |
5849 |
--- a/repoman/lib/repoman/modules/linechecks/helpers/offset.py |
5850 |
+++ /dev/null |
5851 |
@@ -1,21 +0,0 @@ |
5852 |
-import re # pylint: disable=unused-import |
5853 |
- |
5854 |
-from repoman.modules.linechecks.base import LineCheck |
5855 |
- |
5856 |
- |
5857 |
-class NoOffsetWithHelpers(LineCheck): |
5858 |
- """Check that the image location, the alternate root offset, and the |
5859 |
- offset prefix (D, ROOT, ED, EROOT and EPREFIX) are not used with |
5860 |
- helpers""" |
5861 |
- |
5862 |
- repoman_check_name = "variable.usedwithhelpers" |
5863 |
- # Ignore matches in quoted strings like this: |
5864 |
- # elog "installed into ${ROOT}usr/share/php5/apc/." |
5865 |
- _install_funcs = ( |
5866 |
- "docinto|do(compress|dir|hard)" "|exeinto|fowners|fperms|insinto|into" |
5867 |
- ) |
5868 |
- _quoted_vars = "D|ROOT|ED|EROOT|EPREFIX" |
5869 |
- re = re.compile( |
5870 |
- r'^[^#"\']*\b(%s)\s+"?\$\{?(%s)\b.*' % (_install_funcs, _quoted_vars) |
5871 |
- ) |
5872 |
- error = "NO_OFFSET_WITH_HELPERS" |
5873 |
|
5874 |
diff --git a/repoman/lib/repoman/modules/linechecks/nested/__init__.py b/repoman/lib/repoman/modules/linechecks/nested/__init__.py |
5875 |
deleted file mode 100644 |
5876 |
index 83d69127d..000000000 |
5877 |
--- a/repoman/lib/repoman/modules/linechecks/nested/__init__.py |
5878 |
+++ /dev/null |
5879 |
@@ -1,21 +0,0 @@ |
5880 |
-# Copyright 2015-2021 Gentoo Authors |
5881 |
-# Distributed under the terms of the GNU General Public License v2 |
5882 |
- |
5883 |
-doc = """Nested plug-in module for repoman LineChecks. |
5884 |
-Performs nested subshell checks on ebuilds.""" |
5885 |
-__doc__ = doc[:] |
5886 |
- |
5887 |
- |
5888 |
-module_spec = { |
5889 |
- "name": "do", |
5890 |
- "description": doc, |
5891 |
- "provides": { |
5892 |
- "nesteddie-check": { |
5893 |
- "name": "nesteddie", |
5894 |
- "sourcefile": "nested", |
5895 |
- "class": "EbuildNestedDie", |
5896 |
- "description": doc, |
5897 |
- }, |
5898 |
- }, |
5899 |
- "version": 1, |
5900 |
-} |
5901 |
|
5902 |
diff --git a/repoman/lib/repoman/modules/linechecks/nested/nested.py b/repoman/lib/repoman/modules/linechecks/nested/nested.py |
5903 |
deleted file mode 100644 |
5904 |
index fc04bde01..000000000 |
5905 |
--- a/repoman/lib/repoman/modules/linechecks/nested/nested.py |
5906 |
+++ /dev/null |
5907 |
@@ -1,14 +0,0 @@ |
5908 |
-import re |
5909 |
- |
5910 |
-from repoman.modules.linechecks.base import LineCheck |
5911 |
- |
5912 |
- |
5913 |
-class EbuildNestedDie(LineCheck): |
5914 |
- """Check ebuild for nested die statements (die statements in subshells)""" |
5915 |
- |
5916 |
- repoman_check_name = "ebuild.nesteddie" |
5917 |
- nesteddie_re = re.compile(r"^[^#]*\s\(\s[^)]*\bdie\b") |
5918 |
- |
5919 |
- def check(self, num, line): |
5920 |
- if self.nesteddie_re.match(line): |
5921 |
- return self.errors["NESTED_DIE_ERROR"] |
5922 |
|
5923 |
diff --git a/repoman/lib/repoman/modules/linechecks/nested/nesteddie.py b/repoman/lib/repoman/modules/linechecks/nested/nesteddie.py |
5924 |
deleted file mode 100644 |
5925 |
index 4b256bb1f..000000000 |
5926 |
--- a/repoman/lib/repoman/modules/linechecks/nested/nesteddie.py |
5927 |
+++ /dev/null |
5928 |
@@ -1,9 +0,0 @@ |
5929 |
-class EbuildNestedDie(LineCheck): |
5930 |
- """Check ebuild for nested die statements (die statements in subshells)""" |
5931 |
- |
5932 |
- repoman_check_name = "ebuild.nesteddie" |
5933 |
- nesteddie_re = re.compile(r"^[^#]*\s\(\s[^)]*\bdie\b") |
5934 |
- |
5935 |
- def check(self, num, line): |
5936 |
- if self.nesteddie_re.match(line): |
5937 |
- return errors.NESTED_DIE_ERROR |
5938 |
|
5939 |
diff --git a/repoman/lib/repoman/modules/linechecks/patches/__init__.py b/repoman/lib/repoman/modules/linechecks/patches/__init__.py |
5940 |
deleted file mode 100644 |
5941 |
index e4aec16a1..000000000 |
5942 |
--- a/repoman/lib/repoman/modules/linechecks/patches/__init__.py |
5943 |
+++ /dev/null |
5944 |
@@ -1,21 +0,0 @@ |
5945 |
-# Copyright 2015-2021 Gentoo Authors |
5946 |
-# Distributed under the terms of the GNU General Public License v2 |
5947 |
- |
5948 |
-doc = """Patches plug-in module for repoman LineChecks. |
5949 |
-Performs PATCHES variable checks on ebuilds.""" |
5950 |
-__doc__ = doc[:] |
5951 |
- |
5952 |
- |
5953 |
-module_spec = { |
5954 |
- "name": "do", |
5955 |
- "description": doc, |
5956 |
- "provides": { |
5957 |
- "patches-check": { |
5958 |
- "name": "patches", |
5959 |
- "sourcefile": "patches", |
5960 |
- "class": "EbuildPatches", |
5961 |
- "description": doc, |
5962 |
- }, |
5963 |
- }, |
5964 |
- "version": 1, |
5965 |
-} |
5966 |
|
5967 |
diff --git a/repoman/lib/repoman/modules/linechecks/patches/patches.py b/repoman/lib/repoman/modules/linechecks/patches/patches.py |
5968 |
deleted file mode 100644 |
5969 |
index ca9a4cada..000000000 |
5970 |
--- a/repoman/lib/repoman/modules/linechecks/patches/patches.py |
5971 |
+++ /dev/null |
5972 |
@@ -1,22 +0,0 @@ |
5973 |
-import re # pylint: disable=unused-import |
5974 |
- |
5975 |
-from repoman.modules.linechecks.base import LineCheck |
5976 |
- |
5977 |
- |
5978 |
-class EbuildPatches(LineCheck): |
5979 |
- """Ensure ebuilds use bash arrays for PATCHES to ensure white space safety""" |
5980 |
- |
5981 |
- repoman_check_name = "ebuild.patches" |
5982 |
- re = re.compile(r"^\s*PATCHES=[^\(]") |
5983 |
- error = "PATCHES_ERROR" |
5984 |
- |
5985 |
- def check_eapi(self, eapi): |
5986 |
- return eapi in ( |
5987 |
- "0", |
5988 |
- "1", |
5989 |
- "2", |
5990 |
- "3", |
5991 |
- "4", |
5992 |
- "4-slot-abi", |
5993 |
- "5", |
5994 |
- ) |
5995 |
|
5996 |
diff --git a/repoman/lib/repoman/modules/linechecks/phases/__init__.py b/repoman/lib/repoman/modules/linechecks/phases/__init__.py |
5997 |
deleted file mode 100644 |
5998 |
index 880eac02b..000000000 |
5999 |
--- a/repoman/lib/repoman/modules/linechecks/phases/__init__.py |
6000 |
+++ /dev/null |
6001 |
@@ -1,40 +0,0 @@ |
6002 |
-# Copyright 2015-2021 Gentoo Authors |
6003 |
-# Distributed under the terms of the GNU General Public License v2 |
6004 |
- |
6005 |
-doc = """Phases plug-in module for repoman LineChecks. |
6006 |
-Performs phase dependant checks on ebuilds using a PhaseCheck base class. |
6007 |
-""" |
6008 |
-__doc__ = doc[:] |
6009 |
- |
6010 |
- |
6011 |
-module_spec = { |
6012 |
- "name": "do", |
6013 |
- "description": doc, |
6014 |
- "provides": { |
6015 |
- "emakeparallel-check": { |
6016 |
- "name": "emakeparallel", |
6017 |
- "sourcefile": "phase", |
6018 |
- "class": "EMakeParallelDisabled", |
6019 |
- "description": doc, |
6020 |
- }, |
6021 |
- "srccompileeconf-check": { |
6022 |
- "name": "srccompileeconf", |
6023 |
- "sourcefile": "phase", |
6024 |
- "class": "SrcCompileEconf", |
6025 |
- "description": doc, |
6026 |
- }, |
6027 |
- "srcunpackpatches-check": { |
6028 |
- "name": "srcunpackpatches", |
6029 |
- "sourcefile": "phase", |
6030 |
- "class": "SrcUnpackPatches", |
6031 |
- "description": doc, |
6032 |
- }, |
6033 |
- "pmsvariablerefphasescope-check": { |
6034 |
- "name": "pmsvariablerefphasescope", |
6035 |
- "sourcefile": "phase", |
6036 |
- "class": "PMSVariableReference", |
6037 |
- "description": doc, |
6038 |
- }, |
6039 |
- }, |
6040 |
- "version": 1, |
6041 |
-} |
6042 |
|
6043 |
diff --git a/repoman/lib/repoman/modules/linechecks/phases/phase.py b/repoman/lib/repoman/modules/linechecks/phases/phase.py |
6044 |
deleted file mode 100644 |
6045 |
index 5d89b263d..000000000 |
6046 |
--- a/repoman/lib/repoman/modules/linechecks/phases/phase.py |
6047 |
+++ /dev/null |
6048 |
@@ -1,188 +0,0 @@ |
6049 |
-import fnmatch |
6050 |
-import re |
6051 |
-import types |
6052 |
- |
6053 |
-from portage.eapi import ( |
6054 |
- eapi_has_broot, |
6055 |
- eapi_has_sysroot, |
6056 |
- eapi_has_src_prepare_and_src_configure, |
6057 |
- eapi_exports_AA, |
6058 |
- eapi_exports_replace_vars, |
6059 |
- eapi_exports_ECLASSDIR, |
6060 |
- eapi_exports_PORTDIR, |
6061 |
- eapi_supports_prefix, |
6062 |
- eapi_exports_merge_type, |
6063 |
-) |
6064 |
-from repoman.modules.linechecks.base import LineCheck |
6065 |
- |
6066 |
- |
6067 |
-class PhaseCheck(LineCheck): |
6068 |
- """basic class for function detection""" |
6069 |
- |
6070 |
- func_end_re = re.compile(r"^\}$") |
6071 |
- phase_funcs = ( |
6072 |
- "pkg_pretend", |
6073 |
- "pkg_setup", |
6074 |
- "src_unpack", |
6075 |
- "src_prepare", |
6076 |
- "src_configure", |
6077 |
- "src_compile", |
6078 |
- "src_test", |
6079 |
- "src_install", |
6080 |
- "pkg_preinst", |
6081 |
- "pkg_postinst", |
6082 |
- "pkg_prerm", |
6083 |
- "pkg_postrm", |
6084 |
- "pkg_config", |
6085 |
- ) |
6086 |
- phases_re = re.compile("(%s)" % "|".join(phase_funcs)) |
6087 |
- in_phase = "" |
6088 |
- |
6089 |
- def check(self, num, line): |
6090 |
- m = self.phases_re.match(line) |
6091 |
- if m is not None: |
6092 |
- self.in_phase = m.group(1) |
6093 |
- if self.in_phase != "" and self.func_end_re.match(line) is not None: |
6094 |
- self.in_phase = "" |
6095 |
- |
6096 |
- return self.phase_check(num, line) |
6097 |
- |
6098 |
- def phase_check(self, num, line): |
6099 |
- """override this function for your checks""" |
6100 |
- pass |
6101 |
- |
6102 |
- |
6103 |
-class EMakeParallelDisabled(PhaseCheck): |
6104 |
- """Check for emake -j1 calls which disable parallelization.""" |
6105 |
- |
6106 |
- repoman_check_name = "upstream.workaround" |
6107 |
- re = re.compile(r"^\s*emake\s+.*-j\s*1\b") |
6108 |
- |
6109 |
- def phase_check(self, num, line): |
6110 |
- if self.in_phase == "src_compile" or self.in_phase == "src_install": |
6111 |
- if self.re.match(line): |
6112 |
- return self.errors["EMAKE_PARALLEL_DISABLED"] |
6113 |
- |
6114 |
- |
6115 |
-class SrcCompileEconf(PhaseCheck): |
6116 |
- repoman_check_name = "ebuild.minorsyn" |
6117 |
- configure_re = re.compile(r"\s(econf|./configure)") |
6118 |
- |
6119 |
- def check_eapi(self, eapi): |
6120 |
- return eapi_has_src_prepare_and_src_configure(eapi) |
6121 |
- |
6122 |
- def phase_check(self, num, line): |
6123 |
- if self.in_phase == "src_compile": |
6124 |
- m = self.configure_re.match(line) |
6125 |
- if m is not None: |
6126 |
- return ("'%s'" % m.group(1)) + " call should be moved to src_configure" |
6127 |
- |
6128 |
- |
6129 |
-class SrcUnpackPatches(PhaseCheck): |
6130 |
- repoman_check_name = "ebuild.minorsyn" |
6131 |
- src_prepare_tools_re = re.compile(r"\s(e?patch|sed)\s") |
6132 |
- |
6133 |
- def check_eapi(self, eapi): |
6134 |
- return eapi_has_src_prepare_and_src_configure(eapi) |
6135 |
- |
6136 |
- def phase_check(self, num, line): |
6137 |
- if self.in_phase == "src_unpack": |
6138 |
- m = self.src_prepare_tools_re.search(line) |
6139 |
- if m is not None: |
6140 |
- return ("'%s'" % m.group(1)) + " call should be moved to src_prepare" |
6141 |
- |
6142 |
- |
6143 |
-# Refererences |
6144 |
-# - https://projects.gentoo.org/pms/7/pms.html#x1-10900011.1 |
6145 |
-# - https://pkgcore.github.io/pkgcheck/_modules/pkgcheck/checks/codingstyle.html#VariableScopeCheck |
6146 |
-_pms_vars = ( |
6147 |
- ("A", None, ("src_*", "pkg_nofetch")), |
6148 |
- ("AA", eapi_exports_AA, ("src_*", "pkg_nofetch")), |
6149 |
- ("FILESDIR", None, ("src_*",)), |
6150 |
- ("DISTDIR", None, ("src_*",)), |
6151 |
- ("WORKDIR", None, ("src_*",)), |
6152 |
- ("S", None, ("src_*",)), |
6153 |
- ("PORTDIR", eapi_exports_PORTDIR, ("src_*",)), |
6154 |
- ("ECLASSDIR", eapi_exports_ECLASSDIR, ("src_*",)), |
6155 |
- ("ROOT", None, ("pkg_*",)), |
6156 |
- ("EROOT", eapi_supports_prefix, ("pkg_*",)), |
6157 |
- ("SYSROOT", eapi_has_sysroot, ("src_*", "pkg_setup")), |
6158 |
- ("ESYSROOT", eapi_has_sysroot, ("src_*", "pkg_setup")), |
6159 |
- ("BROOT", eapi_has_broot, ("src_*", "pkg_setup")), |
6160 |
- ("D", None, ("src_install", "pkg_preinst", "pkg_postint")), |
6161 |
- ("ED", eapi_supports_prefix, ("src_install", "pkg_preinst", "pkg_postint")), |
6162 |
- ("DESTTREE", None, ("src_install",)), |
6163 |
- ("INSDESTTREE", None, ("src_install",)), |
6164 |
- ("MERGE_TYPE", eapi_exports_merge_type, ("pkg_*",)), |
6165 |
- ("REPLACING_VERSIONS", eapi_exports_replace_vars, ("pkg_*",)), |
6166 |
- ("REPLACED_BY_VERSION", eapi_exports_replace_vars, ("pkg_prerm", "pkg_postrm")), |
6167 |
-) |
6168 |
- |
6169 |
- |
6170 |
-def _compile_phases(): |
6171 |
- phase_vars = {} |
6172 |
- for phase_func in PhaseCheck.phase_funcs: |
6173 |
- for variable, eapi_filter, allowed_scopes in _pms_vars: |
6174 |
- allowed = False |
6175 |
- for scope in allowed_scopes: |
6176 |
- if fnmatch.fnmatch(phase_func, scope): |
6177 |
- allowed = True |
6178 |
- break |
6179 |
- |
6180 |
- if not allowed: |
6181 |
- phase_vars.setdefault(phase_func, []).append((variable, eapi_filter)) |
6182 |
- |
6183 |
- phase_info = {} |
6184 |
- for phase_func, prohibited_vars in phase_vars.items(): |
6185 |
- phase_func_vars = [] |
6186 |
- for variable, eapi_filter in prohibited_vars: |
6187 |
- phase_func_vars.append(variable) |
6188 |
- phase_obj = phase_info[phase_func] = types.SimpleNamespace() |
6189 |
- phase_obj.prohibited_vars = dict(prohibited_vars) |
6190 |
- phase_obj.var_names = "(%s)" % "|".join( |
6191 |
- variable for variable, eapi_filter in prohibited_vars |
6192 |
- ) |
6193 |
- phase_obj.var_reference = re.compile( |
6194 |
- r"\$(\{|)%s(\}|\W)" % (phase_obj.var_names,) |
6195 |
- ) |
6196 |
- |
6197 |
- return phase_info |
6198 |
- |
6199 |
- |
6200 |
-class PMSVariableReference(PhaseCheck): |
6201 |
- """Check phase scope for references to variables specified by PMS""" |
6202 |
- |
6203 |
- repoman_check_name = "variable.phase" |
6204 |
- phase_info = _compile_phases() |
6205 |
- |
6206 |
- def new(self, pkg): |
6207 |
- self._eapi = pkg.eapi |
6208 |
- |
6209 |
- def end(self): |
6210 |
- self._eapi = None |
6211 |
- |
6212 |
- def phase_check(self, num, line): |
6213 |
- try: |
6214 |
- phase_info = self.phase_info[self.in_phase] |
6215 |
- except KeyError: |
6216 |
- return |
6217 |
- |
6218 |
- eapi = self._eapi |
6219 |
- issues = [] |
6220 |
- for m in phase_info.var_reference.finditer(line): |
6221 |
- open_brace = m.group(1) |
6222 |
- var_name = m.group(2) |
6223 |
- close_brace = m.group(3) |
6224 |
- # discard \W if matched by (\}|\W) |
6225 |
- close_brace = close_brace if close_brace == "}" else "" |
6226 |
- if bool(open_brace) != bool(close_brace): |
6227 |
- continue |
6228 |
- var_name = m.group(2) |
6229 |
- eapi_filter = phase_info.prohibited_vars[var_name] |
6230 |
- if eapi_filter is not None and not eapi_filter(eapi): |
6231 |
- continue |
6232 |
- issues.append( |
6233 |
- "phase %s: EAPI %s: variable %s: Forbidden reference to variable specified by PMS" |
6234 |
- % (self.in_phase, eapi, var_name) |
6235 |
- ) |
6236 |
- return issues |
6237 |
|
6238 |
diff --git a/repoman/lib/repoman/modules/linechecks/portage/__init__.py b/repoman/lib/repoman/modules/linechecks/portage/__init__.py |
6239 |
deleted file mode 100644 |
6240 |
index d30877d6d..000000000 |
6241 |
--- a/repoman/lib/repoman/modules/linechecks/portage/__init__.py |
6242 |
+++ /dev/null |
6243 |
@@ -1,27 +0,0 @@ |
6244 |
-# Copyright 2015-2021 Gentoo Authors |
6245 |
-# Distributed under the terms of the GNU General Public License v2 |
6246 |
- |
6247 |
-doc = """Portage plug-in module for repoman LineChecks. |
6248 |
-Performs checks for internal portage variable usage in ebuilds.""" |
6249 |
-__doc__ = doc[:] |
6250 |
- |
6251 |
- |
6252 |
-module_spec = { |
6253 |
- "name": "do", |
6254 |
- "description": doc, |
6255 |
- "provides": { |
6256 |
- "internal-check": { |
6257 |
- "name": "portageinternal", |
6258 |
- "sourcefile": "internal", |
6259 |
- "class": "PortageInternal", |
6260 |
- "description": doc, |
6261 |
- }, |
6262 |
- "portageinternalvariableassignment-check": { |
6263 |
- "name": "portageinternalvariableassignment", |
6264 |
- "sourcefile": "internal", |
6265 |
- "class": "PortageInternalVariableAssignment", |
6266 |
- "description": doc, |
6267 |
- }, |
6268 |
- }, |
6269 |
- "version": 1, |
6270 |
-} |
6271 |
|
6272 |
diff --git a/repoman/lib/repoman/modules/linechecks/portage/internal.py b/repoman/lib/repoman/modules/linechecks/portage/internal.py |
6273 |
deleted file mode 100644 |
6274 |
index 5d6af1088..000000000 |
6275 |
--- a/repoman/lib/repoman/modules/linechecks/portage/internal.py |
6276 |
+++ /dev/null |
6277 |
@@ -1,32 +0,0 @@ |
6278 |
-import re |
6279 |
- |
6280 |
-from repoman.modules.linechecks.base import LineCheck |
6281 |
- |
6282 |
- |
6283 |
-class PortageInternal(LineCheck): |
6284 |
- repoman_check_name = "portage.internal" |
6285 |
- ignore_comment = True |
6286 |
- # Match when the command is preceded only by leading whitespace or a shell |
6287 |
- # operator such as (, {, |, ||, or &&. This prevents false positives in |
6288 |
- # things like elog messages, as reported in bug #413285. |
6289 |
- |
6290 |
- internal_portage_func_or_var = ( |
6291 |
- "ecompress|ecompressdir|env-update|prepall|prepalldocs|preplib" |
6292 |
- ) |
6293 |
- re = re.compile(r"^(\s*|.*[|&{(]+\s*)\b(%s)\b" % internal_portage_func_or_var) |
6294 |
- |
6295 |
- def check(self, num, line): |
6296 |
- """Run the check on line and return error if there is one""" |
6297 |
- m = self.re.match(line) |
6298 |
- if m is not None: |
6299 |
- return "'%s' called" % m.group(2) |
6300 |
- |
6301 |
- |
6302 |
-class PortageInternalVariableAssignment(LineCheck): |
6303 |
- repoman_check_name = "portage.internal" |
6304 |
- internal_assignment = re.compile(r"\s*(export\s+)?(EXTRA_ECONF|EXTRA_EMAKE)\+?=") |
6305 |
- |
6306 |
- def check(self, num, line): |
6307 |
- match = self.internal_assignment.match(line) |
6308 |
- if match is not None: |
6309 |
- return "Assignment to variable %s" % match.group(2) |
6310 |
|
6311 |
diff --git a/repoman/lib/repoman/modules/linechecks/quotes/__init__.py b/repoman/lib/repoman/modules/linechecks/quotes/__init__.py |
6312 |
deleted file mode 100644 |
6313 |
index deb4ced97..000000000 |
6314 |
--- a/repoman/lib/repoman/modules/linechecks/quotes/__init__.py |
6315 |
+++ /dev/null |
6316 |
@@ -1,27 +0,0 @@ |
6317 |
-# Copyright 2015-2021 Gentoo Authors |
6318 |
-# Distributed under the terms of the GNU General Public License v2 |
6319 |
- |
6320 |
-doc = """Nested plug-in module for repoman LineChecks. |
6321 |
-Performs nested subshell checks on ebuilds.""" |
6322 |
-__doc__ = doc[:] |
6323 |
- |
6324 |
- |
6325 |
-module_spec = { |
6326 |
- "name": "do", |
6327 |
- "description": doc, |
6328 |
- "provides": { |
6329 |
- "quote-check": { |
6330 |
- "name": "quote", |
6331 |
- "sourcefile": "quotes", |
6332 |
- "class": "EbuildQuote", |
6333 |
- "description": doc, |
6334 |
- }, |
6335 |
- "quoteda-check": { |
6336 |
- "name": "quoteda", |
6337 |
- "sourcefile": "quoteda", |
6338 |
- "class": "EbuildQuotedA", |
6339 |
- "description": doc, |
6340 |
- }, |
6341 |
- }, |
6342 |
- "version": 1, |
6343 |
-} |
6344 |
|
6345 |
diff --git a/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py b/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py |
6346 |
deleted file mode 100644 |
6347 |
index f44d4e38e..000000000 |
6348 |
--- a/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py |
6349 |
+++ /dev/null |
6350 |
@@ -1,15 +0,0 @@ |
6351 |
-import re |
6352 |
- |
6353 |
-from repoman.modules.linechecks.base import LineCheck |
6354 |
- |
6355 |
- |
6356 |
-class EbuildQuotedA(LineCheck): |
6357 |
- """Ensure ebuilds have no quoting around ${A}""" |
6358 |
- |
6359 |
- repoman_check_name = "ebuild.minorsyn" |
6360 |
- a_quoted = re.compile(r".*\"\$(\{A\}|A)\"") |
6361 |
- |
6362 |
- def check(self, num, line): |
6363 |
- match = self.a_quoted.match(line) |
6364 |
- if match: |
6365 |
- return 'Quoted "${A}"' |
6366 |
|
6367 |
diff --git a/repoman/lib/repoman/modules/linechecks/quotes/quotes.py b/repoman/lib/repoman/modules/linechecks/quotes/quotes.py |
6368 |
deleted file mode 100644 |
6369 |
index c170c10ef..000000000 |
6370 |
--- a/repoman/lib/repoman/modules/linechecks/quotes/quotes.py |
6371 |
+++ /dev/null |
6372 |
@@ -1,92 +0,0 @@ |
6373 |
-import re |
6374 |
- |
6375 |
-from repoman.modules.linechecks.base import LineCheck |
6376 |
- |
6377 |
- |
6378 |
-class EbuildQuote(LineCheck): |
6379 |
- """Ensure ebuilds have valid quoting around things like D,FILESDIR, etc...""" |
6380 |
- |
6381 |
- repoman_check_name = "ebuild.minorsyn" |
6382 |
- _message_commands = ["die", "echo", "eerror", "einfo", "elog", "eqawarn", "ewarn"] |
6383 |
- _message_re = re.compile(r"\s(" + "|".join(_message_commands) + r')\s+"[^"]*"\s*$') |
6384 |
- _ignored_commands = ["local", "export"] + _message_commands |
6385 |
- ignore_line = re.compile( |
6386 |
- r"(^$)|(^\s*#.*)|(^\s*\w+=.*)" |
6387 |
- + r"|(^\s*(" |
6388 |
- + "|".join(_ignored_commands) |
6389 |
- + r")\s+)" |
6390 |
- ) |
6391 |
- ignore_comment = False |
6392 |
- var_names = ["D", "DISTDIR", "FILESDIR", "S", "T", "ROOT", "BROOT", "WORKDIR"] |
6393 |
- |
6394 |
- # EAPI=3/Prefix vars |
6395 |
- var_names += ["ED", "EPREFIX", "EROOT"] |
6396 |
- |
6397 |
- # variables for games.eclass |
6398 |
- var_names += [ |
6399 |
- "Ddir", |
6400 |
- "GAMES_PREFIX_OPT", |
6401 |
- "GAMES_DATADIR", |
6402 |
- "GAMES_DATADIR_BASE", |
6403 |
- "GAMES_SYSCONFDIR", |
6404 |
- "GAMES_STATEDIR", |
6405 |
- "GAMES_LOGDIR", |
6406 |
- "GAMES_BINDIR", |
6407 |
- ] |
6408 |
- |
6409 |
- # variables for multibuild.eclass |
6410 |
- var_names += ["BUILD_DIR"] |
6411 |
- |
6412 |
- var_names = "(%s)" % "|".join(var_names) |
6413 |
- var_reference = re.compile(r"\$(\{%s\}|%s\W)" % (var_names, var_names)) |
6414 |
- missing_quotes = re.compile(r'(\s|^)[^"\'\s]*\$\{?%s\}?[^"\'\s]*(\s|$)' % var_names) |
6415 |
- cond_begin = re.compile(r"(^|\s+)\[\[($|\\$|\s+)") |
6416 |
- cond_end = re.compile(r"(^|\s+)\]\]($|\\$|\s+)") |
6417 |
- |
6418 |
- def check(self, num, line): |
6419 |
- if self.var_reference.search(line) is None: |
6420 |
- return |
6421 |
- # There can be multiple matches / violations on a single line. We |
6422 |
- # have to make sure none of the matches are violators. Once we've |
6423 |
- # found one violator, any remaining matches on the same line can |
6424 |
- # be ignored. |
6425 |
- pos = 0 |
6426 |
- while pos <= len(line) - 1: |
6427 |
- missing_quotes = self.missing_quotes.search(line, pos) |
6428 |
- if not missing_quotes: |
6429 |
- break |
6430 |
- # If the last character of the previous match is a whitespace |
6431 |
- # character, that character may be needed for the next |
6432 |
- # missing_quotes match, so search overlaps by 1 character. |
6433 |
- group = missing_quotes.group() |
6434 |
- pos = missing_quotes.end() - 1 |
6435 |
- |
6436 |
- # Filter out some false positives that can |
6437 |
- # get through the missing_quotes regex. |
6438 |
- if self.var_reference.search(group) is None: |
6439 |
- continue |
6440 |
- |
6441 |
- # Filter matches that appear to be an |
6442 |
- # argument to a message command. |
6443 |
- # For example: false || ewarn "foo $WORKDIR/bar baz" |
6444 |
- message_match = self._message_re.search(line) |
6445 |
- if ( |
6446 |
- message_match is not None |
6447 |
- and message_match.start() < pos |
6448 |
- and message_match.end() > pos |
6449 |
- ): |
6450 |
- break |
6451 |
- |
6452 |
- # This is an attempt to avoid false positives without getting |
6453 |
- # too complex, while possibly allowing some (hopefully |
6454 |
- # unlikely) violations to slip through. We just assume |
6455 |
- # everything is correct if the there is a ' [[ ' or a ' ]] ' |
6456 |
- # anywhere in the whole line (possibly continued over one |
6457 |
- # line). |
6458 |
- if self.cond_begin.search(line) is not None: |
6459 |
- continue |
6460 |
- if self.cond_end.search(line) is not None: |
6461 |
- continue |
6462 |
- |
6463 |
- # Any remaining matches on the same line can be ignored. |
6464 |
- return self.errors["MISSING_QUOTES_ERROR"] |
6465 |
|
6466 |
diff --git a/repoman/lib/repoman/modules/linechecks/uri/__init__.py b/repoman/lib/repoman/modules/linechecks/uri/__init__.py |
6467 |
deleted file mode 100644 |
6468 |
index 4018020c3..000000000 |
6469 |
--- a/repoman/lib/repoman/modules/linechecks/uri/__init__.py |
6470 |
+++ /dev/null |
6471 |
@@ -1,21 +0,0 @@ |
6472 |
-# Copyright 2015-2021 Gentoo Authors |
6473 |
-# Distributed under the terms of the GNU General Public License v2 |
6474 |
- |
6475 |
-doc = """Uri plug-in module for repoman LineChecks. |
6476 |
-Performs HOMEPAGE variable checks on ebuilds.""" |
6477 |
-__doc__ = doc[:] |
6478 |
- |
6479 |
- |
6480 |
-module_spec = { |
6481 |
- "name": "do", |
6482 |
- "description": doc, |
6483 |
- "provides": { |
6484 |
- "httpsuri-check": { |
6485 |
- "name": "httpsuri", |
6486 |
- "sourcefile": "uri", |
6487 |
- "class": "UriUseHttps", |
6488 |
- "description": doc, |
6489 |
- }, |
6490 |
- }, |
6491 |
- "version": 1, |
6492 |
-} |
6493 |
|
6494 |
diff --git a/repoman/lib/repoman/modules/linechecks/uri/uri.py b/repoman/lib/repoman/modules/linechecks/uri/uri.py |
6495 |
deleted file mode 100644 |
6496 |
index 9f3e49fe0..000000000 |
6497 |
--- a/repoman/lib/repoman/modules/linechecks/uri/uri.py |
6498 |
+++ /dev/null |
6499 |
@@ -1,30 +0,0 @@ |
6500 |
-import re # pylint: disable=unused-import |
6501 |
- |
6502 |
-from repoman.modules.linechecks.base import LineCheck |
6503 |
- |
6504 |
- |
6505 |
-class UriUseHttps(LineCheck): |
6506 |
- """Check that we use https:// for known good sites.""" |
6507 |
- |
6508 |
- repoman_check_name = "uri.https" |
6509 |
- _SITES = ( |
6510 |
- r"([-._a-zA-Z0-9]*\.)?apache\.org", |
6511 |
- r"((alioth|packages(\.qa)?|people|www)\.)?debian\.org", |
6512 |
- # Most FDO sites support https, but not all (like tango). |
6513 |
- # List the most common ones here for now. |
6514 |
- r"((anongit|bugs|cgit|dri|patchwork|people|specifications|www|xcb|xorg)\.)?freedesktop\.org", |
6515 |
- r"((bugs|dev|wiki|www)\.)?gentoo\.org", |
6516 |
- r"((wiki)\.)?github\.(io|com)", |
6517 |
- r"savannah\.(non)?gnu\.org", |
6518 |
- r"((gcc|www)\.)?gnu\.org", |
6519 |
- r"curl\.haxx\.se", |
6520 |
- r"((bugzilla|git|mirrors|patchwork|planet|www(\.wiki)?)\.)?kernel\.org", |
6521 |
- r"((bugs|wiki|www)\.)?linuxfoundation\.org", |
6522 |
- r"((docs|pypi|www)\.)?python\.org", |
6523 |
- r"(sf|sourceforge)\.net", |
6524 |
- r"(www\.)?(enlightenment|sourceware|x)\.org", |
6525 |
- ) |
6526 |
- # Try to anchor the end of the URL so we don't get false positives |
6527 |
- # with http://github.com.foo.bar.com/. Unlikely, but possible. |
6528 |
- re = re.compile(r'.*\bhttp://(%s)(\s|["\'/]|$)' % r"|".join(_SITES)) |
6529 |
- error = "URI_HTTPS" |
6530 |
|
6531 |
diff --git a/repoman/lib/repoman/modules/linechecks/use/__init__.py b/repoman/lib/repoman/modules/linechecks/use/__init__.py |
6532 |
deleted file mode 100644 |
6533 |
index 0d738c37c..000000000 |
6534 |
--- a/repoman/lib/repoman/modules/linechecks/use/__init__.py |
6535 |
+++ /dev/null |
6536 |
@@ -1,21 +0,0 @@ |
6537 |
-# Copyright 2015-2021 Gentoo Authors |
6538 |
-# Distributed under the terms of the GNU General Public License v2 |
6539 |
- |
6540 |
-doc = """Use plug-in module for repoman LineChecks. |
6541 |
-Performs Built-With-Use checks on ebuilds.""" |
6542 |
-__doc__ = doc[:] |
6543 |
- |
6544 |
- |
6545 |
-module_spec = { |
6546 |
- "name": "do", |
6547 |
- "description": doc, |
6548 |
- "provides": { |
6549 |
- "builtwith-check": { |
6550 |
- "name": "builtwith", |
6551 |
- "sourcefile": "builtwith", |
6552 |
- "class": "BuiltWithUse", |
6553 |
- "description": doc, |
6554 |
- }, |
6555 |
- }, |
6556 |
- "version": 1, |
6557 |
-} |
6558 |
|
6559 |
diff --git a/repoman/lib/repoman/modules/linechecks/use/builtwith.py b/repoman/lib/repoman/modules/linechecks/use/builtwith.py |
6560 |
deleted file mode 100644 |
6561 |
index 0b16de028..000000000 |
6562 |
--- a/repoman/lib/repoman/modules/linechecks/use/builtwith.py |
6563 |
+++ /dev/null |
6564 |
@@ -1,9 +0,0 @@ |
6565 |
-import re # pylint: disable=unused-import |
6566 |
- |
6567 |
-from repoman.modules.linechecks.base import LineCheck |
6568 |
- |
6569 |
- |
6570 |
-class BuiltWithUse(LineCheck): |
6571 |
- repoman_check_name = "ebuild.minorsyn" |
6572 |
- re = re.compile(r"(^|.*\b)built_with_use\b") |
6573 |
- error = "BUILT_WITH_USE" |
6574 |
|
6575 |
diff --git a/repoman/lib/repoman/modules/linechecks/useless/__init__.py b/repoman/lib/repoman/modules/linechecks/useless/__init__.py |
6576 |
deleted file mode 100644 |
6577 |
index 9be951584..000000000 |
6578 |
--- a/repoman/lib/repoman/modules/linechecks/useless/__init__.py |
6579 |
+++ /dev/null |
6580 |
@@ -1,27 +0,0 @@ |
6581 |
-# Copyright 2015-2021 Gentoo Authors |
6582 |
-# Distributed under the terms of the GNU General Public License v2 |
6583 |
- |
6584 |
-doc = """Useless plug-in module for repoman LineChecks. |
6585 |
-Performs checks for useless operations on ebuilds.""" |
6586 |
-__doc__ = doc[:] |
6587 |
- |
6588 |
- |
6589 |
-module_spec = { |
6590 |
- "name": "do", |
6591 |
- "description": doc, |
6592 |
- "provides": { |
6593 |
- "uselesscds-check": { |
6594 |
- "name": "uselesscds", |
6595 |
- "sourcefile": "cd", |
6596 |
- "class": "EbuildUselessCdS", |
6597 |
- "description": doc, |
6598 |
- }, |
6599 |
- "uselessdodoc-check": { |
6600 |
- "name": "uselessdodoc", |
6601 |
- "sourcefile": "dodoc", |
6602 |
- "class": "EbuildUselessDodoc", |
6603 |
- "description": doc, |
6604 |
- }, |
6605 |
- }, |
6606 |
- "version": 1, |
6607 |
-} |
6608 |
|
6609 |
diff --git a/repoman/lib/repoman/modules/linechecks/useless/cd.py b/repoman/lib/repoman/modules/linechecks/useless/cd.py |
6610 |
deleted file mode 100644 |
6611 |
index 73063209f..000000000 |
6612 |
--- a/repoman/lib/repoman/modules/linechecks/useless/cd.py |
6613 |
+++ /dev/null |
6614 |
@@ -1,24 +0,0 @@ |
6615 |
-import re |
6616 |
- |
6617 |
-from repoman.modules.linechecks.base import LineCheck |
6618 |
- |
6619 |
- |
6620 |
-class EbuildUselessCdS(LineCheck): |
6621 |
- """Check for redundant cd ${S} statements""" |
6622 |
- |
6623 |
- repoman_check_name = "ebuild.minorsyn" |
6624 |
- _src_phases = r"^\s*src_(prepare|configure|compile|install|test)\s*\(\)" |
6625 |
- method_re = re.compile(_src_phases) |
6626 |
- cds_re = re.compile(r'^\s*cd\s+("\$(\{S\}|S)"|\$(\{S\}|S))\s') |
6627 |
- |
6628 |
- def __init__(self, errors): |
6629 |
- self.errors = errors |
6630 |
- self.check_next_line = False |
6631 |
- |
6632 |
- def check(self, num, line): |
6633 |
- if self.check_next_line: |
6634 |
- self.check_next_line = False |
6635 |
- if self.cds_re.match(line): |
6636 |
- return self.errors["REDUNDANT_CD_S_ERROR"] |
6637 |
- elif self.method_re.match(line): |
6638 |
- self.check_next_line = True |
6639 |
|
6640 |
diff --git a/repoman/lib/repoman/modules/linechecks/useless/dodoc.py b/repoman/lib/repoman/modules/linechecks/useless/dodoc.py |
6641 |
deleted file mode 100644 |
6642 |
index 49f6fde91..000000000 |
6643 |
--- a/repoman/lib/repoman/modules/linechecks/useless/dodoc.py |
6644 |
+++ /dev/null |
6645 |
@@ -1,17 +0,0 @@ |
6646 |
-import re |
6647 |
- |
6648 |
-from repoman.modules.linechecks.base import LineCheck |
6649 |
- |
6650 |
- |
6651 |
-class EbuildUselessDodoc(LineCheck): |
6652 |
- """Check ebuild for useless files in dodoc arguments.""" |
6653 |
- |
6654 |
- repoman_check_name = "ebuild.minorsyn" |
6655 |
- uselessdodoc_re = re.compile( |
6656 |
- r"^\s*dodoc(\s+|\s+.*\s+)(ABOUT-NLS|COPYING|LICENCE|LICENSE)($|\s)" |
6657 |
- ) |
6658 |
- |
6659 |
- def check(self, num, line): |
6660 |
- match = self.uselessdodoc_re.match(line) |
6661 |
- if match: |
6662 |
- return "Useless dodoc '%s'" % match.group(2) |
6663 |
|
6664 |
diff --git a/repoman/lib/repoman/modules/linechecks/whitespace/__init__.py b/repoman/lib/repoman/modules/linechecks/whitespace/__init__.py |
6665 |
deleted file mode 100644 |
6666 |
index 17b3abab5..000000000 |
6667 |
--- a/repoman/lib/repoman/modules/linechecks/whitespace/__init__.py |
6668 |
+++ /dev/null |
6669 |
@@ -1,27 +0,0 @@ |
6670 |
-# Copyright 2015-2021 Gentoo Authors |
6671 |
-# Distributed under the terms of the GNU General Public License v2 |
6672 |
- |
6673 |
-doc = """Whitespace plug-in module for repoman LineChecks. |
6674 |
-Performs checks for useless whitespace in ebuilds.""" |
6675 |
-__doc__ = doc[:] |
6676 |
- |
6677 |
- |
6678 |
-module_spec = { |
6679 |
- "name": "do", |
6680 |
- "description": doc, |
6681 |
- "provides": { |
6682 |
- "whitespace-check": { |
6683 |
- "name": "whitespace", |
6684 |
- "sourcefile": "whitespace", |
6685 |
- "class": "EbuildWhitespace", |
6686 |
- "description": doc, |
6687 |
- }, |
6688 |
- "blankline-check": { |
6689 |
- "name": "blankline", |
6690 |
- "sourcefile": "blank", |
6691 |
- "class": "EbuildBlankLine", |
6692 |
- "description": doc, |
6693 |
- }, |
6694 |
- }, |
6695 |
- "version": 1, |
6696 |
-} |
6697 |
|
6698 |
diff --git a/repoman/lib/repoman/modules/linechecks/whitespace/blank.py b/repoman/lib/repoman/modules/linechecks/whitespace/blank.py |
6699 |
deleted file mode 100644 |
6700 |
index 89e38c68c..000000000 |
6701 |
--- a/repoman/lib/repoman/modules/linechecks/whitespace/blank.py |
6702 |
+++ /dev/null |
6703 |
@@ -1,24 +0,0 @@ |
6704 |
-import re |
6705 |
- |
6706 |
-from repoman.modules.linechecks.base import LineCheck |
6707 |
- |
6708 |
- |
6709 |
-class EbuildBlankLine(LineCheck): |
6710 |
- repoman_check_name = "ebuild.minorsyn" |
6711 |
- ignore_comment = False |
6712 |
- blank_line = re.compile(r"^$") |
6713 |
- |
6714 |
- def new(self, pkg): |
6715 |
- self.line_is_blank = False |
6716 |
- |
6717 |
- def check(self, num, line): |
6718 |
- if self.line_is_blank and self.blank_line.match(line): |
6719 |
- return "Useless blank line" |
6720 |
- if self.blank_line.match(line): |
6721 |
- self.line_is_blank = True |
6722 |
- else: |
6723 |
- self.line_is_blank = False |
6724 |
- |
6725 |
- def end(self): |
6726 |
- if self.line_is_blank: |
6727 |
- yield "Useless blank line on last line" |
6728 |
|
6729 |
diff --git a/repoman/lib/repoman/modules/linechecks/whitespace/whitespace.py b/repoman/lib/repoman/modules/linechecks/whitespace/whitespace.py |
6730 |
deleted file mode 100644 |
6731 |
index a1274048d..000000000 |
6732 |
--- a/repoman/lib/repoman/modules/linechecks/whitespace/whitespace.py |
6733 |
+++ /dev/null |
6734 |
@@ -1,20 +0,0 @@ |
6735 |
-import re |
6736 |
- |
6737 |
-from repoman.modules.linechecks.base import LineCheck |
6738 |
- |
6739 |
- |
6740 |
-class EbuildWhitespace(LineCheck): |
6741 |
- """Ensure ebuilds have proper whitespacing""" |
6742 |
- |
6743 |
- repoman_check_name = "ebuild.minorsyn" |
6744 |
- |
6745 |
- ignore_line = re.compile(r"(^$)|(^(\t)*#)") |
6746 |
- ignore_comment = False |
6747 |
- leading_spaces = re.compile(r"^[\S\t]") |
6748 |
- trailing_whitespace = re.compile(r".*([\S]$)") |
6749 |
- |
6750 |
- def check(self, num, line): |
6751 |
- if self.leading_spaces.match(line) is None: |
6752 |
- return self.errors["LEADING_SPACES_ERROR"] |
6753 |
- if self.trailing_whitespace.match(line) is None: |
6754 |
- return self.errors["TRAILING_WHITESPACE_ERROR"] |
6755 |
|
6756 |
diff --git a/repoman/lib/repoman/modules/linechecks/workaround/__init__.py b/repoman/lib/repoman/modules/linechecks/workaround/__init__.py |
6757 |
deleted file mode 100644 |
6758 |
index eff33cf23..000000000 |
6759 |
--- a/repoman/lib/repoman/modules/linechecks/workaround/__init__.py |
6760 |
+++ /dev/null |
6761 |
@@ -1,21 +0,0 @@ |
6762 |
-# Copyright 2015-2021 Gentoo Authors |
6763 |
-# Distributed under the terms of the GNU General Public License v2 |
6764 |
- |
6765 |
-doc = """Workaround plug-in module for repoman LineChecks. |
6766 |
-Performs checks for upstream workarounds in ebuilds.""" |
6767 |
-__doc__ = doc[:] |
6768 |
- |
6769 |
- |
6770 |
-module_spec = { |
6771 |
- "name": "do", |
6772 |
- "description": doc, |
6773 |
- "provides": { |
6774 |
- "noasneeded-check": { |
6775 |
- "name": "noasneeded", |
6776 |
- "sourcefile": "workarounds", |
6777 |
- "class": "NoAsNeeded", |
6778 |
- "description": doc, |
6779 |
- }, |
6780 |
- }, |
6781 |
- "version": 1, |
6782 |
-} |
6783 |
|
6784 |
diff --git a/repoman/lib/repoman/modules/linechecks/workaround/workarounds.py b/repoman/lib/repoman/modules/linechecks/workaround/workarounds.py |
6785 |
deleted file mode 100644 |
6786 |
index 47b6881ff..000000000 |
6787 |
--- a/repoman/lib/repoman/modules/linechecks/workaround/workarounds.py |
6788 |
+++ /dev/null |
6789 |
@@ -1,11 +0,0 @@ |
6790 |
-import re # pylint: disable=unused-import |
6791 |
- |
6792 |
-from repoman.modules.linechecks.base import LineCheck |
6793 |
- |
6794 |
- |
6795 |
-class NoAsNeeded(LineCheck): |
6796 |
- """Check for calls to the no-as-needed function.""" |
6797 |
- |
6798 |
- repoman_check_name = "upstream.workaround" |
6799 |
- re = re.compile(r".*\$\(no-as-needed\)") |
6800 |
- error = "NO_AS_NEEDED" |
6801 |
|
6802 |
diff --git a/repoman/lib/repoman/modules/scan/__init__.py b/repoman/lib/repoman/modules/scan/__init__.py |
6803 |
deleted file mode 100644 |
6804 |
index e69de29bb..000000000 |
6805 |
|
6806 |
diff --git a/repoman/lib/repoman/modules/scan/depend/__init__.py b/repoman/lib/repoman/modules/scan/depend/__init__.py |
6807 |
deleted file mode 100644 |
6808 |
index cac382b6f..000000000 |
6809 |
--- a/repoman/lib/repoman/modules/scan/depend/__init__.py |
6810 |
+++ /dev/null |
6811 |
@@ -1,43 +0,0 @@ |
6812 |
-# Copyright 2015-2021 Gentoo Authors |
6813 |
-# Distributed under the terms of the GNU General Public License v2 |
6814 |
- |
6815 |
-doc = """Depend plug-in module for repoman. |
6816 |
-Performs Dependency checks on ebuilds.""" |
6817 |
-__doc__ = doc[:] |
6818 |
- |
6819 |
- |
6820 |
-module_spec = { |
6821 |
- "name": "depend", |
6822 |
- "description": doc, |
6823 |
- "provides": { |
6824 |
- "profile-module": { |
6825 |
- "name": "profile", |
6826 |
- "sourcefile": "profile", |
6827 |
- "class": "ProfileDependsChecks", |
6828 |
- "description": doc, |
6829 |
- "functions": ["check"], |
6830 |
- "func_desc": {}, |
6831 |
- "mod_kwargs": [ |
6832 |
- "qatracker", |
6833 |
- "portdb", |
6834 |
- "profiles", |
6835 |
- "options", |
6836 |
- "repo_metadata", |
6837 |
- "repo_settings", |
6838 |
- "include_arches", |
6839 |
- "include_profiles", |
6840 |
- "caches", |
6841 |
- "repoman_incrementals", |
6842 |
- "env", |
6843 |
- "have", |
6844 |
- "dev_keywords", |
6845 |
- ], |
6846 |
- "func_kwargs": { |
6847 |
- "ebuild": (None, None), |
6848 |
- "pkg": (None, None), |
6849 |
- }, |
6850 |
- "module_runsIn": ["ebuilds"], |
6851 |
- }, |
6852 |
- }, |
6853 |
- "version": 1, |
6854 |
-} |
6855 |
|
6856 |
diff --git a/repoman/lib/repoman/modules/scan/depend/_depend_checks.py b/repoman/lib/repoman/modules/scan/depend/_depend_checks.py |
6857 |
deleted file mode 100644 |
6858 |
index 11a2fbf56..000000000 |
6859 |
--- a/repoman/lib/repoman/modules/scan/depend/_depend_checks.py |
6860 |
+++ /dev/null |
6861 |
@@ -1,260 +0,0 @@ |
6862 |
-# -*- coding:utf-8 -*- |
6863 |
- |
6864 |
-import collections |
6865 |
- |
6866 |
-from _emerge.Package import Package |
6867 |
- |
6868 |
-from portage.dep import Atom |
6869 |
- |
6870 |
-from repoman.check_missingslot import check_missingslot |
6871 |
- |
6872 |
-# import our initialized portage instance |
6873 |
-from repoman._portage import portage |
6874 |
- |
6875 |
- |
6876 |
-def check_slotop(depstr, is_valid_flag, badsyntax, mytype, qatracker, relative_path): |
6877 |
- """Checks if RDEPEND uses ':=' slot operator |
6878 |
- in '||' style dependencies.""" |
6879 |
- |
6880 |
- try: |
6881 |
- # to find use of ':=' in '||' we preserve |
6882 |
- # tree structure of dependencies |
6883 |
- my_dep_tree = portage.dep.use_reduce( |
6884 |
- depstr, |
6885 |
- flat=False, |
6886 |
- matchall=1, |
6887 |
- is_valid_flag=is_valid_flag, |
6888 |
- opconvert=True, |
6889 |
- token_class=portage.dep.Atom, |
6890 |
- ) |
6891 |
- except portage.exception.InvalidDependString as e: |
6892 |
- my_dep_tree = None |
6893 |
- badsyntax.append((mytype, str(e))) |
6894 |
- |
6895 |
- def _traverse_tree(dep_tree, in_any_of): |
6896 |
- # leaf |
6897 |
- if isinstance(dep_tree, Atom): |
6898 |
- atom = dep_tree |
6899 |
- if in_any_of and atom.slot_operator == "=": |
6900 |
- qatracker.add_error( |
6901 |
- "dependency.badslotop", |
6902 |
- "%s: %s: '%s' uses ':=' slot operator under '||' dep clause." |
6903 |
- % (relative_path, mytype, atom), |
6904 |
- ) |
6905 |
- |
6906 |
- # branches |
6907 |
- if isinstance(dep_tree, list): |
6908 |
- if len(dep_tree) == 0: |
6909 |
- return |
6910 |
- # entering any-of |
6911 |
- if dep_tree[0] == "||": |
6912 |
- _traverse_tree(dep_tree[1:], in_any_of=True) |
6913 |
- else: |
6914 |
- for branch in dep_tree: |
6915 |
- _traverse_tree(branch, in_any_of=in_any_of) |
6916 |
- |
6917 |
- _traverse_tree(my_dep_tree, False) |
6918 |
- |
6919 |
- |
6920 |
-def _depend_checks(ebuild, pkg, portdb, qatracker, repo_metadata, qadata): |
6921 |
- """Checks the ebuild dependencies for errors |
6922 |
- |
6923 |
- @param pkg: Package in which we check (object). |
6924 |
- @param ebuild: Ebuild which we check (object). |
6925 |
- @param portdb: portdb instance |
6926 |
- @param qatracker: QATracker instance |
6927 |
- @param repo_metadata: dictionary of various repository items. |
6928 |
- @returns: (unknown_pkgs, badlicsyntax) |
6929 |
- """ |
6930 |
- |
6931 |
- unknown_pkgs = set() |
6932 |
- |
6933 |
- inherited_java_eclass = ( |
6934 |
- "java-pkg-2" in ebuild.inherited or "java-pkg-opt-2" in ebuild.inherited |
6935 |
- ) |
6936 |
- inherited_wxwidgets_eclass = "wxwidgets" in ebuild.inherited |
6937 |
- # operator_tokens = set(["||", "(", ")"]) |
6938 |
- badsyntax = [] |
6939 |
- for mytype in Package._dep_keys + ("LICENSE", "PROPERTIES"): |
6940 |
- mydepstr = ebuild.metadata[mytype] |
6941 |
- |
6942 |
- buildtime = mytype in Package._buildtime_keys |
6943 |
- runtime = mytype in Package._runtime_keys |
6944 |
- token_class = None |
6945 |
- if mytype.endswith("DEPEND"): |
6946 |
- token_class = portage.dep.Atom |
6947 |
- |
6948 |
- try: |
6949 |
- atoms = portage.dep.use_reduce( |
6950 |
- mydepstr, |
6951 |
- matchall=1, |
6952 |
- flat=True, |
6953 |
- is_valid_flag=pkg.iuse.is_valid_flag, |
6954 |
- token_class=token_class, |
6955 |
- ) |
6956 |
- except portage.exception.InvalidDependString as e: |
6957 |
- atoms = None |
6958 |
- badsyntax.append((mytype, str(e))) |
6959 |
- |
6960 |
- if atoms and mytype.endswith("DEPEND"): |
6961 |
- if runtime and "test?" in mydepstr.split(): |
6962 |
- qatracker.add_error( |
6963 |
- mytype + ".suspect", |
6964 |
- "%s: 'test?' USE conditional in %s" |
6965 |
- % (ebuild.relative_path, mytype), |
6966 |
- ) |
6967 |
- |
6968 |
- for atom in atoms: |
6969 |
- if atom == "||": |
6970 |
- continue |
6971 |
- |
6972 |
- is_blocker = atom.blocker |
6973 |
- |
6974 |
- # Skip dependency.unknown for blockers, so that we |
6975 |
- # don't encourage people to remove necessary blockers, |
6976 |
- # as discussed in bug 382407. We use atom.without_use |
6977 |
- # due to bug 525376. |
6978 |
- if ( |
6979 |
- not is_blocker |
6980 |
- and not portdb.xmatch("match-all", atom.without_use) |
6981 |
- and not atom.cp.startswith("virtual/") |
6982 |
- ): |
6983 |
- unknown_pkgs.add((mytype, atom.unevaluated_atom)) |
6984 |
- |
6985 |
- if not atom.blocker: |
6986 |
- all_deprecated = False |
6987 |
- for pkg_match in portdb.xmatch("match-all", atom): |
6988 |
- if any( |
6989 |
- repo_metadata["package.deprecated"].iterAtomsForPackage( |
6990 |
- pkg_match |
6991 |
- ) |
6992 |
- ): |
6993 |
- all_deprecated = True |
6994 |
- else: |
6995 |
- all_deprecated = False |
6996 |
- break |
6997 |
- |
6998 |
- if all_deprecated: |
6999 |
- qatracker.add_error( |
7000 |
- "dependency.deprecated", |
7001 |
- ebuild.relative_path + ": '%s'" % atom, |
7002 |
- ) |
7003 |
- |
7004 |
- if pkg.category != "virtual": |
7005 |
- if not is_blocker and atom.cp in qadata.suspect_virtual: |
7006 |
- qatracker.add_error( |
7007 |
- "virtual.suspect", |
7008 |
- ebuild.relative_path |
7009 |
- + ": %s: consider using '%s' instead of '%s'" |
7010 |
- % (mytype, qadata.suspect_virtual[atom.cp], atom), |
7011 |
- ) |
7012 |
- if not is_blocker and atom.cp.startswith("perl-core/"): |
7013 |
- qatracker.add_error( |
7014 |
- "dependency.perlcore", |
7015 |
- ebuild.relative_path |
7016 |
- + ": %s: please use '%s' instead of '%s'" |
7017 |
- % ( |
7018 |
- mytype, |
7019 |
- atom.replace("perl-core/", "virtual/perl-"), |
7020 |
- atom, |
7021 |
- ), |
7022 |
- ) |
7023 |
- |
7024 |
- if ( |
7025 |
- buildtime |
7026 |
- and not is_blocker |
7027 |
- and not inherited_java_eclass |
7028 |
- and atom.cp == "virtual/jdk" |
7029 |
- ): |
7030 |
- qatracker.add_error("java.eclassesnotused", ebuild.relative_path) |
7031 |
- elif ( |
7032 |
- buildtime |
7033 |
- and not is_blocker |
7034 |
- and not inherited_wxwidgets_eclass |
7035 |
- and atom.cp == "x11-libs/wxGTK" |
7036 |
- ): |
7037 |
- qatracker.add_error( |
7038 |
- "wxwidgets.eclassnotused", |
7039 |
- "%s: %ss on x11-libs/wxGTK without inheriting" |
7040 |
- " wxwidgets.eclass" % (ebuild.relative_path, mytype), |
7041 |
- ) |
7042 |
- elif runtime: |
7043 |
- if not is_blocker and atom.cp in qadata.suspect_rdepend: |
7044 |
- qatracker.add_error( |
7045 |
- mytype + ".suspect", ebuild.relative_path + ": '%s'" % atom |
7046 |
- ) |
7047 |
- |
7048 |
- if ( |
7049 |
- atom.operator == "~" |
7050 |
- and portage.versions.catpkgsplit(atom.cpv)[3] != "r0" |
7051 |
- ): |
7052 |
- qacat = "dependency.badtilde" |
7053 |
- qatracker.add_error( |
7054 |
- qacat, |
7055 |
- "%s: %s uses the ~ operator" |
7056 |
- " with a non-zero revision: '%s'" |
7057 |
- % (ebuild.relative_path, mytype, atom), |
7058 |
- ) |
7059 |
- # plain =foo-1.2.3 without revision or * |
7060 |
- if atom.operator == "=" and "-r" not in atom.version: |
7061 |
- qacat = "dependency.equalsversion" |
7062 |
- qatracker.add_error( |
7063 |
- qacat, |
7064 |
- "%s: %s uses the = operator with" |
7065 |
- " no revision: '%s'; if any revision is" |
7066 |
- " acceptable, use '~' instead; if only -r0" |
7067 |
- " then please append '-r0' to the dep" |
7068 |
- % (ebuild.relative_path, mytype, atom), |
7069 |
- ) |
7070 |
- |
7071 |
- check_missingslot( |
7072 |
- atom, |
7073 |
- mytype, |
7074 |
- ebuild.eapi, |
7075 |
- portdb, |
7076 |
- qatracker, |
7077 |
- ebuild.relative_path, |
7078 |
- ebuild.metadata, |
7079 |
- ) |
7080 |
- |
7081 |
- if runtime: |
7082 |
- check_slotop( |
7083 |
- mydepstr, |
7084 |
- pkg.iuse.is_valid_flag, |
7085 |
- badsyntax, |
7086 |
- mytype, |
7087 |
- qatracker, |
7088 |
- ebuild.relative_path, |
7089 |
- ) |
7090 |
- |
7091 |
- baddepsyntax = False |
7092 |
- dedup = collections.defaultdict(set) |
7093 |
- for m, b in badsyntax: |
7094 |
- if b in dedup[m]: |
7095 |
- continue |
7096 |
- dedup[m].add(b) |
7097 |
- |
7098 |
- if m.endswith("DEPEND"): |
7099 |
- baddepsyntax = True |
7100 |
- qacat = "dependency.syntax" |
7101 |
- else: |
7102 |
- qacat = m + ".syntax" |
7103 |
- qatracker.add_error(qacat, "%s: %s: %s" % (ebuild.relative_path, m, b)) |
7104 |
- |
7105 |
- # Parse the LICENSE variable, remove USE conditions and flatten it. |
7106 |
- licenses = portage.dep.use_reduce(ebuild.metadata["LICENSE"], matchall=1, flat=True) |
7107 |
- |
7108 |
- # Check each entry to ensure that it exists in ${PORTDIR}/licenses/. |
7109 |
- for lic in licenses: |
7110 |
- # Need to check for "||" manually as no portage |
7111 |
- # function will remove it without removing values. |
7112 |
- if lic not in repo_metadata["liclist"] and lic != "||": |
7113 |
- qatracker.add_error( |
7114 |
- "LICENSE.invalid", "%s: %s" % (ebuild.relative_path, lic) |
7115 |
- ) |
7116 |
- elif lic in repo_metadata["lic_deprecated"]: |
7117 |
- qatracker.add_error( |
7118 |
- "LICENSE.deprecated", "%s: %s" % (ebuild.relative_path, lic) |
7119 |
- ) |
7120 |
- |
7121 |
- return unknown_pkgs, baddepsyntax |
7122 |
|
7123 |
diff --git a/repoman/lib/repoman/modules/scan/depend/_gen_arches.py b/repoman/lib/repoman/modules/scan/depend/_gen_arches.py |
7124 |
deleted file mode 100644 |
7125 |
index 6e3000014..000000000 |
7126 |
--- a/repoman/lib/repoman/modules/scan/depend/_gen_arches.py |
7127 |
+++ /dev/null |
7128 |
@@ -1,67 +0,0 @@ |
7129 |
-# -*- coding:utf-8 -*- |
7130 |
- |
7131 |
- |
7132 |
-def _gen_arches(ebuild, options, repo_settings, profiles): |
7133 |
- """Determines the arches for the ebuild following the profile rules |
7134 |
- |
7135 |
- @param ebuild: Ebuild which we check (object). |
7136 |
- @param profiles: dictionary |
7137 |
- @param options: cli options |
7138 |
- @param repo_settings: repository settings instance |
7139 |
- @returns: dictionary, including arches set |
7140 |
- """ |
7141 |
- if options.ignore_arches: |
7142 |
- arches = [ |
7143 |
- [ |
7144 |
- repo_settings.repoman_settings["ARCH"], |
7145 |
- repo_settings.repoman_settings["ARCH"], |
7146 |
- repo_settings.repoman_settings["ACCEPT_KEYWORDS"].split(), |
7147 |
- ] |
7148 |
- ] |
7149 |
- else: |
7150 |
- arches = set() |
7151 |
- for keyword in ebuild.keywords: |
7152 |
- if keyword[0] == "-": |
7153 |
- continue |
7154 |
- elif keyword[0] == "~": |
7155 |
- arch = keyword[1:] |
7156 |
- if arch == "*": |
7157 |
- for expanded_arch in profiles: |
7158 |
- if expanded_arch == "**": |
7159 |
- continue |
7160 |
- arches.add( |
7161 |
- ( |
7162 |
- keyword, |
7163 |
- expanded_arch, |
7164 |
- (expanded_arch, "~" + expanded_arch), |
7165 |
- ) |
7166 |
- ) |
7167 |
- else: |
7168 |
- arches.add((keyword, arch, (arch, keyword))) |
7169 |
- else: |
7170 |
- # For ebuilds with stable keywords, check if the |
7171 |
- # dependencies are satisfiable for unstable |
7172 |
- # configurations, since use.stable.mask is not |
7173 |
- # applied for unstable configurations (see bug |
7174 |
- # 563546). |
7175 |
- if keyword == "*": |
7176 |
- for expanded_arch in profiles: |
7177 |
- if expanded_arch == "**": |
7178 |
- continue |
7179 |
- arches.add((keyword, expanded_arch, (expanded_arch,))) |
7180 |
- arches.add( |
7181 |
- ( |
7182 |
- keyword, |
7183 |
- expanded_arch, |
7184 |
- (expanded_arch, "~" + expanded_arch), |
7185 |
- ) |
7186 |
- ) |
7187 |
- else: |
7188 |
- arches.add((keyword, keyword, (keyword,))) |
7189 |
- arches.add((keyword, keyword, (keyword, "~" + keyword))) |
7190 |
- if not arches: |
7191 |
- # Use an empty profile for checking dependencies of |
7192 |
- # packages that have empty KEYWORDS. |
7193 |
- arches.add(("**", "**", ("**",))) |
7194 |
- |
7195 |
- return arches |
7196 |
|
7197 |
diff --git a/repoman/lib/repoman/modules/scan/depend/profile.py b/repoman/lib/repoman/modules/scan/depend/profile.py |
7198 |
deleted file mode 100644 |
7199 |
index a0cb3a314..000000000 |
7200 |
--- a/repoman/lib/repoman/modules/scan/depend/profile.py |
7201 |
+++ /dev/null |
7202 |
@@ -1,427 +0,0 @@ |
7203 |
-# -*- coding:utf-8 -*- |
7204 |
- |
7205 |
- |
7206 |
-import copy |
7207 |
-import functools |
7208 |
-import os |
7209 |
-import types |
7210 |
-from pprint import pformat |
7211 |
- |
7212 |
-from _emerge.Package import Package |
7213 |
- |
7214 |
-# import our initialized portage instance |
7215 |
-from repoman._portage import portage |
7216 |
-from repoman.modules.scan.scanbase import ScanBase |
7217 |
-from repoman.modules.scan.depend._depend_checks import _depend_checks |
7218 |
-from repoman.modules.scan.depend._gen_arches import _gen_arches |
7219 |
-from portage.dep import Atom |
7220 |
-from portage.package.ebuild.profile_iuse import iter_iuse_vars |
7221 |
-from portage.util import getconfig |
7222 |
-from portage.util.futures import asyncio |
7223 |
-from portage.util.futures.executor.fork import ForkExecutor |
7224 |
-from portage.util.futures.iter_completed import async_iter_completed |
7225 |
- |
7226 |
- |
7227 |
-def sort_key(item): |
7228 |
- return item[2].sub_path |
7229 |
- |
7230 |
- |
7231 |
-class ProfileDependsChecks(ScanBase): |
7232 |
- """Perform dependency checks for the different profiles""" |
7233 |
- |
7234 |
- def __init__(self, **kwargs): |
7235 |
- """Class init |
7236 |
- |
7237 |
- @param qatracker: QATracker instance |
7238 |
- @param portdb: portdb instance |
7239 |
- @param profiles: dictionary |
7240 |
- @param options: cli options |
7241 |
- @param repo_settings: repository settings instance |
7242 |
- @param include_arches: set |
7243 |
- @param include_profiles: set |
7244 |
- @param caches: dictionary of our caches |
7245 |
- @param repoman_incrementals: tuple |
7246 |
- @param env: the environment |
7247 |
- @param have: dictionary instance |
7248 |
- @param dev_keywords: developer profile keywords |
7249 |
- @param repo_metadata: dictionary of various repository items. |
7250 |
- """ |
7251 |
- self.qatracker = kwargs.get("qatracker") |
7252 |
- self.portdb = kwargs.get("portdb") |
7253 |
- self.profiles = kwargs.get("profiles") |
7254 |
- self.options = kwargs.get("options") |
7255 |
- self.repo_settings = kwargs.get("repo_settings") |
7256 |
- self.include_arches = kwargs.get("include_arches") |
7257 |
- self.include_profiles = kwargs.get("include_profiles") |
7258 |
- self.caches = kwargs.get("caches") |
7259 |
- self.repoman_incrementals = kwargs.get("repoman_incrementals") |
7260 |
- self.env = kwargs.get("env") |
7261 |
- self.have = kwargs.get("have") |
7262 |
- self.dev_keywords = kwargs.get("dev_keywords") |
7263 |
- self.repo_metadata = kwargs.get("repo_metadata") |
7264 |
- |
7265 |
- def check(self, **kwargs): |
7266 |
- """Perform profile dependant dependency checks |
7267 |
- |
7268 |
- @param pkg: Package in which we check (object). |
7269 |
- @param ebuild: Ebuild which we check (object). |
7270 |
- @returns: dictionary |
7271 |
- """ |
7272 |
- ebuild = kwargs.get("ebuild").get() |
7273 |
- pkg = kwargs.get("pkg").get() |
7274 |
- |
7275 |
- ebuild.unknown_pkgs, ebuild.baddepsyntax = _depend_checks( |
7276 |
- ebuild, |
7277 |
- pkg, |
7278 |
- self.portdb, |
7279 |
- self.qatracker, |
7280 |
- self.repo_metadata, |
7281 |
- self.repo_settings.qadata, |
7282 |
- ) |
7283 |
- |
7284 |
- relevant_profiles = [] |
7285 |
- for keyword, arch, groups in _gen_arches( |
7286 |
- ebuild, self.options, self.repo_settings, self.profiles |
7287 |
- ): |
7288 |
- if arch not in self.profiles: |
7289 |
- # A missing profile will create an error further down |
7290 |
- # during the KEYWORDS verification. |
7291 |
- continue |
7292 |
- |
7293 |
- if self.include_arches is not None: |
7294 |
- if arch not in self.include_arches: |
7295 |
- continue |
7296 |
- |
7297 |
- for prof in self.profiles[arch]: |
7298 |
- if self.include_profiles is not None: |
7299 |
- if prof.sub_path not in self.include_profiles: |
7300 |
- continue |
7301 |
- relevant_profiles.append((keyword, groups, prof)) |
7302 |
- |
7303 |
- relevant_profiles.sort(key=sort_key) |
7304 |
- ebuild.relevant_profiles = relevant_profiles |
7305 |
- |
7306 |
- if self.options.jobs <= 1: |
7307 |
- for task in self._iter_tasks(None, None, ebuild, pkg): |
7308 |
- task, results = task |
7309 |
- for result in results: |
7310 |
- self._check_result(task, result) |
7311 |
- |
7312 |
- loop = asyncio.get_event_loop() |
7313 |
- loop.run_until_complete(self._async_check(loop, **kwargs)) |
7314 |
- |
7315 |
- return False |
7316 |
- |
7317 |
- async def _async_check(self, loop, **kwargs): |
7318 |
- """Perform async profile dependant dependency checks |
7319 |
- |
7320 |
- @param arches: |
7321 |
- @param pkg: Package in which we check (object). |
7322 |
- @param ebuild: Ebuild which we check (object). |
7323 |
- @param baddepsyntax: boolean |
7324 |
- @param unknown_pkgs: set of tuples (type, atom.unevaluated_atom) |
7325 |
- @returns: dictionary |
7326 |
- """ |
7327 |
- ebuild = kwargs.get("ebuild").get() |
7328 |
- pkg = kwargs.get("pkg").get() |
7329 |
- unknown_pkgs = ebuild.unknown_pkgs |
7330 |
- baddepsyntax = ebuild.baddepsyntax |
7331 |
- |
7332 |
- # Use max_workers=True to ensure immediate fork, since _iter_tasks |
7333 |
- # needs the fork to create a snapshot of current state. |
7334 |
- executor = ForkExecutor(max_workers=self.options.jobs) |
7335 |
- |
7336 |
- if self.options.jobs > 1: |
7337 |
- for future_done_set in async_iter_completed( |
7338 |
- self._iter_tasks(loop, executor, ebuild, pkg), |
7339 |
- max_jobs=self.options.jobs, |
7340 |
- max_load=self.options.load_average, |
7341 |
- ): |
7342 |
- for task in await future_done_set: |
7343 |
- task, results = task.result() |
7344 |
- for result in results: |
7345 |
- self._check_result(task, result) |
7346 |
- |
7347 |
- if not baddepsyntax and unknown_pkgs: |
7348 |
- type_map = {} |
7349 |
- for mytype, atom in unknown_pkgs: |
7350 |
- type_map.setdefault(mytype, set()).add(atom) |
7351 |
- for mytype, atoms in type_map.items(): |
7352 |
- self.qatracker.add_error( |
7353 |
- "dependency.unknown", |
7354 |
- "%s: %s: %s" |
7355 |
- % (ebuild.relative_path, mytype, ", ".join(sorted(atoms))), |
7356 |
- ) |
7357 |
- |
7358 |
- async def _task(self, task): |
7359 |
- await task.future |
7360 |
- return (task, task.future.result()) |
7361 |
- |
7362 |
- def _iter_tasks(self, loop, executor, ebuild, pkg): |
7363 |
- for keyword, groups, prof in ebuild.relevant_profiles: |
7364 |
- |
7365 |
- is_stable_profile = prof.status == "stable" |
7366 |
- is_dev_profile = prof.status == "dev" and self.options.include_dev |
7367 |
- is_exp_profile = ( |
7368 |
- prof.status == "exp" and self.options.include_exp_profiles == "y" |
7369 |
- ) |
7370 |
- if not (is_stable_profile or is_dev_profile or is_exp_profile): |
7371 |
- continue |
7372 |
- |
7373 |
- dep_settings = self.caches["arch"].get(prof.sub_path) |
7374 |
- if dep_settings is None: |
7375 |
- dep_settings = portage.config( |
7376 |
- config_profile_path=prof.abs_path, |
7377 |
- config_incrementals=self.repoman_incrementals, |
7378 |
- config_root=self.repo_settings.config_root, |
7379 |
- local_config=False, |
7380 |
- _unmatched_removal=self.options.unmatched_removal, |
7381 |
- env=self.env, |
7382 |
- repositories=self.repo_settings.repoman_settings.repositories, |
7383 |
- ) |
7384 |
- |
7385 |
- if not prof.abs_path: |
7386 |
- self._populate_implicit_iuse( |
7387 |
- dep_settings, self.repo_settings.repo_config.eclass_db.porttrees |
7388 |
- ) |
7389 |
- |
7390 |
- dep_settings.categories = self.repo_settings.repoman_settings.categories |
7391 |
- if self.options.without_mask: |
7392 |
- dep_settings._mask_manager_obj = copy.deepcopy( |
7393 |
- dep_settings._mask_manager |
7394 |
- ) |
7395 |
- dep_settings._mask_manager._pmaskdict.clear() |
7396 |
- self.caches["arch"][prof.sub_path] = dep_settings |
7397 |
- |
7398 |
- xmatch_cache_key = (prof.sub_path, tuple(groups)) |
7399 |
- xcache = self.caches["arch_xmatch"].get(xmatch_cache_key) |
7400 |
- if xcache is None: |
7401 |
- self.portdb.melt() |
7402 |
- self.portdb.freeze() |
7403 |
- xcache = self.portdb.xcache |
7404 |
- xcache.update(self.caches["shared_xmatch"]) |
7405 |
- self.caches["arch_xmatch"][xmatch_cache_key] = xcache |
7406 |
- |
7407 |
- self.repo_settings.trees[self.repo_settings.root][ |
7408 |
- "porttree" |
7409 |
- ].settings = dep_settings |
7410 |
- self.portdb.settings = dep_settings |
7411 |
- self.portdb.xcache = xcache |
7412 |
- |
7413 |
- dep_settings["ACCEPT_KEYWORDS"] = " ".join(groups) |
7414 |
- # just in case, prevent config.reset() from nuking these. |
7415 |
- dep_settings.backup_changes("ACCEPT_KEYWORDS") |
7416 |
- |
7417 |
- # This attribute is used in dbapi._match_use() to apply |
7418 |
- # use.stable.{mask,force} settings based on the stable |
7419 |
- # status of the parent package. This is required in order |
7420 |
- # for USE deps of unstable packages to be resolved correctly, |
7421 |
- # since otherwise use.stable.{mask,force} settings of |
7422 |
- # dependencies may conflict (see bug #456342). |
7423 |
- dep_settings._parent_stable = dep_settings._isStable(pkg) |
7424 |
- |
7425 |
- # Handle package.use*.{force,mask) calculation, for use |
7426 |
- # in dep_check. |
7427 |
- dep_settings.useforce = dep_settings._use_manager.getUseForce( |
7428 |
- pkg, stable=dep_settings._parent_stable |
7429 |
- ) |
7430 |
- dep_settings.usemask = dep_settings._use_manager.getUseMask( |
7431 |
- pkg, stable=dep_settings._parent_stable |
7432 |
- ) |
7433 |
- |
7434 |
- task = types.SimpleNamespace(ebuild=ebuild, prof=prof, keyword=keyword) |
7435 |
- |
7436 |
- target = functools.partial(self._task_subprocess, task, pkg, dep_settings) |
7437 |
- |
7438 |
- if self.options.jobs <= 1: |
7439 |
- yield (task, target()) |
7440 |
- else: |
7441 |
- task.future = asyncio.ensure_future( |
7442 |
- loop.run_in_executor(executor, target), loop=loop |
7443 |
- ) |
7444 |
- yield asyncio.ensure_future(self._task(task), loop=loop) |
7445 |
- |
7446 |
- def _task_subprocess(self, task, pkg, dep_settings): |
7447 |
- ebuild = task.ebuild |
7448 |
- baddepsyntax = ebuild.baddepsyntax |
7449 |
- results = [] |
7450 |
- prof = task.prof |
7451 |
- if not baddepsyntax: |
7452 |
- ismasked = not ebuild.archs or pkg.cpv not in self.portdb.xmatch( |
7453 |
- "match-visible", |
7454 |
- Atom("%s::%s" % (pkg.cp, self.repo_settings.repo_config.name)), |
7455 |
- ) |
7456 |
- if ismasked: |
7457 |
- if not self.have["pmasked"]: |
7458 |
- self.have["pmasked"] = bool( |
7459 |
- dep_settings._getMaskAtom(pkg.cpv, ebuild.metadata) |
7460 |
- ) |
7461 |
- if self.options.ignore_masked: |
7462 |
- return results |
7463 |
- # we are testing deps for a masked package; give it some lee-way |
7464 |
- suffix = "masked" |
7465 |
- matchmode = "minimum-all-ignore-profile" |
7466 |
- else: |
7467 |
- suffix = "" |
7468 |
- matchmode = "minimum-visible" |
7469 |
- |
7470 |
- if not self.have["dev_keywords"]: |
7471 |
- self.have["dev_keywords"] = bool( |
7472 |
- self.dev_keywords.intersection(ebuild.keywords) |
7473 |
- ) |
7474 |
- |
7475 |
- if prof.status == "dev": |
7476 |
- suffix = suffix + "indev" |
7477 |
- elif prof.status == "exp": |
7478 |
- suffix = suffix + "inexp" |
7479 |
- |
7480 |
- for mytype in Package._dep_keys: |
7481 |
- |
7482 |
- mykey = "dependency.bad" + suffix |
7483 |
- myvalue = ebuild.metadata[mytype] |
7484 |
- if not myvalue: |
7485 |
- continue |
7486 |
- |
7487 |
- success, atoms = portage.dep_check( |
7488 |
- myvalue, |
7489 |
- self.portdb, |
7490 |
- dep_settings, |
7491 |
- use="all", |
7492 |
- mode=matchmode, |
7493 |
- trees=self.repo_settings.trees, |
7494 |
- ) |
7495 |
- |
7496 |
- results.append( |
7497 |
- types.SimpleNamespace( |
7498 |
- atoms=atoms, success=success, mykey=mykey, mytype=mytype |
7499 |
- ) |
7500 |
- ) |
7501 |
- |
7502 |
- return results |
7503 |
- |
7504 |
- def _check_result(self, task, result): |
7505 |
- prof = task.prof |
7506 |
- keyword = task.keyword |
7507 |
- ebuild = task.ebuild |
7508 |
- unknown_pkgs = ebuild.unknown_pkgs |
7509 |
- |
7510 |
- success = result.success |
7511 |
- atoms = result.atoms |
7512 |
- mykey = result.mykey |
7513 |
- mytype = result.mytype |
7514 |
- |
7515 |
- if success: |
7516 |
- if atoms: |
7517 |
- |
7518 |
- # Don't bother with dependency.unknown for |
7519 |
- # cases in which *DEPEND.bad is triggered. |
7520 |
- for atom in atoms: |
7521 |
- # dep_check returns all blockers and they |
7522 |
- # aren't counted for *DEPEND.bad, so we |
7523 |
- # ignore them here. |
7524 |
- if not atom.blocker: |
7525 |
- unknown_pkgs.discard((mytype, atom.unevaluated_atom)) |
7526 |
- |
7527 |
- if not prof.sub_path: |
7528 |
- # old-style virtuals currently aren't |
7529 |
- # resolvable with empty profile, since |
7530 |
- # 'virtuals' mappings are unavailable |
7531 |
- # (it would be expensive to search |
7532 |
- # for PROVIDE in all ebuilds) |
7533 |
- atoms = [ |
7534 |
- atom |
7535 |
- for atom in atoms |
7536 |
- if not ( |
7537 |
- atom.cp.startswith("virtual/") |
7538 |
- and not self.portdb.cp_list(atom.cp) |
7539 |
- ) |
7540 |
- ] |
7541 |
- |
7542 |
- # we have some unsolvable deps |
7543 |
- # remove ! deps, which always show up as unsatisfiable |
7544 |
- all_atoms = [ |
7545 |
- str(atom.unevaluated_atom) for atom in atoms if not atom.blocker |
7546 |
- ] |
7547 |
- |
7548 |
- # if we emptied out our list, continue: |
7549 |
- if not all_atoms: |
7550 |
- return |
7551 |
- |
7552 |
- # Filter out duplicates. We do this by hand (rather |
7553 |
- # than use a set) so the order is stable and better |
7554 |
- # matches the order that's in the ebuild itself. |
7555 |
- atoms = [] |
7556 |
- for atom in all_atoms: |
7557 |
- if atom not in atoms: |
7558 |
- atoms.append(atom) |
7559 |
- |
7560 |
- if self.options.output_style in ["column"]: |
7561 |
- self.qatracker.add_error( |
7562 |
- mykey, |
7563 |
- "%s: %s: %s(%s) %s" |
7564 |
- % (ebuild.relative_path, mytype, keyword, prof, repr(atoms)), |
7565 |
- ) |
7566 |
- else: |
7567 |
- self.qatracker.add_error( |
7568 |
- mykey, |
7569 |
- "%s: %s: %s(%s)\n%s" |
7570 |
- % ( |
7571 |
- ebuild.relative_path, |
7572 |
- mytype, |
7573 |
- keyword, |
7574 |
- prof, |
7575 |
- pformat(atoms, indent=6), |
7576 |
- ), |
7577 |
- ) |
7578 |
- else: |
7579 |
- if self.options.output_style in ["column"]: |
7580 |
- self.qatracker.add_error( |
7581 |
- mykey, |
7582 |
- "%s: %s: %s(%s) %s" |
7583 |
- % (ebuild.relative_path, mytype, keyword, prof, repr(atoms)), |
7584 |
- ) |
7585 |
- else: |
7586 |
- self.qatracker.add_error( |
7587 |
- mykey, |
7588 |
- "%s: %s: %s(%s)\n%s" |
7589 |
- % ( |
7590 |
- ebuild.relative_path, |
7591 |
- mytype, |
7592 |
- keyword, |
7593 |
- prof, |
7594 |
- pformat(atoms, indent=6), |
7595 |
- ), |
7596 |
- ) |
7597 |
- |
7598 |
- @property |
7599 |
- def runInEbuilds(self): |
7600 |
- """Ebuild level scans""" |
7601 |
- return (True, [self.check]) |
7602 |
- |
7603 |
- @staticmethod |
7604 |
- def _populate_implicit_iuse(config, repo_locations): |
7605 |
- """ |
7606 |
- Populate implicit IUSE for the empty profile, see bug 660982. |
7607 |
- |
7608 |
- @param config: config instance for the empty profile |
7609 |
- @type config: portage.config |
7610 |
- @param repo_locations: locations of repositories containing relevant |
7611 |
- implicit IUSE settings |
7612 |
- @type repo_locations: list |
7613 |
- """ |
7614 |
- dest = config.configdict["defaults"] |
7615 |
- for location in repo_locations: |
7616 |
- for parent_dir, dirs, files in os.walk(os.path.join(location, "profiles")): |
7617 |
- src = getconfig(os.path.join(parent_dir, "make.defaults")) |
7618 |
- if not src: |
7619 |
- continue |
7620 |
- for k, v in iter_iuse_vars(src): |
7621 |
- v_before = dest.get(k) |
7622 |
- if v_before is not None: |
7623 |
- merged_values = set(v_before.split()) |
7624 |
- merged_values.update(v.split()) |
7625 |
- v = " ".join(sorted(merged_values)) |
7626 |
- dest[k] = v |
7627 |
- |
7628 |
- config.regenerate() |
7629 |
- config._init_iuse() |
7630 |
|
7631 |
diff --git a/repoman/lib/repoman/modules/scan/directories/__init__.py b/repoman/lib/repoman/modules/scan/directories/__init__.py |
7632 |
deleted file mode 100644 |
7633 |
index 68596267d..000000000 |
7634 |
--- a/repoman/lib/repoman/modules/scan/directories/__init__.py |
7635 |
+++ /dev/null |
7636 |
@@ -1,53 +0,0 @@ |
7637 |
-# Copyright 2015-2021 Gentoo Authors |
7638 |
-# Distributed under the terms of the GNU General Public License v2 |
7639 |
- |
7640 |
-doc = """Directories plug-in module for repoman. |
7641 |
-Performs an FilesChecks check on ebuilds.""" |
7642 |
-__doc__ = doc[:] |
7643 |
- |
7644 |
- |
7645 |
-module_spec = { |
7646 |
- "name": "directories", |
7647 |
- "description": doc, |
7648 |
- "provides": { |
7649 |
- "directories-module": { |
7650 |
- "name": "files", |
7651 |
- "sourcefile": "files", |
7652 |
- "class": "FileChecks", |
7653 |
- "description": doc, |
7654 |
- "functions": ["check"], |
7655 |
- "func_kwargs": {}, |
7656 |
- "mod_kwargs": [ |
7657 |
- "portdb", |
7658 |
- "qatracker", |
7659 |
- "repo_settings", |
7660 |
- "vcs_settings", |
7661 |
- ], |
7662 |
- "func_kwargs": { |
7663 |
- "changed": (None, None), |
7664 |
- "checkdir": (None, None), |
7665 |
- "checkdirlist": (None, None), |
7666 |
- "checkdir_relative": (None, None), |
7667 |
- }, |
7668 |
- "module_runsIn": ["pkgs"], |
7669 |
- }, |
7670 |
- "mtime-module": { |
7671 |
- "name": "mtime", |
7672 |
- "sourcefile": "mtime", |
7673 |
- "class": "MtimeChecks", |
7674 |
- "description": doc, |
7675 |
- "functions": ["check"], |
7676 |
- "func_kwargs": {}, |
7677 |
- "mod_kwargs": [ |
7678 |
- "vcs_settings", |
7679 |
- ], |
7680 |
- "func_kwargs": { |
7681 |
- "changed": (None, None), |
7682 |
- "ebuild": (None, None), |
7683 |
- "pkg": (None, None), |
7684 |
- }, |
7685 |
- "module_runsIn": ["ebuilds"], |
7686 |
- }, |
7687 |
- }, |
7688 |
- "version": 1, |
7689 |
-} |
7690 |
|
7691 |
diff --git a/repoman/lib/repoman/modules/scan/directories/files.py b/repoman/lib/repoman/modules/scan/directories/files.py |
7692 |
deleted file mode 100644 |
7693 |
index 246d88483..000000000 |
7694 |
--- a/repoman/lib/repoman/modules/scan/directories/files.py |
7695 |
+++ /dev/null |
7696 |
@@ -1,99 +0,0 @@ |
7697 |
-# -*- coding:utf-8 -*- |
7698 |
- |
7699 |
-"""repoman/checks/diretories/files.py |
7700 |
- |
7701 |
-""" |
7702 |
- |
7703 |
-import io |
7704 |
- |
7705 |
-from portage import _encodings, _unicode_encode |
7706 |
-from portage import os |
7707 |
- |
7708 |
-from repoman.modules.vcs.vcs import vcs_new_changed |
7709 |
-from repoman.modules.scan.scanbase import ScanBase |
7710 |
- |
7711 |
- |
7712 |
-class FileChecks(ScanBase): |
7713 |
- """Performs various file checks in the package's directory""" |
7714 |
- |
7715 |
- def __init__(self, **kwargs): |
7716 |
- """ |
7717 |
- @param portdb: portdb instance |
7718 |
- @param qatracker: QATracker instance |
7719 |
- @param repo_settings: settings instance |
7720 |
- @param vcs_settings: VCSSettings instance |
7721 |
- """ |
7722 |
- super(FileChecks, self).__init__(**kwargs) |
7723 |
- self.portdb = kwargs.get("portdb") |
7724 |
- self.qatracker = kwargs.get("qatracker") |
7725 |
- self.repo_settings = kwargs.get("repo_settings") |
7726 |
- self.repoman_settings = self.repo_settings.repoman_settings |
7727 |
- self.vcs_settings = kwargs.get("vcs_settings") |
7728 |
- |
7729 |
- def check(self, **kwargs): |
7730 |
- """Checks the ebuild sources and files for errors |
7731 |
- |
7732 |
- @param checkdir: string, directory path |
7733 |
- @param checkdir_relative: repolevel determined path |
7734 |
- @param changed: dictionary instance |
7735 |
- @returns: dictionary |
7736 |
- """ |
7737 |
- checkdir = kwargs.get("checkdir") |
7738 |
- checkdirlist = kwargs.get("checkdirlist").get() |
7739 |
- checkdir_relative = kwargs.get("checkdir_relative") |
7740 |
- changed = kwargs.get("changed").changed |
7741 |
- new = kwargs.get("changed").new |
7742 |
- for y_file in checkdirlist: |
7743 |
- index = self.repo_settings.repo_config.find_invalid_path_char(y_file) |
7744 |
- if index != -1: |
7745 |
- y_relative = os.path.join(checkdir_relative, y_file) |
7746 |
- invcs = self.vcs_settings.vcs is not None |
7747 |
- inchangeset = vcs_new_changed(y_relative, changed, new) |
7748 |
- if invcs and not inchangeset: |
7749 |
- # If the file isn't in the VCS new or changed set, then |
7750 |
- # assume that it's an irrelevant temporary file (Manifest |
7751 |
- # entries are not generated for file names containing |
7752 |
- # prohibited characters). See bug #406877. |
7753 |
- index = -1 |
7754 |
- if index != -1: |
7755 |
- self.qatracker.add_error( |
7756 |
- "file.name", "%s/%s: char '%s'" % (checkdir, y_file, y_file[index]) |
7757 |
- ) |
7758 |
- |
7759 |
- if not ( |
7760 |
- y_file in ("ChangeLog", "metadata.xml") or y_file.endswith(".ebuild") |
7761 |
- ): |
7762 |
- continue |
7763 |
- f = None |
7764 |
- try: |
7765 |
- line = 1 |
7766 |
- f = io.open( |
7767 |
- _unicode_encode( |
7768 |
- os.path.join(checkdir, y_file), |
7769 |
- encoding=_encodings["fs"], |
7770 |
- errors="strict", |
7771 |
- ), |
7772 |
- mode="r", |
7773 |
- encoding=_encodings["repo.content"], |
7774 |
- ) |
7775 |
- for l in f: |
7776 |
- line += 1 |
7777 |
- except UnicodeDecodeError as ue: |
7778 |
- s = ue.object[: ue.start] |
7779 |
- l2 = s.count("\n") |
7780 |
- line += l2 |
7781 |
- if l2 != 0: |
7782 |
- s = s[s.rfind("\n") + 1 :] |
7783 |
- self.qatracker.add_error( |
7784 |
- "file.UTF8", |
7785 |
- "%s/%s: line %i, just after: '%s'" % (checkdir, y_file, line, s), |
7786 |
- ) |
7787 |
- finally: |
7788 |
- if f is not None: |
7789 |
- f.close() |
7790 |
- return False |
7791 |
- |
7792 |
- @property |
7793 |
- def runInPkgs(self): |
7794 |
- """Package level scans""" |
7795 |
- return (True, [self.check]) |
7796 |
|
7797 |
diff --git a/repoman/lib/repoman/modules/scan/directories/mtime.py b/repoman/lib/repoman/modules/scan/directories/mtime.py |
7798 |
deleted file mode 100644 |
7799 |
index 34e210257..000000000 |
7800 |
--- a/repoman/lib/repoman/modules/scan/directories/mtime.py |
7801 |
+++ /dev/null |
7802 |
@@ -1,30 +0,0 @@ |
7803 |
-from repoman.modules.scan.scanbase import ScanBase |
7804 |
- |
7805 |
- |
7806 |
-class MtimeChecks(ScanBase): |
7807 |
- def __init__(self, **kwargs): |
7808 |
- self.vcs_settings = kwargs.get("vcs_settings") |
7809 |
- |
7810 |
- def check(self, **kwargs): |
7811 |
- """Perform a changelog and untracked checks on the ebuild |
7812 |
- |
7813 |
- @param pkg: Package in which we check (object). |
7814 |
- @param ebuild: Ebuild which we check (object). |
7815 |
- @param changed: dictionary instance |
7816 |
- @returns: dictionary |
7817 |
- """ |
7818 |
- ebuild = kwargs.get("ebuild").get() |
7819 |
- changed = kwargs.get("changed") |
7820 |
- pkg = kwargs.get("pkg").get() |
7821 |
- if not self.vcs_settings.vcs_preserves_mtime: |
7822 |
- if ( |
7823 |
- ebuild.ebuild_path not in changed.new_ebuilds |
7824 |
- and ebuild.ebuild_path not in changed.ebuilds |
7825 |
- ): |
7826 |
- pkg.mtime = None |
7827 |
- return False |
7828 |
- |
7829 |
- @property |
7830 |
- def runInEbuilds(self): |
7831 |
- """Ebuild level scans""" |
7832 |
- return (True, [self.check]) |
7833 |
|
7834 |
diff --git a/repoman/lib/repoman/modules/scan/eapi/__init__.py b/repoman/lib/repoman/modules/scan/eapi/__init__.py |
7835 |
deleted file mode 100644 |
7836 |
index a86d74b3c..000000000 |
7837 |
--- a/repoman/lib/repoman/modules/scan/eapi/__init__.py |
7838 |
+++ /dev/null |
7839 |
@@ -1,28 +0,0 @@ |
7840 |
-# Copyright 2015-2021 Gentoo Authors |
7841 |
-# Distributed under the terms of the GNU General Public License v2 |
7842 |
- |
7843 |
-doc = """Eapi plug-in module for repoman. |
7844 |
-Performs an IsEbuild check on ebuilds.""" |
7845 |
-__doc__ = doc[:] |
7846 |
- |
7847 |
- |
7848 |
-module_spec = { |
7849 |
- "name": "eapi", |
7850 |
- "description": doc, |
7851 |
- "provides": { |
7852 |
- "live-module": { |
7853 |
- "name": "eapi", |
7854 |
- "sourcefile": "eapi", |
7855 |
- "class": "EAPIChecks", |
7856 |
- "description": doc, |
7857 |
- "functions": ["check"], |
7858 |
- "func_kwargs": {}, |
7859 |
- "mod_kwargs": ["qatracker", "repo_settings"], |
7860 |
- "func_kwargs": { |
7861 |
- "ebuild": (None, None), |
7862 |
- }, |
7863 |
- "module_runsIn": ["ebuilds"], |
7864 |
- }, |
7865 |
- }, |
7866 |
- "version": 1, |
7867 |
-} |
7868 |
|
7869 |
diff --git a/repoman/lib/repoman/modules/scan/eapi/eapi.py b/repoman/lib/repoman/modules/scan/eapi/eapi.py |
7870 |
deleted file mode 100644 |
7871 |
index df7c220e6..000000000 |
7872 |
--- a/repoman/lib/repoman/modules/scan/eapi/eapi.py |
7873 |
+++ /dev/null |
7874 |
@@ -1,50 +0,0 @@ |
7875 |
-"""eapi.py |
7876 |
-Perform checks on the EAPI variable. |
7877 |
-""" |
7878 |
- |
7879 |
-from repoman.modules.scan.scanbase import ScanBase |
7880 |
- |
7881 |
- |
7882 |
-class EAPIChecks(ScanBase): |
7883 |
- """Perform checks on the EAPI variable.""" |
7884 |
- |
7885 |
- def __init__(self, **kwargs): |
7886 |
- """ |
7887 |
- @param qatracker: QATracker instance |
7888 |
- @param repo_settings: Repository settings |
7889 |
- """ |
7890 |
- self.qatracker = kwargs.get("qatracker") |
7891 |
- self.repo_settings = kwargs.get("repo_settings") |
7892 |
- |
7893 |
- def check(self, **kwargs): |
7894 |
- """ |
7895 |
- @param pkg: Package in which we check (object). |
7896 |
- @param ebuild: Ebuild which we check (object). |
7897 |
- @returns: dictionary |
7898 |
- """ |
7899 |
- ebuild = kwargs.get("ebuild").get() |
7900 |
- |
7901 |
- if not self._checkBanned(ebuild): |
7902 |
- self._checkDeprecated(ebuild) |
7903 |
- return False |
7904 |
- |
7905 |
- def _checkBanned(self, ebuild): |
7906 |
- if self.repo_settings.repo_config.eapi_is_banned(ebuild.eapi): |
7907 |
- self.qatracker.add_error( |
7908 |
- "repo.eapi-banned", "%s: %s" % (ebuild.relative_path, ebuild.eapi) |
7909 |
- ) |
7910 |
- return True |
7911 |
- return False |
7912 |
- |
7913 |
- def _checkDeprecated(self, ebuild): |
7914 |
- if self.repo_settings.repo_config.eapi_is_deprecated(ebuild.eapi): |
7915 |
- self.qatracker.add_error( |
7916 |
- "repo.eapi-deprecated", "%s: %s" % (ebuild.relative_path, ebuild.eapi) |
7917 |
- ) |
7918 |
- return True |
7919 |
- return False |
7920 |
- |
7921 |
- @property |
7922 |
- def runInEbuilds(self): |
7923 |
- """Ebuild level scans""" |
7924 |
- return (True, [self.check]) |
7925 |
|
7926 |
diff --git a/repoman/lib/repoman/modules/scan/ebuild/__init__.py b/repoman/lib/repoman/modules/scan/ebuild/__init__.py |
7927 |
deleted file mode 100644 |
7928 |
index 029b5628d..000000000 |
7929 |
--- a/repoman/lib/repoman/modules/scan/ebuild/__init__.py |
7930 |
+++ /dev/null |
7931 |
@@ -1,66 +0,0 @@ |
7932 |
-# Copyright 2015-2021 Gentoo Authors |
7933 |
-# Distributed under the terms of the GNU General Public License v2 |
7934 |
- |
7935 |
-doc = """Ebuild plug-in module for repoman. |
7936 |
-Performs an IsEbuild check on ebuilds.""" |
7937 |
-__doc__ = doc[:] |
7938 |
- |
7939 |
- |
7940 |
-module_spec = { |
7941 |
- "name": "ebuild", |
7942 |
- "description": doc, |
7943 |
- "provides": { |
7944 |
- "ebuild-module": { |
7945 |
- "name": "ebuild", |
7946 |
- "sourcefile": "ebuild", |
7947 |
- "class": "Ebuild", |
7948 |
- "description": doc, |
7949 |
- "functions": ["check"], |
7950 |
- "func_desc": {}, |
7951 |
- "mod_kwargs": [ |
7952 |
- "qatracker", |
7953 |
- "repo_settings", |
7954 |
- "vcs_settings", |
7955 |
- "checks", |
7956 |
- "portdb", |
7957 |
- ], |
7958 |
- "func_kwargs": { |
7959 |
- "can_force": (None, None), |
7960 |
- "catdir": (None, None), |
7961 |
- "changed": (None, None), |
7962 |
- "changelog_modified": (None, None), |
7963 |
- "checkdir": (None, None), |
7964 |
- "checkdirlist": (None, None), |
7965 |
- "ebuild": ("Future", "UNSET"), |
7966 |
- "pkg": ("Future", "UNSET"), |
7967 |
- "pkgdir": (None, None), |
7968 |
- "pkgs": ("Future", "dict"), |
7969 |
- "repolevel": (None, None), |
7970 |
- "validity_future": (None, None), |
7971 |
- "xpkg": (None, None), |
7972 |
- "y_ebuild": (None, None), |
7973 |
- }, |
7974 |
- "module_runsIn": ["pkgs", "ebuilds"], |
7975 |
- }, |
7976 |
- "multicheck-module": { |
7977 |
- "name": "multicheck", |
7978 |
- "sourcefile": "multicheck", |
7979 |
- "class": "MultiCheck", |
7980 |
- "description": doc, |
7981 |
- "functions": ["check"], |
7982 |
- "func_kwargs": {}, |
7983 |
- "mod_kwargs": [ |
7984 |
- "qatracker", |
7985 |
- "options", |
7986 |
- "repo_settings", |
7987 |
- "linechecks", |
7988 |
- ], |
7989 |
- "func_kwargs": { |
7990 |
- "ebuild": (None, None), |
7991 |
- "pkg": (None, None), |
7992 |
- }, |
7993 |
- "module_runsIn": ["ebuilds"], |
7994 |
- }, |
7995 |
- }, |
7996 |
- "version": 1, |
7997 |
-} |
7998 |
|
7999 |
diff --git a/repoman/lib/repoman/modules/scan/ebuild/ebuild.py b/repoman/lib/repoman/modules/scan/ebuild/ebuild.py |
8000 |
deleted file mode 100644 |
8001 |
index ae3275780..000000000 |
8002 |
--- a/repoman/lib/repoman/modules/scan/ebuild/ebuild.py |
8003 |
+++ /dev/null |
8004 |
@@ -1,263 +0,0 @@ |
8005 |
-# -*- coding:utf-8 -*- |
8006 |
- |
8007 |
-import re |
8008 |
-import stat |
8009 |
- |
8010 |
-from _emerge.Package import Package |
8011 |
-from _emerge.RootConfig import RootConfig |
8012 |
- |
8013 |
-from repoman.modules.scan.scanbase import ScanBase |
8014 |
- |
8015 |
-# import our initialized portage instance |
8016 |
-from repoman._portage import portage |
8017 |
- |
8018 |
-from portage import os |
8019 |
-from portage.exception import InvalidPackageName |
8020 |
- |
8021 |
-pv_toolong_re = re.compile(r"[0-9]{19,}") |
8022 |
- |
8023 |
- |
8024 |
-class Ebuild(ScanBase): |
8025 |
- """Class to run primary checks on ebuilds""" |
8026 |
- |
8027 |
- def __init__(self, **kwargs): |
8028 |
- """Class init |
8029 |
- |
8030 |
- @param qatracker: QATracker instance |
8031 |
- @param portdb: portdb instance |
8032 |
- @param repo_settings: repository settings instance |
8033 |
- @param vcs_settings: VCSSettings instance |
8034 |
- @param checks: checks dictionary |
8035 |
- """ |
8036 |
- super(Ebuild, self).__init__(**kwargs) |
8037 |
- self.qatracker = kwargs.get("qatracker") |
8038 |
- self.portdb = kwargs.get("portdb") |
8039 |
- self.repo_settings = kwargs.get("repo_settings") |
8040 |
- self.vcs_settings = kwargs.get("vcs_settings") |
8041 |
- self.checks = kwargs.get("checks") |
8042 |
- self.root_config = RootConfig( |
8043 |
- self.repo_settings.repoman_settings, |
8044 |
- self.repo_settings.trees[self.repo_settings.root], |
8045 |
- None, |
8046 |
- ) |
8047 |
- self.changed = None |
8048 |
- self.xpkg = None |
8049 |
- self.y_ebuild = None |
8050 |
- self.pkg = None |
8051 |
- self.metadata = None |
8052 |
- self.eapi = None |
8053 |
- self.inherited = None |
8054 |
- self.live_ebuild = None |
8055 |
- self.keywords = None |
8056 |
- self.pkgs = {} |
8057 |
- |
8058 |
- def _set_paths(self, **kwargs): |
8059 |
- repolevel = kwargs.get("repolevel") |
8060 |
- self.relative_path = os.path.join(self.xpkg, self.y_ebuild + ".ebuild") |
8061 |
- self.full_path = os.path.join(self.repo_settings.repodir, self.relative_path) |
8062 |
- self.ebuild_path = self.y_ebuild + ".ebuild" |
8063 |
- if repolevel < 3: |
8064 |
- self.ebuild_path = os.path.join(kwargs.get("pkgdir"), self.ebuild_path) |
8065 |
- if repolevel < 2: |
8066 |
- self.ebuild_path = os.path.join(kwargs.get("catdir"), self.ebuild_path) |
8067 |
- self.ebuild_path = os.path.join(".", self.ebuild_path) |
8068 |
- |
8069 |
- @property |
8070 |
- def untracked(self): |
8071 |
- """Determines and returns if the ebuild is not tracked by the vcs""" |
8072 |
- do_check = self.vcs_settings.vcs in ("cvs", "svn", "bzr") |
8073 |
- really_notadded = ( |
8074 |
- self.checks["ebuild_notadded"] |
8075 |
- and self.y_ebuild not in self.vcs_settings.eadded |
8076 |
- ) |
8077 |
- if do_check and really_notadded: |
8078 |
- # ebuild not added to vcs |
8079 |
- return True |
8080 |
- return False |
8081 |
- |
8082 |
- def check(self, **kwargs): |
8083 |
- """Perform a changelog and untracked checks on the ebuild |
8084 |
- |
8085 |
- @param xpkg: Package in which we check (object). |
8086 |
- @param y_ebuild: Ebuild which we check (string). |
8087 |
- @param changed: dictionary instance |
8088 |
- @param repolevel: The depth within the repository |
8089 |
- @param catdir: The category directiory |
8090 |
- @param pkgdir: the package directory |
8091 |
- @returns: dictionary, including {ebuild object} |
8092 |
- """ |
8093 |
- self.xpkg = kwargs.get("xpkg") |
8094 |
- self.y_ebuild = kwargs.get("y_ebuild") |
8095 |
- self.changed = kwargs.get("changed") |
8096 |
- changelog_modified = kwargs.get("changelog_modified") |
8097 |
- self._set_paths(**kwargs) |
8098 |
- |
8099 |
- if ( |
8100 |
- self.checks["changelog"] |
8101 |
- and not changelog_modified |
8102 |
- and self.ebuild_path in self.changed.new_ebuilds |
8103 |
- ): |
8104 |
- self.qatracker.add_error("changelog.ebuildadded", self.relative_path) |
8105 |
- |
8106 |
- if self.untracked: |
8107 |
- # ebuild not added to vcs |
8108 |
- self.qatracker.add_error( |
8109 |
- "ebuild.notadded", self.xpkg + "/" + self.y_ebuild + ".ebuild" |
8110 |
- ) |
8111 |
- # update the dynamic data |
8112 |
- dyn_ebuild = kwargs.get("ebuild") |
8113 |
- dyn_ebuild.set(self) |
8114 |
- return False |
8115 |
- |
8116 |
- def set_pkg_data(self, **kwargs): |
8117 |
- """Sets some classwide data needed for some of the checks |
8118 |
- |
8119 |
- @returns: dictionary |
8120 |
- """ |
8121 |
- self.pkg = self.pkgs[self.y_ebuild] |
8122 |
- self.metadata = self.pkg._metadata |
8123 |
- self.eapi = self.metadata["EAPI"] |
8124 |
- self.inherited = self.pkg.inherited |
8125 |
- self.live_ebuild = "live" in self.metadata["PROPERTIES"].split() |
8126 |
- self.keywords = self.metadata["KEYWORDS"].split() |
8127 |
- self.archs = set( |
8128 |
- kw.lstrip("~") for kw in self.keywords if not kw.startswith("-") |
8129 |
- ) |
8130 |
- return False |
8131 |
- |
8132 |
- def bad_split_check(self, **kwargs): |
8133 |
- """Checks for bad category/package splits. |
8134 |
- |
8135 |
- @param pkgdir: string: path |
8136 |
- @returns: dictionary |
8137 |
- """ |
8138 |
- pkgdir = kwargs.get("pkgdir") |
8139 |
- myesplit = portage.pkgsplit(self.y_ebuild) |
8140 |
- is_bad_split = myesplit is None or myesplit[0] != self.xpkg.split("/")[-1] |
8141 |
- if is_bad_split: |
8142 |
- is_pv_toolong = pv_toolong_re.search(myesplit[1]) |
8143 |
- is_pv_toolong2 = pv_toolong_re.search(myesplit[2]) |
8144 |
- if is_pv_toolong or is_pv_toolong2: |
8145 |
- self.qatracker.add_error( |
8146 |
- "ebuild.invalidname", self.xpkg + "/" + self.y_ebuild + ".ebuild" |
8147 |
- ) |
8148 |
- return True |
8149 |
- elif myesplit[0] != pkgdir: |
8150 |
- print(pkgdir, myesplit[0]) |
8151 |
- self.qatracker.add_error( |
8152 |
- "ebuild.namenomatch", self.xpkg + "/" + self.y_ebuild + ".ebuild" |
8153 |
- ) |
8154 |
- return True |
8155 |
- return False |
8156 |
- |
8157 |
- def pkg_invalid(self, **kwargs): |
8158 |
- """Sets some pkg info and checks for invalid packages |
8159 |
- |
8160 |
- @param validity_future: Future instance |
8161 |
- @returns: dictionary, including {pkg object} |
8162 |
- """ |
8163 |
- fuse = kwargs.get("validity_future") |
8164 |
- dyn_pkg = kwargs.get("pkg") |
8165 |
- if self.pkg.invalid: |
8166 |
- for k, msgs in self.pkg.invalid.items(): |
8167 |
- for msg in msgs: |
8168 |
- self.qatracker.add_error(k, "%s: %s" % (self.relative_path, msg)) |
8169 |
- # update the dynamic data |
8170 |
- fuse.set(False, ignore_InvalidState=True) |
8171 |
- dyn_pkg.set(self.pkg) |
8172 |
- return True |
8173 |
- # update the dynamic data |
8174 |
- dyn_pkg.set(self.pkg) |
8175 |
- return False |
8176 |
- |
8177 |
- def check_isebuild(self, **kwargs): |
8178 |
- """Test the file for qualifications that is is an ebuild |
8179 |
- |
8180 |
- @param checkdirlist: list of files in the current package directory |
8181 |
- @param checkdir: current package directory path |
8182 |
- @param xpkg: current package directory being checked |
8183 |
- @param validity_future: Future instance |
8184 |
- @returns: dictionary, including {pkgs, can_force} |
8185 |
- """ |
8186 |
- checkdirlist = kwargs.get("checkdirlist").get() |
8187 |
- checkdir = kwargs.get("checkdir") |
8188 |
- xpkg = kwargs.get("xpkg") |
8189 |
- fuse = kwargs.get("validity_future") |
8190 |
- can_force = kwargs.get("can_force") |
8191 |
- self.continue_ = False |
8192 |
- ebuildlist = [] |
8193 |
- pkgs = {} |
8194 |
- for y in checkdirlist: |
8195 |
- file_is_ebuild = y.endswith(".ebuild") |
8196 |
- file_should_be_non_executable = ( |
8197 |
- y in self.repo_settings.qadata.no_exec or file_is_ebuild |
8198 |
- ) |
8199 |
- |
8200 |
- if file_should_be_non_executable: |
8201 |
- file_is_executable = ( |
8202 |
- stat.S_IMODE(os.stat(os.path.join(checkdir, y)).st_mode) & 0o111 |
8203 |
- ) |
8204 |
- |
8205 |
- if file_is_executable: |
8206 |
- self.qatracker.add_error( |
8207 |
- "file.executable", os.path.join(checkdir, y) |
8208 |
- ) |
8209 |
- if file_is_ebuild: |
8210 |
- pf = y[:-7] |
8211 |
- ebuildlist.append(pf) |
8212 |
- catdir = xpkg.split("/")[0] |
8213 |
- cpv = "%s/%s" % (catdir, pf) |
8214 |
- allvars = self.repo_settings.qadata.allvars |
8215 |
- try: |
8216 |
- myaux = dict(zip(allvars, self.portdb.aux_get(cpv, allvars))) |
8217 |
- except KeyError: |
8218 |
- fuse.set(False, ignore_InvalidState=True) |
8219 |
- self.qatracker.add_error("ebuild.syntax", os.path.join(xpkg, y)) |
8220 |
- continue |
8221 |
- except IOError: |
8222 |
- fuse.set(False, ignore_InvalidState=True) |
8223 |
- self.qatracker.add_error("ebuild.output", os.path.join(xpkg, y)) |
8224 |
- continue |
8225 |
- except InvalidPackageName: |
8226 |
- fuse.set(False, ignore_InvalidState=True) |
8227 |
- self.qatracker.add_error( |
8228 |
- "ebuild.invalidname", os.path.join(xpkg, y) |
8229 |
- ) |
8230 |
- continue |
8231 |
- if not portage.eapi_is_supported(myaux["EAPI"]): |
8232 |
- fuse.set(False, ignore_InvalidState=True) |
8233 |
- self.qatracker.add_error("EAPI.unsupported", os.path.join(xpkg, y)) |
8234 |
- continue |
8235 |
- pkgs[pf] = Package( |
8236 |
- cpv=cpv, |
8237 |
- metadata=myaux, |
8238 |
- root_config=self.root_config, |
8239 |
- type_name="ebuild", |
8240 |
- ) |
8241 |
- |
8242 |
- if len(pkgs) != len(ebuildlist): |
8243 |
- # If we can't access all the metadata then it's totally unsafe to |
8244 |
- # commit since there's no way to generate a correct Manifest. |
8245 |
- # Do not try to do any more QA checks on this package since missing |
8246 |
- # metadata leads to false positives for several checks, and false |
8247 |
- # positives confuse users. |
8248 |
- self.continue_ = True |
8249 |
- can_force.set(False, ignore_InvalidState=True) |
8250 |
- self.pkgs = pkgs |
8251 |
- # set our updated data |
8252 |
- dyn_pkgs = kwargs.get("pkgs") |
8253 |
- dyn_pkgs.set(pkgs) |
8254 |
- return self.continue_ |
8255 |
- |
8256 |
- @property |
8257 |
- def runInPkgs(self): |
8258 |
- """Package level scans""" |
8259 |
- return (True, [self.check_isebuild]) |
8260 |
- |
8261 |
- @property |
8262 |
- def runInEbuilds(self): |
8263 |
- """Ebuild level scans""" |
8264 |
- return ( |
8265 |
- True, |
8266 |
- [self.check, self.set_pkg_data, self.bad_split_check, self.pkg_invalid], |
8267 |
- ) |
8268 |
|
8269 |
diff --git a/repoman/lib/repoman/modules/scan/ebuild/multicheck.py b/repoman/lib/repoman/modules/scan/ebuild/multicheck.py |
8270 |
deleted file mode 100644 |
8271 |
index 1db0dfc92..000000000 |
8272 |
--- a/repoman/lib/repoman/modules/scan/ebuild/multicheck.py |
8273 |
+++ /dev/null |
8274 |
@@ -1,62 +0,0 @@ |
8275 |
-"""multicheck.py |
8276 |
-Perform multiple different checks on an ebuild |
8277 |
-""" |
8278 |
- |
8279 |
-import io |
8280 |
- |
8281 |
-from portage import _encodings, _unicode_encode |
8282 |
- |
8283 |
-from repoman.modules.scan.scanbase import ScanBase |
8284 |
-from repoman.modules.linechecks.controller import LineCheckController |
8285 |
- |
8286 |
- |
8287 |
-class MultiCheck(ScanBase): |
8288 |
- """Class to run multiple different checks on an ebuild""" |
8289 |
- |
8290 |
- def __init__(self, **kwargs): |
8291 |
- """Class init |
8292 |
- |
8293 |
- @param qatracker: QATracker instance |
8294 |
- @param options: the run time cli options |
8295 |
- """ |
8296 |
- self.qatracker = kwargs.get("qatracker") |
8297 |
- self.options = kwargs.get("options") |
8298 |
- self.controller = LineCheckController( |
8299 |
- kwargs.get("repo_settings"), kwargs.get("linechecks") |
8300 |
- ) |
8301 |
- self.controller.checks_init(self.options.experimental_inherit == "y") |
8302 |
- |
8303 |
- def check(self, **kwargs): |
8304 |
- """Check the ebuild for utf-8 encoding |
8305 |
- |
8306 |
- @param pkg: Package in which we check (object). |
8307 |
- @param ebuild: Ebuild which we check (object). |
8308 |
- @returns: dictionary |
8309 |
- """ |
8310 |
- ebuild = kwargs.get("ebuild").get() |
8311 |
- pkg = kwargs.get("pkg").get() |
8312 |
- try: |
8313 |
- # All ebuilds should have utf_8 encoding. |
8314 |
- f = io.open( |
8315 |
- _unicode_encode( |
8316 |
- ebuild.full_path, encoding=_encodings["fs"], errors="strict" |
8317 |
- ), |
8318 |
- mode="r", |
8319 |
- encoding=_encodings["repo.content"], |
8320 |
- ) |
8321 |
- try: |
8322 |
- for check_name, e in self.controller.run_checks(f, pkg): |
8323 |
- self.qatracker.add_error( |
8324 |
- check_name, ebuild.relative_path + ": %s" % e |
8325 |
- ) |
8326 |
- finally: |
8327 |
- f.close() |
8328 |
- except UnicodeDecodeError: |
8329 |
- # A file.UTF8 failure will have already been recorded. |
8330 |
- pass |
8331 |
- return False |
8332 |
- |
8333 |
- @property |
8334 |
- def runInEbuilds(self): |
8335 |
- """Ebuild level scans""" |
8336 |
- return (True, [self.check]) |
8337 |
|
8338 |
diff --git a/repoman/lib/repoman/modules/scan/eclasses/__init__.py b/repoman/lib/repoman/modules/scan/eclasses/__init__.py |
8339 |
deleted file mode 100644 |
8340 |
index 8a14000e8..000000000 |
8341 |
--- a/repoman/lib/repoman/modules/scan/eclasses/__init__.py |
8342 |
+++ /dev/null |
8343 |
@@ -1,49 +0,0 @@ |
8344 |
-# Copyright 2015-2021 Gentoo Authors |
8345 |
-# Distributed under the terms of the GNU General Public License v2 |
8346 |
- |
8347 |
-doc = """Eclasses plug-in module for repoman. |
8348 |
-Performs an live and ruby eclass checks on ebuilds.""" |
8349 |
-__doc__ = doc[:] |
8350 |
- |
8351 |
- |
8352 |
-module_spec = { |
8353 |
- "name": "eclasses", |
8354 |
- "description": doc, |
8355 |
- "provides": { |
8356 |
- "live-module": { |
8357 |
- "name": "live", |
8358 |
- "sourcefile": "live", |
8359 |
- "class": "LiveEclassChecks", |
8360 |
- "description": doc, |
8361 |
- "functions": ["check"], |
8362 |
- "func_kwargs": {}, |
8363 |
- "mod_kwargs": [ |
8364 |
- "qatracker", |
8365 |
- "repo_metadata", |
8366 |
- "repo_settings", |
8367 |
- ], |
8368 |
- "func_kwargs": { |
8369 |
- "ebuild": (None, None), |
8370 |
- "pkg": (None, None), |
8371 |
- "xpkg": (None, None), |
8372 |
- "y_ebuild": (None, None), |
8373 |
- }, |
8374 |
- "module_runsIn": ["ebuilds"], |
8375 |
- }, |
8376 |
- "ruby-module": { |
8377 |
- "name": "ruby", |
8378 |
- "sourcefile": "ruby", |
8379 |
- "class": "RubyEclassChecks", |
8380 |
- "description": doc, |
8381 |
- "functions": ["check"], |
8382 |
- "func_kwargs": {}, |
8383 |
- "mod_kwargs": ["qatracker", "repo_settings"], |
8384 |
- "func_kwargs": { |
8385 |
- "ebuild": (None, None), |
8386 |
- "pkg": (None, None), |
8387 |
- }, |
8388 |
- "module_runsIn": ["ebuilds"], |
8389 |
- }, |
8390 |
- }, |
8391 |
- "version": 1, |
8392 |
-} |
8393 |
|
8394 |
diff --git a/repoman/lib/repoman/modules/scan/eclasses/live.py b/repoman/lib/repoman/modules/scan/eclasses/live.py |
8395 |
deleted file mode 100644 |
8396 |
index 82ee168ed..000000000 |
8397 |
--- a/repoman/lib/repoman/modules/scan/eclasses/live.py |
8398 |
+++ /dev/null |
8399 |
@@ -1,77 +0,0 @@ |
8400 |
-"""live.py |
8401 |
-Performs Live eclass checks |
8402 |
-""" |
8403 |
- |
8404 |
-from repoman._portage import portage |
8405 |
-from repoman.modules.scan.scanbase import ScanBase |
8406 |
- |
8407 |
- |
8408 |
-class LiveEclassChecks(ScanBase): |
8409 |
- """Performs checks for the usage of Live eclasses in ebuilds""" |
8410 |
- |
8411 |
- def __init__(self, **kwargs): |
8412 |
- """ |
8413 |
- @param qatracker: QATracker instance |
8414 |
- """ |
8415 |
- self.qatracker = kwargs.get("qatracker") |
8416 |
- self.pmaskdict = kwargs.get("repo_metadata")["pmaskdict"] |
8417 |
- self.repo_settings = kwargs.get("repo_settings") |
8418 |
- |
8419 |
- def check(self, **kwargs): |
8420 |
- """Ebuilds that inherit a "Live" eclass (darcs, subversion, git, cvs, |
8421 |
- etc..) should not be allowed to be marked stable |
8422 |
- |
8423 |
- @param pkg: Package in which we check (object). |
8424 |
- @param xpkg: Package in which we check (string). |
8425 |
- @param ebuild: Ebuild which we check (object). |
8426 |
- @param y_ebuild: Ebuild which we check (string). |
8427 |
- @returns: boolean |
8428 |
- """ |
8429 |
- pkg = kwargs.get("pkg").result() |
8430 |
- package = kwargs.get("xpkg") |
8431 |
- ebuild = kwargs.get("ebuild").get() |
8432 |
- y_ebuild = kwargs.get("y_ebuild") |
8433 |
- |
8434 |
- if ebuild.live_ebuild and self.repo_settings.repo_config.name == "gentoo": |
8435 |
- return self.check_live(pkg, package, ebuild, y_ebuild) |
8436 |
- return False |
8437 |
- |
8438 |
- def check_live(self, pkg, package, ebuild, y_ebuild): |
8439 |
- """Perform the live vcs check |
8440 |
- |
8441 |
- @param pkg: Package in which we check (object). |
8442 |
- @param xpkg: Package in which we check (string). |
8443 |
- @param ebuild: Ebuild which we check (object). |
8444 |
- @param y_ebuild: Ebuild which we check (string). |
8445 |
- @returns: boolean |
8446 |
- """ |
8447 |
- keywords = ebuild.keywords |
8448 |
- is_stable = lambda kw: not kw.startswith("~") and not kw.startswith("-") |
8449 |
- bad_stable_keywords = list(filter(is_stable, keywords)) |
8450 |
- |
8451 |
- if bad_stable_keywords: |
8452 |
- self.qatracker.add_error( |
8453 |
- "LIVEVCS.stable", |
8454 |
- "%s/%s.ebuild with stable keywords: %s" |
8455 |
- % (package, y_ebuild, bad_stable_keywords), |
8456 |
- ) |
8457 |
- |
8458 |
- good_keywords_exist = len(bad_stable_keywords) < len(keywords) |
8459 |
- if good_keywords_exist and not self._has_global_mask(pkg, self.pmaskdict): |
8460 |
- self.qatracker.add_error("LIVEVCS.unmasked", ebuild.relative_path) |
8461 |
- return False |
8462 |
- |
8463 |
- @staticmethod |
8464 |
- def _has_global_mask(pkg, global_pmaskdict): |
8465 |
- mask_atoms = global_pmaskdict.get(pkg.cp) |
8466 |
- if mask_atoms: |
8467 |
- pkg_list = [pkg] |
8468 |
- for x in mask_atoms: |
8469 |
- if portage.dep.match_from_list(x, pkg_list): |
8470 |
- return x |
8471 |
- return None |
8472 |
- |
8473 |
- @property |
8474 |
- def runInEbuilds(self): |
8475 |
- """Ebuild level scans""" |
8476 |
- return (True, [self.check]) |
8477 |
|
8478 |
diff --git a/repoman/lib/repoman/modules/scan/eclasses/ruby.py b/repoman/lib/repoman/modules/scan/eclasses/ruby.py |
8479 |
deleted file mode 100644 |
8480 |
index 16043ee0c..000000000 |
8481 |
--- a/repoman/lib/repoman/modules/scan/eclasses/ruby.py |
8482 |
+++ /dev/null |
8483 |
@@ -1,49 +0,0 @@ |
8484 |
-"""ruby.py |
8485 |
-Performs Ruby eclass checks |
8486 |
-""" |
8487 |
- |
8488 |
-from repoman.modules.scan.scanbase import ScanBase |
8489 |
- |
8490 |
- |
8491 |
-class RubyEclassChecks(ScanBase): |
8492 |
- """Performs checks for the usage of Ruby eclasses in ebuilds""" |
8493 |
- |
8494 |
- def __init__(self, **kwargs): |
8495 |
- """ |
8496 |
- @param qatracker: QATracker instance |
8497 |
- """ |
8498 |
- super(RubyEclassChecks, self).__init__(**kwargs) |
8499 |
- self.qatracker = kwargs.get("qatracker") |
8500 |
- self.repo_settings = kwargs.get("repo_settings") |
8501 |
- self.old_ruby_eclasses = ["ruby-ng", "ruby-fakegem", "ruby"] |
8502 |
- |
8503 |
- def check(self, **kwargs): |
8504 |
- """Check ebuilds that inherit the ruby eclasses |
8505 |
- |
8506 |
- @param pkg: Package in which we check (object). |
8507 |
- @param ebuild: Ebuild which we check (object). |
8508 |
- @returns: dictionary |
8509 |
- """ |
8510 |
- pkg = kwargs.get("pkg").get() |
8511 |
- ebuild = kwargs.get("ebuild").get() |
8512 |
- is_inherited = lambda eclass: eclass in pkg.inherited |
8513 |
- is_old_ruby_eclass_inherited = filter(is_inherited, self.old_ruby_eclasses) |
8514 |
- |
8515 |
- if is_old_ruby_eclass_inherited: |
8516 |
- ruby_intersection = pkg.iuse.all.intersection( |
8517 |
- self.repo_settings.qadata.ruby_deprecated |
8518 |
- ) |
8519 |
- |
8520 |
- if ruby_intersection: |
8521 |
- for myruby in ruby_intersection: |
8522 |
- self.qatracker.add_error( |
8523 |
- "IUSE.rubydeprecated", |
8524 |
- (ebuild.relative_path + ": Deprecated ruby target: %s") |
8525 |
- % myruby, |
8526 |
- ) |
8527 |
- return False |
8528 |
- |
8529 |
- @property |
8530 |
- def runInEbuilds(self): |
8531 |
- """Ebuild level scans""" |
8532 |
- return (True, [self.check]) |
8533 |
|
8534 |
diff --git a/repoman/lib/repoman/modules/scan/fetch/__init__.py b/repoman/lib/repoman/modules/scan/fetch/__init__.py |
8535 |
deleted file mode 100644 |
8536 |
index 9bd9d468d..000000000 |
8537 |
--- a/repoman/lib/repoman/modules/scan/fetch/__init__.py |
8538 |
+++ /dev/null |
8539 |
@@ -1,37 +0,0 @@ |
8540 |
-# Copyright 2015-2021 Gentoo Authors |
8541 |
-# Distributed under the terms of the GNU General Public License v2 |
8542 |
- |
8543 |
-doc = """fetches plug-in module for repoman. |
8544 |
-Performs fetch related checks on ebuilds.""" |
8545 |
-__doc__ = doc[:] |
8546 |
- |
8547 |
- |
8548 |
-module_spec = { |
8549 |
- "name": "fetches", |
8550 |
- "description": doc, |
8551 |
- "provides": { |
8552 |
- "fetches-module": { |
8553 |
- "name": "fetches", |
8554 |
- "sourcefile": "fetches", |
8555 |
- "class": "FetchChecks", |
8556 |
- "description": doc, |
8557 |
- "functions": ["check"], |
8558 |
- "func_desc": {}, |
8559 |
- "mod_kwargs": [ |
8560 |
- "portdb", |
8561 |
- "qatracker", |
8562 |
- "repo_settings", |
8563 |
- "vcs_settings", |
8564 |
- ], |
8565 |
- "func_kwargs": { |
8566 |
- "changed": (None, None), |
8567 |
- "checkdir": (None, None), |
8568 |
- "checkdir_relative": (None, None), |
8569 |
- "ebuild": (None, None), |
8570 |
- "xpkg": (None, None), |
8571 |
- }, |
8572 |
- "module_runsIn": ["pkgs", "ebuilds"], |
8573 |
- }, |
8574 |
- }, |
8575 |
- "version": 1, |
8576 |
-} |
8577 |
|
8578 |
diff --git a/repoman/lib/repoman/modules/scan/fetch/fetches.py b/repoman/lib/repoman/modules/scan/fetch/fetches.py |
8579 |
deleted file mode 100644 |
8580 |
index 56a36a13f..000000000 |
8581 |
--- a/repoman/lib/repoman/modules/scan/fetch/fetches.py |
8582 |
+++ /dev/null |
8583 |
@@ -1,205 +0,0 @@ |
8584 |
-# -*- coding:utf-8 -*- |
8585 |
- |
8586 |
-"""fetches.py |
8587 |
-Performs the src_uri fetchlist and files checks |
8588 |
-""" |
8589 |
- |
8590 |
-from stat import S_ISDIR |
8591 |
- |
8592 |
-# import our initialized portage instance |
8593 |
-from repoman._portage import portage |
8594 |
-from repoman.modules.vcs.vcs import vcs_new_changed |
8595 |
-from repoman.modules.scan.scanbase import ScanBase |
8596 |
- |
8597 |
-from portage import os |
8598 |
- |
8599 |
- |
8600 |
-class FetchChecks(ScanBase): |
8601 |
- """Performs checks on the files needed for the ebuild""" |
8602 |
- |
8603 |
- def __init__(self, **kwargs): |
8604 |
- """ |
8605 |
- @param portdb: portdb instance |
8606 |
- @param qatracker: QATracker instance |
8607 |
- @param repo_settings: repository settings instance |
8608 |
- @param vcs_settings: VCSSettings instance |
8609 |
- """ |
8610 |
- super(FetchChecks, self).__init__(**kwargs) |
8611 |
- self.portdb = kwargs.get("portdb") |
8612 |
- self.qatracker = kwargs.get("qatracker") |
8613 |
- self.repo_settings = kwargs.get("repo_settings") |
8614 |
- self.repoman_settings = self.repo_settings.repoman_settings |
8615 |
- self.vcs_settings = kwargs.get("vcs_settings") |
8616 |
- self._src_uri_error = False |
8617 |
- |
8618 |
- # TODO: Build a regex instead here, for the SRC_URI.mirror check. |
8619 |
- self.thirdpartymirrors = {} |
8620 |
- profile_thirdpartymirrors = ( |
8621 |
- self.repo_settings.repoman_settings.thirdpartymirrors().items() |
8622 |
- ) |
8623 |
- for mirror_alias, mirrors in profile_thirdpartymirrors: |
8624 |
- # Skip thirdpartymirrors that do not list more than one mirror |
8625 |
- # anymore. There is no point in using mirror:// there and this |
8626 |
- # means that the thirdpartymirrors entry will most likely |
8627 |
- # be removed anyway. |
8628 |
- if len(mirrors) <= 1: |
8629 |
- continue |
8630 |
- for mirror in mirrors: |
8631 |
- if not mirror.endswith("/"): |
8632 |
- mirror += "/" |
8633 |
- self.thirdpartymirrors[mirror] = mirror_alias |
8634 |
- |
8635 |
- def check(self, **kwargs): |
8636 |
- """Checks the ebuild sources and files for errors |
8637 |
- |
8638 |
- @param xpkg: the pacakge being checked |
8639 |
- @param checkdir: string, directory path |
8640 |
- @param checkdir_relative: repolevel determined path |
8641 |
- @returns: boolean |
8642 |
- """ |
8643 |
- xpkg = kwargs.get("xpkg") |
8644 |
- checkdir = kwargs.get("checkdir") |
8645 |
- checkdir_relative = kwargs.get("checkdir_relative") |
8646 |
- changed = kwargs.get("changed").changed |
8647 |
- new = kwargs.get("changed").new |
8648 |
- _digests = self.digests(checkdir) |
8649 |
- fetchlist_dict = portage.FetchlistDict( |
8650 |
- checkdir, self.repoman_settings, self.portdb |
8651 |
- ) |
8652 |
- myfiles_all = [] |
8653 |
- self._src_uri_error = False |
8654 |
- for mykey in fetchlist_dict: |
8655 |
- try: |
8656 |
- myfiles_all.extend(fetchlist_dict[mykey]) |
8657 |
- except portage.exception.InvalidDependString as e: |
8658 |
- self._src_uri_error = True |
8659 |
- try: |
8660 |
- self.portdb.aux_get(mykey, ["SRC_URI"]) |
8661 |
- except KeyError: |
8662 |
- # This will be reported as an "ebuild.syntax" error. |
8663 |
- pass |
8664 |
- else: |
8665 |
- self.qatracker.add_error( |
8666 |
- "SRC_URI.syntax", "%s.ebuild SRC_URI: %s" % (mykey, e) |
8667 |
- ) |
8668 |
- del fetchlist_dict |
8669 |
- if not self._src_uri_error: |
8670 |
- # This test can produce false positives if SRC_URI could not |
8671 |
- # be parsed for one or more ebuilds. There's no point in |
8672 |
- # producing a false error here since the root cause will |
8673 |
- # produce a valid error elsewhere, such as "SRC_URI.syntax" |
8674 |
- # or "ebuild.sytax". |
8675 |
- myfiles_all = set(myfiles_all) |
8676 |
- for entry in _digests: |
8677 |
- if entry not in myfiles_all: |
8678 |
- self.qatracker.add_error("digest.unused", checkdir + "::" + entry) |
8679 |
- for entry in myfiles_all: |
8680 |
- if entry not in _digests: |
8681 |
- self.qatracker.add_error("digest.missing", checkdir + "::" + entry) |
8682 |
- del myfiles_all |
8683 |
- |
8684 |
- if os.path.exists(checkdir + "/files"): |
8685 |
- filesdirlist = os.listdir(checkdir + "/files") |
8686 |
- |
8687 |
- # Recurse through files directory, use filesdirlist as a stack; |
8688 |
- # appending directories as needed, |
8689 |
- # so people can't hide > 20k files in a subdirectory. |
8690 |
- while filesdirlist: |
8691 |
- y = filesdirlist.pop(0) |
8692 |
- relative_path = os.path.join(xpkg, "files", y) |
8693 |
- full_path = os.path.join(self.repo_settings.repodir, relative_path) |
8694 |
- try: |
8695 |
- mystat = os.stat(full_path) |
8696 |
- except OSError as oe: |
8697 |
- if oe.errno == 2: |
8698 |
- # don't worry about it. it likely was removed via fix above. |
8699 |
- continue |
8700 |
- else: |
8701 |
- raise oe |
8702 |
- if S_ISDIR(mystat.st_mode): |
8703 |
- if self.vcs_settings.status.isVcsDir(y): |
8704 |
- continue |
8705 |
- for z in os.listdir(checkdir + "/files/" + y): |
8706 |
- if self.vcs_settings.status.isVcsDir(z): |
8707 |
- continue |
8708 |
- filesdirlist.append(y + "/" + z) |
8709 |
- # Current policy is no files over 20 KiB, these are the checks. |
8710 |
- # File size over 20 KiB causes an error. |
8711 |
- elif mystat.st_size > 20480: |
8712 |
- self.qatracker.add_error( |
8713 |
- "file.size", |
8714 |
- "(%d KiB) %s/files/%s" % (mystat.st_size // 1024, xpkg, y), |
8715 |
- ) |
8716 |
- elif mystat.st_size == 0: |
8717 |
- self.qatracker.add_error("file.empty", "%s/files/%s" % (xpkg, y)) |
8718 |
- |
8719 |
- index = self.repo_settings.repo_config.find_invalid_path_char(y) |
8720 |
- if index != -1: |
8721 |
- y_relative = os.path.join(checkdir_relative, "files", y) |
8722 |
- if self.vcs_settings.vcs is not None and not vcs_new_changed( |
8723 |
- y_relative, changed, new |
8724 |
- ): |
8725 |
- # If the file isn't in the VCS new or changed set, then |
8726 |
- # assume that it's an irrelevant temporary file (Manifest |
8727 |
- # entries are not generated for file names containing |
8728 |
- # prohibited characters). See bug #406877. |
8729 |
- index = -1 |
8730 |
- if index != -1: |
8731 |
- self.qatracker.add_error( |
8732 |
- "file.name", "%s/files/%s: char '%s'" % (checkdir, y, y[index]) |
8733 |
- ) |
8734 |
- return False |
8735 |
- |
8736 |
- def digests(self, checkdir): |
8737 |
- """Returns the freshly loaded digests |
8738 |
- |
8739 |
- @param checkdir: string, directory path |
8740 |
- """ |
8741 |
- mf = self.repoman_settings.repositories.get_repo_for_location( |
8742 |
- os.path.dirname(os.path.dirname(checkdir)) |
8743 |
- ) |
8744 |
- mf = mf.load_manifest(checkdir, self.repoman_settings["DISTDIR"]) |
8745 |
- _digests = mf.getTypeDigests("DIST") |
8746 |
- del mf |
8747 |
- return _digests |
8748 |
- |
8749 |
- def check_mirrors(self, **kwargs): |
8750 |
- """Check that URIs don't reference a server from thirdpartymirrors |
8751 |
- |
8752 |
- @param ebuild: Ebuild which we check (object). |
8753 |
- @returns: boolean |
8754 |
- """ |
8755 |
- ebuild = kwargs.get("ebuild").get() |
8756 |
- |
8757 |
- for uri in portage.dep.use_reduce( |
8758 |
- ebuild.metadata["SRC_URI"], |
8759 |
- matchall=True, |
8760 |
- is_src_uri=True, |
8761 |
- eapi=ebuild.eapi, |
8762 |
- flat=True, |
8763 |
- ): |
8764 |
- contains_mirror = False |
8765 |
- for mirror, mirror_alias in self.thirdpartymirrors.items(): |
8766 |
- if uri.startswith(mirror): |
8767 |
- contains_mirror = True |
8768 |
- break |
8769 |
- if not contains_mirror: |
8770 |
- continue |
8771 |
- |
8772 |
- new_uri = "mirror://%s/%s" % (mirror_alias, uri[len(mirror) :]) |
8773 |
- self.qatracker.add_error( |
8774 |
- "SRC_URI.mirror", |
8775 |
- "%s: '%s' found in thirdpartymirrors, use '%s'" |
8776 |
- % (ebuild.relative_path, mirror, new_uri), |
8777 |
- ) |
8778 |
- return False |
8779 |
- |
8780 |
- @property |
8781 |
- def runInPkgs(self): |
8782 |
- """Package level scans""" |
8783 |
- return (True, [self.check]) |
8784 |
- |
8785 |
- @property |
8786 |
- def runInEbuilds(self): |
8787 |
- """Ebuild level scans""" |
8788 |
- return (True, [self.check_mirrors]) |
8789 |
|
8790 |
diff --git a/repoman/lib/repoman/modules/scan/keywords/__init__.py b/repoman/lib/repoman/modules/scan/keywords/__init__.py |
8791 |
deleted file mode 100644 |
8792 |
index a830e35ba..000000000 |
8793 |
--- a/repoman/lib/repoman/modules/scan/keywords/__init__.py |
8794 |
+++ /dev/null |
8795 |
@@ -1,37 +0,0 @@ |
8796 |
-# Copyright 2015-2021 Gentoo Authors |
8797 |
-# Distributed under the terms of the GNU General Public License v2 |
8798 |
- |
8799 |
-doc = """Keywords plug-in module for repoman. |
8800 |
-Performs keywords checks on ebuilds.""" |
8801 |
-__doc__ = doc[:] |
8802 |
- |
8803 |
- |
8804 |
-module_spec = { |
8805 |
- "name": "keywords", |
8806 |
- "description": doc, |
8807 |
- "provides": { |
8808 |
- "keywords-module": { |
8809 |
- "name": "keywords", |
8810 |
- "sourcefile": "keywords", |
8811 |
- "class": "KeywordChecks", |
8812 |
- "description": doc, |
8813 |
- "functions": ["prepare", "check"], |
8814 |
- "func_desc": {}, |
8815 |
- "mod_kwargs": [ |
8816 |
- "qatracker", |
8817 |
- "options", |
8818 |
- "repo_metadata", |
8819 |
- "profiles", |
8820 |
- ], |
8821 |
- "func_kwargs": { |
8822 |
- "changed": (None, None), |
8823 |
- "ebuild": ("Future", "UNSET"), |
8824 |
- "pkg": ("Future", "UNSET"), |
8825 |
- "xpkg": None, |
8826 |
- "y_ebuild": (None, None), |
8827 |
- }, |
8828 |
- "module_runsIn": ["pkgs", "ebuilds", "final"], |
8829 |
- }, |
8830 |
- }, |
8831 |
- "version": 1, |
8832 |
-} |
8833 |
|
8834 |
diff --git a/repoman/lib/repoman/modules/scan/keywords/keywords.py b/repoman/lib/repoman/modules/scan/keywords/keywords.py |
8835 |
deleted file mode 100644 |
8836 |
index 1e00421c6..000000000 |
8837 |
--- a/repoman/lib/repoman/modules/scan/keywords/keywords.py |
8838 |
+++ /dev/null |
8839 |
@@ -1,179 +0,0 @@ |
8840 |
-# -*- coding:utf-8 -*- |
8841 |
- |
8842 |
-"""keywords.py |
8843 |
-Perform KEYWORDS related checks |
8844 |
- |
8845 |
-""" |
8846 |
- |
8847 |
-from repoman.modules.scan.scanbase import ScanBase |
8848 |
- |
8849 |
- |
8850 |
-class KeywordChecks(ScanBase): |
8851 |
- """Perform checks on the KEYWORDS of an ebuild""" |
8852 |
- |
8853 |
- def __init__(self, **kwargs): |
8854 |
- """ |
8855 |
- @param qatracker: QATracker instance |
8856 |
- @param options: argparse options instance |
8857 |
- """ |
8858 |
- super(KeywordChecks, self).__init__(**kwargs) |
8859 |
- self.qatracker = kwargs.get("qatracker") |
8860 |
- self.options = kwargs.get("options") |
8861 |
- self.repo_metadata = kwargs.get("repo_metadata") |
8862 |
- self.profiles = kwargs.get("profiles") |
8863 |
- self.slot_keywords = {} |
8864 |
- |
8865 |
- def prepare(self, **kwargs): |
8866 |
- """Prepare the checks for the next package.""" |
8867 |
- self.slot_keywords = {} |
8868 |
- self.dropped_keywords = {} |
8869 |
- return False |
8870 |
- |
8871 |
- def check(self, **kwargs): |
8872 |
- """Perform the check. |
8873 |
- |
8874 |
- @param pkg: Package in which we check (object). |
8875 |
- @param xpkg: Package in which we check (string). |
8876 |
- @param ebuild: Ebuild which we check (object). |
8877 |
- @param y_ebuild: Ebuild which we check (string). |
8878 |
- @param ebuild_archs: Just the architectures (no prefixes) of the ebuild. |
8879 |
- @param changed: Changes instance |
8880 |
- @returns: dictionary |
8881 |
- """ |
8882 |
- pkg = kwargs.get("pkg").get() |
8883 |
- xpkg = kwargs.get("xpkg") |
8884 |
- ebuild = kwargs.get("ebuild").get() |
8885 |
- y_ebuild = kwargs.get("y_ebuild") |
8886 |
- changed = kwargs.get("changed") |
8887 |
- if not self.options.straight_to_stable: |
8888 |
- self._checkAddedWithStableKeywords( |
8889 |
- xpkg, ebuild, y_ebuild, ebuild.keywords, changed |
8890 |
- ) |
8891 |
- |
8892 |
- self._checkForDroppedKeywords(pkg, ebuild, ebuild.archs) |
8893 |
- |
8894 |
- self._checkForInvalidKeywords(ebuild, xpkg, y_ebuild) |
8895 |
- |
8896 |
- self._checkForMaskLikeKeywords(xpkg, y_ebuild, ebuild.keywords) |
8897 |
- |
8898 |
- self._checkForUnsortedKeywords(ebuild, xpkg, y_ebuild) |
8899 |
- |
8900 |
- self.slot_keywords[pkg.slot].update(ebuild.archs) |
8901 |
- return False |
8902 |
- |
8903 |
- def check_dropped_keywords(self, **kwargs): |
8904 |
- """Report on any dropped keywords for the latest ebuild in a slot |
8905 |
- |
8906 |
- @returns: boolean |
8907 |
- """ |
8908 |
- for ebuild, arches in self.dropped_keywords.values(): |
8909 |
- if arches: |
8910 |
- self.qatracker.add_error( |
8911 |
- "KEYWORDS.dropped", "%s: %s" % (ebuild, " ".join(sorted(arches))) |
8912 |
- ) |
8913 |
- return False |
8914 |
- |
8915 |
- @staticmethod |
8916 |
- def _isKeywordStable(keyword): |
8917 |
- return not keyword.startswith("~") and not keyword.startswith("-") |
8918 |
- |
8919 |
- def _checkAddedWithStableKeywords( |
8920 |
- self, package, ebuild, y_ebuild, keywords, changed |
8921 |
- ): |
8922 |
- catdir, pkgdir = package.split("/") |
8923 |
- |
8924 |
- stable_keywords = list(filter(self._isKeywordStable, keywords)) |
8925 |
- if stable_keywords: |
8926 |
- if ebuild.ebuild_path in changed.new_ebuilds and catdir != "virtual": |
8927 |
- stable_keywords.sort() |
8928 |
- self.qatracker.add_error( |
8929 |
- "KEYWORDS.stable", |
8930 |
- "%s/%s.ebuild added with stable keywords: %s" |
8931 |
- % (package, y_ebuild, " ".join(stable_keywords)), |
8932 |
- ) |
8933 |
- |
8934 |
- def _checkForDroppedKeywords(self, pkg, ebuild, ebuild_archs): |
8935 |
- previous_keywords = self.slot_keywords.get(pkg.slot) |
8936 |
- if previous_keywords is None: |
8937 |
- self.slot_keywords[pkg.slot] = set() |
8938 |
- elif ebuild_archs and "*" not in ebuild_archs and not ebuild.live_ebuild: |
8939 |
- self.slot_keywords[pkg.slot].update(ebuild_archs) |
8940 |
- dropped_keywords = previous_keywords.difference(ebuild_archs) |
8941 |
- self.dropped_keywords[pkg.slot] = ( |
8942 |
- ebuild.relative_path, |
8943 |
- {arch for arch in dropped_keywords}, |
8944 |
- ) |
8945 |
- |
8946 |
- def _checkForInvalidKeywords(self, ebuild, xpkg, y_ebuild): |
8947 |
- myuse = ebuild.keywords |
8948 |
- |
8949 |
- for mykey in myuse: |
8950 |
- if mykey not in ("-*", "*", "~*"): |
8951 |
- myskey = mykey |
8952 |
- |
8953 |
- if not self._isKeywordStable(myskey[:1]): |
8954 |
- myskey = myskey[1:] |
8955 |
- |
8956 |
- if myskey not in self.repo_metadata["kwlist"]: |
8957 |
- self.qatracker.add_error( |
8958 |
- "KEYWORDS.invalid", "%s/%s.ebuild: %s" % (xpkg, y_ebuild, mykey) |
8959 |
- ) |
8960 |
- elif myskey not in self.profiles: |
8961 |
- self.qatracker.add_error( |
8962 |
- "KEYWORDS.invalid", |
8963 |
- "%s/%s.ebuild: %s (profile invalid)" % (xpkg, y_ebuild, mykey), |
8964 |
- ) |
8965 |
- |
8966 |
- def _checkForMaskLikeKeywords(self, xpkg, y_ebuild, keywords): |
8967 |
- # KEYWORDS="-*" is a stupid replacement for package.mask |
8968 |
- # and screws general KEYWORDS semantics |
8969 |
- if "-*" in keywords: |
8970 |
- haskeyword = False |
8971 |
- |
8972 |
- for kw in keywords: |
8973 |
- if kw[0] == "~": |
8974 |
- kw = kw[1:] |
8975 |
- if kw in self.repo_metadata["kwlist"]: |
8976 |
- haskeyword = True |
8977 |
- |
8978 |
- if not haskeyword: |
8979 |
- self.qatracker.add_error( |
8980 |
- "KEYWORDS.stupid", "%s/%s.ebuild" % (xpkg, y_ebuild) |
8981 |
- ) |
8982 |
- |
8983 |
- def _checkForUnsortedKeywords(self, ebuild, xpkg, y_ebuild): |
8984 |
- """Ebuilds that contain KEYWORDS |
8985 |
- which are not sorted alphabetically.""" |
8986 |
- |
8987 |
- def sort_keywords(kw): |
8988 |
- # Split keywords containing hyphens. The part after |
8989 |
- # the hyphen should be treated as the primary key. |
8990 |
- # This is consistent with ekeyword. |
8991 |
- parts = list(reversed(kw.lstrip("~-").split("-", 1))) |
8992 |
- # Hack to make sure that keywords |
8993 |
- # without hyphens are sorted first |
8994 |
- if len(parts) == 1: |
8995 |
- parts.insert(0, "") |
8996 |
- return parts |
8997 |
- |
8998 |
- sorted_keywords = sorted(ebuild.keywords, key=sort_keywords) |
8999 |
- if sorted_keywords != ebuild.keywords: |
9000 |
- self.qatracker.add_error( |
9001 |
- "KEYWORDS.unsorted", |
9002 |
- "%s/%s.ebuild contains unsorted keywords" % (xpkg, y_ebuild), |
9003 |
- ) |
9004 |
- |
9005 |
- @property |
9006 |
- def runInPkgs(self): |
9007 |
- """Package level scans""" |
9008 |
- return (True, [self.prepare]) |
9009 |
- |
9010 |
- @property |
9011 |
- def runInEbuilds(self): |
9012 |
- """Ebuild level scans""" |
9013 |
- return (True, [self.check]) |
9014 |
- |
9015 |
- @property |
9016 |
- def runInFinal(self): |
9017 |
- """Final package level scans""" |
9018 |
- return (True, [self.check_dropped_keywords]) |
9019 |
|
9020 |
diff --git a/repoman/lib/repoman/modules/scan/manifest/__init__.py b/repoman/lib/repoman/modules/scan/manifest/__init__.py |
9021 |
deleted file mode 100644 |
9022 |
index 2315a2a7e..000000000 |
9023 |
--- a/repoman/lib/repoman/modules/scan/manifest/__init__.py |
9024 |
+++ /dev/null |
9025 |
@@ -1,34 +0,0 @@ |
9026 |
-# Copyright 2015-2021 Gentoo Authors |
9027 |
-# Distributed under the terms of the GNU General Public License v2 |
9028 |
- |
9029 |
-doc = """Ebuild plug-in module for repoman. |
9030 |
-Performs an IsEbuild check on ebuilds.""" |
9031 |
-__doc__ = doc[:] |
9032 |
- |
9033 |
- |
9034 |
-module_spec = { |
9035 |
- "name": "manifest", |
9036 |
- "description": doc, |
9037 |
- "provides": { |
9038 |
- "manifest-module": { |
9039 |
- "name": "manifests", |
9040 |
- "sourcefile": "manifests", |
9041 |
- "class": "Manifests", |
9042 |
- "description": doc, |
9043 |
- "functions": ["check", "create_manifest", "digest_check"], |
9044 |
- "func_desc": {}, |
9045 |
- "mod_kwargs": [ |
9046 |
- "options", |
9047 |
- "portdb", |
9048 |
- "qatracker", |
9049 |
- "repo_settings", |
9050 |
- ], |
9051 |
- "func_kwargs": { |
9052 |
- "checkdir": (None, None), |
9053 |
- "xpkg": (None, None), |
9054 |
- }, |
9055 |
- "module_runsIn": ["pkgs"], |
9056 |
- }, |
9057 |
- }, |
9058 |
- "version": 1, |
9059 |
-} |
9060 |
|
9061 |
diff --git a/repoman/lib/repoman/modules/scan/manifest/manifests.py b/repoman/lib/repoman/modules/scan/manifest/manifests.py |
9062 |
deleted file mode 100644 |
9063 |
index 24b4e7f9b..000000000 |
9064 |
--- a/repoman/lib/repoman/modules/scan/manifest/manifests.py |
9065 |
+++ /dev/null |
9066 |
@@ -1,56 +0,0 @@ |
9067 |
-# -*- coding:utf-8 -*- |
9068 |
- |
9069 |
-# import our initialized portage instance |
9070 |
-from repoman._portage import portage |
9071 |
-from repoman.modules.scan.scanbase import ScanBase |
9072 |
- |
9073 |
-from portage import os |
9074 |
- |
9075 |
- |
9076 |
-class Manifests(ScanBase): |
9077 |
- """Creates as well as checks pkg Manifest entries/files""" |
9078 |
- |
9079 |
- def __init__(self, **kwargs): |
9080 |
- """Class init |
9081 |
- |
9082 |
- @param options: the run time cli options |
9083 |
- @param portdb: portdb instance |
9084 |
- @param qatracker: QATracker instance |
9085 |
- @param repo_settings: repository settings instance |
9086 |
- """ |
9087 |
- self.options = kwargs.get("options") |
9088 |
- self.portdb = kwargs.get("portdb") |
9089 |
- self.qatracker = kwargs.get("qatracker") |
9090 |
- self.repoman_settings = kwargs.get("repo_settings").repoman_settings |
9091 |
- |
9092 |
- def check(self, **kwargs): |
9093 |
- """Perform a changelog and untracked checks on the ebuild |
9094 |
- |
9095 |
- @param xpkg: Package in which we check (object). |
9096 |
- @param checkdir: the current package directory |
9097 |
- @returns: dictionary |
9098 |
- """ |
9099 |
- checkdir = kwargs.get("checkdir") |
9100 |
- xpkg = kwargs.get("xpkg") |
9101 |
- if self.options.pretend: |
9102 |
- return False |
9103 |
- self.digest_check(xpkg, checkdir) |
9104 |
- if self.options.mode == "manifest-check": |
9105 |
- return True |
9106 |
- return False |
9107 |
- |
9108 |
- def digest_check(self, xpkg, checkdir): |
9109 |
- """Check the manifest entries, report any Q/A errors |
9110 |
- |
9111 |
- @param xpkg: the cat/pkg name to check |
9112 |
- @param checkdir: the directory path to check""" |
9113 |
- self.repoman_settings["O"] = checkdir |
9114 |
- self.repoman_settings["PORTAGE_QUIET"] = "1" |
9115 |
- if not portage.digestcheck([], self.repoman_settings, strict=1): |
9116 |
- self.qatracker.add_error("manifest.bad", os.path.join(xpkg, "Manifest")) |
9117 |
- self.repoman_settings.pop("PORTAGE_QUIET", None) |
9118 |
- |
9119 |
- @property |
9120 |
- def runInPkgs(self): |
9121 |
- """Package level scans""" |
9122 |
- return (True, [self.check]) |
9123 |
|
9124 |
diff --git a/repoman/lib/repoman/modules/scan/metadata/__init__.py b/repoman/lib/repoman/modules/scan/metadata/__init__.py |
9125 |
deleted file mode 100644 |
9126 |
index c133b1b37..000000000 |
9127 |
--- a/repoman/lib/repoman/modules/scan/metadata/__init__.py |
9128 |
+++ /dev/null |
9129 |
@@ -1,89 +0,0 @@ |
9130 |
-# Copyright 2015-2021 Gentoo Authors |
9131 |
-# Distributed under the terms of the GNU General Public License v2 |
9132 |
- |
9133 |
-doc = """Metadata plug-in module for repoman. |
9134 |
-Performs metadata checks on packages.""" |
9135 |
-__doc__ = doc[:] |
9136 |
- |
9137 |
- |
9138 |
-module_spec = { |
9139 |
- "name": "metadata", |
9140 |
- "description": doc, |
9141 |
- "provides": { |
9142 |
- "pkg-metadata": { |
9143 |
- "name": "pkgmetadata", |
9144 |
- "sourcefile": "pkgmetadata", |
9145 |
- "class": "PkgMetadata", |
9146 |
- "description": doc, |
9147 |
- "functions": ["check"], |
9148 |
- "func_desc": {}, |
9149 |
- "mod_kwargs": [ |
9150 |
- "repo_settings", |
9151 |
- "qatracker", |
9152 |
- "options", |
9153 |
- "metadata_xsd", |
9154 |
- "uselist", |
9155 |
- ], |
9156 |
- "func_kwargs": { |
9157 |
- "checkdir": (None, None), |
9158 |
- "checkdirlist": (None, None), |
9159 |
- "ebuild": (None, None), |
9160 |
- "pkg": (None, None), |
9161 |
- "repolevel": (None, None), |
9162 |
- "validity_future": (None, None), |
9163 |
- "xpkg": (None, None), |
9164 |
- "y_ebuild": (None, None), |
9165 |
- }, |
9166 |
- "module_runsIn": ["pkgs", "ebuilds", "final"], |
9167 |
- }, |
9168 |
- "ebuild-metadata": { |
9169 |
- "name": "ebuild_metadata", |
9170 |
- "sourcefile": "ebuild_metadata", |
9171 |
- "class": "EbuildMetadata", |
9172 |
- "description": doc, |
9173 |
- "functions": ["check"], |
9174 |
- "func_desc": {}, |
9175 |
- "mod_kwargs": [ |
9176 |
- "qatracker", |
9177 |
- "repo_settings", |
9178 |
- ], |
9179 |
- "func_kwargs": { |
9180 |
- "catdir": (None, None), |
9181 |
- "ebuild": (None, None), |
9182 |
- "xpkg": (None, None), |
9183 |
- "y_ebuild": (None, None), |
9184 |
- }, |
9185 |
- "module_runsIn": ["ebuilds"], |
9186 |
- }, |
9187 |
- "description-metadata": { |
9188 |
- "name": "description", |
9189 |
- "sourcefile": "description", |
9190 |
- "class": "DescriptionChecks", |
9191 |
- "description": doc, |
9192 |
- "functions": ["check"], |
9193 |
- "func_desc": {}, |
9194 |
- "mod_kwargs": ["qatracker", "repo_settings"], |
9195 |
- "func_kwargs": { |
9196 |
- "ebuild": (None, None), |
9197 |
- "pkg": ("Future", "UNSET"), |
9198 |
- }, |
9199 |
- "module_runsIn": ["ebuilds"], |
9200 |
- }, |
9201 |
- "restrict-metadata": { |
9202 |
- "name": "restrict", |
9203 |
- "sourcefile": "restrict", |
9204 |
- "class": "RestrictChecks", |
9205 |
- "description": doc, |
9206 |
- "functions": ["check"], |
9207 |
- "func_desc": {}, |
9208 |
- "mod_kwargs": ["qatracker", "repo_settings"], |
9209 |
- "func_kwargs": { |
9210 |
- "ebuild": (None, None), |
9211 |
- "xpkg": (None, None), |
9212 |
- "y_ebuild": (None, None), |
9213 |
- }, |
9214 |
- "module_runsIn": ["ebuilds"], |
9215 |
- }, |
9216 |
- }, |
9217 |
- "version": 1, |
9218 |
-} |
9219 |
|
9220 |
diff --git a/repoman/lib/repoman/modules/scan/metadata/description.py b/repoman/lib/repoman/modules/scan/metadata/description.py |
9221 |
deleted file mode 100644 |
9222 |
index c9fb5e7f9..000000000 |
9223 |
--- a/repoman/lib/repoman/modules/scan/metadata/description.py |
9224 |
+++ /dev/null |
9225 |
@@ -1,44 +0,0 @@ |
9226 |
-"""description.py |
9227 |
-Perform checks on the DESCRIPTION variable. |
9228 |
-""" |
9229 |
- |
9230 |
-from repoman.modules.scan.scanbase import ScanBase |
9231 |
- |
9232 |
- |
9233 |
-class DescriptionChecks(ScanBase): |
9234 |
- """Perform checks on the DESCRIPTION variable.""" |
9235 |
- |
9236 |
- def __init__(self, **kwargs): |
9237 |
- """ |
9238 |
- @param qatracker: QATracker instance |
9239 |
- """ |
9240 |
- self.qatracker = kwargs.get("qatracker") |
9241 |
- self.repo_settings = kwargs.get("repo_settings") |
9242 |
- |
9243 |
- def checkTooLong(self, **kwargs): |
9244 |
- """ |
9245 |
- @param pkg: Package in which we check (object). |
9246 |
- @param ebuild: Ebuild which we check (object). |
9247 |
- """ |
9248 |
- ebuild = kwargs.get("ebuild").get() |
9249 |
- pkg = kwargs.get("pkg").get() |
9250 |
- # 14 is the length of DESCRIPTION="" |
9251 |
- if len(pkg._metadata["DESCRIPTION"]) > self.repo_settings.qadata.max_desc_len: |
9252 |
- self.qatracker.add_error( |
9253 |
- "DESCRIPTION.toolong", |
9254 |
- "%s: DESCRIPTION is %d characters (max %d)" |
9255 |
- % ( |
9256 |
- ebuild.relative_path, |
9257 |
- len(pkg._metadata["DESCRIPTION"]), |
9258 |
- self.repo_settings.qadata.max_desc_len, |
9259 |
- ), |
9260 |
- ) |
9261 |
- return False |
9262 |
- |
9263 |
- @property |
9264 |
- def runInPkgs(self): |
9265 |
- return (False, []) |
9266 |
- |
9267 |
- @property |
9268 |
- def runInEbuilds(self): |
9269 |
- return (True, [self.checkTooLong]) |
9270 |
|
9271 |
diff --git a/repoman/lib/repoman/modules/scan/metadata/ebuild_metadata.py b/repoman/lib/repoman/modules/scan/metadata/ebuild_metadata.py |
9272 |
deleted file mode 100644 |
9273 |
index fd0552ce7..000000000 |
9274 |
--- a/repoman/lib/repoman/modules/scan/metadata/ebuild_metadata.py |
9275 |
+++ /dev/null |
9276 |
@@ -1,84 +0,0 @@ |
9277 |
-# -*- coding:utf-8 -*- |
9278 |
- |
9279 |
-"""Ebuild Metadata Checks""" |
9280 |
- |
9281 |
-import re |
9282 |
- |
9283 |
-from repoman.modules.scan.scanbase import ScanBase |
9284 |
- |
9285 |
-from portage.dep import use_reduce |
9286 |
- |
9287 |
-NON_ASCII_RE = re.compile(r"[^\x00-\x7f]") |
9288 |
-URISCHEME_RE = re.compile(r"^[a-z][0-9a-z\-\.\+]+://") |
9289 |
- |
9290 |
- |
9291 |
-class EbuildMetadata(ScanBase): |
9292 |
- def __init__(self, **kwargs): |
9293 |
- self.qatracker = kwargs.get("qatracker") |
9294 |
- self.repo_settings = kwargs.get("repo_settings") |
9295 |
- |
9296 |
- def invalidchar(self, **kwargs): |
9297 |
- ebuild = kwargs.get("ebuild").get() |
9298 |
- for k, v in ebuild.metadata.items(): |
9299 |
- if not isinstance(v, str): |
9300 |
- continue |
9301 |
- m = NON_ASCII_RE.search(v) |
9302 |
- if m is not None: |
9303 |
- self.qatracker.add_error( |
9304 |
- "variable.invalidchar", |
9305 |
- "%s: %s variable contains non-ASCII " |
9306 |
- "character at position %s" |
9307 |
- % (ebuild.relative_path, k, m.start() + 1), |
9308 |
- ) |
9309 |
- return False |
9310 |
- |
9311 |
- def missing(self, **kwargs): |
9312 |
- ebuild = kwargs.get("ebuild").get() |
9313 |
- for pos, missing_var in enumerate(self.repo_settings.qadata.missingvars): |
9314 |
- if not ebuild.metadata.get(missing_var): |
9315 |
- if kwargs.get("catdir") in ( |
9316 |
- "acct-group", |
9317 |
- "acct-user", |
9318 |
- "virtual", |
9319 |
- ) and missing_var in ("HOMEPAGE", "LICENSE"): |
9320 |
- continue |
9321 |
- if ebuild.live_ebuild and missing_var == "KEYWORDS": |
9322 |
- continue |
9323 |
- myqakey = self.repo_settings.qadata.missingvars[pos] + ".missing" |
9324 |
- self.qatracker.add_error( |
9325 |
- myqakey, |
9326 |
- "%s/%s.ebuild" % (kwargs.get("xpkg"), kwargs.get("y_ebuild")), |
9327 |
- ) |
9328 |
- return False |
9329 |
- |
9330 |
- def virtual(self, **kwargs): |
9331 |
- ebuild = kwargs.get("ebuild").get() |
9332 |
- if kwargs.get("catdir") == "virtual": |
9333 |
- for var in ("HOMEPAGE", "LICENSE"): |
9334 |
- if ebuild.metadata.get(var): |
9335 |
- myqakey = var + ".virtual" |
9336 |
- self.qatracker.add_error(myqakey, ebuild.relative_path) |
9337 |
- return False |
9338 |
- |
9339 |
- def homepage_urischeme(self, **kwargs): |
9340 |
- ebuild = kwargs.get("ebuild").get() |
9341 |
- if kwargs.get("catdir") != "virtual": |
9342 |
- for homepage in use_reduce( |
9343 |
- ebuild.metadata["HOMEPAGE"], matchall=True, flat=True |
9344 |
- ): |
9345 |
- if URISCHEME_RE.match(homepage) is None: |
9346 |
- self.qatracker.add_error( |
9347 |
- "HOMEPAGE.missingurischeme", ebuild.relative_path |
9348 |
- ) |
9349 |
- return False |
9350 |
- |
9351 |
- @property |
9352 |
- def runInPkgs(self): |
9353 |
- return (False, []) |
9354 |
- |
9355 |
- @property |
9356 |
- def runInEbuilds(self): |
9357 |
- return ( |
9358 |
- True, |
9359 |
- [self.invalidchar, self.missing, self.virtual, self.homepage_urischeme], |
9360 |
- ) |
9361 |
|
9362 |
diff --git a/repoman/lib/repoman/modules/scan/metadata/pkgmetadata.py b/repoman/lib/repoman/modules/scan/metadata/pkgmetadata.py |
9363 |
deleted file mode 100644 |
9364 |
index 0fb97a0df..000000000 |
9365 |
--- a/repoman/lib/repoman/modules/scan/metadata/pkgmetadata.py |
9366 |
+++ /dev/null |
9367 |
@@ -1,221 +0,0 @@ |
9368 |
-# -*- coding:utf-8 -*- |
9369 |
- |
9370 |
-"""Package Metadata Checks operations""" |
9371 |
- |
9372 |
-import sys |
9373 |
-import re |
9374 |
- |
9375 |
-from itertools import chain |
9376 |
-from collections import Counter |
9377 |
- |
9378 |
-try: |
9379 |
- from lxml import etree |
9380 |
- from lxml.etree import ParserError |
9381 |
-except (SystemExit, KeyboardInterrupt): |
9382 |
- raise |
9383 |
-except (ImportError, SystemError, RuntimeError, Exception): |
9384 |
- # broken or missing xml support |
9385 |
- # https://bugs.python.org/issue14988 |
9386 |
- msg = ["Please emerge dev-python/lxml in order to use repoman."] |
9387 |
- from portage.output import EOutput |
9388 |
- |
9389 |
- out = EOutput() |
9390 |
- for line in msg: |
9391 |
- out.eerror(line) |
9392 |
- sys.exit(1) |
9393 |
- |
9394 |
-# import our initialized portage instance |
9395 |
-from repoman._portage import portage # pylint: disable=unused-import |
9396 |
-from repoman.metadata import metadata_dtd_uri |
9397 |
-from repoman.modules.scan.scanbase import ScanBase |
9398 |
- |
9399 |
-# pylint: disable=ungrouped-imports |
9400 |
-from portage.exception import InvalidAtom |
9401 |
-from portage import os |
9402 |
-from portage.dep import Atom |
9403 |
-from portage.xml.metadata import parse_metadata_use |
9404 |
- |
9405 |
-from .use_flags import USEFlagChecks |
9406 |
- |
9407 |
-metadata_xml_encoding = "UTF-8" |
9408 |
-metadata_xml_declaration = '<?xml version="1.0" encoding="%s"?>' % ( |
9409 |
- metadata_xml_encoding, |
9410 |
-) |
9411 |
-metadata_doctype_name = "pkgmetadata" |
9412 |
- |
9413 |
- |
9414 |
-class PkgMetadata(ScanBase, USEFlagChecks): |
9415 |
- """Package metadata.xml checks""" |
9416 |
- |
9417 |
- def __init__(self, **kwargs): |
9418 |
- """PkgMetadata init function |
9419 |
- |
9420 |
- @param repo_settings: settings instance |
9421 |
- @param qatracker: QATracker instance |
9422 |
- @param options: argparse options instance |
9423 |
- @param metadata_xsd: path of metadata.xsd |
9424 |
- """ |
9425 |
- super(PkgMetadata, self).__init__(**kwargs) |
9426 |
- repo_settings = kwargs.get("repo_settings") |
9427 |
- self.qatracker = kwargs.get("qatracker") |
9428 |
- self.options = kwargs.get("options") |
9429 |
- self.metadata_xsd = kwargs.get("metadata_xsd") |
9430 |
- self.globalUseFlags = kwargs.get("uselist") |
9431 |
- self.repoman_settings = repo_settings.repoman_settings |
9432 |
- self.musedict = {} |
9433 |
- self.muselist = set() |
9434 |
- |
9435 |
- def check(self, **kwargs): |
9436 |
- """Performs the checks on the metadata.xml for the package |
9437 |
- @param xpkg: the pacakge being checked |
9438 |
- @param checkdir: string, directory path |
9439 |
- @param checkdirlist: list of checkdir's |
9440 |
- @param repolevel: integer |
9441 |
- @returns: boolean |
9442 |
- """ |
9443 |
- xpkg = kwargs.get("xpkg") |
9444 |
- checkdir = kwargs.get("checkdir") |
9445 |
- checkdirlist = kwargs.get("checkdirlist").get() |
9446 |
- |
9447 |
- self.musedict = {} |
9448 |
- if self.options.mode in ["manifest"]: |
9449 |
- self.muselist = frozenset(self.musedict) |
9450 |
- return False |
9451 |
- |
9452 |
- # metadata.xml file check |
9453 |
- if "metadata.xml" not in checkdirlist: |
9454 |
- self.qatracker.add_error("metadata.missing", xpkg + "/metadata.xml") |
9455 |
- self.muselist = frozenset(self.musedict) |
9456 |
- return False |
9457 |
- |
9458 |
- # metadata.xml parse check |
9459 |
- metadata_bad = False |
9460 |
- |
9461 |
- # read metadata.xml into memory |
9462 |
- try: |
9463 |
- _metadata_xml = etree.parse(os.path.join(checkdir, "metadata.xml")) |
9464 |
- except (ParserError, SyntaxError, EnvironmentError) as e: |
9465 |
- metadata_bad = True |
9466 |
- self.qatracker.add_error("metadata.bad", "%s/metadata.xml: %s" % (xpkg, e)) |
9467 |
- del e |
9468 |
- self.muselist = frozenset(self.musedict) |
9469 |
- return False |
9470 |
- |
9471 |
- indentation_chars = Counter() |
9472 |
- for l in etree.tostring(_metadata_xml).splitlines(): |
9473 |
- indentation_chars.update(re.match(rb"\s*", l).group(0)) |
9474 |
- if len(indentation_chars) > 1: |
9475 |
- self.qatracker.add_error( |
9476 |
- "metadata.warning", |
9477 |
- "%s/metadata.xml: %s" |
9478 |
- % (xpkg, "inconsistent use of tabs and spaces in indentation"), |
9479 |
- ) |
9480 |
- |
9481 |
- xml_encoding = _metadata_xml.docinfo.encoding |
9482 |
- if xml_encoding.upper() != metadata_xml_encoding: |
9483 |
- self.qatracker.add_error( |
9484 |
- "metadata.bad", |
9485 |
- "%s/metadata.xml: " |
9486 |
- "xml declaration encoding should be '%s', not '%s'" |
9487 |
- % (xpkg, metadata_xml_encoding, xml_encoding), |
9488 |
- ) |
9489 |
- |
9490 |
- if not _metadata_xml.docinfo.doctype: |
9491 |
- metadata_bad = True |
9492 |
- self.qatracker.add_error( |
9493 |
- "metadata.bad", "%s/metadata.xml: %s" % (xpkg, "DOCTYPE is missing") |
9494 |
- ) |
9495 |
- else: |
9496 |
- doctype_system = _metadata_xml.docinfo.system_url |
9497 |
- if doctype_system != metadata_dtd_uri: |
9498 |
- if doctype_system is None: |
9499 |
- system_problem = "but it is undefined" |
9500 |
- else: |
9501 |
- system_problem = "not '%s'" % doctype_system |
9502 |
- self.qatracker.add_error( |
9503 |
- "metadata.bad", |
9504 |
- "%s/metadata.xml: " |
9505 |
- "DOCTYPE: SYSTEM should refer to '%s', %s" |
9506 |
- % (xpkg, metadata_dtd_uri, system_problem), |
9507 |
- ) |
9508 |
- doctype_name = _metadata_xml.docinfo.doctype.split(" ")[1] |
9509 |
- if doctype_name != metadata_doctype_name: |
9510 |
- self.qatracker.add_error( |
9511 |
- "metadata.bad", |
9512 |
- "%s/metadata.xml: " |
9513 |
- "DOCTYPE: name should be '%s', not '%s'" |
9514 |
- % (xpkg, metadata_doctype_name, doctype_name), |
9515 |
- ) |
9516 |
- |
9517 |
- # load USE flags from metadata.xml |
9518 |
- self.musedict = parse_metadata_use(_metadata_xml) |
9519 |
- for atom in chain(*self.musedict.values()): |
9520 |
- if atom is None: |
9521 |
- continue |
9522 |
- try: |
9523 |
- atom = Atom(atom) |
9524 |
- except InvalidAtom as e: |
9525 |
- self.qatracker.add_error( |
9526 |
- "metadata.bad", "%s/metadata.xml: Invalid atom: %s" % (xpkg, e) |
9527 |
- ) |
9528 |
- else: |
9529 |
- if atom.cp != xpkg: |
9530 |
- self.qatracker.add_error( |
9531 |
- "metadata.bad", |
9532 |
- "%s/metadata.xml: Atom contains " |
9533 |
- "unexpected cat/pn: %s" % (xpkg, atom), |
9534 |
- ) |
9535 |
- |
9536 |
- # Only carry out if in package directory or check forced |
9537 |
- if not metadata_bad: |
9538 |
- validator = etree.XMLSchema(file=self.metadata_xsd) |
9539 |
- if not validator.validate(_metadata_xml): |
9540 |
- self._add_validate_errors(xpkg, validator.error_log) |
9541 |
- self.muselist = frozenset(self.musedict) |
9542 |
- return False |
9543 |
- |
9544 |
- def check_unused(self, **kwargs): |
9545 |
- """Reports on any unused metadata.xml use descriptions |
9546 |
- |
9547 |
- @param xpkg: the pacakge being checked |
9548 |
- @param used_useflags: use flag list |
9549 |
- @param validity_future: Future instance |
9550 |
- """ |
9551 |
- xpkg = kwargs.get("xpkg") |
9552 |
- valid_state = kwargs.get("validity_future").get() |
9553 |
- # check if there are unused local USE-descriptions in metadata.xml |
9554 |
- # (unless there are any invalids, to avoid noise) |
9555 |
- if valid_state: |
9556 |
- for myflag in self.muselist.difference(self.usedUseFlags): |
9557 |
- self.qatracker.add_error( |
9558 |
- "metadata.bad", |
9559 |
- "%s/metadata.xml: unused local USE-description: '%s'" |
9560 |
- % (xpkg, myflag), |
9561 |
- ) |
9562 |
- return False |
9563 |
- |
9564 |
- def _add_validate_errors(self, xpkg, log): |
9565 |
- listed = set() |
9566 |
- for error in log: |
9567 |
- msg_prefix = error.message.split(":", 1)[0] |
9568 |
- info = "%s %s" % (error.line, msg_prefix) |
9569 |
- if info not in listed: |
9570 |
- listed.add(info) |
9571 |
- self.qatracker.add_error( |
9572 |
- "metadata.bad", |
9573 |
- "%s/metadata.xml: line: %s, %s" % (xpkg, error.line, error.message), |
9574 |
- ) |
9575 |
- |
9576 |
- @property |
9577 |
- def runInPkgs(self): |
9578 |
- """Package level scans""" |
9579 |
- return (True, [self.check]) |
9580 |
- |
9581 |
- @property |
9582 |
- def runInEbuilds(self): |
9583 |
- return (True, [self.check_useflags]) |
9584 |
- |
9585 |
- @property |
9586 |
- def runInFinal(self): |
9587 |
- """Final scans at the package level""" |
9588 |
- return (True, [self.check_unused]) |
9589 |
|
9590 |
diff --git a/repoman/lib/repoman/modules/scan/metadata/restrict.py b/repoman/lib/repoman/modules/scan/metadata/restrict.py |
9591 |
deleted file mode 100644 |
9592 |
index 036af88f6..000000000 |
9593 |
--- a/repoman/lib/repoman/modules/scan/metadata/restrict.py |
9594 |
+++ /dev/null |
9595 |
@@ -1,58 +0,0 @@ |
9596 |
-"""restrict.py |
9597 |
-Perform checks on the RESTRICT variable. |
9598 |
-""" |
9599 |
- |
9600 |
-# import our initialized portage instance |
9601 |
-from repoman._portage import portage |
9602 |
- |
9603 |
-from repoman.modules.scan.scanbase import ScanBase |
9604 |
- |
9605 |
- |
9606 |
-class RestrictChecks(ScanBase): |
9607 |
- """Perform checks on the RESTRICT variable.""" |
9608 |
- |
9609 |
- def __init__(self, **kwargs): |
9610 |
- """ |
9611 |
- @param qatracker: QATracker instance |
9612 |
- """ |
9613 |
- self.qatracker = kwargs.get("qatracker") |
9614 |
- self.repo_settings = kwargs.get("repo_settings") |
9615 |
- if self.repo_settings.repo_config.restrict_allowed is None: |
9616 |
- self._restrict_allowed = self.repo_settings.qadata.valid_restrict |
9617 |
- else: |
9618 |
- self._restrict_allowed = self.repo_settings.repo_config.restrict_allowed |
9619 |
- |
9620 |
- def check(self, **kwargs): |
9621 |
- xpkg = kwargs.get("xpkg") |
9622 |
- ebuild = kwargs.get("ebuild").get() |
9623 |
- y_ebuild = kwargs.get("y_ebuild") |
9624 |
- myrestrict = None |
9625 |
- |
9626 |
- try: |
9627 |
- myrestrict = portage.dep.use_reduce( |
9628 |
- ebuild.metadata["RESTRICT"], matchall=1, flat=True |
9629 |
- ) |
9630 |
- except portage.exception.InvalidDependString as e: |
9631 |
- self.qatracker.add_error( |
9632 |
- "RESTRICT.syntax", "%s: RESTRICT: %s" % (ebuild.relative_path, e) |
9633 |
- ) |
9634 |
- del e |
9635 |
- |
9636 |
- if myrestrict: |
9637 |
- myrestrict = set(myrestrict) |
9638 |
- mybadrestrict = myrestrict.difference(self._restrict_allowed) |
9639 |
- |
9640 |
- if mybadrestrict: |
9641 |
- for mybad in mybadrestrict: |
9642 |
- self.qatracker.add_error( |
9643 |
- "RESTRICT.invalid", "%s/%s.ebuild: %s" % (xpkg, y_ebuild, mybad) |
9644 |
- ) |
9645 |
- return False |
9646 |
- |
9647 |
- @property |
9648 |
- def runInPkgs(self): |
9649 |
- return (False, []) |
9650 |
- |
9651 |
- @property |
9652 |
- def runInEbuilds(self): |
9653 |
- return (True, [self.check]) |
9654 |
|
9655 |
diff --git a/repoman/lib/repoman/modules/scan/metadata/use_flags.py b/repoman/lib/repoman/modules/scan/metadata/use_flags.py |
9656 |
deleted file mode 100644 |
9657 |
index f2116800e..000000000 |
9658 |
--- a/repoman/lib/repoman/modules/scan/metadata/use_flags.py |
9659 |
+++ /dev/null |
9660 |
@@ -1,103 +0,0 @@ |
9661 |
-# -*- coding:utf-8 -*- |
9662 |
- |
9663 |
-"""use_flags.py |
9664 |
-Performs USE flag related checks |
9665 |
-""" |
9666 |
- |
9667 |
-# import our centrally initialized portage instance |
9668 |
-from repoman._portage import portage |
9669 |
- |
9670 |
-from portage import eapi |
9671 |
-from portage.eapi import eapi_has_iuse_defaults, eapi_has_required_use |
9672 |
- |
9673 |
- |
9674 |
-class USEFlagChecks: |
9675 |
- """Performs checks on USE flags listed in the ebuilds and metadata.xml""" |
9676 |
- |
9677 |
- def __init__(self, **kwargs): |
9678 |
- """Class init |
9679 |
- |
9680 |
- @param qatracker: QATracker instance |
9681 |
- @param globalUseFlags: Global USE flags |
9682 |
- """ |
9683 |
- super(USEFlagChecks, self).__init__() |
9684 |
- self.qatracker = None |
9685 |
- self.globalUseFlags = None |
9686 |
- self.useFlags = [] |
9687 |
- self.defaultUseFlags = [] |
9688 |
- self.usedUseFlags = set() |
9689 |
- |
9690 |
- def check_useflags(self, **kwargs): |
9691 |
- """Perform the check. |
9692 |
- |
9693 |
- @param pkg: Package in which we check (object). |
9694 |
- @param xpkg: Package in which we check (string). |
9695 |
- @param ebuild: Ebuild which we check (object). |
9696 |
- @param y_ebuild: Ebuild which we check (string). |
9697 |
- @returns: dictionary, including {ebuild_UsedUseFlags, used_useflags} |
9698 |
- """ |
9699 |
- pkg = kwargs.get("pkg").get() |
9700 |
- package = kwargs.get("xpkg") |
9701 |
- ebuild = kwargs.get("ebuild").get() |
9702 |
- y_ebuild = kwargs.get("y_ebuild") |
9703 |
- # reset state variables for the run |
9704 |
- self.useFlags = [] |
9705 |
- self.defaultUseFlags = [] |
9706 |
- # perform the checks |
9707 |
- self._checkGlobal(pkg) |
9708 |
- self._checkMetadata(package, ebuild, y_ebuild, self.muselist) |
9709 |
- self._checkRequiredUSE(pkg, ebuild) |
9710 |
- return False |
9711 |
- |
9712 |
- def _checkGlobal(self, pkg): |
9713 |
- for myflag in pkg._metadata["IUSE"].split(): |
9714 |
- flag_name = myflag.lstrip("+-") |
9715 |
- self.usedUseFlags.add(flag_name) |
9716 |
- if myflag != flag_name: |
9717 |
- self.defaultUseFlags.append(myflag) |
9718 |
- if flag_name not in self.globalUseFlags: |
9719 |
- self.useFlags.append(flag_name) |
9720 |
- |
9721 |
- def _checkMetadata(self, package, ebuild, y_ebuild, localUseFlags): |
9722 |
- for mypos in range(len(self.useFlags) - 1, -1, -1): |
9723 |
- if self.useFlags[mypos] and (self.useFlags[mypos] in localUseFlags): |
9724 |
- del self.useFlags[mypos] |
9725 |
- |
9726 |
- if self.defaultUseFlags and not eapi_has_iuse_defaults(eapi): |
9727 |
- for myflag in self.defaultUseFlags: |
9728 |
- self.qatracker.add_error( |
9729 |
- "EAPI.incompatible", |
9730 |
- "%s: IUSE defaults" |
9731 |
- " not supported with EAPI='%s': '%s'" |
9732 |
- % (ebuild.relative_path, eapi, myflag), |
9733 |
- ) |
9734 |
- |
9735 |
- for mypos in range(len(self.useFlags)): |
9736 |
- self.qatracker.add_error( |
9737 |
- "IUSE.invalid", |
9738 |
- "%s/%s.ebuild: %s" % (package, y_ebuild, self.useFlags[mypos]), |
9739 |
- ) |
9740 |
- |
9741 |
- def _checkRequiredUSE(self, pkg, ebuild): |
9742 |
- required_use = pkg._metadata["REQUIRED_USE"] |
9743 |
- if required_use: |
9744 |
- if not eapi_has_required_use(eapi): |
9745 |
- self.qatracker.add_error( |
9746 |
- "EAPI.incompatible", |
9747 |
- "%s: REQUIRED_USE" |
9748 |
- " not supported with EAPI='%s'" |
9749 |
- % ( |
9750 |
- ebuild.relative_path, |
9751 |
- eapi, |
9752 |
- ), |
9753 |
- ) |
9754 |
- try: |
9755 |
- portage.dep.check_required_use( |
9756 |
- required_use, (), pkg.iuse.is_valid_flag, eapi=eapi |
9757 |
- ) |
9758 |
- except portage.exception.InvalidDependString as e: |
9759 |
- self.qatracker.add_error( |
9760 |
- "REQUIRED_USE.syntax", |
9761 |
- "%s: REQUIRED_USE: %s" % (ebuild.relative_path, e), |
9762 |
- ) |
9763 |
- del e |
9764 |
|
9765 |
diff --git a/repoman/lib/repoman/modules/scan/module.py b/repoman/lib/repoman/modules/scan/module.py |
9766 |
deleted file mode 100644 |
9767 |
index 9e67f9bd6..000000000 |
9768 |
--- a/repoman/lib/repoman/modules/scan/module.py |
9769 |
+++ /dev/null |
9770 |
@@ -1,127 +0,0 @@ |
9771 |
-""" |
9772 |
-moudules/scan/module.py |
9773 |
-Module loading and run list generator |
9774 |
-""" |
9775 |
- |
9776 |
-import logging |
9777 |
-import os |
9778 |
-import yaml |
9779 |
- |
9780 |
-import portage |
9781 |
-from portage.module import InvalidModuleName, Modules |
9782 |
-from portage.util import stack_lists |
9783 |
-from repoman import _not_installed |
9784 |
-from repoman.config import ConfigError |
9785 |
- |
9786 |
-MODULES_PATH = os.path.dirname(__file__) |
9787 |
-# initial development debug info |
9788 |
-logging.debug("module path: %s", MODULES_PATH) |
9789 |
- |
9790 |
- |
9791 |
-class ModuleConfig: |
9792 |
- """Holds the scan modules configuration information and |
9793 |
- creates the ordered list of modulles to run""" |
9794 |
- |
9795 |
- def __init__(self, configpaths, valid_versions=None, repository_modules=False): |
9796 |
- """Module init |
9797 |
- |
9798 |
- @param configpaths: ordered list of filepaths to load |
9799 |
- """ |
9800 |
- if repository_modules: |
9801 |
- self.configpaths = [ |
9802 |
- os.path.join(path, "repository.yaml") for path in configpaths |
9803 |
- ] |
9804 |
- elif _not_installed: |
9805 |
- self.configpaths = [ |
9806 |
- os.path.realpath( |
9807 |
- os.path.join( |
9808 |
- os.path.dirname( |
9809 |
- os.path.dirname( |
9810 |
- os.path.dirname( |
9811 |
- os.path.dirname(os.path.dirname(__file__)) |
9812 |
- ) |
9813 |
- ) |
9814 |
- ), |
9815 |
- "cnf/repository/repository.yaml", |
9816 |
- ) |
9817 |
- ) |
9818 |
- ] |
9819 |
- else: |
9820 |
- self.configpaths = [ |
9821 |
- os.path.join( |
9822 |
- portage.const.EPREFIX or "/", |
9823 |
- "usr/share/repoman/repository/repository.yaml", |
9824 |
- ) |
9825 |
- ] |
9826 |
- logging.debug("ModuleConfig; configpaths: %s", self.configpaths) |
9827 |
- |
9828 |
- self.controller = Modules(path=MODULES_PATH, namepath="repoman.modules.scan") |
9829 |
- logging.debug("ModuleConfig; module_names: %s", self.controller.module_names) |
9830 |
- |
9831 |
- self._configs = None |
9832 |
- self.enabled = [] |
9833 |
- self.pkgs_loop = [] |
9834 |
- self.ebuilds_loop = [] |
9835 |
- self.final_loop = [] |
9836 |
- self.modules_forced = ["ebuild", "mtime"] |
9837 |
- self.load_configs(valid_versions=valid_versions) |
9838 |
- for loop in ["pkgs", "ebuilds", "final"]: |
9839 |
- logging.debug("ModuleConfig; Processing loop %s", loop) |
9840 |
- setattr(self, "%s_loop" % loop, self._determine_list(loop)) |
9841 |
- self.linechecks = stack_lists( |
9842 |
- c["linechecks_modules"].split() for c in self._configs |
9843 |
- ) |
9844 |
- |
9845 |
- def load_configs(self, configpaths=None, valid_versions=None): |
9846 |
- """load the config files in order |
9847 |
- |
9848 |
- @param configpaths: ordered list of filepaths to load |
9849 |
- """ |
9850 |
- if configpaths: |
9851 |
- self.configpaths = configpaths |
9852 |
- elif not self.configpaths: |
9853 |
- logging.error("ModuleConfig; Error: No repository.yaml files defined") |
9854 |
- configs = [] |
9855 |
- for path in self.configpaths: |
9856 |
- logging.debug("ModuleConfig; Processing: %s", path) |
9857 |
- if os.path.exists(path): |
9858 |
- try: |
9859 |
- with open(path, "r") as inputfile: |
9860 |
- configs.append(yaml.safe_load(inputfile)) |
9861 |
- except IOError as error: |
9862 |
- logging, error("Failed to load file: %s", inputfile) |
9863 |
- logging.exception(error) |
9864 |
- else: |
9865 |
- if configs[-1]["version"] not in valid_versions: |
9866 |
- raise ConfigError( |
9867 |
- "Invalid file version: %s in: %s\nPlease upgrade repoman" |
9868 |
- % (configs["version"], path) |
9869 |
- ) |
9870 |
- logging.debug("ModuleConfig; completed : %s", path) |
9871 |
- logging.debug("ModuleConfig; new _configs: %s", configs) |
9872 |
- self._configs = configs |
9873 |
- |
9874 |
- def _determine_list(self, loop): |
9875 |
- """Determine the ordered list from the config data and |
9876 |
- the moule_runsIn value in the module_spec |
9877 |
- |
9878 |
- @returns: list of modules |
9879 |
- """ |
9880 |
- lists = [c["scan_modules"].split() for c in self._configs] |
9881 |
- stacked = self.modules_forced + stack_lists(lists) |
9882 |
- mlist = [] |
9883 |
- try: |
9884 |
- for mod in stacked: |
9885 |
- logging.debug( |
9886 |
- "ModuleConfig; checking loop %s, module: %s, in: %s", |
9887 |
- loop, |
9888 |
- mod, |
9889 |
- self.controller.get_spec(mod, "module_runsIn"), |
9890 |
- ) |
9891 |
- if loop in self.controller.get_spec(mod, "module_runsIn"): |
9892 |
- mlist.append(mod) |
9893 |
- except InvalidModuleName: |
9894 |
- logging.error("ModuleConfig; unknown module: %s, skipping", mod) |
9895 |
- |
9896 |
- logging.debug("ModuleConfig; mlist: %s", mlist) |
9897 |
- return mlist |
9898 |
|
9899 |
diff --git a/repoman/lib/repoman/modules/scan/options/__init__.py b/repoman/lib/repoman/modules/scan/options/__init__.py |
9900 |
deleted file mode 100644 |
9901 |
index ce57cbbfc..000000000 |
9902 |
--- a/repoman/lib/repoman/modules/scan/options/__init__.py |
9903 |
+++ /dev/null |
9904 |
@@ -1,28 +0,0 @@ |
9905 |
-# Copyright 2015-2021 Gentoo Authors |
9906 |
-# Distributed under the terms of the GNU General Public License v2 |
9907 |
- |
9908 |
-doc = """Options plug-in module for repoman. |
9909 |
-Performs option related actions on ebuilds.""" |
9910 |
-__doc__ = doc[:] |
9911 |
- |
9912 |
- |
9913 |
-module_spec = { |
9914 |
- "name": "options", |
9915 |
- "description": doc, |
9916 |
- "provides": { |
9917 |
- "options-module": { |
9918 |
- "name": "options", |
9919 |
- "sourcefile": "options", |
9920 |
- "class": "Options", |
9921 |
- "description": doc, |
9922 |
- "functions": ["is_forced"], |
9923 |
- "func_desc": {}, |
9924 |
- "mod_kwargs": [ |
9925 |
- "options", |
9926 |
- ], |
9927 |
- "func_kwargs": {}, |
9928 |
- "module_runsIn": ["ebuilds"], |
9929 |
- }, |
9930 |
- }, |
9931 |
- "version": 1, |
9932 |
-} |
9933 |
|
9934 |
diff --git a/repoman/lib/repoman/modules/scan/options/options.py b/repoman/lib/repoman/modules/scan/options/options.py |
9935 |
deleted file mode 100644 |
9936 |
index 2a16be7ef..000000000 |
9937 |
--- a/repoman/lib/repoman/modules/scan/options/options.py |
9938 |
+++ /dev/null |
9939 |
@@ -1,27 +0,0 @@ |
9940 |
-from repoman.modules.scan.scanbase import ScanBase |
9941 |
- |
9942 |
- |
9943 |
-class Options(ScanBase): |
9944 |
- def __init__(self, **kwargs): |
9945 |
- """Class init function |
9946 |
- |
9947 |
- @param options: argparse options instance |
9948 |
- """ |
9949 |
- self.options = kwargs.get("options") |
9950 |
- |
9951 |
- def is_forced(self, **kwargs): |
9952 |
- """Simple boolean function to trigger a skip past some additional checks |
9953 |
- |
9954 |
- @returns: dictionary |
9955 |
- """ |
9956 |
- if self.options.force: |
9957 |
- # The dep_check() calls are the most expensive QA test. If --force |
9958 |
- # is enabled, there's no point in wasting time on these since the |
9959 |
- # user is intent on forcing the commit anyway. |
9960 |
- return True |
9961 |
- return False |
9962 |
- |
9963 |
- @property |
9964 |
- def runInEbuilds(self): |
9965 |
- """Ebuild level scans""" |
9966 |
- return (True, [self.is_forced]) |
9967 |
|
9968 |
diff --git a/repoman/lib/repoman/modules/scan/scan.py b/repoman/lib/repoman/modules/scan/scan.py |
9969 |
deleted file mode 100644 |
9970 |
index 30de50c35..000000000 |
9971 |
--- a/repoman/lib/repoman/modules/scan/scan.py |
9972 |
+++ /dev/null |
9973 |
@@ -1,67 +0,0 @@ |
9974 |
-# -*- coding:utf-8 -*- |
9975 |
- |
9976 |
-""" |
9977 |
-moudules/scan.py |
9978 |
-Module specific package scan list generator |
9979 |
-""" |
9980 |
- |
9981 |
-import logging |
9982 |
-import os |
9983 |
-import sys |
9984 |
- |
9985 |
-from repoman.errors import caterror |
9986 |
- |
9987 |
- |
9988 |
-def scan(repolevel, reposplit, startdir, categories, repo_settings): |
9989 |
- """Generate a list of pkgs to scan |
9990 |
- |
9991 |
- @param repolevel: integer, number of subdirectories deep from the tree root |
9992 |
- @param reposplit: list of the path subdirs |
9993 |
- @param startdir: the top level directory to begin scanning from |
9994 |
- @param categories: list of known categories |
9995 |
- @param repo_settings: repository settings instance |
9996 |
- @returns: scanlist, sorted list of pkgs to scan |
9997 |
- """ |
9998 |
- scanlist = [] |
9999 |
- if repolevel == 2: |
10000 |
- # we are inside a category directory |
10001 |
- catdir = reposplit[-1] |
10002 |
- if catdir not in categories: |
10003 |
- caterror(catdir, repo_settings.repodir) |
10004 |
- mydirlist = os.listdir(startdir) |
10005 |
- for x in mydirlist: |
10006 |
- if x == "CVS" or x.startswith("."): |
10007 |
- continue |
10008 |
- if os.path.isdir(startdir + "/" + x): |
10009 |
- scanlist.append(catdir + "/" + x) |
10010 |
- # repo_subdir = catdir + os.sep |
10011 |
- elif repolevel == 1: |
10012 |
- for x in categories: |
10013 |
- if not os.path.isdir(startdir + "/" + x): |
10014 |
- continue |
10015 |
- for y in os.listdir(startdir + "/" + x): |
10016 |
- if y == "CVS" or y.startswith("."): |
10017 |
- continue |
10018 |
- if os.path.isdir(startdir + "/" + x + "/" + y): |
10019 |
- scanlist.append(x + "/" + y) |
10020 |
- # repo_subdir = "" |
10021 |
- elif repolevel == 3: |
10022 |
- catdir = reposplit[-2] |
10023 |
- if catdir not in categories: |
10024 |
- caterror(catdir, repo_settings.repodir) |
10025 |
- scanlist.append(catdir + "/" + reposplit[-1]) |
10026 |
- # repo_subdir = scanlist[-1] + os.sep |
10027 |
- else: |
10028 |
- msg = ( |
10029 |
- "Repoman is unable to determine PORTDIR or PORTDIR_OVERLAY" |
10030 |
- + " from the current working directory" |
10031 |
- ) |
10032 |
- logging.critical(msg) |
10033 |
- sys.exit(1) |
10034 |
- |
10035 |
- # repo_subdir_len = len(repo_subdir) |
10036 |
- scanlist.sort() |
10037 |
- |
10038 |
- logging.debug("Found the following packages to scan:\n%s" % "\n".join(scanlist)) |
10039 |
- |
10040 |
- return scanlist |
10041 |
|
10042 |
diff --git a/repoman/lib/repoman/modules/scan/scanbase.py b/repoman/lib/repoman/modules/scan/scanbase.py |
10043 |
deleted file mode 100644 |
10044 |
index 5a7cd6219..000000000 |
10045 |
--- a/repoman/lib/repoman/modules/scan/scanbase.py |
10046 |
+++ /dev/null |
10047 |
@@ -1,79 +0,0 @@ |
10048 |
-# -*- coding:utf-8 -*- |
10049 |
- |
10050 |
- |
10051 |
-class ScanBase: |
10052 |
- """Skeleton class for performing a scan for one or more items |
10053 |
- to check in a pkg directory or ebuild.""" |
10054 |
- |
10055 |
- def __init__(self, **kwargs): |
10056 |
- """Class init |
10057 |
- |
10058 |
- @param kwargs: an optional dictionary of common repository |
10059 |
- wide parameters that may be required. |
10060 |
- """ |
10061 |
- # Since no two checks are identicle as to what kwargs are needed, |
10062 |
- # this does not define any from it here. |
10063 |
- super(ScanBase, self).__init__() |
10064 |
- |
10065 |
- """ # sample check |
10066 |
- def check_foo(self, **kwargs): |
10067 |
- '''Class check skeleton function. Define this for a |
10068 |
- specific check to perform. |
10069 |
- |
10070 |
- @param kwargs: an optional dictionary of dynamic package and or ebuild |
10071 |
- specific data that may be required. Dynamic data can |
10072 |
- vary depending what checks have run before it. |
10073 |
- So execution order can be important. |
10074 |
- ''' |
10075 |
- # Insert the code for the check here |
10076 |
- # It should return a dictionary of at least {'continue': False} |
10077 |
- # The continue attribute will default to False if not returned. |
10078 |
- # This will allow the loop to continue with the next check in the list. |
10079 |
- # Include any additional dynamic data that needs to be added or updated. |
10080 |
- return False # used as a continue True/False value |
10081 |
- """ |
10082 |
- |
10083 |
- @property |
10084 |
- def runInPkgs(self): |
10085 |
- """Package level scans""" |
10086 |
- # default no run (False) and empty list of functions to run |
10087 |
- # override this method to define a function or |
10088 |
- # functions to run in this process loop |
10089 |
- # return a tuple of a boolean or boolean result and an ordered list |
10090 |
- # of functions to run. ie: return (True, [self.check_foo]) |
10091 |
- # in this way, it can be dynamically determined at run time, if |
10092 |
- # later stage scans are to be run. |
10093 |
- # This class instance is maintaned for all stages, so data can be |
10094 |
- # carried over from stage to stage |
10095 |
- # next stage is runInEbuilds |
10096 |
- return (False, []) |
10097 |
- |
10098 |
- @property |
10099 |
- def runInEbuilds(self): |
10100 |
- """Ebuild level scans""" |
10101 |
- # default empty list of functions to run |
10102 |
- # override this method to define a function or |
10103 |
- # functions to run in this process loop |
10104 |
- # return a tuple of a boolean or boolean result and an ordered list |
10105 |
- # of functions to run. ie: return (True, [self.check_bar]) |
10106 |
- # in this way, it can be dynamically determined at run time, if |
10107 |
- # later stage scans are to be run. |
10108 |
- # This class instance is maintaned for all stages, so data can be |
10109 |
- # carried over from stage to stage |
10110 |
- # next stage is runInFinal |
10111 |
- return (False, []) |
10112 |
- |
10113 |
- @property |
10114 |
- def runInFinal(self): |
10115 |
- """Final scans at the package level""" |
10116 |
- # default empty list of functions to run |
10117 |
- # override this method to define a function or |
10118 |
- # functions to run in this process loop |
10119 |
- # return a tuple of a boolean or boolean result and an ordered list |
10120 |
- # of functions to run. ie: return (True, [self.check_baz]) |
10121 |
- # in this way, it can be dynamically determined at run time, if |
10122 |
- # later stage scans are to be run. |
10123 |
- # This class instance is maintaned for all stages, so data can be |
10124 |
- # carried over from stage to stage |
10125 |
- # runInFinal is currently the last stage of scans performed. |
10126 |
- return (False, []) |
10127 |
|
10128 |
diff --git a/repoman/lib/repoman/modules/vcs/None/__init__.py b/repoman/lib/repoman/modules/vcs/None/__init__.py |
10129 |
deleted file mode 100644 |
10130 |
index dc9eb51ad..000000000 |
10131 |
--- a/repoman/lib/repoman/modules/vcs/None/__init__.py |
10132 |
+++ /dev/null |
10133 |
@@ -1,32 +0,0 @@ |
10134 |
-# Copyright 2014-2015 Gentoo Foundation |
10135 |
-# Distributed under the terms of the GNU General Public License v2 |
10136 |
- |
10137 |
-doc = """None (non vcs type) plug-in module for portage. |
10138 |
-Performs various git actions and checks on repositories.""" |
10139 |
-__doc__ = doc[:] |
10140 |
- |
10141 |
- |
10142 |
-module_spec = { |
10143 |
- "name": "None", |
10144 |
- "description": doc, |
10145 |
- "provides": { |
10146 |
- "None-module": { |
10147 |
- "name": "None_status", |
10148 |
- "sourcefile": "status", |
10149 |
- "class": "Status", |
10150 |
- "description": doc, |
10151 |
- "functions": ["check", "supports_gpg_sign", "detect_conflicts"], |
10152 |
- "func_desc": {}, |
10153 |
- "vcs_preserves_mtime": False, |
10154 |
- "needs_keyword_expansion": False, |
10155 |
- }, |
10156 |
- "None-changes": { |
10157 |
- "name": "None_changes", |
10158 |
- "sourcefile": "changes", |
10159 |
- "class": "Changes", |
10160 |
- "description": doc, |
10161 |
- "functions": ["scan"], |
10162 |
- "func_desc": {}, |
10163 |
- }, |
10164 |
- }, |
10165 |
-} |
10166 |
|
10167 |
diff --git a/repoman/lib/repoman/modules/vcs/None/changes.py b/repoman/lib/repoman/modules/vcs/None/changes.py |
10168 |
deleted file mode 100644 |
10169 |
index 4164c84bf..000000000 |
10170 |
--- a/repoman/lib/repoman/modules/vcs/None/changes.py |
10171 |
+++ /dev/null |
10172 |
@@ -1,50 +0,0 @@ |
10173 |
-""" |
10174 |
-None module Changes class submodule |
10175 |
-""" |
10176 |
- |
10177 |
-from repoman.modules.vcs.changes import ChangesBase |
10178 |
- |
10179 |
- |
10180 |
-class Changes(ChangesBase): |
10181 |
- """Class object to scan and hold the resultant data |
10182 |
- for all changes to process. |
10183 |
- """ |
10184 |
- |
10185 |
- vcs = "None" |
10186 |
- |
10187 |
- def __init__(self, options, repo_settings): |
10188 |
- """Class init |
10189 |
- |
10190 |
- @param options: the run time cli options |
10191 |
- @param repo_settings: RepoSettings instance |
10192 |
- """ |
10193 |
- super(Changes, self).__init__(options, repo_settings) |
10194 |
- |
10195 |
- def scan(self): |
10196 |
- """VCS type scan function, looks for all detectable changes""" |
10197 |
- pass |
10198 |
- |
10199 |
- def add_items(self, autoadd): |
10200 |
- """Add files to the vcs's modified or new index |
10201 |
- |
10202 |
- @param autoadd: the files to add to the vcs modified index""" |
10203 |
- pass |
10204 |
- |
10205 |
- def commit(self, myfiles, commitmessagefile): |
10206 |
- """None commit function |
10207 |
- |
10208 |
- @param commitfiles: list of files to commit |
10209 |
- @param commitmessagefile: file containing the commit message |
10210 |
- @returns: The sub-command exit value or 0 |
10211 |
- """ |
10212 |
- commit_cmd = [] |
10213 |
- # substitute a bogus vcs value for pretend output |
10214 |
- commit_cmd.append("pretend") |
10215 |
- commit_cmd.extend(self.vcs_settings.vcs_global_opts) |
10216 |
- commit_cmd.append("commit") |
10217 |
- commit_cmd.extend(self.vcs_settings.vcs_local_opts) |
10218 |
- commit_cmd.extend(["-F", commitmessagefile]) |
10219 |
- commit_cmd.extend(f.lstrip("./") for f in myfiles) |
10220 |
- |
10221 |
- print("(%s)" % (" ".join(commit_cmd),)) |
10222 |
- return 0 |
10223 |
|
10224 |
diff --git a/repoman/lib/repoman/modules/vcs/None/status.py b/repoman/lib/repoman/modules/vcs/None/status.py |
10225 |
deleted file mode 100644 |
10226 |
index c5809bc9e..000000000 |
10227 |
--- a/repoman/lib/repoman/modules/vcs/None/status.py |
10228 |
+++ /dev/null |
10229 |
@@ -1,52 +0,0 @@ |
10230 |
-""" |
10231 |
-None (non-VCS) module Status class submodule |
10232 |
-""" |
10233 |
- |
10234 |
- |
10235 |
-class Status: |
10236 |
- """Performs status checks on the svn repository""" |
10237 |
- |
10238 |
- def __init__(self, qatracker, eadded): |
10239 |
- """Class init |
10240 |
- |
10241 |
- @param qatracker: QATracker class instance |
10242 |
- @param eadded: list |
10243 |
- """ |
10244 |
- self.qatracker = qatracker |
10245 |
- self.eadded = eadded |
10246 |
- |
10247 |
- def check(self, checkdir, checkdir_relative, xpkg): |
10248 |
- """Perform the svn status check |
10249 |
- |
10250 |
- @param checkdir: string of the directory being checked |
10251 |
- @param checkdir_relative: string of the relative directory being checked |
10252 |
- @param xpkg: string of the package being checked |
10253 |
- @returns: boolean |
10254 |
- """ |
10255 |
- return True |
10256 |
- |
10257 |
- @staticmethod |
10258 |
- def detect_conflicts(options): |
10259 |
- """Are there any merge conflicts present in the VCS tracking system |
10260 |
- |
10261 |
- @param options: command line options |
10262 |
- @returns: Boolean |
10263 |
- """ |
10264 |
- return False |
10265 |
- |
10266 |
- @staticmethod |
10267 |
- def supports_gpg_sign(): |
10268 |
- """Does this vcs system support gpg commit signatures |
10269 |
- |
10270 |
- @returns: Boolean |
10271 |
- """ |
10272 |
- return False |
10273 |
- |
10274 |
- @staticmethod |
10275 |
- def isVcsDir(dirname): |
10276 |
- """Is the directory belong to the vcs system |
10277 |
- |
10278 |
- @param dirname: string, directory name |
10279 |
- @returns: Boolean |
10280 |
- """ |
10281 |
- return False |
10282 |
|
10283 |
diff --git a/repoman/lib/repoman/modules/vcs/__init__.py b/repoman/lib/repoman/modules/vcs/__init__.py |
10284 |
deleted file mode 100644 |
10285 |
index 85cc979c0..000000000 |
10286 |
--- a/repoman/lib/repoman/modules/vcs/__init__.py |
10287 |
+++ /dev/null |
10288 |
@@ -1,12 +0,0 @@ |
10289 |
-import os |
10290 |
-from portage.module import Modules |
10291 |
- |
10292 |
-path = os.path.dirname(__file__) |
10293 |
-# initial development debug info |
10294 |
-# print("module path:", path) |
10295 |
- |
10296 |
-module_controller = Modules(path=path, namepath="repoman.modules.vcs") |
10297 |
- |
10298 |
-# initial development debug info |
10299 |
-# print(module_controller.module_names) |
10300 |
-module_names = module_controller.module_names[:] |
10301 |
|
10302 |
diff --git a/repoman/lib/repoman/modules/vcs/bzr/__init__.py b/repoman/lib/repoman/modules/vcs/bzr/__init__.py |
10303 |
deleted file mode 100644 |
10304 |
index 982017da6..000000000 |
10305 |
--- a/repoman/lib/repoman/modules/vcs/bzr/__init__.py |
10306 |
+++ /dev/null |
10307 |
@@ -1,32 +0,0 @@ |
10308 |
-# Copyright 2014-2015 Gentoo Foundation |
10309 |
-# Distributed under the terms of the GNU General Public License v2 |
10310 |
- |
10311 |
-doc = """Bazaar (bzr) plug-in module for portage. |
10312 |
-Performs variaous Bazaar actions and checks on repositories.""" |
10313 |
-__doc__ = doc[:] |
10314 |
- |
10315 |
- |
10316 |
-module_spec = { |
10317 |
- "name": "bzr", |
10318 |
- "description": doc, |
10319 |
- "provides": { |
10320 |
- "bzr-module": { |
10321 |
- "name": "bzr_status", |
10322 |
- "sourcefile": "status", |
10323 |
- "class": "Status", |
10324 |
- "description": doc, |
10325 |
- "functions": ["check", "supports_gpg_sign", "detect_conflicts"], |
10326 |
- "func_desc": {}, |
10327 |
- "vcs_preserves_mtime": True, |
10328 |
- "needs_keyword_expansion": False, |
10329 |
- }, |
10330 |
- "bzr-changes": { |
10331 |
- "name": "bzr_changes", |
10332 |
- "sourcefile": "changes", |
10333 |
- "class": "Changes", |
10334 |
- "description": doc, |
10335 |
- "functions": ["scan"], |
10336 |
- "func_desc": {}, |
10337 |
- }, |
10338 |
- }, |
10339 |
-} |
10340 |
|
10341 |
diff --git a/repoman/lib/repoman/modules/vcs/bzr/changes.py b/repoman/lib/repoman/modules/vcs/bzr/changes.py |
10342 |
deleted file mode 100644 |
10343 |
index 0366b3862..000000000 |
10344 |
--- a/repoman/lib/repoman/modules/vcs/bzr/changes.py |
10345 |
+++ /dev/null |
10346 |
@@ -1,77 +0,0 @@ |
10347 |
-""" |
10348 |
-Bazaar module Changes class submodule |
10349 |
-""" |
10350 |
- |
10351 |
-from repoman.modules.vcs.changes import ChangesBase |
10352 |
-from repoman._subprocess import repoman_popen |
10353 |
-from repoman._portage import portage # pylint: disable=unused-import |
10354 |
-from portage import os |
10355 |
-from portage.package.ebuild.digestgen import digestgen |
10356 |
- |
10357 |
- |
10358 |
-class Changes(ChangesBase): |
10359 |
- """Class object to scan and hold the resultant data |
10360 |
- for all changes to process. |
10361 |
- """ |
10362 |
- |
10363 |
- vcs = "bzr" |
10364 |
- |
10365 |
- def __init__(self, options, repo_settings): |
10366 |
- """Class init |
10367 |
- |
10368 |
- @param options: the run time cli options |
10369 |
- @param repo_settings: RepoSettings instance |
10370 |
- """ |
10371 |
- super(Changes, self).__init__(options, repo_settings) |
10372 |
- |
10373 |
- def _scan(self): |
10374 |
- """VCS type scan function, looks for all detectable changes""" |
10375 |
- with repoman_popen("bzr status -S .") as f: |
10376 |
- bzrstatus = f.readlines() |
10377 |
- self.changed = [ |
10378 |
- "./" + elem.split()[-1:][0].split("/")[-1:][0] |
10379 |
- for elem in bzrstatus |
10380 |
- if elem and elem[1:2] == "M" |
10381 |
- ] |
10382 |
- self.new = [ |
10383 |
- "./" + elem.split()[-1:][0].split("/")[-1:][0] |
10384 |
- for elem in bzrstatus |
10385 |
- if elem and (elem[1:2] == "NK" or elem[0:1] == "R") |
10386 |
- ] |
10387 |
- self.removed = [ |
10388 |
- "./" + elem.split()[-3:-2][0].split("/")[-1:][0] |
10389 |
- for elem in bzrstatus |
10390 |
- if elem and (elem[1:2] == "K" or elem[0:1] == "R") |
10391 |
- ] |
10392 |
- self.bzrstatus = bzrstatus |
10393 |
- # Bazaar expands nothing. |
10394 |
- |
10395 |
- @property |
10396 |
- def unadded(self): |
10397 |
- """Bazzar method of getting the unadded files in the repository""" |
10398 |
- if self._unadded is not None: |
10399 |
- return self._unadded |
10400 |
- self._unadded = [ |
10401 |
- "./" + elem.rstrip().split()[1].split("/")[-1:][0] |
10402 |
- for elem in self.bzrstatus |
10403 |
- if elem.startswith("?") or elem[0:2] == " D" |
10404 |
- ] |
10405 |
- return self._unadded |
10406 |
- |
10407 |
- def digest_regen( |
10408 |
- self, updates, removed, manifests, scanner, broken_changelog_manifests |
10409 |
- ): |
10410 |
- """Regenerate manifests |
10411 |
- |
10412 |
- @param updates: updated files |
10413 |
- @param removed: removed files |
10414 |
- @param manifests: Manifest files |
10415 |
- @param scanner: The repoman.scanner.Scanner instance |
10416 |
- @param broken_changelog_manifests: broken changelog manifests |
10417 |
- """ |
10418 |
- if broken_changelog_manifests: |
10419 |
- for x in broken_changelog_manifests: |
10420 |
- self.repoman_settings["O"] = os.path.join(self.repo_settings.repodir, x) |
10421 |
- digestgen( |
10422 |
- mysettings=self.repoman_settings, myportdb=self.repo_settings.portdb |
10423 |
- ) |
10424 |
|
10425 |
diff --git a/repoman/lib/repoman/modules/vcs/bzr/status.py b/repoman/lib/repoman/modules/vcs/bzr/status.py |
10426 |
deleted file mode 100644 |
10427 |
index 5ca18c4f6..000000000 |
10428 |
--- a/repoman/lib/repoman/modules/vcs/bzr/status.py |
10429 |
+++ /dev/null |
10430 |
@@ -1,72 +0,0 @@ |
10431 |
-""" |
10432 |
-Bazaar module Status class submodule |
10433 |
-""" |
10434 |
- |
10435 |
-from repoman._portage import portage |
10436 |
-from portage import os |
10437 |
- |
10438 |
-# pylint: disable=ungrouped-imports |
10439 |
-from repoman._subprocess import repoman_popen |
10440 |
- |
10441 |
- |
10442 |
-class Status: |
10443 |
- """Performs status checks on the svn repository""" |
10444 |
- |
10445 |
- def __init__(self, qatracker, eadded): |
10446 |
- """Class init |
10447 |
- |
10448 |
- @param qatracker: QATracker class instance |
10449 |
- @param eadded: list |
10450 |
- """ |
10451 |
- self.qatracker = qatracker |
10452 |
- self.eadded = eadded |
10453 |
- |
10454 |
- def check(self, checkdir, checkdir_relative, xpkg): |
10455 |
- """Perform the svn status check |
10456 |
- |
10457 |
- @param checkdir: string of the directory being checked |
10458 |
- @param checkdir_relative: string of the relative directory being checked |
10459 |
- @param xpkg: string of the package being checked |
10460 |
- @returns: boolean |
10461 |
- """ |
10462 |
- try: |
10463 |
- myf = repoman_popen( |
10464 |
- "bzr ls -v --kind=file " + portage._shell_quote(checkdir) |
10465 |
- ) |
10466 |
- myl = myf.readlines() |
10467 |
- myf.close() |
10468 |
- except IOError: |
10469 |
- raise |
10470 |
- for l in myl: |
10471 |
- if l[1:2] == "?": |
10472 |
- continue |
10473 |
- l = l.split()[-1] |
10474 |
- if l[-7:] == ".ebuild": |
10475 |
- self.eadded.append(os.path.basename(l[:-7])) |
10476 |
- return True |
10477 |
- |
10478 |
- @staticmethod |
10479 |
- def detect_conflicts(options): |
10480 |
- """Are there any merge conflicts present in the VCS tracking system |
10481 |
- |
10482 |
- @param options: command line options |
10483 |
- @returns: Boolean |
10484 |
- """ |
10485 |
- return False |
10486 |
- |
10487 |
- @staticmethod |
10488 |
- def supports_gpg_sign(): |
10489 |
- """Does this vcs system support gpg commit signatures |
10490 |
- |
10491 |
- @returns: Boolean |
10492 |
- """ |
10493 |
- return False |
10494 |
- |
10495 |
- @staticmethod |
10496 |
- def isVcsDir(dirname): |
10497 |
- """Does the directory belong to the vcs system |
10498 |
- |
10499 |
- @param dirname: string, directory name |
10500 |
- @returns: Boolean |
10501 |
- """ |
10502 |
- return dirname in [".bzr"] |
10503 |
|
10504 |
diff --git a/repoman/lib/repoman/modules/vcs/changes.py b/repoman/lib/repoman/modules/vcs/changes.py |
10505 |
deleted file mode 100644 |
10506 |
index c1c7b0909..000000000 |
10507 |
--- a/repoman/lib/repoman/modules/vcs/changes.py |
10508 |
+++ /dev/null |
10509 |
@@ -1,170 +0,0 @@ |
10510 |
-""" |
10511 |
-Base Changes class |
10512 |
-""" |
10513 |
- |
10514 |
-import logging |
10515 |
-import os |
10516 |
-import subprocess |
10517 |
-import sys |
10518 |
-from itertools import chain |
10519 |
- |
10520 |
-from repoman._portage import portage |
10521 |
-from portage import _unicode_encode |
10522 |
-from portage.process import spawn |
10523 |
- |
10524 |
- |
10525 |
-class ChangesBase: |
10526 |
- """Base Class object to scan and hold the resultant data |
10527 |
- for all changes to process. |
10528 |
- """ |
10529 |
- |
10530 |
- vcs = "None" |
10531 |
- |
10532 |
- def __init__(self, options, repo_settings): |
10533 |
- """Class init function |
10534 |
- |
10535 |
- @param options: the run time cli options |
10536 |
- @param repo_settings: RepoSettings instance |
10537 |
- """ |
10538 |
- self.options = options |
10539 |
- self.repo_settings = repo_settings |
10540 |
- self.repoman_settings = repo_settings.repoman_settings |
10541 |
- self.vcs_settings = repo_settings.vcs_settings |
10542 |
- self._reset() |
10543 |
- |
10544 |
- def _reset(self): |
10545 |
- """Reset the class variables for a new run""" |
10546 |
- self.new_ebuilds = set() |
10547 |
- self.ebuilds = set() |
10548 |
- self.changelogs = set() |
10549 |
- self.changed = [] |
10550 |
- self.new = [] |
10551 |
- self.removed = [] |
10552 |
- self.no_expansion = set() |
10553 |
- self._expansion = None |
10554 |
- self._deleted = None |
10555 |
- self._unadded = None |
10556 |
- |
10557 |
- def scan(self): |
10558 |
- """Scan the vcs for detectable changes. |
10559 |
- |
10560 |
- base method which calls the subclassing VCS module's _scan() |
10561 |
- then updates some classwide variables. |
10562 |
- """ |
10563 |
- self._reset() |
10564 |
- |
10565 |
- if self.vcs: |
10566 |
- self._scan() |
10567 |
- self.new_ebuilds.update(x for x in self.new if x.endswith(".ebuild")) |
10568 |
- self.ebuilds.update(x for x in self.changed if x.endswith(".ebuild")) |
10569 |
- self.changelogs.update( |
10570 |
- x |
10571 |
- for x in chain(self.changed, self.new) |
10572 |
- if os.path.basename(x) == "ChangeLog" |
10573 |
- ) |
10574 |
- |
10575 |
- def _scan(self): |
10576 |
- """Placeholder for subclassing""" |
10577 |
- pass |
10578 |
- |
10579 |
- @property |
10580 |
- def has_deleted(self): |
10581 |
- """Placeholder for VCS that requires manual deletion of files""" |
10582 |
- return self.deleted != [] |
10583 |
- |
10584 |
- @property |
10585 |
- def has_changes(self): |
10586 |
- """Placeholder for VCS repo common has changes result""" |
10587 |
- changed = self.changed or self.new or self.removed or self.deleted |
10588 |
- return changed != [] |
10589 |
- |
10590 |
- @property |
10591 |
- def unadded(self): |
10592 |
- """Override this function as needed""" |
10593 |
- return [] |
10594 |
- |
10595 |
- @property |
10596 |
- def deleted(self): |
10597 |
- """Override this function as needed""" |
10598 |
- return [] |
10599 |
- |
10600 |
- @property |
10601 |
- def expansion(self): |
10602 |
- """Override this function as needed""" |
10603 |
- return {} |
10604 |
- |
10605 |
- def thick_manifest(self, updates, headers, no_expansion, expansion): |
10606 |
- """Create a thick manifest |
10607 |
- |
10608 |
- @param updates: |
10609 |
- @param headers: |
10610 |
- @param no_expansion: |
10611 |
- @param expansion: |
10612 |
- """ |
10613 |
- pass |
10614 |
- |
10615 |
- def digest_regen( |
10616 |
- self, updates, removed, manifests, scanner, broken_changelog_manifests |
10617 |
- ): |
10618 |
- """Regenerate manifests |
10619 |
- |
10620 |
- @param updates: updated files |
10621 |
- @param removed: removed files |
10622 |
- @param manifests: Manifest files |
10623 |
- @param scanner: The repoman.scanner.Scanner instance |
10624 |
- @param broken_changelog_manifests: broken changelog manifests |
10625 |
- """ |
10626 |
- pass |
10627 |
- |
10628 |
- @staticmethod |
10629 |
- def clear_attic(headers): |
10630 |
- """Old CVS leftover |
10631 |
- |
10632 |
- @param headers: file headers""" |
10633 |
- pass |
10634 |
- |
10635 |
- def update_index(self, mymanifests, myupdates): |
10636 |
- """Update the vcs's modified index if it is needed |
10637 |
- |
10638 |
- @param mymanifests: manifest files updated |
10639 |
- @param myupdates: other files updated""" |
10640 |
- pass |
10641 |
- |
10642 |
- def add_items(self, autoadd): |
10643 |
- """Add files to the vcs's modified or new index |
10644 |
- |
10645 |
- @param autoadd: the files to add to the vcs modified index""" |
10646 |
- add_cmd = [self.vcs, "add"] |
10647 |
- add_cmd += autoadd |
10648 |
- if self.options.pretend: |
10649 |
- portage.writemsg_stdout("(%s)\n" % " ".join(add_cmd), noiselevel=-1) |
10650 |
- else: |
10651 |
- add_cmd = [_unicode_encode(arg) for arg in add_cmd] |
10652 |
- retcode = subprocess.call(add_cmd) |
10653 |
- if retcode != os.EX_OK: |
10654 |
- logging.error( |
10655 |
- "Exiting on %s error code: %s\n", self.vcs_settings.vcs, retcode |
10656 |
- ) |
10657 |
- sys.exit(retcode) |
10658 |
- |
10659 |
- def commit(self, commitfiles, commitmessagefile): |
10660 |
- """Common generic commit function |
10661 |
- |
10662 |
- @param commitfiles: list of files to commit |
10663 |
- @param commitmessagefile: file containing the commit message |
10664 |
- @returns: The sub-command exit value or 0 |
10665 |
- """ |
10666 |
- commit_cmd = [] |
10667 |
- commit_cmd.append(self.vcs) |
10668 |
- commit_cmd.extend(self.vcs_settings.vcs_global_opts) |
10669 |
- commit_cmd.append("commit") |
10670 |
- commit_cmd.extend(self.vcs_settings.vcs_local_opts) |
10671 |
- commit_cmd.extend(["-F", commitmessagefile]) |
10672 |
- commit_cmd.extend(f.lstrip("./") for f in commitfiles) |
10673 |
- |
10674 |
- if self.options.pretend: |
10675 |
- print("(%s)" % (" ".join(commit_cmd),)) |
10676 |
- return 0 |
10677 |
- else: |
10678 |
- retval = spawn(commit_cmd, env=self.repo_settings.commit_env) |
10679 |
- return retval |
10680 |
|
10681 |
diff --git a/repoman/lib/repoman/modules/vcs/cvs/__init__.py b/repoman/lib/repoman/modules/vcs/cvs/__init__.py |
10682 |
deleted file mode 100644 |
10683 |
index f71f806fb..000000000 |
10684 |
--- a/repoman/lib/repoman/modules/vcs/cvs/__init__.py |
10685 |
+++ /dev/null |
10686 |
@@ -1,32 +0,0 @@ |
10687 |
-# Copyright 2014-2015 Gentoo Foundation |
10688 |
-# Distributed under the terms of the GNU General Public License v2 |
10689 |
- |
10690 |
-doc = """CVS (cvs) plug-in module for portage. |
10691 |
-Performs variaous CVS actions and checks on repositories.""" |
10692 |
-__doc__ = doc[:] |
10693 |
- |
10694 |
- |
10695 |
-module_spec = { |
10696 |
- "name": "cvs", |
10697 |
- "description": doc, |
10698 |
- "provides": { |
10699 |
- "cvs-status": { |
10700 |
- "name": "cvs_status", |
10701 |
- "sourcefile": "status", |
10702 |
- "class": "Status", |
10703 |
- "description": doc, |
10704 |
- "functions": ["check", "supports_gpg_sign", "detect_conflicts"], |
10705 |
- "func_desc": {}, |
10706 |
- "vcs_preserves_mtime": True, |
10707 |
- "needs_keyword_expansion": True, |
10708 |
- }, |
10709 |
- "cvs-changes": { |
10710 |
- "name": "cvs_changes", |
10711 |
- "sourcefile": "changes", |
10712 |
- "class": "Changes", |
10713 |
- "description": doc, |
10714 |
- "functions": ["scan"], |
10715 |
- "func_desc": {}, |
10716 |
- }, |
10717 |
- }, |
10718 |
-} |
10719 |
|
10720 |
diff --git a/repoman/lib/repoman/modules/vcs/cvs/changes.py b/repoman/lib/repoman/modules/vcs/cvs/changes.py |
10721 |
deleted file mode 100644 |
10722 |
index be382f291..000000000 |
10723 |
--- a/repoman/lib/repoman/modules/vcs/cvs/changes.py |
10724 |
+++ /dev/null |
10725 |
@@ -1,134 +0,0 @@ |
10726 |
-""" |
10727 |
-CVS module Changes class submodule |
10728 |
-""" |
10729 |
- |
10730 |
-import re |
10731 |
-from itertools import chain |
10732 |
- |
10733 |
-from repoman._portage import portage |
10734 |
-from repoman.modules.vcs.changes import ChangesBase |
10735 |
-from repoman.modules.vcs.vcs import vcs_files_to_cps |
10736 |
-from repoman._subprocess import repoman_getstatusoutput |
10737 |
- |
10738 |
-from portage import _encodings, _unicode_encode |
10739 |
-from portage import cvstree, os |
10740 |
-from portage.output import green |
10741 |
-from portage.package.ebuild.digestgen import digestgen |
10742 |
- |
10743 |
- |
10744 |
-class Changes(ChangesBase): |
10745 |
- """Class object to scan and hold the resultant data |
10746 |
- for all changes to process. |
10747 |
- """ |
10748 |
- |
10749 |
- vcs = "cvs" |
10750 |
- |
10751 |
- def __init__(self, options, repo_settings): |
10752 |
- """Class init |
10753 |
- |
10754 |
- @param options: the run time cli options |
10755 |
- @param repo_settings: RepoSettings instance |
10756 |
- """ |
10757 |
- super(Changes, self).__init__(options, repo_settings) |
10758 |
- self._tree = None |
10759 |
- |
10760 |
- def _scan(self): |
10761 |
- """VCS type scan function, looks for all detectable changes""" |
10762 |
- self._tree = portage.cvstree.getentries("./", recursive=1) |
10763 |
- self.changed = cvstree.findchanged(self._tree, recursive=1, basedir="./") |
10764 |
- self.new = cvstree.findnew(self._tree, recursive=1, basedir="./") |
10765 |
- self.removed = cvstree.findremoved(self._tree, recursive=1, basedir="./") |
10766 |
- bin_blob_pattern = re.compile("^-kb$") |
10767 |
- self.no_expansion = set( |
10768 |
- portage.cvstree.findoption( |
10769 |
- self._tree, bin_blob_pattern, recursive=1, basedir="./" |
10770 |
- ) |
10771 |
- ) |
10772 |
- |
10773 |
- @property |
10774 |
- def unadded(self): |
10775 |
- """VCS method of getting the unadded files in the repository""" |
10776 |
- if self._unadded is not None: |
10777 |
- return self._unadded |
10778 |
- self._unadded = portage.cvstree.findunadded( |
10779 |
- self._tree, recursive=1, basedir="./" |
10780 |
- ) |
10781 |
- return self._unadded |
10782 |
- |
10783 |
- @staticmethod |
10784 |
- def clear_attic(headers): |
10785 |
- """Clear the attic (inactive files) |
10786 |
- |
10787 |
- @param headers: file headers |
10788 |
- """ |
10789 |
- cvs_header_re = re.compile(rb"^#\s*\$Header.*\$$") |
10790 |
- attic_str = b"/Attic/" |
10791 |
- attic_replace = b"/" |
10792 |
- for x in headers: |
10793 |
- f = open( |
10794 |
- _unicode_encode(x, encoding=_encodings["fs"], errors="strict"), |
10795 |
- mode="rb", |
10796 |
- ) |
10797 |
- mylines = f.readlines() |
10798 |
- f.close() |
10799 |
- modified = False |
10800 |
- for i, line in enumerate(mylines): |
10801 |
- if cvs_header_re.match(line) is not None and attic_str in line: |
10802 |
- mylines[i] = line.replace(attic_str, attic_replace) |
10803 |
- modified = True |
10804 |
- if modified: |
10805 |
- portage.util.write_atomic(x, b"".join(mylines), mode="wb") |
10806 |
- |
10807 |
- def thick_manifest(self, updates, headers, no_expansion, expansion): |
10808 |
- """Create a thick manifest |
10809 |
- |
10810 |
- @param updates: |
10811 |
- @param headers: |
10812 |
- @param no_expansion: |
10813 |
- @param expansion: |
10814 |
- """ |
10815 |
- headerstring = r"'\$(Header|Id).*\$'" |
10816 |
- |
10817 |
- for _file in updates: |
10818 |
- |
10819 |
- # for CVS, no_expansion contains files that are excluded from expansion |
10820 |
- if _file in no_expansion: |
10821 |
- continue |
10822 |
- |
10823 |
- _out = repoman_getstatusoutput( |
10824 |
- "egrep -q %s %s" % (headerstring, portage._shell_quote(_file)) |
10825 |
- ) |
10826 |
- if _out[0] == 0: |
10827 |
- headers.append(_file) |
10828 |
- |
10829 |
- print("%s have headers that will change." % green(str(len(headers)))) |
10830 |
- print( |
10831 |
- "* Files with headers will" |
10832 |
- " cause the manifests to be changed and committed separately." |
10833 |
- ) |
10834 |
- |
10835 |
- def digest_regen( |
10836 |
- self, updates, removed, manifests, scanner, broken_changelog_manifests |
10837 |
- ): |
10838 |
- """Regenerate manifests |
10839 |
- |
10840 |
- @param updates: updated files |
10841 |
- @param removed: removed files |
10842 |
- @param manifests: Manifest files |
10843 |
- @param scanner: The repoman.scanner.Scanner instance |
10844 |
- @param broken_changelog_manifests: broken changelog manifests |
10845 |
- """ |
10846 |
- if updates or removed: |
10847 |
- for x in sorted( |
10848 |
- vcs_files_to_cps( |
10849 |
- chain(updates, removed, manifests), |
10850 |
- self.repo_settings.repodir, |
10851 |
- scanner.repolevel, |
10852 |
- scanner.reposplit, |
10853 |
- scanner.categories, |
10854 |
- ) |
10855 |
- ): |
10856 |
- self.repoman_settings["O"] = os.path.join(self.repo_settings.repodir, x) |
10857 |
- digestgen( |
10858 |
- mysettings=self.repoman_settings, myportdb=self.repo_settings.portdb |
10859 |
- ) |
10860 |
|
10861 |
diff --git a/repoman/lib/repoman/modules/vcs/cvs/status.py b/repoman/lib/repoman/modules/vcs/cvs/status.py |
10862 |
deleted file mode 100644 |
10863 |
index 0d131c75a..000000000 |
10864 |
--- a/repoman/lib/repoman/modules/vcs/cvs/status.py |
10865 |
+++ /dev/null |
10866 |
@@ -1,134 +0,0 @@ |
10867 |
-""" |
10868 |
-CVS module Status class submodule |
10869 |
-""" |
10870 |
- |
10871 |
-import logging |
10872 |
-import subprocess |
10873 |
-import sys |
10874 |
- |
10875 |
-from repoman._portage import portage # pylint: disable=unused-import |
10876 |
-from portage import os |
10877 |
-from portage.const import BASH_BINARY |
10878 |
-from portage.output import red, green |
10879 |
-from portage import _unicode_encode, _unicode_decode |
10880 |
- |
10881 |
- |
10882 |
-class Status: |
10883 |
- """Performs status checks on the svn repository""" |
10884 |
- |
10885 |
- def __init__(self, qatracker, eadded): |
10886 |
- """Class init |
10887 |
- |
10888 |
- @param qatracker: QATracker class instance |
10889 |
- @param eadded: list |
10890 |
- """ |
10891 |
- self.qatracker = qatracker |
10892 |
- self.eadded = eadded |
10893 |
- |
10894 |
- def check(self, checkdir, checkdir_relative, xpkg): |
10895 |
- """Perform the svn status check |
10896 |
- |
10897 |
- @param checkdir: string of the directory being checked |
10898 |
- @param checkdir_relative: string of the relative directory being checked |
10899 |
- @param xpkg: string of the package being checked |
10900 |
- @returns: boolean |
10901 |
- """ |
10902 |
- try: |
10903 |
- myf = open(checkdir + "/CVS/Entries", "r") |
10904 |
- myl = myf.readlines() |
10905 |
- myf.close() |
10906 |
- except IOError: |
10907 |
- self.qatracker.add_error("CVS/Entries.IO_error", checkdir + "/CVS/Entries") |
10908 |
- return True |
10909 |
- for l in myl: |
10910 |
- if l[0] != "/": |
10911 |
- continue |
10912 |
- splitl = l[1:].split("/") |
10913 |
- if not len(splitl): |
10914 |
- continue |
10915 |
- if splitl[0][-7:] == ".ebuild": |
10916 |
- self.eadded.append(splitl[0][:-7]) |
10917 |
- return True |
10918 |
- |
10919 |
- @staticmethod |
10920 |
- def detect_conflicts(options): |
10921 |
- """Determine if the checkout has cvs conflicts. |
10922 |
- |
10923 |
- TODO(antarus): Also this should probably not call sys.exit() as |
10924 |
- repoman is run on >1 packages and one failure should not cause |
10925 |
- subsequent packages to fail. |
10926 |
- |
10927 |
- Returns: |
10928 |
- None (calls sys.exit on fatal problems) |
10929 |
- """ |
10930 |
- |
10931 |
- cmd = ( |
10932 |
- r"cvs -n up 2>/dev/null | " |
10933 |
- r"egrep '^[^\?] .*' | " |
10934 |
- r"egrep -v '^. .*/digest-[^/]+|^cvs server: .* -- ignored$'" |
10935 |
- ) |
10936 |
- msg = "Performing a %s with a little magic grep to check for updates." % green( |
10937 |
- "cvs -n up" |
10938 |
- ) |
10939 |
- |
10940 |
- logging.info(msg) |
10941 |
- # Use Popen instead of getstatusoutput(), in order to avoid |
10942 |
- # unicode handling problems (see bug #310789). |
10943 |
- args = [BASH_BINARY, "-c", cmd] |
10944 |
- args = [_unicode_encode(x) for x in args] |
10945 |
- proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
10946 |
- out = _unicode_decode(proc.communicate()[0]) |
10947 |
- proc.wait() |
10948 |
- mylines = out.splitlines() |
10949 |
- myupdates = [] |
10950 |
- for line in mylines: |
10951 |
- if not line: |
10952 |
- continue |
10953 |
- |
10954 |
- # [ ] Unmodified (SVN) [U] Updates [P] Patches |
10955 |
- # [M] Modified [A] Added [R] Removed / Replaced |
10956 |
- # [D] Deleted |
10957 |
- if line[0] not in " UPMARD": |
10958 |
- # Stray Manifest is fine, we will readd it anyway. |
10959 |
- if line[0] == "?" and line[1:].lstrip() == "Manifest": |
10960 |
- continue |
10961 |
- logging.error( |
10962 |
- red( |
10963 |
- "!!! Please fix the following issues reported " |
10964 |
- "from cvs: %s" % green("(U,P,M,A,R,D are ok)") |
10965 |
- ) |
10966 |
- ) |
10967 |
- logging.error(red("!!! Note: This is a pretend/no-modify pass...")) |
10968 |
- logging.error(out) |
10969 |
- sys.exit(1) |
10970 |
- elif line[0] in "UP": |
10971 |
- myupdates.append(line[2:]) |
10972 |
- |
10973 |
- if myupdates: |
10974 |
- logging.info(green("Fetching trivial updates...")) |
10975 |
- if options.pretend: |
10976 |
- logging.info("(cvs update " + " ".join(myupdates) + ")") |
10977 |
- retval = os.EX_OK |
10978 |
- else: |
10979 |
- retval = os.system("cvs update " + " ".join(myupdates)) |
10980 |
- if retval != os.EX_OK: |
10981 |
- logging.fatal("!!! cvs exited with an error. Terminating.") |
10982 |
- sys.exit(retval) |
10983 |
- return False |
10984 |
- |
10985 |
- @staticmethod |
10986 |
- def supports_gpg_sign(): |
10987 |
- """Does this vcs system support gpg commit signatures |
10988 |
- |
10989 |
- @returns: Boolean |
10990 |
- """ |
10991 |
- return False |
10992 |
- |
10993 |
- @staticmethod |
10994 |
- def isVcsDir(dirname): |
10995 |
- """Does the directory belong to the vcs system |
10996 |
- |
10997 |
- @param dirname: string, directory name |
10998 |
- @returns: Boolean |
10999 |
- """ |
11000 |
- return dirname in ["CVS"] |
11001 |
|
11002 |
diff --git a/repoman/lib/repoman/modules/vcs/git/__init__.py b/repoman/lib/repoman/modules/vcs/git/__init__.py |
11003 |
deleted file mode 100644 |
11004 |
index c3005fc41..000000000 |
11005 |
--- a/repoman/lib/repoman/modules/vcs/git/__init__.py |
11006 |
+++ /dev/null |
11007 |
@@ -1,32 +0,0 @@ |
11008 |
-# Copyright 2014-2015 Gentoo Foundation |
11009 |
-# Distributed under the terms of the GNU General Public License v2 |
11010 |
- |
11011 |
-doc = """Git (git) plug-in module for portage. |
11012 |
-Performs variaous git actions and checks on repositories.""" |
11013 |
-__doc__ = doc[:] |
11014 |
- |
11015 |
- |
11016 |
-module_spec = { |
11017 |
- "name": "git", |
11018 |
- "description": doc, |
11019 |
- "provides": { |
11020 |
- "git-module": { |
11021 |
- "name": "git_status", |
11022 |
- "sourcefile": "status", |
11023 |
- "class": "Status", |
11024 |
- "description": doc, |
11025 |
- "functions": ["check", "supports_gpg_sign", "detect_conflicts"], |
11026 |
- "func_desc": {}, |
11027 |
- "vcs_preserves_mtime": False, |
11028 |
- "needs_keyword_expansion": False, |
11029 |
- }, |
11030 |
- "git-changes": { |
11031 |
- "name": "git_changes", |
11032 |
- "sourcefile": "changes", |
11033 |
- "class": "Changes", |
11034 |
- "description": doc, |
11035 |
- "functions": ["scan"], |
11036 |
- "func_desc": {}, |
11037 |
- }, |
11038 |
- }, |
11039 |
-} |
11040 |
|
11041 |
diff --git a/repoman/lib/repoman/modules/vcs/git/changes.py b/repoman/lib/repoman/modules/vcs/git/changes.py |
11042 |
deleted file mode 100644 |
11043 |
index 3430cf3ec..000000000 |
11044 |
--- a/repoman/lib/repoman/modules/vcs/git/changes.py |
11045 |
+++ /dev/null |
11046 |
@@ -1,145 +0,0 @@ |
11047 |
-""" |
11048 |
-Git module Changes class submodule |
11049 |
-""" |
11050 |
- |
11051 |
-import logging |
11052 |
-import sys |
11053 |
- |
11054 |
-from repoman._portage import portage # pylint: disable=unused-import |
11055 |
-from repoman.modules.vcs.changes import ChangesBase |
11056 |
-from repoman._subprocess import repoman_popen |
11057 |
- |
11058 |
-from portage import os |
11059 |
-from portage.package.ebuild.digestgen import digestgen |
11060 |
-from portage.process import spawn |
11061 |
-from portage.util import writemsg_level |
11062 |
- |
11063 |
- |
11064 |
-class Changes(ChangesBase): |
11065 |
- """Class object to scan and hold the resultant data |
11066 |
- for all changes to process. |
11067 |
- """ |
11068 |
- |
11069 |
- vcs = "git" |
11070 |
- |
11071 |
- def __init__(self, options, repo_settings): |
11072 |
- """Class init |
11073 |
- |
11074 |
- @param options: the run time cli options |
11075 |
- @param repo_settings: RepoSettings instance |
11076 |
- """ |
11077 |
- super(Changes, self).__init__(options, repo_settings) |
11078 |
- |
11079 |
- def _scan(self, _reindex=None): |
11080 |
- """ |
11081 |
- VCS type scan function, looks for all detectable changes |
11082 |
- |
11083 |
- @param _reindex: ensure that the git index reflects the state on |
11084 |
- disk for files returned by git diff-index (this parameter is |
11085 |
- used in recursive calls and it's not intended to be used for |
11086 |
- any other reason) |
11087 |
- @type _reindex: bool |
11088 |
- """ |
11089 |
- # Automatically reindex for commit mode, but not for other modes |
11090 |
- # were the user might not want changes to be staged in the index. |
11091 |
- if _reindex is None and self.options.mode == "commit": |
11092 |
- _reindex = True |
11093 |
- |
11094 |
- with repoman_popen( |
11095 |
- "git diff-index --name-only " "--relative --diff-filter=M HEAD" |
11096 |
- ) as f: |
11097 |
- changed = f.readlines() |
11098 |
- self.changed = ["./" + elem[:-1] for elem in changed] |
11099 |
- del changed |
11100 |
- |
11101 |
- with repoman_popen( |
11102 |
- "git diff-index --name-only " "--relative --diff-filter=A HEAD" |
11103 |
- ) as f: |
11104 |
- new = f.readlines() |
11105 |
- self.new = ["./" + elem[:-1] for elem in new] |
11106 |
- del new |
11107 |
- |
11108 |
- with repoman_popen( |
11109 |
- "git diff-index --name-only " "--relative --diff-filter=D HEAD" |
11110 |
- ) as f: |
11111 |
- removed = f.readlines() |
11112 |
- self.removed = ["./" + elem[:-1] for elem in removed] |
11113 |
- del removed |
11114 |
- if _reindex and (self.changed or self.new or self.removed): |
11115 |
- self.update_index([], self.changed + self.new + self.removed) |
11116 |
- self._scan(_reindex=False) |
11117 |
- |
11118 |
- @property |
11119 |
- def unadded(self): |
11120 |
- """VCS method of getting the unadded files in the repository""" |
11121 |
- if self._unadded is not None: |
11122 |
- return self._unadded |
11123 |
- # get list of files not under version control or missing |
11124 |
- with repoman_popen("git ls-files --others") as f: |
11125 |
- unadded = f.readlines() |
11126 |
- self._unadded = ["./" + elem[:-1] for elem in unadded] |
11127 |
- del unadded |
11128 |
- return self._unadded |
11129 |
- |
11130 |
- def digest_regen( |
11131 |
- self, updates, removed, manifests, scanner, broken_changelog_manifests |
11132 |
- ): |
11133 |
- """Regenerate manifests |
11134 |
- |
11135 |
- @param updates: updated files |
11136 |
- @param removed: removed files |
11137 |
- @param manifests: Manifest files |
11138 |
- @param scanner: The repoman.scanner.Scanner instance |
11139 |
- @param broken_changelog_manifests: broken changelog manifests |
11140 |
- """ |
11141 |
- if broken_changelog_manifests: |
11142 |
- for x in broken_changelog_manifests: |
11143 |
- self.repoman_settings["O"] = os.path.join(self.repo_settings.repodir, x) |
11144 |
- digestgen( |
11145 |
- mysettings=self.repoman_settings, myportdb=self.repo_settings.portdb |
11146 |
- ) |
11147 |
- |
11148 |
- def update_index(self, mymanifests, myupdates): |
11149 |
- """Update the vcs's modified index if it is needed |
11150 |
- |
11151 |
- @param mymanifests: manifest files updated |
11152 |
- @param myupdates: other files updated""" |
11153 |
- # It's not safe to use the git commit -a option since there might |
11154 |
- # be some modified files elsewhere in the working tree that the |
11155 |
- # user doesn't want to commit. Therefore, call git update-index |
11156 |
- # in order to ensure that the index is updated with the latest |
11157 |
- # versions of all new and modified files in the relevant portion |
11158 |
- # of the working tree. |
11159 |
- myfiles = mymanifests + myupdates |
11160 |
- myfiles.sort() |
11161 |
- update_index_cmd = ["git", "update-index", "--add", "--remove"] |
11162 |
- update_index_cmd.extend(f.lstrip("./") for f in myfiles) |
11163 |
- if self.options.pretend: |
11164 |
- print("(%s)" % (" ".join(update_index_cmd),)) |
11165 |
- else: |
11166 |
- retval = spawn(update_index_cmd, env=os.environ) |
11167 |
- if retval != os.EX_OK: |
11168 |
- writemsg_level( |
11169 |
- "!!! Exiting on %s (shell) " |
11170 |
- "error code: %s\n" % (self.vcs_settings.vcs, retval), |
11171 |
- level=logging.ERROR, |
11172 |
- noiselevel=-1, |
11173 |
- ) |
11174 |
- sys.exit(retval) |
11175 |
- |
11176 |
- def commit(self, myfiles, commitmessagefile): |
11177 |
- """Git commit function |
11178 |
- |
11179 |
- @param commitfiles: list of files to commit |
11180 |
- @param commitmessagefile: file containing the commit message |
11181 |
- @returns: The sub-command exit value or 0 |
11182 |
- """ |
11183 |
- retval = super(Changes, self).commit(myfiles, commitmessagefile) |
11184 |
- if retval != os.EX_OK: |
11185 |
- if ( |
11186 |
- self.repo_settings.repo_config.sign_commit |
11187 |
- and not self.vcs_settings.status.supports_gpg_sign() |
11188 |
- ): |
11189 |
- # Inform user that newer git is needed (bug #403323). |
11190 |
- logging.error("Git >=1.7.9 is required for signed commits!") |
11191 |
- return retval |
11192 |
|
11193 |
diff --git a/repoman/lib/repoman/modules/vcs/git/status.py b/repoman/lib/repoman/modules/vcs/git/status.py |
11194 |
deleted file mode 100644 |
11195 |
index ec2e3a655..000000000 |
11196 |
--- a/repoman/lib/repoman/modules/vcs/git/status.py |
11197 |
+++ /dev/null |
11198 |
@@ -1,80 +0,0 @@ |
11199 |
-""" |
11200 |
-Git module Status class submodule |
11201 |
-""" |
11202 |
- |
11203 |
-import re |
11204 |
- |
11205 |
-from repoman._portage import portage |
11206 |
-from portage import os |
11207 |
- |
11208 |
-# pylint: disable=ungrouped-imports |
11209 |
-from repoman._subprocess import repoman_popen, repoman_getstatusoutput |
11210 |
- |
11211 |
- |
11212 |
-class Status: |
11213 |
- """Performs status checks on the git repository""" |
11214 |
- |
11215 |
- def __init__(self, qatracker, eadded): |
11216 |
- """Class init |
11217 |
- |
11218 |
- @param qatracker: QATracker class instance |
11219 |
- @param eadded: list |
11220 |
- """ |
11221 |
- self.qatracker = qatracker |
11222 |
- self.eadded = eadded |
11223 |
- |
11224 |
- def check(self, checkdir, checkdir_relative, xpkg): |
11225 |
- """Perform the git status check |
11226 |
- |
11227 |
- @param checkdir: string of the directory being checked |
11228 |
- @param checkdir_relative: string of the relative directory being checked |
11229 |
- @param xpkg: string of the package being checked |
11230 |
- @returns: boolean |
11231 |
- """ |
11232 |
- with repoman_popen( |
11233 |
- "git ls-files --others %s" % (portage._shell_quote(checkdir_relative),) |
11234 |
- ) as myf: |
11235 |
- for l in myf: |
11236 |
- if l[:-1][-7:] == ".ebuild": |
11237 |
- self.qatracker.add_error( |
11238 |
- "ebuild.notadded", os.path.join(xpkg, os.path.basename(l[:-1])) |
11239 |
- ) |
11240 |
- return True |
11241 |
- |
11242 |
- @staticmethod |
11243 |
- def detect_conflicts(options): |
11244 |
- """Are there any merge conflicts present in the VCS tracking system |
11245 |
- |
11246 |
- @param options: command line options |
11247 |
- @returns: Boolean |
11248 |
- """ |
11249 |
- return False |
11250 |
- |
11251 |
- @staticmethod |
11252 |
- def supports_gpg_sign(): |
11253 |
- """Does this vcs system support gpg commit signatures |
11254 |
- |
11255 |
- @returns: Boolean |
11256 |
- """ |
11257 |
- status, cmd_output = repoman_getstatusoutput("git --version") |
11258 |
- cmd_output = cmd_output.split() |
11259 |
- if cmd_output: |
11260 |
- version = re.match(r"^(\d+)\.(\d+)\.(\d+)", cmd_output[-1]) |
11261 |
- if version is not None: |
11262 |
- version = [int(x) for x in version.groups()] |
11263 |
- if ( |
11264 |
- version[0] > 1 |
11265 |
- or (version[0] == 1 and version[1] > 7) |
11266 |
- or (version[0] == 1 and version[1] == 7 and version[2] >= 9) |
11267 |
- ): |
11268 |
- return True |
11269 |
- return False |
11270 |
- |
11271 |
- @staticmethod |
11272 |
- def isVcsDir(dirname): |
11273 |
- """Does the directory belong to the vcs system |
11274 |
- |
11275 |
- @param dirname: string, directory name |
11276 |
- @returns: Boolean |
11277 |
- """ |
11278 |
- return dirname in [".git"] |
11279 |
|
11280 |
diff --git a/repoman/lib/repoman/modules/vcs/hg/__init__.py b/repoman/lib/repoman/modules/vcs/hg/__init__.py |
11281 |
deleted file mode 100644 |
11282 |
index 4b96b04c8..000000000 |
11283 |
--- a/repoman/lib/repoman/modules/vcs/hg/__init__.py |
11284 |
+++ /dev/null |
11285 |
@@ -1,32 +0,0 @@ |
11286 |
-# Copyright 2014-2015 Gentoo Foundation |
11287 |
-# Distributed under the terms of the GNU General Public License v2 |
11288 |
- |
11289 |
-doc = """Mercurial (hg) plug-in module for portage. |
11290 |
-Performs variaous mercurial actions and checks on repositories.""" |
11291 |
-__doc__ = doc[:] |
11292 |
- |
11293 |
- |
11294 |
-module_spec = { |
11295 |
- "name": "hg", |
11296 |
- "description": doc, |
11297 |
- "provides": { |
11298 |
- "hg-module": { |
11299 |
- "name": "hg_status", |
11300 |
- "sourcefile": "status", |
11301 |
- "class": "Status", |
11302 |
- "description": doc, |
11303 |
- "functions": ["check", "supports_gpg_sign", "detect_conflicts"], |
11304 |
- "func_desc": {}, |
11305 |
- "vcs_preserves_mtime": False, |
11306 |
- "needs_keyword_expansion": False, |
11307 |
- }, |
11308 |
- "hg-changes": { |
11309 |
- "name": "hg_changes", |
11310 |
- "sourcefile": "changes", |
11311 |
- "class": "Changes", |
11312 |
- "description": doc, |
11313 |
- "functions": ["scan"], |
11314 |
- "func_desc": {}, |
11315 |
- }, |
11316 |
- }, |
11317 |
-} |
11318 |
|
11319 |
diff --git a/repoman/lib/repoman/modules/vcs/hg/changes.py b/repoman/lib/repoman/modules/vcs/hg/changes.py |
11320 |
deleted file mode 100644 |
11321 |
index 3ce1763b7..000000000 |
11322 |
--- a/repoman/lib/repoman/modules/vcs/hg/changes.py |
11323 |
+++ /dev/null |
11324 |
@@ -1,109 +0,0 @@ |
11325 |
-""" |
11326 |
-Mercurial module Changes class submodule |
11327 |
-""" |
11328 |
- |
11329 |
-from repoman._portage import portage # pylint: disable=unused-import |
11330 |
-from repoman.modules.vcs.changes import ChangesBase |
11331 |
-from repoman._subprocess import repoman_popen |
11332 |
- |
11333 |
-from portage import os |
11334 |
-from portage.package.ebuild.digestgen import digestgen |
11335 |
-from portage.process import spawn |
11336 |
- |
11337 |
- |
11338 |
-class Changes(ChangesBase): |
11339 |
- """Class object to scan and hold the resultant data |
11340 |
- for all changes to process. |
11341 |
- """ |
11342 |
- |
11343 |
- vcs = "hg" |
11344 |
- |
11345 |
- def __init__(self, options, repo_settings): |
11346 |
- """Class init |
11347 |
- |
11348 |
- @param options: the run time cli options |
11349 |
- @param repo_settings: RepoSettings instance |
11350 |
- """ |
11351 |
- super(Changes, self).__init__(options, repo_settings) |
11352 |
- |
11353 |
- def _scan(self): |
11354 |
- """VCS type scan function, looks for all detectable changes""" |
11355 |
- with repoman_popen("hg status --no-status --modified .") as f: |
11356 |
- changed = f.readlines() |
11357 |
- self.changed = ["./" + elem.rstrip() for elem in changed] |
11358 |
- del changed |
11359 |
- |
11360 |
- with repoman_popen("hg status --no-status --added .") as f: |
11361 |
- new = f.readlines() |
11362 |
- self.new = ["./" + elem.rstrip() for elem in new] |
11363 |
- del new |
11364 |
- |
11365 |
- with repoman_popen("hg status --no-status --removed .") as f: |
11366 |
- removed = f.readlines() |
11367 |
- self.removed = ["./" + elem.rstrip() for elem in removed] |
11368 |
- del removed |
11369 |
- |
11370 |
- @property |
11371 |
- def unadded(self): |
11372 |
- """VCS method of getting the unadded files in the repository""" |
11373 |
- if self._unadded is not None: |
11374 |
- return self._unadded |
11375 |
- with repoman_popen("hg status --no-status --unknown .") as f: |
11376 |
- unadded = f.readlines() |
11377 |
- self._unadded = ["./" + elem.rstrip() for elem in unadded] |
11378 |
- del unadded |
11379 |
- return self._unadded |
11380 |
- |
11381 |
- @property |
11382 |
- def deleted(self): |
11383 |
- """VCS method of getting the deleted files in the repository""" |
11384 |
- if self._deleted is not None: |
11385 |
- return self._deleted |
11386 |
- # Mercurial doesn't handle manually deleted files as removed from |
11387 |
- # the repository, so the user need to remove them before commit, |
11388 |
- # using "hg remove [FILES]" |
11389 |
- with repoman_popen("hg status --no-status --deleted .") as f: |
11390 |
- deleted = f.readlines() |
11391 |
- self._deleted = ["./" + elem.rstrip() for elem in deleted] |
11392 |
- del deleted |
11393 |
- return self._deleted |
11394 |
- |
11395 |
- def digest_regen( |
11396 |
- self, updates, removed, manifests, scanner, broken_changelog_manifests |
11397 |
- ): |
11398 |
- """Regenerate manifests |
11399 |
- |
11400 |
- @param updates: updated files |
11401 |
- @param removed: removed files |
11402 |
- @param manifests: Manifest files |
11403 |
- @param scanner: The repoman.scanner.Scanner instance |
11404 |
- @param broken_changelog_manifests: broken changelog manifests |
11405 |
- """ |
11406 |
- if broken_changelog_manifests: |
11407 |
- for x in broken_changelog_manifests: |
11408 |
- self.repoman_settings["O"] = os.path.join(self.repo_settings.repodir, x) |
11409 |
- digestgen( |
11410 |
- mysettings=self.repoman_settings, myportdb=self.repo_settings.portdb |
11411 |
- ) |
11412 |
- |
11413 |
- def commit(self, myfiles, commitmessagefile): |
11414 |
- """Hg commit function |
11415 |
- |
11416 |
- @param commitfiles: list of files to commit |
11417 |
- @param commitmessagefile: file containing the commit message |
11418 |
- @returns: The sub-command exit value or 0 |
11419 |
- """ |
11420 |
- commit_cmd = [] |
11421 |
- commit_cmd.append(self.vcs) |
11422 |
- commit_cmd.extend(self.vcs_settings.vcs_global_opts) |
11423 |
- commit_cmd.append("commit") |
11424 |
- commit_cmd.extend(self.vcs_settings.vcs_local_opts) |
11425 |
- commit_cmd.extend(["--logfile", commitmessagefile]) |
11426 |
- commit_cmd.extend(myfiles) |
11427 |
- |
11428 |
- if self.options.pretend: |
11429 |
- print("(%s)" % (" ".join(commit_cmd),)) |
11430 |
- return 0 |
11431 |
- else: |
11432 |
- retval = spawn(commit_cmd, env=self.repo_settings.commit_env) |
11433 |
- return retval |
11434 |
|
11435 |
diff --git a/repoman/lib/repoman/modules/vcs/hg/status.py b/repoman/lib/repoman/modules/vcs/hg/status.py |
11436 |
deleted file mode 100644 |
11437 |
index 2b56f2e1f..000000000 |
11438 |
--- a/repoman/lib/repoman/modules/vcs/hg/status.py |
11439 |
+++ /dev/null |
11440 |
@@ -1,68 +0,0 @@ |
11441 |
-""" |
11442 |
-Mercurial module Status class submodule |
11443 |
-""" |
11444 |
- |
11445 |
-from repoman._portage import portage |
11446 |
-from portage import os |
11447 |
- |
11448 |
-# pylint: disable=ungrouped-imports |
11449 |
-from repoman._subprocess import repoman_popen |
11450 |
- |
11451 |
- |
11452 |
-class Status: |
11453 |
- """Performs status checks on the svn repository""" |
11454 |
- |
11455 |
- def __init__(self, qatracker, eadded): |
11456 |
- """Class init |
11457 |
- |
11458 |
- @param qatracker: QATracker class instance |
11459 |
- @param eadded: list |
11460 |
- """ |
11461 |
- self.qatracker = qatracker |
11462 |
- self.eadded = eadded |
11463 |
- |
11464 |
- def check(self, checkdir, checkdir_relative, xpkg): |
11465 |
- """Perform the svn status check |
11466 |
- |
11467 |
- @param checkdir: string of the directory being checked |
11468 |
- @param checkdir_relative: string of the relative directory being checked |
11469 |
- @param xpkg: string of the package being checked |
11470 |
- @returns: boolean |
11471 |
- """ |
11472 |
- myf = repoman_popen( |
11473 |
- "hg status --no-status --unknown %s" |
11474 |
- % (portage._shell_quote(checkdir_relative),) |
11475 |
- ) |
11476 |
- for l in myf: |
11477 |
- if l[:-1][-7:] == ".ebuild": |
11478 |
- self.qatracker.add_error( |
11479 |
- "ebuild.notadded", os.path.join(xpkg, os.path.basename(l[:-1])) |
11480 |
- ) |
11481 |
- myf.close() |
11482 |
- return True |
11483 |
- |
11484 |
- @staticmethod |
11485 |
- def detect_conflicts(options): |
11486 |
- """Are there any merge conflicts present in the VCS tracking system |
11487 |
- |
11488 |
- @param options: command line options |
11489 |
- @returns: Boolean |
11490 |
- """ |
11491 |
- return False |
11492 |
- |
11493 |
- @staticmethod |
11494 |
- def supports_gpg_sign(): |
11495 |
- """Does this vcs system support gpg commit signatures |
11496 |
- |
11497 |
- @returns: Boolean |
11498 |
- """ |
11499 |
- return False |
11500 |
- |
11501 |
- @staticmethod |
11502 |
- def isVcsDir(dirname): |
11503 |
- """Does the directory belong to the vcs system |
11504 |
- |
11505 |
- @param dirname: string, directory name |
11506 |
- @returns: Boolean |
11507 |
- """ |
11508 |
- return dirname in [".hg"] |
11509 |
|
11510 |
diff --git a/repoman/lib/repoman/modules/vcs/settings.py b/repoman/lib/repoman/modules/vcs/settings.py |
11511 |
deleted file mode 100644 |
11512 |
index b186b7044..000000000 |
11513 |
--- a/repoman/lib/repoman/modules/vcs/settings.py |
11514 |
+++ /dev/null |
11515 |
@@ -1,113 +0,0 @@ |
11516 |
-""" |
11517 |
-Repoman VCSSettings modules |
11518 |
-""" |
11519 |
- |
11520 |
-import logging |
11521 |
-import sys |
11522 |
- |
11523 |
-from portage.output import red |
11524 |
- |
11525 |
-from repoman.modules.vcs import module_controller, module_names |
11526 |
-from repoman.modules.vcs.vcs import FindVCS |
11527 |
-from repoman.qa_tracker import QATracker |
11528 |
- |
11529 |
- |
11530 |
-class VCSSettings: |
11531 |
- """Holds various VCS settings""" |
11532 |
- |
11533 |
- def __init__(self, options=None, repoman_settings=None, repo_settings=None): |
11534 |
- """Class init function |
11535 |
- |
11536 |
- @param options: the run time cli options |
11537 |
- @param repoman_settings: portage.config settings instance |
11538 |
- @param repo_settings: RepoSettings instance |
11539 |
- """ |
11540 |
- self.options = options |
11541 |
- self.repoman_settings = repoman_settings |
11542 |
- self.repo_settings = repo_settings |
11543 |
- if options.vcs: |
11544 |
- if options.vcs in module_names: |
11545 |
- self.vcs = options.vcs |
11546 |
- else: |
11547 |
- self.vcs = None |
11548 |
- else: |
11549 |
- vcses = FindVCS() |
11550 |
- if len(vcses) > 1: |
11551 |
- print( |
11552 |
- red( |
11553 |
- "*** Ambiguous workdir -- more than one VCS found" |
11554 |
- " at the same depth: %s." % ", ".join(vcses) |
11555 |
- ) |
11556 |
- ) |
11557 |
- print( |
11558 |
- red( |
11559 |
- "*** Please either clean up your workdir" |
11560 |
- " or specify --vcs option." |
11561 |
- ) |
11562 |
- ) |
11563 |
- sys.exit(1) |
11564 |
- elif vcses: |
11565 |
- self.vcs = vcses[0] |
11566 |
- else: |
11567 |
- self.vcs = None |
11568 |
- |
11569 |
- if options.if_modified == "y" and self.vcs is None: |
11570 |
- logging.info( |
11571 |
- "Not in a version controlled repository; " "disabling --if-modified." |
11572 |
- ) |
11573 |
- options.if_modified = "n" |
11574 |
- |
11575 |
- # initialize our instance placeholders |
11576 |
- self._status = None |
11577 |
- self._changes = None |
11578 |
- # get our vcs plugin controller and available module names |
11579 |
- self.module_controller = module_controller |
11580 |
- self.module_names = module_names |
11581 |
- |
11582 |
- # Disable copyright/mtime check if vcs does not preserve mtime (bug #324075). |
11583 |
- if str(self.vcs) in self.module_controller.parents: |
11584 |
- self.vcs_preserves_mtime = module_controller.modules[ |
11585 |
- "%s_status" % self.vcs |
11586 |
- ]["vcs_preserves_mtime"] |
11587 |
- else: |
11588 |
- self.vcs_preserves_mtime = False |
11589 |
- logging.error("VCSSettings: Unknown VCS type: %s", self.vcs) |
11590 |
- logging.error("Available modules: %s", module_controller.parents) |
11591 |
- |
11592 |
- self.needs_keyword_expansion = module_controller.modules[ |
11593 |
- "%s_status" % self.vcs |
11594 |
- ]["needs_keyword_expansion"] |
11595 |
- self.vcs_local_opts = repoman_settings.get("REPOMAN_VCS_LOCAL_OPTS", "").split() |
11596 |
- self.vcs_global_opts = repoman_settings.get("REPOMAN_VCS_GLOBAL_OPTS") |
11597 |
- if self.vcs_global_opts is None: |
11598 |
- if self.vcs in ("cvs", "svn"): |
11599 |
- self.vcs_global_opts = "-q" |
11600 |
- else: |
11601 |
- self.vcs_global_opts = "" |
11602 |
- self.vcs_global_opts = self.vcs_global_opts.split() |
11603 |
- |
11604 |
- if options.mode == "commit" and not options.pretend and not self.vcs: |
11605 |
- logging.info( |
11606 |
- "Not in a version controlled repository; " "enabling pretend mode." |
11607 |
- ) |
11608 |
- options.pretend = True |
11609 |
- self.qatracker = QATracker() |
11610 |
- self.eadded = [] |
11611 |
- |
11612 |
- @property |
11613 |
- def status(self): |
11614 |
- """Initializes and returns the class instance |
11615 |
- of the vcs's Status class""" |
11616 |
- if not self._status: |
11617 |
- status = self.module_controller.get_class("%s_status" % self.vcs) |
11618 |
- self._status = status(self.qatracker, self.eadded) |
11619 |
- return self._status |
11620 |
- |
11621 |
- @property |
11622 |
- def changes(self): |
11623 |
- """Initializes and returns the class instance |
11624 |
- of the vcs's Changes class""" |
11625 |
- if not self._changes: |
11626 |
- changes = self.module_controller.get_class("%s_changes" % self.vcs) |
11627 |
- self._changes = changes(self.options, self.repo_settings) |
11628 |
- return self._changes |
11629 |
|
11630 |
diff --git a/repoman/lib/repoman/modules/vcs/svn/__init__.py b/repoman/lib/repoman/modules/vcs/svn/__init__.py |
11631 |
deleted file mode 100644 |
11632 |
index f8da39363..000000000 |
11633 |
--- a/repoman/lib/repoman/modules/vcs/svn/__init__.py |
11634 |
+++ /dev/null |
11635 |
@@ -1,32 +0,0 @@ |
11636 |
-# Copyright 2014-2015 Gentoo Foundation |
11637 |
-# Distributed under the terms of the GNU General Public License v2 |
11638 |
- |
11639 |
-doc = """Subversion (svn) plug-in module for portage. |
11640 |
-Performs variaous subversion actions and checks on repositories.""" |
11641 |
-__doc__ = doc[:] |
11642 |
- |
11643 |
- |
11644 |
-module_spec = { |
11645 |
- "name": "svn", |
11646 |
- "description": doc, |
11647 |
- "provides": { |
11648 |
- "svn-module": { |
11649 |
- "name": "svn_status", |
11650 |
- "sourcefile": "status", |
11651 |
- "class": "Status", |
11652 |
- "description": doc, |
11653 |
- "functions": ["check", "supports_gpg_sign", "detect_conflicts"], |
11654 |
- "func_desc": {}, |
11655 |
- "vcs_preserves_mtime": False, |
11656 |
- "needs_keyword_expansion": True, |
11657 |
- }, |
11658 |
- "svn-changes": { |
11659 |
- "name": "svn_changes", |
11660 |
- "sourcefile": "changes", |
11661 |
- "class": "Changes", |
11662 |
- "description": doc, |
11663 |
- "functions": ["scan"], |
11664 |
- "func_desc": {}, |
11665 |
- }, |
11666 |
- }, |
11667 |
-} |
11668 |
|
11669 |
diff --git a/repoman/lib/repoman/modules/vcs/svn/changes.py b/repoman/lib/repoman/modules/vcs/svn/changes.py |
11670 |
deleted file mode 100644 |
11671 |
index e437325db..000000000 |
11672 |
--- a/repoman/lib/repoman/modules/vcs/svn/changes.py |
11673 |
+++ /dev/null |
11674 |
@@ -1,156 +0,0 @@ |
11675 |
-""" |
11676 |
-Subversion module Changes class submodule |
11677 |
-""" |
11678 |
- |
11679 |
-from itertools import chain |
11680 |
- |
11681 |
-from repoman.modules.vcs.changes import ChangesBase |
11682 |
-from repoman._subprocess import repoman_popen |
11683 |
-from repoman._subprocess import repoman_getstatusoutput |
11684 |
-from repoman.modules.vcs.vcs import vcs_files_to_cps |
11685 |
-from repoman._portage import portage |
11686 |
-from portage import os |
11687 |
-from portage.output import green |
11688 |
-from portage.package.ebuild.digestgen import digestgen |
11689 |
- |
11690 |
- |
11691 |
-class Changes(ChangesBase): |
11692 |
- """Class object to scan and hold the resultant data |
11693 |
- for all changes to process. |
11694 |
- """ |
11695 |
- |
11696 |
- vcs = "svn" |
11697 |
- |
11698 |
- def __init__(self, options, repo_settings): |
11699 |
- """Class init |
11700 |
- |
11701 |
- @param options: the run time cli options |
11702 |
- @param repo_settings: RepoSettings instance |
11703 |
- """ |
11704 |
- super(Changes, self).__init__(options, repo_settings) |
11705 |
- |
11706 |
- def _scan(self): |
11707 |
- """VCS type scan function, looks for all detectable changes""" |
11708 |
- with repoman_popen("svn status") as f: |
11709 |
- svnstatus = f.readlines() |
11710 |
- self.changed = [ |
11711 |
- "./" + elem.split()[-1:][0] |
11712 |
- for elem in svnstatus |
11713 |
- if elem and elem[:1] in "MR" |
11714 |
- ] |
11715 |
- self.new = [ |
11716 |
- "./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("A") |
11717 |
- ] |
11718 |
- self.removed = [ |
11719 |
- "./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("D") |
11720 |
- ] |
11721 |
- |
11722 |
- @property |
11723 |
- def expansion(self): |
11724 |
- """VCS method of getting the expanded keywords in the repository""" |
11725 |
- if self._expansion is not None: |
11726 |
- return self._expansion |
11727 |
- # Subversion expands keywords specified in svn:keywords properties. |
11728 |
- with repoman_popen("svn propget -R svn:keywords") as f: |
11729 |
- props = f.readlines() |
11730 |
- self._expansion = dict( |
11731 |
- ("./" + prop.split(" - ")[0], prop.split(" - ")[1].split()) |
11732 |
- for prop in props |
11733 |
- if " - " in prop |
11734 |
- ) |
11735 |
- del props |
11736 |
- return self._expansion |
11737 |
- |
11738 |
- @property |
11739 |
- def unadded(self): |
11740 |
- """VCS method of getting the unadded files in the repository""" |
11741 |
- if self._unadded is not None: |
11742 |
- return self._unadded |
11743 |
- with repoman_popen("svn status --no-ignore") as f: |
11744 |
- svnstatus = f.readlines() |
11745 |
- self._unadded = [ |
11746 |
- "./" + elem.rstrip().split()[1] |
11747 |
- for elem in svnstatus |
11748 |
- if elem.startswith("?") or elem.startswith("I") |
11749 |
- ] |
11750 |
- del svnstatus |
11751 |
- return self._unadded |
11752 |
- |
11753 |
- def thick_manifest(self, updates, headers, no_expansion, expansion): |
11754 |
- """Create a thick manifest |
11755 |
- |
11756 |
- @param updates: |
11757 |
- @param headers: |
11758 |
- @param no_expansion: |
11759 |
- @param expansion: |
11760 |
- """ |
11761 |
- svn_keywords = dict( |
11762 |
- (k.lower(), k) |
11763 |
- for k in [ |
11764 |
- "Rev", |
11765 |
- "Revision", |
11766 |
- "LastChangedRevision", |
11767 |
- "Date", |
11768 |
- "LastChangedDate", |
11769 |
- "Author", |
11770 |
- "LastChangedBy", |
11771 |
- "URL", |
11772 |
- "HeadURL", |
11773 |
- "Id", |
11774 |
- "Header", |
11775 |
- ] |
11776 |
- ) |
11777 |
- |
11778 |
- for _file in updates: |
11779 |
- # for SVN, expansion contains files that are included in expansion |
11780 |
- if _file not in expansion: |
11781 |
- continue |
11782 |
- |
11783 |
- # Subversion keywords are case-insensitive |
11784 |
- # in svn:keywords properties, |
11785 |
- # but case-sensitive in contents of files. |
11786 |
- enabled_keywords = [] |
11787 |
- for k in expansion[_file]: |
11788 |
- keyword = svn_keywords.get(k.lower()) |
11789 |
- if keyword is not None: |
11790 |
- enabled_keywords.append(keyword) |
11791 |
- |
11792 |
- headerstring = r"'\$(%s).*\$'" % "|".join(enabled_keywords) |
11793 |
- |
11794 |
- _out = repoman_getstatusoutput( |
11795 |
- "egrep -q %s %s" % (headerstring, portage._shell_quote(_file)) |
11796 |
- ) |
11797 |
- if _out[0] == 0: |
11798 |
- headers.append(_file) |
11799 |
- |
11800 |
- print("%s have headers that will change." % green(str(len(headers)))) |
11801 |
- print( |
11802 |
- "* Files with headers will" |
11803 |
- " cause the manifests to be changed and committed separately." |
11804 |
- ) |
11805 |
- |
11806 |
- def digest_regen( |
11807 |
- self, updates, removed, manifests, scanner, broken_changelog_manifests |
11808 |
- ): |
11809 |
- """Regenerate manifests |
11810 |
- |
11811 |
- @param updates: updated files |
11812 |
- @param removed: removed files |
11813 |
- @param manifests: Manifest files |
11814 |
- @param scanner: The repoman.scanner.Scanner instance |
11815 |
- @param broken_changelog_manifests: broken changelog manifests |
11816 |
- """ |
11817 |
- if updates or removed: |
11818 |
- for x in sorted( |
11819 |
- vcs_files_to_cps( |
11820 |
- chain(updates, removed, manifests), |
11821 |
- scanner.repo_settings.repodir, |
11822 |
- scanner.repolevel, |
11823 |
- scanner.reposplit, |
11824 |
- scanner.categories, |
11825 |
- ) |
11826 |
- ): |
11827 |
- self.repoman_settings["O"] = os.path.join(self.repo_settings.repodir, x) |
11828 |
- digestgen( |
11829 |
- mysettings=self.repoman_settings, myportdb=self.repo_settings.portdb |
11830 |
- ) |
11831 |
|
11832 |
diff --git a/repoman/lib/repoman/modules/vcs/svn/status.py b/repoman/lib/repoman/modules/vcs/svn/status.py |
11833 |
deleted file mode 100644 |
11834 |
index 2e6ee927d..000000000 |
11835 |
--- a/repoman/lib/repoman/modules/vcs/svn/status.py |
11836 |
+++ /dev/null |
11837 |
@@ -1,151 +0,0 @@ |
11838 |
-""" |
11839 |
-Subversion module Status class submodule |
11840 |
-""" |
11841 |
- |
11842 |
-import logging |
11843 |
-import subprocess |
11844 |
-import sys |
11845 |
- |
11846 |
-from repoman._portage import portage |
11847 |
-from portage import os |
11848 |
-from portage.const import BASH_BINARY |
11849 |
-from portage.output import red, green |
11850 |
-from portage import _unicode_encode, _unicode_decode |
11851 |
- |
11852 |
-# pylint: disable=ungrouped-imports |
11853 |
-from repoman._subprocess import repoman_popen |
11854 |
- |
11855 |
- |
11856 |
-class Status: |
11857 |
- """Performs status checks on the svn repository""" |
11858 |
- |
11859 |
- def __init__(self, qatracker, eadded): |
11860 |
- """Class init |
11861 |
- |
11862 |
- @param qatracker: QATracker class instance |
11863 |
- @param eadded: list |
11864 |
- """ |
11865 |
- self.qatracker = qatracker |
11866 |
- self.eadded = eadded |
11867 |
- |
11868 |
- def check(self, checkdir, checkdir_relative, xpkg): |
11869 |
- """Perform the svn status check |
11870 |
- |
11871 |
- @param checkdir: string of the directory being checked |
11872 |
- @param checkdir_relative: string of the relative directory being checked |
11873 |
- @param xpkg: string of the package being checked |
11874 |
- @returns: boolean |
11875 |
- """ |
11876 |
- try: |
11877 |
- myf = repoman_popen( |
11878 |
- "svn status --depth=files --verbose " + portage._shell_quote(checkdir) |
11879 |
- ) |
11880 |
- myl = myf.readlines() |
11881 |
- myf.close() |
11882 |
- except IOError: |
11883 |
- raise |
11884 |
- for l in myl: |
11885 |
- if l[:1] == "?": |
11886 |
- continue |
11887 |
- if l[:7] == " >": |
11888 |
- # tree conflict, new in subversion 1.6 |
11889 |
- continue |
11890 |
- l = l.split()[-1] |
11891 |
- if l[-7:] == ".ebuild": |
11892 |
- self.eadded.append(os.path.basename(l[:-7])) |
11893 |
- try: |
11894 |
- myf = repoman_popen("svn status " + portage._shell_quote(checkdir)) |
11895 |
- myl = myf.readlines() |
11896 |
- myf.close() |
11897 |
- except IOError: |
11898 |
- raise |
11899 |
- for l in myl: |
11900 |
- if l[0] == "A": |
11901 |
- l = l.rstrip().split(" ")[-1] |
11902 |
- if l[-7:] == ".ebuild": |
11903 |
- self.eadded.append(os.path.basename(l[:-7])) |
11904 |
- return True |
11905 |
- |
11906 |
- @staticmethod |
11907 |
- def detect_conflicts(options): |
11908 |
- """Determine if the checkout has problems like cvs conflicts. |
11909 |
- |
11910 |
- If you want more vcs support here just keep adding if blocks... |
11911 |
- This could be better. |
11912 |
- |
11913 |
- TODO(antarus): Also this should probably not call sys.exit() as |
11914 |
- repoman is run on >1 packages and one failure should not cause |
11915 |
- subsequent packages to fail. |
11916 |
- |
11917 |
- Args: |
11918 |
- vcs - A string identifying the version control system in use |
11919 |
- Returns: boolean |
11920 |
- (calls sys.exit on fatal problems) |
11921 |
- """ |
11922 |
- |
11923 |
- cmd = "svn status -u 2>&1 | egrep -v '^. +.*/digest-[^/]+' | head -n-1" |
11924 |
- msg = "Performing a %s with a little magic grep to check for updates." % green( |
11925 |
- "svn status -u" |
11926 |
- ) |
11927 |
- |
11928 |
- logging.info(msg) |
11929 |
- # Use Popen instead of getstatusoutput(), in order to avoid |
11930 |
- # unicode handling problems (see bug #310789). |
11931 |
- args = [BASH_BINARY, "-c", cmd] |
11932 |
- args = [_unicode_encode(x) for x in args] |
11933 |
- proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
11934 |
- out = _unicode_decode(proc.communicate()[0]) |
11935 |
- proc.wait() |
11936 |
- mylines = out.splitlines() |
11937 |
- myupdates = [] |
11938 |
- for line in mylines: |
11939 |
- if not line: |
11940 |
- continue |
11941 |
- |
11942 |
- # [ ] Unmodified (SVN) [U] Updates [P] Patches |
11943 |
- # [M] Modified [A] Added [R] Removed / Replaced |
11944 |
- # [D] Deleted |
11945 |
- if line[0] not in " UPMARD": |
11946 |
- # Stray Manifest is fine, we will readd it anyway. |
11947 |
- if line[0] == "?" and line[1:].lstrip() == "Manifest": |
11948 |
- continue |
11949 |
- logging.error( |
11950 |
- red( |
11951 |
- "!!! Please fix the following issues reported " |
11952 |
- "from cvs: %s" % green("(U,P,M,A,R,D are ok)") |
11953 |
- ) |
11954 |
- ) |
11955 |
- logging.error(red("!!! Note: This is a pretend/no-modify pass...")) |
11956 |
- logging.error(out) |
11957 |
- sys.exit(1) |
11958 |
- elif line[8] == "*": |
11959 |
- myupdates.append(line[9:].lstrip(" 1234567890")) |
11960 |
- |
11961 |
- if myupdates: |
11962 |
- logging.info(green("Fetching trivial updates...")) |
11963 |
- if options.pretend: |
11964 |
- logging.info("(svn update " + " ".join(myupdates) + ")") |
11965 |
- retval = os.EX_OK |
11966 |
- else: |
11967 |
- retval = os.system("svn update " + " ".join(myupdates)) |
11968 |
- if retval != os.EX_OK: |
11969 |
- logging.fatal("!!! svn exited with an error. Terminating.") |
11970 |
- sys.exit(retval) |
11971 |
- return False |
11972 |
- |
11973 |
- @staticmethod |
11974 |
- def supports_gpg_sign(): |
11975 |
- """Does this vcs system support gpg commit signatures |
11976 |
- |
11977 |
- @returns: Boolean |
11978 |
- """ |
11979 |
- return False |
11980 |
- |
11981 |
- @staticmethod |
11982 |
- def isVcsDir(dirname): |
11983 |
- """Does the directory belong to the vcs system |
11984 |
- |
11985 |
- @param dirname: string, directory name |
11986 |
- @returns: Boolean |
11987 |
- """ |
11988 |
- return dirname in [".svn"] |
11989 |
|
11990 |
diff --git a/repoman/lib/repoman/modules/vcs/vcs.py b/repoman/lib/repoman/modules/vcs/vcs.py |
11991 |
deleted file mode 100644 |
11992 |
index 1ee8b52ff..000000000 |
11993 |
--- a/repoman/lib/repoman/modules/vcs/vcs.py |
11994 |
+++ /dev/null |
11995 |
@@ -1,145 +0,0 @@ |
11996 |
-# -*- coding:utf-8 -*- |
11997 |
- |
11998 |
-import collections |
11999 |
-import logging |
12000 |
- |
12001 |
-from itertools import chain |
12002 |
- |
12003 |
-from portage import os |
12004 |
- |
12005 |
- |
12006 |
-_vcs_type = collections.namedtuple("_vcs_type", "name dir_name file_name") |
12007 |
- |
12008 |
-_FindVCS_data = ( |
12009 |
- _vcs_type(name="git", dir_name=".git", file_name=".git"), |
12010 |
- _vcs_type(name="bzr", dir_name=".bzr", file_name=""), |
12011 |
- _vcs_type(name="hg", dir_name=".hg", file_name=""), |
12012 |
- _vcs_type(name="svn", dir_name=".svn", file_name=""), |
12013 |
-) |
12014 |
- |
12015 |
- |
12016 |
-def FindVCS(cwd=None): |
12017 |
- """ |
12018 |
- Try to figure out in what VCS' working tree we are. |
12019 |
- |
12020 |
- @param cwd: working directory (default is os.getcwd()) |
12021 |
- @type cwd: str |
12022 |
- @return: list of strings describing the discovered vcs types |
12023 |
- @rtype: list |
12024 |
- """ |
12025 |
- |
12026 |
- if cwd is None: |
12027 |
- cwd = os.getcwd() |
12028 |
- |
12029 |
- outvcs = [] |
12030 |
- |
12031 |
- def seek(depth=None): |
12032 |
- """Seek for VCSes that have a top-level data directory only. |
12033 |
- |
12034 |
- @param depth: integer |
12035 |
- @returns: list of strings |
12036 |
- """ |
12037 |
- retvcs = [] |
12038 |
- pathprep = cwd |
12039 |
- |
12040 |
- while depth is None or depth > 0: |
12041 |
- for vcs_type in _FindVCS_data: |
12042 |
- vcs_dir = os.path.join(pathprep, vcs_type.dir_name) |
12043 |
- if os.path.isdir(vcs_dir): |
12044 |
- logging.debug( |
12045 |
- "FindVCS: found %(name)s dir: %(vcs_dir)s" |
12046 |
- % {"name": vcs_type.name, "vcs_dir": os.path.abspath(vcs_dir)} |
12047 |
- ) |
12048 |
- retvcs.append(vcs_type.name) |
12049 |
- elif vcs_type.file_name: |
12050 |
- vcs_file = os.path.join(pathprep, vcs_type.file_name) |
12051 |
- if os.path.exists(vcs_file): |
12052 |
- logging.debug( |
12053 |
- "FindVCS: found %(name)s file: %(vcs_file)s" |
12054 |
- % { |
12055 |
- "name": vcs_type.name, |
12056 |
- "vcs_file": os.path.abspath(vcs_file), |
12057 |
- } |
12058 |
- ) |
12059 |
- retvcs.append(vcs_type.name) |
12060 |
- |
12061 |
- if retvcs: |
12062 |
- break |
12063 |
- pathprep = os.path.join(pathprep, "..") |
12064 |
- if os.path.realpath(pathprep).strip("/") == "": |
12065 |
- break |
12066 |
- if depth is not None: |
12067 |
- depth = depth - 1 |
12068 |
- |
12069 |
- return retvcs |
12070 |
- |
12071 |
- # Level zero VCS-es. |
12072 |
- if os.path.isdir(os.path.join(cwd, "CVS")): |
12073 |
- outvcs.append("cvs") |
12074 |
- if os.path.isdir(".svn"): # <1.7 |
12075 |
- outvcs.append(os.path.join(cwd, "svn")) |
12076 |
- |
12077 |
- # If we already found one of 'level zeros', just take a quick look |
12078 |
- # at the current directory. Otherwise, seek parents till we get |
12079 |
- # something or reach root. |
12080 |
- if outvcs: |
12081 |
- outvcs.extend(seek(1)) |
12082 |
- else: |
12083 |
- outvcs = seek() |
12084 |
- |
12085 |
- if len(outvcs) > 1: |
12086 |
- # eliminate duplicates, like for svn in bug #391199 |
12087 |
- outvcs = list(set(outvcs)) |
12088 |
- |
12089 |
- return outvcs |
12090 |
- |
12091 |
- |
12092 |
-def vcs_files_to_cps(vcs_file_iter, repodir, repolevel, reposplit, categories): |
12093 |
- """ |
12094 |
- Iterate over the given modified file paths returned from the vcs, |
12095 |
- and return a frozenset containing category/pn strings for each |
12096 |
- modified package. |
12097 |
- """ |
12098 |
- |
12099 |
- modified_cps = [] |
12100 |
- |
12101 |
- if repolevel == 3: |
12102 |
- if reposplit[-2] in categories and next(vcs_file_iter, None) is not None: |
12103 |
- modified_cps.append("/".join(reposplit[-2:])) |
12104 |
- |
12105 |
- elif repolevel == 2: |
12106 |
- category = reposplit[-1] |
12107 |
- if category in categories: |
12108 |
- for filename in vcs_file_iter: |
12109 |
- f_split = filename.split(os.sep) |
12110 |
- # ['.', pn, ...] |
12111 |
- if len(f_split) > 2: |
12112 |
- modified_cps.append(category + "/" + f_split[1]) |
12113 |
- |
12114 |
- else: |
12115 |
- # repolevel == 1 |
12116 |
- for filename in vcs_file_iter: |
12117 |
- f_split = filename.split(os.sep) |
12118 |
- # ['.', category, pn, ...] |
12119 |
- if len(f_split) > 3 and f_split[1] in categories: |
12120 |
- modified_cps.append("/".join(f_split[1:3])) |
12121 |
- |
12122 |
- # Exclude packages that have been removed, since calling |
12123 |
- # code assumes that the packages exist. |
12124 |
- return frozenset( |
12125 |
- x for x in frozenset(modified_cps) if os.path.exists(os.path.join(repodir, x)) |
12126 |
- ) |
12127 |
- |
12128 |
- |
12129 |
-def vcs_new_changed(relative_path, mychanged, mynew): |
12130 |
- """Check if any vcs tracked file have been modified |
12131 |
- |
12132 |
- @param relative_path: |
12133 |
- @param mychanged: iterable of changed files |
12134 |
- @param mynew: iterable of new files |
12135 |
- @returns boolean |
12136 |
- """ |
12137 |
- for x in chain(mychanged, mynew): |
12138 |
- if x == relative_path: |
12139 |
- return True |
12140 |
- return False |
12141 |
|
12142 |
diff --git a/repoman/lib/repoman/profile.py b/repoman/lib/repoman/profile.py |
12143 |
deleted file mode 100644 |
12144 |
index b317189ef..000000000 |
12145 |
--- a/repoman/lib/repoman/profile.py |
12146 |
+++ /dev/null |
12147 |
@@ -1,94 +0,0 @@ |
12148 |
-# -*- coding:utf-8 -*- |
12149 |
- |
12150 |
-from portage import normalize_path |
12151 |
-from portage import os |
12152 |
-from portage.output import red |
12153 |
- |
12154 |
- |
12155 |
-class ProfileDesc: |
12156 |
- __slots__ = ( |
12157 |
- "abs_path", |
12158 |
- "arch", |
12159 |
- "status", |
12160 |
- "sub_path", |
12161 |
- "tree_path", |
12162 |
- ) |
12163 |
- |
12164 |
- def __init__(self, arch, status, sub_path, tree_path): |
12165 |
- self.arch = arch |
12166 |
- self.status = status |
12167 |
- if sub_path: |
12168 |
- sub_path = normalize_path(sub_path.lstrip(os.sep)) |
12169 |
- self.sub_path = sub_path |
12170 |
- self.tree_path = tree_path |
12171 |
- if tree_path: |
12172 |
- self.abs_path = os.path.join(tree_path, "profiles", self.sub_path) |
12173 |
- else: |
12174 |
- self.abs_path = tree_path |
12175 |
- |
12176 |
- def __str__(self): |
12177 |
- if self.sub_path: |
12178 |
- return self.sub_path |
12179 |
- return "empty profile" |
12180 |
- |
12181 |
- |
12182 |
-valid_profile_types = frozenset(["dev", "exp", "stable"]) |
12183 |
- |
12184 |
- |
12185 |
-def dev_profile_keywords(profiles): |
12186 |
- """ |
12187 |
- Create a set of KEYWORDS values that exist in 'dev' |
12188 |
- profiles. These are used |
12189 |
- to trigger a message notifying the user when they might |
12190 |
- want to add the --include-dev option. |
12191 |
- """ |
12192 |
- type_arch_map = {} |
12193 |
- for arch, arch_profiles in profiles.items(): |
12194 |
- for prof in arch_profiles: |
12195 |
- arch_set = type_arch_map.get(prof.status) |
12196 |
- if arch_set is None: |
12197 |
- arch_set = set() |
12198 |
- type_arch_map[prof.status] = arch_set |
12199 |
- arch_set.add(arch) |
12200 |
- |
12201 |
- dev_keywords = type_arch_map.get("dev", set()) |
12202 |
- dev_keywords.update(["~" + arch for arch in dev_keywords]) |
12203 |
- return frozenset(dev_keywords) |
12204 |
- |
12205 |
- |
12206 |
-def setup_profile(profile_list): |
12207 |
- # Ensure that profile sub_path attributes are unique. Process in reverse order |
12208 |
- # so that profiles with duplicate sub_path from overlays will override |
12209 |
- # profiles with the same sub_path from parent repos. |
12210 |
- profiles = {} |
12211 |
- profile_list.reverse() |
12212 |
- profile_sub_paths = set() |
12213 |
- for prof in profile_list: |
12214 |
- if prof.sub_path in profile_sub_paths: |
12215 |
- continue |
12216 |
- profile_sub_paths.add(prof.sub_path) |
12217 |
- profiles.setdefault(prof.arch, []).append(prof) |
12218 |
- |
12219 |
- # Use an empty profile for checking dependencies of |
12220 |
- # packages that have empty KEYWORDS. |
12221 |
- prof = ProfileDesc("**", "stable", "", "") |
12222 |
- profiles.setdefault(prof.arch, []).append(prof) |
12223 |
- return profiles |
12224 |
- |
12225 |
- |
12226 |
-def check_profiles(profiles, archlist): |
12227 |
- for x in archlist: |
12228 |
- if x[0] == "~": |
12229 |
- continue |
12230 |
- if x not in profiles: |
12231 |
- print( |
12232 |
- red('"%s" doesn\'t have a valid profile listed in profiles.desc.' % x) |
12233 |
- ) |
12234 |
- print( |
12235 |
- red( |
12236 |
- 'You need to either "cvs update" your profiles dir' |
12237 |
- " or follow this" |
12238 |
- ) |
12239 |
- ) |
12240 |
- print(red("up with the " + x + " team.")) |
12241 |
- print() |
12242 |
|
12243 |
diff --git a/repoman/lib/repoman/qa_data.py b/repoman/lib/repoman/qa_data.py |
12244 |
deleted file mode 100644 |
12245 |
index 0892c1f5c..000000000 |
12246 |
--- a/repoman/lib/repoman/qa_data.py |
12247 |
+++ /dev/null |
12248 |
@@ -1,210 +0,0 @@ |
12249 |
-# -*- coding:utf-8 -*- |
12250 |
- |
12251 |
-import logging |
12252 |
-import os |
12253 |
- |
12254 |
-from _emerge.Package import Package |
12255 |
- |
12256 |
-# import our initialized portage instance |
12257 |
-from repoman import _not_installed |
12258 |
-from repoman._portage import portage |
12259 |
-from repoman.config import load_config |
12260 |
- |
12261 |
- |
12262 |
-class QAData: |
12263 |
- def __init__(self): |
12264 |
- # Create the main exported data variables |
12265 |
- self.max_desc_len = None |
12266 |
- self.allowed_filename_chars = None |
12267 |
- self.qahelp = None |
12268 |
- self.qacats = None |
12269 |
- self.qawarnings = None |
12270 |
- self.missingvars = None |
12271 |
- self.allvars = None |
12272 |
- self.valid_restrict = None |
12273 |
- self.suspect_rdepend = None |
12274 |
- self.suspect_virtual = None |
12275 |
- self.ruby_deprecated = None |
12276 |
- self.no_exec = None |
12277 |
- |
12278 |
- def load_repo_config(self, repopaths, options, valid_versions): |
12279 |
- """Load the repository repoman qa_data.yml config |
12280 |
- |
12281 |
- @param repopaths: list of strings, The path of the repository being scanned |
12282 |
- This could be a parent repository using the |
12283 |
- repoman_masters layout.conf variable |
12284 |
- """ |
12285 |
- # add our base qahelp |
12286 |
- repository_modules = options.experimental_repository_modules == "y" |
12287 |
- if _not_installed: |
12288 |
- cnfdir = os.path.realpath( |
12289 |
- os.path.join( |
12290 |
- os.path.dirname(os.path.dirname(os.path.dirname(__file__))), |
12291 |
- "cnf/qa_data", |
12292 |
- ) |
12293 |
- ) |
12294 |
- else: |
12295 |
- cnfdir = os.path.join( |
12296 |
- portage.const.EPREFIX or "/", "usr/share/repoman/qa_data" |
12297 |
- ) |
12298 |
- repomanpaths = [os.path.join(cnfdir, _file_) for _file_ in os.listdir(cnfdir)] |
12299 |
- logging.debug("QAData: cnfdir: %s, repomanpaths: %s", cnfdir, repomanpaths) |
12300 |
- if repository_modules: |
12301 |
- repopaths = [os.path.join(path, "qa_data.yaml") for path in repopaths] |
12302 |
- elif _not_installed: |
12303 |
- repopaths = [ |
12304 |
- os.path.realpath( |
12305 |
- os.path.join( |
12306 |
- os.path.dirname(os.path.dirname(os.path.dirname(__file__))), |
12307 |
- "cnf/repository/qa_data.yaml", |
12308 |
- ) |
12309 |
- ) |
12310 |
- ] |
12311 |
- else: |
12312 |
- repopaths = [ |
12313 |
- os.path.join( |
12314 |
- portage.const.EPREFIX or "/", |
12315 |
- "usr/share/repoman/repository/qa_data.yaml", |
12316 |
- ) |
12317 |
- ] |
12318 |
- infopaths = repomanpaths + repopaths |
12319 |
- |
12320 |
- qadata = load_config(infopaths, None, valid_versions) |
12321 |
- if qadata == {}: |
12322 |
- logging.error( |
12323 |
- "QAData: Failed to load a valid 'qa_data.yaml' file at paths: %s", |
12324 |
- infopaths, |
12325 |
- ) |
12326 |
- return False |
12327 |
- self.max_desc_len = qadata.get("max_description_length", 80) |
12328 |
- self.allowed_filename_chars = qadata.get( |
12329 |
- "allowed_filename_chars", "a-zA-Z0-9._-+:" |
12330 |
- ) |
12331 |
- |
12332 |
- self.qahelp = qadata["qahelp"] |
12333 |
- logging.debug("qa_help primary keys: %s", sorted(self.qahelp)) |
12334 |
- |
12335 |
- self.qacats = [] |
12336 |
- for x in sorted(self.qahelp): |
12337 |
- for y in sorted(self.qahelp[x]): |
12338 |
- self.qacats.append(".".join([x, y])) |
12339 |
- self.qacats.sort() |
12340 |
- |
12341 |
- self.qawarnings = set(qadata.get("qawarnings", [])) |
12342 |
- if options.experimental_inherit == "y": |
12343 |
- # This is experimental, so it's non-fatal. |
12344 |
- self.qawarnings.add("inherit.missing") |
12345 |
- |
12346 |
- self.missingvars = qadata.get("missingvars", []) |
12347 |
- logging.debug("QAData: missingvars: %s", self.missingvars) |
12348 |
- self.allvars = set(portage.auxdbkeys) |
12349 |
- self.allvars.update(Package.metadata_keys) |
12350 |
- self.allvars = sorted(self.allvars) |
12351 |
- |
12352 |
- for x in self.missingvars: |
12353 |
- x += ".missing" |
12354 |
- if x not in self.qacats: |
12355 |
- logging.warning( |
12356 |
- 'QAData: * missingvars values need to be added to qahelp ("%s")' % x |
12357 |
- ) |
12358 |
- self.qacats.append(x) |
12359 |
- self.qawarnings.add(x) |
12360 |
- |
12361 |
- self.valid_restrict = frozenset(qadata.get("valid_restrict", [])) |
12362 |
- |
12363 |
- self.suspect_rdepend = frozenset(qadata.get("suspect_rdepend", [])) |
12364 |
- |
12365 |
- self.suspect_virtual = qadata.get("suspect_virtual", {}) |
12366 |
- |
12367 |
- self.ruby_deprecated = frozenset(qadata.get("ruby_deprecated", [])) |
12368 |
- |
12369 |
- # file.executable |
12370 |
- self.no_exec = frozenset(qadata.get("no_exec_files", [])) |
12371 |
- logging.debug("QAData: completed loading file: %s", repopaths) |
12372 |
- return True |
12373 |
- |
12374 |
- |
12375 |
-def format_qa_output(formatter, fails, dofull, dofail, options, qawarnings): |
12376 |
- """Helper function that formats output properly |
12377 |
- |
12378 |
- @param formatter: an instance of Formatter |
12379 |
- @type formatter: Formatter |
12380 |
- @param fails: dict of qa status failures |
12381 |
- @type fails: dict |
12382 |
- @param dofull: Whether to print full results or a summary |
12383 |
- @type dofull: boolean |
12384 |
- @param dofail: Whether failure was hard or soft |
12385 |
- @type dofail: boolean |
12386 |
- @param options: The command-line options provided to repoman |
12387 |
- @type options: Namespace |
12388 |
- @param qawarnings: the set of warning types |
12389 |
- @type qawarnings: set |
12390 |
- @return: None (modifies formatter) |
12391 |
- """ |
12392 |
- full = options.mode == "full" |
12393 |
- # we only want key value pairs where value > 0 |
12394 |
- for category in sorted(fails): |
12395 |
- number = len(fails[category]) |
12396 |
- formatter.add_literal_data(" " + category) |
12397 |
- spacing_width = 30 - len(category) |
12398 |
- if category in qawarnings: |
12399 |
- formatter.push_style("WARN") |
12400 |
- else: |
12401 |
- formatter.push_style("BAD") |
12402 |
- formatter.add_literal_data(" [fatal]") |
12403 |
- spacing_width -= 8 |
12404 |
- |
12405 |
- formatter.add_literal_data(" " * spacing_width) |
12406 |
- formatter.add_literal_data("%s" % number) |
12407 |
- formatter.pop_style() |
12408 |
- formatter.add_line_break() |
12409 |
- if not dofull: |
12410 |
- if not full and dofail and category in qawarnings: |
12411 |
- # warnings are considered noise when there are failures |
12412 |
- continue |
12413 |
- fails_list = fails[category] |
12414 |
- if not full and len(fails_list) > 12: |
12415 |
- fails_list = fails_list[:12] |
12416 |
- for failure in fails_list: |
12417 |
- formatter.add_literal_data(" " + failure) |
12418 |
- formatter.add_line_break() |
12419 |
- |
12420 |
- |
12421 |
-def format_qa_output_column(formatter, fails, dofull, dofail, options, qawarnings): |
12422 |
- """Helper function that formats output in a machine-parseable column format |
12423 |
- |
12424 |
- @param formatter: an instance of Formatter |
12425 |
- @type formatter: Formatter |
12426 |
- @param fails: dict of qa status failures |
12427 |
- @type fails: dict |
12428 |
- @param dofull: Whether to print full results or a summary |
12429 |
- @type dofull: boolean |
12430 |
- @param dofail: Whether failure was hard or soft |
12431 |
- @type dofail: boolean |
12432 |
- @param options: The command-line options provided to repoman |
12433 |
- @type options: Namespace |
12434 |
- @param qawarnings: the set of warning types |
12435 |
- @type qawarnings: set |
12436 |
- @return: None (modifies formatter) |
12437 |
- """ |
12438 |
- full = options.mode == "full" |
12439 |
- for category in sorted(fails): |
12440 |
- number = len(fails[category]) |
12441 |
- formatter.add_literal_data("NumberOf " + category + " ") |
12442 |
- if category in qawarnings: |
12443 |
- formatter.push_style("WARN") |
12444 |
- else: |
12445 |
- formatter.push_style("BAD") |
12446 |
- formatter.add_literal_data("%s" % number) |
12447 |
- formatter.pop_style() |
12448 |
- formatter.add_line_break() |
12449 |
- if not dofull: |
12450 |
- if not full and dofail and category in qawarnings: |
12451 |
- # warnings are considered noise when there are failures |
12452 |
- continue |
12453 |
- fails_list = fails[category] |
12454 |
- if not full and len(fails_list) > 12: |
12455 |
- fails_list = fails_list[:12] |
12456 |
- for failure in fails_list: |
12457 |
- formatter.add_literal_data(category + " " + failure) |
12458 |
- formatter.add_line_break() |
12459 |
|
12460 |
diff --git a/repoman/lib/repoman/qa_tracker.py b/repoman/lib/repoman/qa_tracker.py |
12461 |
deleted file mode 100644 |
12462 |
index 6cb5f3207..000000000 |
12463 |
--- a/repoman/lib/repoman/qa_tracker.py |
12464 |
+++ /dev/null |
12465 |
@@ -1,46 +0,0 @@ |
12466 |
-import logging |
12467 |
-import sys |
12468 |
- |
12469 |
- |
12470 |
-class QATracker: |
12471 |
- """Track all occurrances of Q/A problems detected""" |
12472 |
- |
12473 |
- def __init__(self, qacats=None, qawarnings=None): |
12474 |
- self.fails = {} |
12475 |
- self.warns = {} |
12476 |
- self.qacats = qacats |
12477 |
- self.qawarnings = qawarnings |
12478 |
- |
12479 |
- def add_error(self, detected_qa, info): |
12480 |
- """Add the Q/A error to the database of detected problems |
12481 |
- |
12482 |
- @param detected_qa: string, member of qa_data.qacats list |
12483 |
- @param info: string, details of the detected problem |
12484 |
- """ |
12485 |
- if detected_qa not in self.qacats: |
12486 |
- logging.error( |
12487 |
- "QATracker: Exiting on error. Unknown detected_qa type passed " |
12488 |
- "in to add_error(): %s, %s" % (detected_qa, info) |
12489 |
- ) |
12490 |
- sys.exit(1) |
12491 |
- try: |
12492 |
- self.fails[detected_qa].append(info) |
12493 |
- except KeyError: |
12494 |
- self.fails[detected_qa] = [info] |
12495 |
- |
12496 |
- def add_warning(self, detected_qa, info): |
12497 |
- """Add the Q/A warning to the database of detected problems |
12498 |
- |
12499 |
- @param detected_qa: string, member of qa_data.qawarnings list |
12500 |
- @param info: string, details of the detected problem |
12501 |
- """ |
12502 |
- if detected_qa not in self.qawarnings: |
12503 |
- logging.error( |
12504 |
- "QATracker: Exiting on error. Unknown detected_qa type passed " |
12505 |
- "in to add_warning(): %s, %s" % (detected_qa, info) |
12506 |
- ) |
12507 |
- sys.exit(1) |
12508 |
- try: |
12509 |
- self.warns[detected_qa].append(info) |
12510 |
- except KeyError: |
12511 |
- self.warns[detected_qa] = [info] |
12512 |
|
12513 |
diff --git a/repoman/lib/repoman/repos.py b/repoman/lib/repoman/repos.py |
12514 |
deleted file mode 100644 |
12515 |
index d89e0508a..000000000 |
12516 |
--- a/repoman/lib/repoman/repos.py |
12517 |
+++ /dev/null |
12518 |
@@ -1,377 +0,0 @@ |
12519 |
-# -*- coding:utf-8 -*- |
12520 |
- |
12521 |
- |
12522 |
-import io |
12523 |
-import logging |
12524 |
-import re |
12525 |
-import sys |
12526 |
-import textwrap |
12527 |
- |
12528 |
-# import our initialized portage instance |
12529 |
-from repoman._portage import portage |
12530 |
- |
12531 |
-from portage import os |
12532 |
-from portage import _encodings |
12533 |
-from portage import _unicode_encode |
12534 |
-from portage.checksum import get_valid_checksum_keys |
12535 |
-from portage.repository.config import allow_profile_repo_deps |
12536 |
- |
12537 |
-# pylint: disable=ungrouped-imports |
12538 |
-from repoman.errors import err |
12539 |
-from repoman.profile import ProfileDesc, valid_profile_types |
12540 |
- |
12541 |
-GPG_KEY_ID_REGEX = r"(0x)?([0-9a-fA-F]{8}){1,5}!?" |
12542 |
-bad = portage.output.create_color_func("BAD") |
12543 |
- |
12544 |
- |
12545 |
-class RepoSettings: |
12546 |
- """Holds our repo specific settings""" |
12547 |
- |
12548 |
- def __init__( |
12549 |
- self, |
12550 |
- config_root, |
12551 |
- portdir, |
12552 |
- portdir_overlay, |
12553 |
- repoman_settings=None, |
12554 |
- vcs_settings=None, |
12555 |
- options=None, |
12556 |
- qadata=None, |
12557 |
- ): |
12558 |
- self.config_root = config_root |
12559 |
- self.repoman_settings = repoman_settings |
12560 |
- self.vcs_settings = vcs_settings |
12561 |
- |
12562 |
- self.repositories = self.repoman_settings.repositories |
12563 |
- |
12564 |
- # Ensure that current repository is in the list of enabled repositories. |
12565 |
- self.repodir = os.path.realpath(portdir_overlay) |
12566 |
- try: |
12567 |
- self.repositories.get_repo_for_location(self.repodir) |
12568 |
- except KeyError: |
12569 |
- self._add_repo(config_root, portdir_overlay) |
12570 |
- |
12571 |
- # Determine the master config loading list |
12572 |
- self.masters_list = [] |
12573 |
- # get out repo masters value |
12574 |
- masters = self.repositories.get_repo_for_location(self.repodir).masters |
12575 |
- for repo in masters: |
12576 |
- self.masters_list.append(os.path.join(repo.location, "metadata", "repoman")) |
12577 |
- self.masters_list.append(os.path.join(self.repodir, "metadata", "repoman")) |
12578 |
- |
12579 |
- logging.debug("RepoSettings: init(); load qadata") |
12580 |
- # load the repo specific configuration |
12581 |
- self.qadata = qadata |
12582 |
- if not self.qadata.load_repo_config( |
12583 |
- self.masters_list, options, repoman_settings.valid_versions |
12584 |
- ): |
12585 |
- logging.error("Aborting...") |
12586 |
- sys.exit(1) |
12587 |
- logging.debug("RepoSettings: qadata loaded: %s", qadata.no_exec) |
12588 |
- |
12589 |
- self.root = self.repoman_settings["EROOT"] |
12590 |
- self.trees = { |
12591 |
- self.root: {"porttree": portage.portagetree(settings=self.repoman_settings)} |
12592 |
- } |
12593 |
- self.portdb = self.trees[self.root]["porttree"].dbapi |
12594 |
- |
12595 |
- # Constrain dependency resolution to the master(s) |
12596 |
- # that are specified in layout.conf. |
12597 |
- self.repo_config = self.repositories.get_repo_for_location(self.repodir) |
12598 |
- self.portdb.porttrees = list(self.repo_config.eclass_db.porttrees) |
12599 |
- self.portdir = self.portdb.porttrees[0] |
12600 |
- self.commit_env = os.environ.copy() |
12601 |
- # list() is for iteration on a copy. |
12602 |
- for repo in list(self.repositories): |
12603 |
- # all paths are canonical |
12604 |
- if repo.location not in self.repo_config.eclass_db.porttrees: |
12605 |
- del self.repositories[repo.name] |
12606 |
- |
12607 |
- if self.repo_config.sign_commit and options.mode in ( |
12608 |
- "commit", |
12609 |
- "fix", |
12610 |
- "manifest", |
12611 |
- ): |
12612 |
- if vcs_settings.vcs: |
12613 |
- func = getattr(self, "_vcs_gpg_%s" % vcs_settings.vcs) |
12614 |
- func() |
12615 |
- else: |
12616 |
- logging.warning("No VCS type detected, unable to sign the commit") |
12617 |
- |
12618 |
- # In order to disable manifest signatures, repos may set |
12619 |
- # "sign-manifests = false" in metadata/layout.conf. This |
12620 |
- # can be used to prevent merge conflicts like those that |
12621 |
- # thin-manifests is designed to prevent. |
12622 |
- self.sign_manifests = ( |
12623 |
- "sign" in self.repoman_settings.features and self.repo_config.sign_manifest |
12624 |
- ) |
12625 |
- |
12626 |
- if ( |
12627 |
- self.repo_config.sign_manifest |
12628 |
- and self.repo_config.name == "gentoo" |
12629 |
- and options.mode in ("commit",) |
12630 |
- and not self.sign_manifests |
12631 |
- ): |
12632 |
- msg = ( |
12633 |
- "The '%s' repository has manifest signatures enabled, " |
12634 |
- "but FEATURES=sign is currently disabled. In order to avoid this " |
12635 |
- "warning, enable FEATURES=sign in make.conf. Alternatively, " |
12636 |
- "repositories can disable manifest signatures by setting " |
12637 |
- "'sign-manifests = false' in metadata/layout.conf." |
12638 |
- ) % (self.repo_config.name,) |
12639 |
- for line in textwrap.wrap(msg, 60): |
12640 |
- logging.warn(line) |
12641 |
- |
12642 |
- is_commit = options.mode in ("commit",) |
12643 |
- valid_gpg_key = self.repoman_settings.get("PORTAGE_GPG_KEY") and re.match( |
12644 |
- r"^%s$" % GPG_KEY_ID_REGEX, self.repoman_settings["PORTAGE_GPG_KEY"] |
12645 |
- ) |
12646 |
- |
12647 |
- if self.sign_manifests and is_commit and not valid_gpg_key: |
12648 |
- logging.error( |
12649 |
- "PORTAGE_GPG_KEY value is invalid: %s" |
12650 |
- % self.repoman_settings["PORTAGE_GPG_KEY"] |
12651 |
- ) |
12652 |
- sys.exit(1) |
12653 |
- |
12654 |
- manifest_hashes = self.repo_config.manifest_hashes |
12655 |
- manifest_required_hashes = self.repo_config.manifest_required_hashes |
12656 |
- if manifest_hashes is None: |
12657 |
- manifest_hashes = portage.const.MANIFEST2_HASH_DEFAULTS |
12658 |
- manifest_required_hashes = manifest_hashes |
12659 |
- |
12660 |
- if options.mode in ("commit", "fix", "manifest"): |
12661 |
- missing_required_hashes = manifest_required_hashes.difference( |
12662 |
- manifest_hashes |
12663 |
- ) |
12664 |
- if missing_required_hashes: |
12665 |
- msg = ( |
12666 |
- "The 'manifest-hashes' setting in the '%s' repository's " |
12667 |
- "metadata/layout.conf does not contain the '%s' hashes which " |
12668 |
- "are listed in 'manifest-required-hashes'. Please fix that " |
12669 |
- "file if you want to generate valid manifests for " |
12670 |
- "this repository." |
12671 |
- ) % (self.repo_config.name, " ".join(missing_required_hashes)) |
12672 |
- for line in textwrap.wrap(msg, 70): |
12673 |
- logging.error(line) |
12674 |
- sys.exit(1) |
12675 |
- |
12676 |
- unsupported_hashes = manifest_hashes.difference(get_valid_checksum_keys()) |
12677 |
- if unsupported_hashes: |
12678 |
- msg = ( |
12679 |
- "The 'manifest-hashes' setting in the '%s' repository's " |
12680 |
- "metadata/layout.conf contains one or more hash types '%s' " |
12681 |
- "which are not supported by this portage version. You will " |
12682 |
- "have to upgrade portage if you want to generate valid " |
12683 |
- "manifests for this repository." |
12684 |
- ) % (self.repo_config.name, " ".join(sorted(unsupported_hashes))) |
12685 |
- for line in textwrap.wrap(msg, 70): |
12686 |
- logging.error(line) |
12687 |
- sys.exit(1) |
12688 |
- |
12689 |
- def _add_repo(self, config_root, portdir_overlay): |
12690 |
- self.repo_conf = portage.repository.config |
12691 |
- self.repo_name = self.repo_conf.RepoConfig._read_valid_repo_name( |
12692 |
- portdir_overlay |
12693 |
- )[0] |
12694 |
- self.layout_conf_data = self.repo_conf.parse_layout_conf(portdir_overlay)[0] |
12695 |
- if self.layout_conf_data["repo-name"]: |
12696 |
- self.repo_name = self.layout_conf_data["repo-name"] |
12697 |
- tmp_conf_file = io.StringIO( |
12698 |
- textwrap.dedent( |
12699 |
- """ |
12700 |
- [%s] |
12701 |
- location = %s |
12702 |
- """ |
12703 |
- ) |
12704 |
- % (self.repo_name, portdir_overlay) |
12705 |
- ) |
12706 |
- # Ensure that the repository corresponding to $PWD overrides a |
12707 |
- # repository of the same name referenced by the existing PORTDIR |
12708 |
- # or PORTDIR_OVERLAY settings. |
12709 |
- self.repoman_settings["PORTDIR_OVERLAY"] = "%s %s" % ( |
12710 |
- self.repoman_settings.get("PORTDIR_OVERLAY", ""), |
12711 |
- portage._shell_quote(portdir_overlay), |
12712 |
- ) |
12713 |
- self.repositories = self.repo_conf.load_repository_config( |
12714 |
- self.repoman_settings, extra_files=[tmp_conf_file] |
12715 |
- ) |
12716 |
- # We have to call the config constructor again so that attributes |
12717 |
- # dependent on config.repositories are initialized correctly. |
12718 |
- self.repoman_settings = portage.config( |
12719 |
- config_root=config_root, local_config=False, repositories=self.repositories |
12720 |
- ) |
12721 |
- |
12722 |
- ########## |
12723 |
- # future vcs plugin functions |
12724 |
- ########## |
12725 |
- |
12726 |
- def _vcs_gpg_bzr(self): |
12727 |
- pass |
12728 |
- |
12729 |
- def _vcs_gpg_cvs(self): |
12730 |
- pass |
12731 |
- |
12732 |
- def _vcs_gpg_git(self): |
12733 |
- # NOTE: It's possible to use --gpg-sign=key_id to specify the key in |
12734 |
- # the commit arguments. If key_id is unspecified, then it must be |
12735 |
- # configured by `git config user.signingkey key_id`. |
12736 |
- self.vcs_settings.vcs_local_opts.append("--gpg-sign") |
12737 |
- if self.repoman_settings.get("PORTAGE_GPG_DIR"): |
12738 |
- # Pass GNUPGHOME to git for bug #462362. |
12739 |
- self.commit_env["GNUPGHOME"] = self.repoman_settings["PORTAGE_GPG_DIR"] |
12740 |
- |
12741 |
- # Pass GPG_TTY to git for bug #477728. |
12742 |
- try: |
12743 |
- self.commit_env["GPG_TTY"] = os.ttyname(sys.stdin.fileno()) |
12744 |
- except OSError: |
12745 |
- pass |
12746 |
- |
12747 |
- def _vcs_gpg_hg(self): |
12748 |
- pass |
12749 |
- |
12750 |
- def _vcs_gpg_svn(self): |
12751 |
- pass |
12752 |
- |
12753 |
- |
12754 |
-def list_checks(kwlist, liclist, uselist, repoman_settings): |
12755 |
- liclist_deprecated = set() |
12756 |
- if "DEPRECATED" in repoman_settings._license_manager._license_groups: |
12757 |
- liclist_deprecated.update( |
12758 |
- repoman_settings._license_manager.expandLicenseTokens(["@DEPRECATED"]) |
12759 |
- ) |
12760 |
- |
12761 |
- if not liclist: |
12762 |
- logging.fatal("Couldn't find licenses?") |
12763 |
- sys.exit(1) |
12764 |
- |
12765 |
- if not kwlist: |
12766 |
- logging.fatal("Couldn't read KEYWORDS from arch.list") |
12767 |
- sys.exit(1) |
12768 |
- |
12769 |
- if not uselist: |
12770 |
- logging.fatal("Couldn't find use.desc?") |
12771 |
- sys.exit(1) |
12772 |
- return liclist_deprecated |
12773 |
- |
12774 |
- |
12775 |
-def repo_metadata(portdb, repoman_settings): |
12776 |
- # get lists of valid keywords, licenses, and use |
12777 |
- kwlist = set() |
12778 |
- liclist = set() |
12779 |
- uselist = set() |
12780 |
- profile_list = [] |
12781 |
- global_pmasklines = [] |
12782 |
- |
12783 |
- for repo in portdb.repositories: |
12784 |
- path = repo.location |
12785 |
- |
12786 |
- try: |
12787 |
- liclist.update(os.listdir(os.path.join(path, "licenses"))) |
12788 |
- except OSError: |
12789 |
- pass |
12790 |
- kwlist.update(portage.grabfile(os.path.join(path, "profiles", "arch.list"))) |
12791 |
- |
12792 |
- use_desc = portage.grabfile(os.path.join(path, "profiles", "use.desc")) |
12793 |
- for x in use_desc: |
12794 |
- x = x.split() |
12795 |
- if x: |
12796 |
- uselist.add(x[0]) |
12797 |
- |
12798 |
- expand_desc_dir = os.path.join(path, "profiles", "desc") |
12799 |
- try: |
12800 |
- expand_list = os.listdir(expand_desc_dir) |
12801 |
- except OSError: |
12802 |
- pass |
12803 |
- else: |
12804 |
- for fn in expand_list: |
12805 |
- if not fn[-5:] == ".desc": |
12806 |
- continue |
12807 |
- use_prefix = fn[:-5].lower() + "_" |
12808 |
- for x in portage.grabfile(os.path.join(expand_desc_dir, fn)): |
12809 |
- x = x.split() |
12810 |
- if x: |
12811 |
- uselist.add(use_prefix + x[0]) |
12812 |
- |
12813 |
- global_pmasklines.append( |
12814 |
- portage.util.grabfile_package( |
12815 |
- os.path.join(path, "profiles", "package.mask"), |
12816 |
- recursive=1, |
12817 |
- verify_eapi=True, |
12818 |
- allow_repo=allow_profile_repo_deps(repo), |
12819 |
- ) |
12820 |
- ) |
12821 |
- |
12822 |
- desc_path = os.path.join(path, "profiles", "profiles.desc") |
12823 |
- try: |
12824 |
- desc_file = io.open( |
12825 |
- _unicode_encode(desc_path, encoding=_encodings["fs"], errors="strict"), |
12826 |
- mode="r", |
12827 |
- encoding=_encodings["repo.content"], |
12828 |
- errors="replace", |
12829 |
- ) |
12830 |
- except EnvironmentError: |
12831 |
- pass |
12832 |
- else: |
12833 |
- for i, x in enumerate(desc_file): |
12834 |
- if x[0] == "#": |
12835 |
- continue |
12836 |
- arch = x.split() |
12837 |
- if len(arch) == 0: |
12838 |
- continue |
12839 |
- if len(arch) != 3: |
12840 |
- err( |
12841 |
- 'wrong format: "%s" in %s line %d' |
12842 |
- % ( |
12843 |
- bad(x.strip()), |
12844 |
- desc_path, |
12845 |
- i + 1, |
12846 |
- ) |
12847 |
- ) |
12848 |
- elif arch[0] not in kwlist: |
12849 |
- err( |
12850 |
- 'invalid arch: "%s" in %s line %d' |
12851 |
- % ( |
12852 |
- bad(arch[0]), |
12853 |
- desc_path, |
12854 |
- i + 1, |
12855 |
- ) |
12856 |
- ) |
12857 |
- elif arch[2] not in valid_profile_types: |
12858 |
- err( |
12859 |
- 'invalid profile type: "%s" in %s line %d' |
12860 |
- % ( |
12861 |
- bad(arch[2]), |
12862 |
- desc_path, |
12863 |
- i + 1, |
12864 |
- ) |
12865 |
- ) |
12866 |
- profile_desc = ProfileDesc(arch[0], arch[2], arch[1], path) |
12867 |
- if not os.path.isdir(profile_desc.abs_path): |
12868 |
- logging.error( |
12869 |
- "Invalid %s profile (%s) for arch %s in %s line %d", |
12870 |
- arch[2], |
12871 |
- arch[1], |
12872 |
- arch[0], |
12873 |
- desc_path, |
12874 |
- i + 1, |
12875 |
- ) |
12876 |
- continue |
12877 |
- if os.path.exists(os.path.join(profile_desc.abs_path, "deprecated")): |
12878 |
- continue |
12879 |
- profile_list.append(profile_desc) |
12880 |
- desc_file.close() |
12881 |
- |
12882 |
- global_pmasklines = portage.util.stack_lists(global_pmasklines, incremental=1) |
12883 |
- global_pmaskdict = {} |
12884 |
- for x in global_pmasklines: |
12885 |
- global_pmaskdict.setdefault(x.cp, []).append(x) |
12886 |
- del global_pmasklines |
12887 |
- |
12888 |
- return ( |
12889 |
- kwlist, |
12890 |
- liclist, |
12891 |
- uselist, |
12892 |
- profile_list, |
12893 |
- global_pmaskdict, |
12894 |
- list_checks(kwlist, liclist, uselist, repoman_settings), |
12895 |
- ) |
12896 |
|
12897 |
diff --git a/repoman/lib/repoman/scanner.py b/repoman/lib/repoman/scanner.py |
12898 |
deleted file mode 100644 |
12899 |
index 890950c65..000000000 |
12900 |
--- a/repoman/lib/repoman/scanner.py |
12901 |
+++ /dev/null |
12902 |
@@ -1,484 +0,0 @@ |
12903 |
-# -*- coding:utf-8 -*- |
12904 |
- |
12905 |
-import logging |
12906 |
-import portage |
12907 |
- |
12908 |
-from itertools import chain |
12909 |
- |
12910 |
-from portage import normalize_path |
12911 |
-from portage import os |
12912 |
-from portage._sets.base import InternalPackageSet |
12913 |
-from portage.output import green |
12914 |
-from portage.util.futures.extendedfutures import ExtendedFuture |
12915 |
- |
12916 |
-from repoman.metadata import get_metadata_xsd |
12917 |
-from repoman.modules.commit import repochecks |
12918 |
-from repoman.modules.commit import manifest |
12919 |
-from repoman.profile import check_profiles, dev_profile_keywords, setup_profile |
12920 |
-from repoman.repos import repo_metadata |
12921 |
-from repoman.modules.scan.module import ModuleConfig |
12922 |
-from repoman.modules.scan.scan import scan |
12923 |
-from repoman.modules.vcs.vcs import vcs_files_to_cps |
12924 |
- |
12925 |
- |
12926 |
-DATA_TYPES = {"dict": dict, "Future": ExtendedFuture, "list": list, "set": set} |
12927 |
- |
12928 |
- |
12929 |
-class Scanner: |
12930 |
- """Primary scan class. Operates all the small Q/A tests and checks""" |
12931 |
- |
12932 |
- def __init__( |
12933 |
- self, repo_settings, myreporoot, config_root, options, vcs_settings, mydir, env |
12934 |
- ): |
12935 |
- """Class __init__""" |
12936 |
- self.repo_settings = repo_settings |
12937 |
- self.config_root = config_root |
12938 |
- self.options = options |
12939 |
- self.vcs_settings = vcs_settings |
12940 |
- self.env = env |
12941 |
- |
12942 |
- # Repoman sets it's own ACCEPT_KEYWORDS and we don't want it to |
12943 |
- # behave incrementally. |
12944 |
- self.repoman_incrementals = tuple( |
12945 |
- x for x in portage.const.INCREMENTALS if x != "ACCEPT_KEYWORDS" |
12946 |
- ) |
12947 |
- |
12948 |
- self.categories = [] |
12949 |
- for path in self.repo_settings.repo_config.eclass_db.porttrees: |
12950 |
- self.categories.extend( |
12951 |
- portage.util.grabfile(os.path.join(path, "profiles", "categories")) |
12952 |
- ) |
12953 |
- self.repo_settings.repoman_settings.categories = frozenset( |
12954 |
- portage.util.stack_lists([self.categories], incremental=1) |
12955 |
- ) |
12956 |
- self.categories = self.repo_settings.repoman_settings.categories |
12957 |
- |
12958 |
- self.portdb = repo_settings.portdb |
12959 |
- self.portdb.settings = self.repo_settings.repoman_settings |
12960 |
- |
12961 |
- digest_only = ( |
12962 |
- self.options.mode != "manifest-check" and self.options.digest == "y" |
12963 |
- ) |
12964 |
- self.generate_manifest = digest_only or self.options.mode in ( |
12965 |
- "manifest", |
12966 |
- "commit", |
12967 |
- "fix", |
12968 |
- ) |
12969 |
- |
12970 |
- # We really only need to cache the metadata that's necessary for visibility |
12971 |
- # filtering. Anything else can be discarded to reduce memory consumption. |
12972 |
- if not self.generate_manifest: |
12973 |
- # Don't do this when generating manifests, since that uses |
12974 |
- # additional keys if spawn_nofetch is called (RESTRICT and |
12975 |
- # DEFINED_PHASES). |
12976 |
- self.portdb._aux_cache_keys.clear() |
12977 |
- self.portdb._aux_cache_keys.update( |
12978 |
- ["EAPI", "IUSE", "KEYWORDS", "repository", "SLOT"] |
12979 |
- ) |
12980 |
- |
12981 |
- self.reposplit = myreporoot.split(os.path.sep) |
12982 |
- self.repolevel = len(self.reposplit) |
12983 |
- |
12984 |
- if self.options.mode == "commit": |
12985 |
- repochecks.commit_check(self.repolevel, self.reposplit) |
12986 |
- repochecks.conflict_check(self.vcs_settings, self.options) |
12987 |
- |
12988 |
- # Make startdir relative to the canonical repodir, so that we can pass |
12989 |
- # it to digestgen and it won't have to be canonicalized again. |
12990 |
- if self.repolevel == 1: |
12991 |
- startdir = self.repo_settings.repodir |
12992 |
- else: |
12993 |
- startdir = normalize_path(mydir) |
12994 |
- startdir = os.path.join( |
12995 |
- self.repo_settings.repodir, |
12996 |
- *startdir.split(os.sep)[-2 - self.repolevel + 3 :] |
12997 |
- ) |
12998 |
- |
12999 |
- # get lists of valid keywords, licenses, and use |
13000 |
- new_data = repo_metadata(self.portdb, self.repo_settings.repoman_settings) |
13001 |
- ( |
13002 |
- kwlist, |
13003 |
- liclist, |
13004 |
- uselist, |
13005 |
- profile_list, |
13006 |
- global_pmaskdict, |
13007 |
- liclist_deprecated, |
13008 |
- ) = new_data |
13009 |
- self.repo_metadata = { |
13010 |
- "kwlist": kwlist, |
13011 |
- "liclist": liclist, |
13012 |
- "uselist": uselist, |
13013 |
- "profile_list": profile_list, |
13014 |
- "pmaskdict": global_pmaskdict, |
13015 |
- "lic_deprecated": liclist_deprecated, |
13016 |
- "package.deprecated": InternalPackageSet( |
13017 |
- initial_atoms=portage.util.stack_lists( |
13018 |
- [ |
13019 |
- portage.util.grabfile_package( |
13020 |
- os.path.join(path, "profiles", "package.deprecated"), |
13021 |
- recursive=True, |
13022 |
- ) |
13023 |
- for path in self.portdb.porttrees |
13024 |
- ], |
13025 |
- incremental=True, |
13026 |
- ) |
13027 |
- ), |
13028 |
- } |
13029 |
- |
13030 |
- self.repo_settings.repoman_settings["PORTAGE_ARCHLIST"] = " ".join( |
13031 |
- sorted(kwlist) |
13032 |
- ) |
13033 |
- self.repo_settings.repoman_settings.backup_changes("PORTAGE_ARCHLIST") |
13034 |
- |
13035 |
- profiles = setup_profile(profile_list) |
13036 |
- |
13037 |
- check_profiles(profiles, self.repo_settings.repoman_settings.archlist()) |
13038 |
- |
13039 |
- scanlist = scan( |
13040 |
- self.repolevel, |
13041 |
- self.reposplit, |
13042 |
- startdir, |
13043 |
- self.categories, |
13044 |
- self.repo_settings, |
13045 |
- ) |
13046 |
- |
13047 |
- self.dev_keywords = dev_profile_keywords(profiles) |
13048 |
- |
13049 |
- self.qatracker = self.vcs_settings.qatracker |
13050 |
- |
13051 |
- if ( |
13052 |
- self.options.echangelog is None |
13053 |
- and self.repo_settings.repo_config.update_changelog |
13054 |
- ): |
13055 |
- self.options.echangelog = "y" |
13056 |
- |
13057 |
- if self.vcs_settings.vcs is None: |
13058 |
- self.options.echangelog = "n" |
13059 |
- |
13060 |
- # Initialize the ModuleConfig class here |
13061 |
- # TODO Add layout.conf masters repository.yml config to the list to load/stack |
13062 |
- self.moduleconfig = ModuleConfig( |
13063 |
- self.repo_settings.masters_list, |
13064 |
- self.repo_settings.repoman_settings.valid_versions, |
13065 |
- repository_modules=self.options.experimental_repository_modules == "y", |
13066 |
- ) |
13067 |
- |
13068 |
- checks = {} |
13069 |
- # The --echangelog option causes automatic ChangeLog generation, |
13070 |
- # which invalidates changelog.ebuildadded and changelog.missing |
13071 |
- # checks. |
13072 |
- # Note: Some don't use ChangeLogs in distributed SCMs. |
13073 |
- # It will be generated on server side from scm log, |
13074 |
- # before package moves to the rsync server. |
13075 |
- # This is needed because they try to avoid merge collisions. |
13076 |
- # Gentoo's Council decided to always use the ChangeLog file. |
13077 |
- # TODO: shouldn't this just be switched on the repo, iso the VCS? |
13078 |
- is_echangelog_enabled = self.options.echangelog in ("y", "force") |
13079 |
- self.vcs_settings.vcs_is_cvs_or_svn = self.vcs_settings.vcs in ("cvs", "svn") |
13080 |
- checks["changelog"] = ( |
13081 |
- not is_echangelog_enabled and self.vcs_settings.vcs_is_cvs_or_svn |
13082 |
- ) |
13083 |
- |
13084 |
- if self.options.mode == "manifest" or self.options.quiet: |
13085 |
- pass |
13086 |
- elif self.options.pretend: |
13087 |
- print(green("\nRepoMan does a once-over of the neighborhood...")) |
13088 |
- else: |
13089 |
- print(green("\nRepoMan scours the neighborhood...")) |
13090 |
- |
13091 |
- self.changed = self.vcs_settings.changes |
13092 |
- # bypass unneeded VCS operations if not needed |
13093 |
- if self.options.if_modified == "y" or self.options.mode not in ( |
13094 |
- "manifest", |
13095 |
- "manifest-check", |
13096 |
- ): |
13097 |
- self.changed.scan() |
13098 |
- |
13099 |
- self.have = { |
13100 |
- "pmasked": False, |
13101 |
- "dev_keywords": False, |
13102 |
- } |
13103 |
- |
13104 |
- # NOTE: match-all caches are not shared due to potential |
13105 |
- # differences between profiles in _get_implicit_iuse. |
13106 |
- self.caches = { |
13107 |
- "arch": {}, |
13108 |
- "arch_xmatch": {}, |
13109 |
- "shared_xmatch": {"cp-list": {}}, |
13110 |
- } |
13111 |
- |
13112 |
- self.include_arches = None |
13113 |
- if self.options.include_arches: |
13114 |
- self.include_arches = set() |
13115 |
- self.include_arches.update( |
13116 |
- *[x.split() for x in self.options.include_arches] |
13117 |
- ) |
13118 |
- self.include_profiles = None |
13119 |
- if self.options.include_profiles: |
13120 |
- self.include_profiles = set() |
13121 |
- self.include_profiles.update( |
13122 |
- *[x.split() for x in self.options.include_profiles] |
13123 |
- ) |
13124 |
- |
13125 |
- # Disable the "self.modules['Ebuild'].notadded" check when not in commit mode and |
13126 |
- # running `svn status` in every package dir will be too expensive. |
13127 |
- checks["ebuild_notadded"] = not ( |
13128 |
- self.vcs_settings.vcs == "svn" |
13129 |
- and self.repolevel < 3 |
13130 |
- and self.options.mode != "commit" |
13131 |
- ) |
13132 |
- |
13133 |
- self.effective_scanlist = scanlist |
13134 |
- if self.options.if_modified == "y": |
13135 |
- self.effective_scanlist = sorted( |
13136 |
- vcs_files_to_cps( |
13137 |
- chain(self.changed.changed, self.changed.new, self.changed.removed), |
13138 |
- self.repo_settings.repodir, |
13139 |
- self.repolevel, |
13140 |
- self.reposplit, |
13141 |
- self.categories, |
13142 |
- ) |
13143 |
- ) |
13144 |
- |
13145 |
- # Create our kwargs dict here to initialize the plugins with |
13146 |
- self.kwargs = { |
13147 |
- "repo_settings": self.repo_settings, |
13148 |
- "portdb": self.portdb, |
13149 |
- "qatracker": self.qatracker, |
13150 |
- "vcs_settings": self.vcs_settings, |
13151 |
- "options": self.options, |
13152 |
- "metadata_xsd": get_metadata_xsd(self.repo_settings), |
13153 |
- "uselist": uselist, |
13154 |
- "checks": checks, |
13155 |
- "repo_metadata": self.repo_metadata, |
13156 |
- "profiles": profiles, |
13157 |
- "include_arches": self.include_arches, |
13158 |
- "include_profiles": self.include_profiles, |
13159 |
- "caches": self.caches, |
13160 |
- "repoman_incrementals": self.repoman_incrementals, |
13161 |
- "env": self.env, |
13162 |
- "have": self.have, |
13163 |
- "dev_keywords": self.dev_keywords, |
13164 |
- "linechecks": self.moduleconfig.linechecks, |
13165 |
- } |
13166 |
- # initialize the plugin checks here |
13167 |
- self.modules = {} |
13168 |
- self._ext_futures = {} |
13169 |
- self.pkg_level_futures = None |
13170 |
- |
13171 |
- def set_kwargs(self, mod): |
13172 |
- """Creates a limited set of kwargs to pass to the module's __init__() |
13173 |
- |
13174 |
- @param mod: module name string |
13175 |
- @returns: dictionary |
13176 |
- """ |
13177 |
- kwargs = {} |
13178 |
- for key in self.moduleconfig.controller.modules[mod]["mod_kwargs"]: |
13179 |
- kwargs[key] = self.kwargs[key] |
13180 |
- return kwargs |
13181 |
- |
13182 |
- def set_func_kwargs(self, mod, dynamic_data=None): |
13183 |
- """Updates the dynamic_data dictionary with any new key, value pairs. |
13184 |
- Creates a limited set of kwargs to pass to the modulefunctions to run |
13185 |
- |
13186 |
- @param mod: module name string |
13187 |
- @param dynamic_data: dictionary structure |
13188 |
- @returns: dictionary |
13189 |
- """ |
13190 |
- func_kwargs = self.moduleconfig.controller.modules[mod]["func_kwargs"] |
13191 |
- # determine new keys |
13192 |
- required = set(list(func_kwargs)) |
13193 |
- exist = set(list(dynamic_data)) |
13194 |
- new = required.difference(exist) |
13195 |
- # update dynamic_data with initialized entries |
13196 |
- for key in new: |
13197 |
- logging.debug("set_func_kwargs(); adding: %s, %s", key, func_kwargs[key]) |
13198 |
- if func_kwargs[key][0] in ["Future", "ExtendedFuture"]: |
13199 |
- if key not in self._ext_futures: |
13200 |
- logging.debug( |
13201 |
- "Adding a new key: %s to the ExtendedFuture dict", key |
13202 |
- ) |
13203 |
- self._ext_futures[key] = func_kwargs[key] |
13204 |
- self._set_future(dynamic_data, key, func_kwargs[key]) |
13205 |
- else: # builtin python data type |
13206 |
- dynamic_data[key] = DATA_TYPES[func_kwargs[key][0]]() |
13207 |
- kwargs = {} |
13208 |
- for key in required: |
13209 |
- kwargs[key] = dynamic_data[key] |
13210 |
- return kwargs |
13211 |
- |
13212 |
- def reset_futures(self, dynamic_data): |
13213 |
- """Reset any Future data types |
13214 |
- |
13215 |
- @param dynamic_data: dictionary |
13216 |
- """ |
13217 |
- for key in list(self._ext_futures): |
13218 |
- if key not in self.pkg_level_futures: |
13219 |
- self._set_future(dynamic_data, key, self._ext_futures[key]) |
13220 |
- |
13221 |
- @staticmethod |
13222 |
- def _set_future(dynamic_data, key, data): |
13223 |
- """Set a dynamic_data key to a new ExtendedFuture instance |
13224 |
- |
13225 |
- @param dynamic_data: dictionary |
13226 |
- @param key: tuple of (dictionary-key, default-value) |
13227 |
- """ |
13228 |
- if data[0] in ["Future", "ExtendedFuture"]: |
13229 |
- if data[1] in ["UNSET"]: |
13230 |
- dynamic_data[key] = ExtendedFuture() |
13231 |
- else: |
13232 |
- if data[1] in DATA_TYPES: |
13233 |
- default = DATA_TYPES[data[1]]() |
13234 |
- else: |
13235 |
- default = data[1] |
13236 |
- dynamic_data[key] = ExtendedFuture(default) |
13237 |
- |
13238 |
- def scan_pkgs(self, can_force): |
13239 |
- for xpkg in self.effective_scanlist: |
13240 |
- xpkg_continue = False |
13241 |
- # ebuilds and digests added to cvs respectively. |
13242 |
- logging.info("checking package %s", xpkg) |
13243 |
- # save memory by discarding xmatch caches from previous package(s) |
13244 |
- self.caches["arch_xmatch"].clear() |
13245 |
- catdir, pkgdir = xpkg.split("/") |
13246 |
- checkdir = self.repo_settings.repodir + "/" + xpkg |
13247 |
- checkdir_relative = "" |
13248 |
- if self.repolevel < 3: |
13249 |
- checkdir_relative = os.path.join(pkgdir, checkdir_relative) |
13250 |
- if self.repolevel < 2: |
13251 |
- checkdir_relative = os.path.join(catdir, checkdir_relative) |
13252 |
- checkdir_relative = os.path.join(".", checkdir_relative) |
13253 |
- |
13254 |
- # Run the status check |
13255 |
- if self.kwargs["checks"]["ebuild_notadded"]: |
13256 |
- self.vcs_settings.status.check(checkdir, checkdir_relative, xpkg) |
13257 |
- |
13258 |
- if self.generate_manifest: |
13259 |
- if not manifest.Manifest(**self.kwargs).update_manifest(checkdir): |
13260 |
- self.qatracker.add_error( |
13261 |
- "manifest.bad", os.path.join(xpkg, "Manifest") |
13262 |
- ) |
13263 |
- if self.options.mode == "manifest": |
13264 |
- continue |
13265 |
- checkdirlist = os.listdir(checkdir) |
13266 |
- |
13267 |
- dynamic_data = { |
13268 |
- "changelog_modified": False, |
13269 |
- "checkdirlist": ExtendedFuture(checkdirlist), |
13270 |
- "checkdir": checkdir, |
13271 |
- "xpkg": xpkg, |
13272 |
- "changed": self.changed, |
13273 |
- "checkdir_relative": checkdir_relative, |
13274 |
- "can_force": can_force, |
13275 |
- "repolevel": self.repolevel, |
13276 |
- "catdir": catdir, |
13277 |
- "pkgdir": pkgdir, |
13278 |
- "validity_future": ExtendedFuture(True), |
13279 |
- "y_ebuild": None, |
13280 |
- # this needs to be reset at the pkg level only, |
13281 |
- # easiest is to just initialize it here |
13282 |
- "muselist": ExtendedFuture(set()), |
13283 |
- "src_uri_error": ExtendedFuture(), |
13284 |
- } |
13285 |
- self.pkg_level_futures = [ |
13286 |
- "checkdirlist", |
13287 |
- "muselist", |
13288 |
- "pkgs", |
13289 |
- "src_uri_error", |
13290 |
- "validity_future", |
13291 |
- ] |
13292 |
- # need to set it up for ==> self.modules or some other ordered list |
13293 |
- logging.debug("***** starting pkgs_loop: %s", self.moduleconfig.pkgs_loop) |
13294 |
- for mod in self.moduleconfig.pkgs_loop: |
13295 |
- mod_class = self.moduleconfig.controller.get_class(mod) |
13296 |
- logging.debug("Initializing class name: %s", mod_class.__name__) |
13297 |
- self.modules[mod_class.__name__] = mod_class(**self.set_kwargs(mod)) |
13298 |
- logging.debug("scan_pkgs; module: %s", mod_class.__name__) |
13299 |
- do_it, functions = self.modules[mod_class.__name__].runInPkgs |
13300 |
- if do_it: |
13301 |
- for func in functions: |
13302 |
- _continue = func(**self.set_func_kwargs(mod, dynamic_data)) |
13303 |
- if _continue: |
13304 |
- # If we can't access all the metadata then it's totally unsafe to |
13305 |
- # commit since there's no way to generate a correct Manifest. |
13306 |
- # Do not try to do any more QA checks on this package since missing |
13307 |
- # metadata leads to false positives for several checks, and false |
13308 |
- # positives confuse users. |
13309 |
- xpkg_continue = True |
13310 |
- break |
13311 |
- |
13312 |
- if xpkg_continue: |
13313 |
- continue |
13314 |
- |
13315 |
- # Sort ebuilds in ascending order for the KEYWORDS.dropped check. |
13316 |
- pkgs = dynamic_data["pkgs"].get() |
13317 |
- ebuildlist = sorted(pkgs.values()) |
13318 |
- ebuildlist = [pkg.pf for pkg in ebuildlist] |
13319 |
- |
13320 |
- if self.kwargs["checks"]["changelog"] and "ChangeLog" not in checkdirlist: |
13321 |
- self.qatracker.add_error("changelog.missing", xpkg + "/ChangeLog") |
13322 |
- |
13323 |
- changelog_path = os.path.join(checkdir_relative, "ChangeLog") |
13324 |
- dynamic_data["changelog_modified"] = ( |
13325 |
- changelog_path in self.changed.changelogs |
13326 |
- ) |
13327 |
- |
13328 |
- self._scan_ebuilds(ebuildlist, dynamic_data) |
13329 |
- |
13330 |
- def _scan_ebuilds(self, ebuildlist, dynamic_data): |
13331 |
- |
13332 |
- for y_ebuild in ebuildlist: |
13333 |
- self.reset_futures(dynamic_data) |
13334 |
- dynamic_data["y_ebuild"] = y_ebuild |
13335 |
- |
13336 |
- # initialize per ebuild plugin checks here |
13337 |
- # need to set it up for ==> self.modules_list or some other ordered list |
13338 |
- for mod in self.moduleconfig.ebuilds_loop: |
13339 |
- if mod: |
13340 |
- mod_class = self.moduleconfig.controller.get_class(mod) |
13341 |
- if mod_class.__name__ not in self.modules: |
13342 |
- logging.debug("Initializing class name: %s", mod_class.__name__) |
13343 |
- self.modules[mod_class.__name__] = mod_class( |
13344 |
- **self.set_kwargs(mod) |
13345 |
- ) |
13346 |
- logging.debug("scan_ebuilds: module: %s", mod_class.__name__) |
13347 |
- do_it, functions = self.modules[mod_class.__name__].runInEbuilds |
13348 |
- logging.debug( |
13349 |
- "do_it: %s, functions: %s", do_it, [x.__name__ for x in functions] |
13350 |
- ) |
13351 |
- if do_it: |
13352 |
- for func in functions: |
13353 |
- logging.debug("\tRunning function: %s", func) |
13354 |
- _continue = func(**self.set_func_kwargs(mod, dynamic_data)) |
13355 |
- if _continue: |
13356 |
- # If we can't access all the metadata then it's totally unsafe to |
13357 |
- # commit since there's no way to generate a correct Manifest. |
13358 |
- # Do not try to do any more QA checks on this package since missing |
13359 |
- # metadata leads to false positives for several checks, and false |
13360 |
- # positives confuse users. |
13361 |
- # logging.debug("\t>>> Continuing") |
13362 |
- break |
13363 |
- |
13364 |
- logging.debug("Finished ebuild plugin loop, continuing...") |
13365 |
- |
13366 |
- # Final checks |
13367 |
- # initialize per pkg plugin final checks here |
13368 |
- # need to set it up for ==> self.modules_list or some other ordered list |
13369 |
- for mod in self.moduleconfig.final_loop: |
13370 |
- if mod: |
13371 |
- mod_class = self.moduleconfig.controller.get_class(mod) |
13372 |
- if mod_class.__name__ not in self.modules: |
13373 |
- logging.debug("Initializing class name: %s", mod_class.__name__) |
13374 |
- self.modules[mod_class.__name__] = mod_class(**self.set_kwargs(mod)) |
13375 |
- logging.debug("scan_ebuilds final checks: module: %s", mod_class.__name__) |
13376 |
- do_it, functions = self.modules[mod_class.__name__].runInFinal |
13377 |
- logging.debug( |
13378 |
- "do_it: %s, functions: %s", do_it, [x.__name__ for x in functions] |
13379 |
- ) |
13380 |
- if do_it: |
13381 |
- for func in functions: |
13382 |
- logging.debug("\tRunning function: %s", func) |
13383 |
- _continue = func(**self.set_func_kwargs(mod, dynamic_data)) |
13384 |
- if _continue: |
13385 |
- # logging.debug("\t>>> Continuing") |
13386 |
- break |
13387 |
|
13388 |
diff --git a/repoman/lib/repoman/tests/.gnupg/openpgp-revocs.d/06B3A311BD775C280D22A9305D90EA06352177F6.rev b/repoman/lib/repoman/tests/.gnupg/openpgp-revocs.d/06B3A311BD775C280D22A9305D90EA06352177F6.rev |
13389 |
deleted file mode 100644 |
13390 |
index a6752fd30..000000000 |
13391 |
--- a/repoman/lib/repoman/tests/.gnupg/openpgp-revocs.d/06B3A311BD775C280D22A9305D90EA06352177F6.rev |
13392 |
+++ /dev/null |
13393 |
@@ -1,37 +0,0 @@ |
13394 |
-This is a revocation certificate for the OpenPGP key: |
13395 |
- |
13396 |
-pub rsa4096 2020-07-14 [S] |
13397 |
- 06B3A311BD775C280D22A9305D90EA06352177F6 |
13398 |
-uid Gentoo Portage Test Trusted Key (Test Only, Do NOT Trust!!!) (Gentoo Test Key) <test@×××××××.org> |
13399 |
- |
13400 |
-A revocation certificate is a kind of "kill switch" to publicly |
13401 |
-declare that a key shall not anymore be used. It is not possible |
13402 |
-to retract such a revocation certificate once it has been published. |
13403 |
- |
13404 |
-Use it to revoke this key in case of a compromise or loss of |
13405 |
-the secret key. However, if the secret key is still accessible, |
13406 |
-it is better to generate a new revocation certificate and give |
13407 |
-a reason for the revocation. For details see the description of |
13408 |
-of the gpg command "--generate-revocation" in the GnuPG manual. |
13409 |
- |
13410 |
-To avoid an accidental use of this file, a colon has been inserted |
13411 |
-before the 5 dashes below. Remove this colon with a text editor |
13412 |
-before importing and publishing this revocation certificate. |
13413 |
- |
13414 |
-:-----BEGIN PGP PUBLIC KEY BLOCK----- |
13415 |
-Comment: This is a revocation certificate |
13416 |
- |
13417 |
-iQI2BCABCAAgFiEEBrOjEb13XCgNIqkwXZDqBjUhd/YFAl8OFTwCHQAACgkQXZDq |
13418 |
-BjUhd/aXCA/+OgzosMDaDe5DNwkSi2yKdC2X18v8JcaYnXBUR93nXA0LVN7iVWkR |
13419 |
-WEH3NuVspQZ5vK+3AHTKabqZFC/buA5oQOH01Ncd4lQISfOOhFiBn5DIPX31BVT0 |
13420 |
-iPmVkcxHAD4031ptP4oat6EFclT13SRchtlnAO04JofeHnzQIw3SozQGzXpAA1g4 |
13421 |
-BogQ0HWA88HzuEYYE+e/yzZL4D496X1DTaXksg0Py5c4SS6u5pND6lcUtAGxAwa9 |
13422 |
-sJFPs+coeURaRV99CrJfdh4u2OkvINTfrKOS6NFBQq6HVH5mLsRXZlcE4Oo4d+fN |
13423 |
-XoPrTZnRUqpJADUdjHFvO/lr0fArJTS5IQCVBNFeCMlvgmUPeKWJ1r6Uiwe/UHor |
13424 |
-9OP/tK97EqpsaXmHbo0jOUkn5iiUwy784+JBSSu/Q2NxqcBr74aaRdfxvs62dmv7 |
13425 |
-droCDQi3ebqTdnlDSaeCIWHyVlSroOhZ+ZETVy193K1X7VXFX3hYKiJ3G8QZwy3e |
13426 |
-AlsVGjIHWfC+K+enIn+uwSUvOWPN3upK8kqMRuXvAOppFCE4sTqNbxUnHHXaqo/r |
13427 |
-s1q6zVsWVILBk97BHlJph2IaqhV7iIgPU97/r4U/BT11VqDFdVSHcXcs4PDNs5vh |
13428 |
-6qttaDiyDqZjwMr+0iDoouHxFpqY8e+3M2gycUgGr2XV6ML0pXE6BqA= |
13429 |
-=nIjC |
13430 |
------END PGP PUBLIC KEY BLOCK----- |
13431 |
|
13432 |
diff --git a/repoman/lib/repoman/tests/.gnupg/openpgp-revocs.d/8DEDA2CDED49C8809287B89D8812797DDF1DD192.rev b/repoman/lib/repoman/tests/.gnupg/openpgp-revocs.d/8DEDA2CDED49C8809287B89D8812797DDF1DD192.rev |
13433 |
deleted file mode 100644 |
13434 |
index 456e0aa50..000000000 |
13435 |
--- a/repoman/lib/repoman/tests/.gnupg/openpgp-revocs.d/8DEDA2CDED49C8809287B89D8812797DDF1DD192.rev |
13436 |
+++ /dev/null |
13437 |
@@ -1,37 +0,0 @@ |
13438 |
-This is a revocation certificate for the OpenPGP key: |
13439 |
- |
13440 |
-pub rsa4096 2020-07-14 [S] |
13441 |
- 8DEDA2CDED49C8809287B89D8812797DDF1DD192 |
13442 |
-uid Gentoo Portage Test Untrusted Key (Test Only, Do NOT Trust!!!) (Gentoo Test Key) <test@×××××××.org> |
13443 |
- |
13444 |
-A revocation certificate is a kind of "kill switch" to publicly |
13445 |
-declare that a key shall not anymore be used. It is not possible |
13446 |
-to retract such a revocation certificate once it has been published. |
13447 |
- |
13448 |
-Use it to revoke this key in case of a compromise or loss of |
13449 |
-the secret key. However, if the secret key is still accessible, |
13450 |
-it is better to generate a new revocation certificate and give |
13451 |
-a reason for the revocation. For details see the description of |
13452 |
-of the gpg command "--generate-revocation" in the GnuPG manual. |
13453 |
- |
13454 |
-To avoid an accidental use of this file, a colon has been inserted |
13455 |
-before the 5 dashes below. Remove this colon with a text editor |
13456 |
-before importing and publishing this revocation certificate. |
13457 |
- |
13458 |
-:-----BEGIN PGP PUBLIC KEY BLOCK----- |
13459 |
-Comment: This is a revocation certificate |
13460 |
- |
13461 |
-iQI2BCABCAAgFiEEje2ize1JyICSh7idiBJ5fd8d0ZIFAl8OFXUCHQAACgkQiBJ5 |
13462 |
-fd8d0ZKdwxAAhmkC0V+OLyOU9PCV6ogD9/3b3nVqNIreoc+gxHTLmEvxiMSItqmq |
13463 |
-DkcW9RJKAduA/HiLZQ8Yzxw+ldC6kuWqYEjNpSM54VDkrgOePi8W1bVDTCoSp7bo |
13464 |
-0JOG4frieqIxA6lhAA2UppH7EPRXoODPLYqooNxWAs3xxVrR6eGAb5l8NXzrymvN |
13465 |
-acFfOZ0s5FgADQskQHWVq6TaJn9DrcZxd+b+plSwPYDXqzTChKQ5jw7uMAPUvDkG |
13466 |
-JUWgoKiKSrK64bslUq8aEDEZQ4uxjyEi6G0vO/wPL/ysGhS7KkPgCZsEfNjWjajb |
13467 |
-jAsdvl1raoHxK/O7llMNr9uRAZtC56pJ//SRDc3kylZrkAo0RNoXQFowT739HWei |
13468 |
-2UkCFDfz488VKKrOI8TzTyUvLFEo14ZAXGg1wdHaGnbYMzxpKjP15alOFo6fKIcS |
13469 |
-Kz1f/Mab4wf4Sg0XAjQ9pnai1/U9ZF3/NSnRtYgJkLCrIEtRLrgSHJsLDPxjCfGV |
13470 |
-jWszAbIk167aA0yKsSmuwkpc5bZqqBaTo904r857fxyt5Les6SOHsV7iNXt7F+am |
13471 |
-03Y6u6m2eROba7M67l115vTyYcw5EZVp5j0nI81PXsC9X2DD1ci5xrNmPyEeupC4 |
13472 |
-7y7mcGbUYPJAJHJ0kHG4ZYLnNMl42ZYr1ssEeasDwUsLWgVqvx9RkKI= |
13473 |
-=kVUQ |
13474 |
------END PGP PUBLIC KEY BLOCK----- |
13475 |
|
13476 |
diff --git a/repoman/lib/repoman/tests/.gnupg/private-keys-v1.d/273B030399E7BEA66A9AD42216DE7CA17BA5D42E.key b/repoman/lib/repoman/tests/.gnupg/private-keys-v1.d/273B030399E7BEA66A9AD42216DE7CA17BA5D42E.key |
13477 |
deleted file mode 100644 |
13478 |
index 0bd1026ad..000000000 |
13479 |
Binary files a/repoman/lib/repoman/tests/.gnupg/private-keys-v1.d/273B030399E7BEA66A9AD42216DE7CA17BA5D42E.key and /dev/null differ |
13480 |
|
13481 |
diff --git a/repoman/lib/repoman/tests/.gnupg/private-keys-v1.d/C99796FB85B0C3DF03314A11B5850C51167D6282.key b/repoman/lib/repoman/tests/.gnupg/private-keys-v1.d/C99796FB85B0C3DF03314A11B5850C51167D6282.key |
13482 |
deleted file mode 100644 |
13483 |
index 8e29ef43c..000000000 |
13484 |
Binary files a/repoman/lib/repoman/tests/.gnupg/private-keys-v1.d/C99796FB85B0C3DF03314A11B5850C51167D6282.key and /dev/null differ |
13485 |
|
13486 |
diff --git a/repoman/lib/repoman/tests/.gnupg/pubring.kbx b/repoman/lib/repoman/tests/.gnupg/pubring.kbx |
13487 |
deleted file mode 100644 |
13488 |
index f6367f83b..000000000 |
13489 |
Binary files a/repoman/lib/repoman/tests/.gnupg/pubring.kbx and /dev/null differ |
13490 |
|
13491 |
diff --git a/repoman/lib/repoman/tests/.gnupg/trustdb.gpg b/repoman/lib/repoman/tests/.gnupg/trustdb.gpg |
13492 |
deleted file mode 100644 |
13493 |
index db5b1023b..000000000 |
13494 |
Binary files a/repoman/lib/repoman/tests/.gnupg/trustdb.gpg and /dev/null differ |
13495 |
|
13496 |
diff --git a/repoman/lib/repoman/tests/__init__.py b/repoman/lib/repoman/tests/__init__.py |
13497 |
deleted file mode 100644 |
13498 |
index ba0872c5b..000000000 |
13499 |
--- a/repoman/lib/repoman/tests/__init__.py |
13500 |
+++ /dev/null |
13501 |
@@ -1,328 +0,0 @@ |
13502 |
-# tests/__init__.py -- Portage Unit Test functionality |
13503 |
-# Copyright 2006-2021 Gentoo Authors |
13504 |
-# Distributed under the terms of the GNU General Public License v2 |
13505 |
- |
13506 |
-import argparse |
13507 |
-import sys |
13508 |
-import time |
13509 |
-import unittest |
13510 |
- |
13511 |
-from unittest.runner import TextTestResult as _TextTestResult |
13512 |
- |
13513 |
-import repoman |
13514 |
-from repoman import REPOMAN_BASE_PATH |
13515 |
-from repoman._portage import portage |
13516 |
- |
13517 |
-from portage import os |
13518 |
-from portage import _encodings |
13519 |
-from portage import _unicode_decode |
13520 |
-from portage.const import EPREFIX, GLOBAL_CONFIG_PATH, PORTAGE_BIN_PATH |
13521 |
- |
13522 |
-if repoman._not_installed: |
13523 |
- cnf_path = os.path.join(REPOMAN_BASE_PATH, "cnf") |
13524 |
- cnf_path_repoman = cnf_path |
13525 |
- cnf_etc_path = cnf_path |
13526 |
- cnf_bindir = os.path.join(REPOMAN_BASE_PATH, "bin") |
13527 |
- cnf_sbindir = cnf_bindir |
13528 |
-else: |
13529 |
- cnf_path = os.path.join(EPREFIX or "/", GLOBAL_CONFIG_PATH) |
13530 |
- cnf_path_repoman = os.path.join( |
13531 |
- EPREFIX or "/", sys.prefix.lstrip(os.sep), "share", "repoman" |
13532 |
- ) |
13533 |
- cnf_etc_path = os.path.join(EPREFIX or "/", "etc") |
13534 |
- cnf_eprefix = EPREFIX |
13535 |
- cnf_bindir = os.path.join(EPREFIX or "/", "usr", "bin") |
13536 |
- cnf_sbindir = os.path.join(EPREFIX or "/", "usr", "sbin") |
13537 |
- |
13538 |
- |
13539 |
-def main(): |
13540 |
- suite = unittest.TestSuite() |
13541 |
- basedir = os.path.dirname(os.path.realpath(__file__)) |
13542 |
- |
13543 |
- usage = "usage: %s [options] [tests to run]" % os.path.basename(sys.argv[0]) |
13544 |
- parser = argparse.ArgumentParser(usage=usage) |
13545 |
- parser.add_argument( |
13546 |
- "-l", "--list", help="list all tests", action="store_true", dest="list_tests" |
13547 |
- ) |
13548 |
- options, args = parser.parse_known_args(args=sys.argv) |
13549 |
- |
13550 |
- if ( |
13551 |
- os.environ.get("NOCOLOR") in ("yes", "true") |
13552 |
- or os.environ.get("TERM") == "dumb" |
13553 |
- or not sys.stdout.isatty() |
13554 |
- ): |
13555 |
- portage.output.nocolor() |
13556 |
- |
13557 |
- if options.list_tests: |
13558 |
- testdir = os.path.dirname(sys.argv[0]) |
13559 |
- for mydir in getTestDirs(basedir): |
13560 |
- testsubdir = os.path.basename(mydir) |
13561 |
- for name in getTestNames(mydir): |
13562 |
- print("%s/%s/%s.py" % (testdir, testsubdir, name)) |
13563 |
- return os.EX_OK |
13564 |
- |
13565 |
- if len(args) > 1: |
13566 |
- suite.addTests(getTestFromCommandLine(args[1:], basedir)) |
13567 |
- else: |
13568 |
- for mydir in getTestDirs(basedir): |
13569 |
- suite.addTests(getTests(os.path.join(basedir, mydir), basedir)) |
13570 |
- |
13571 |
- result = TextTestRunner(verbosity=2).run(suite) |
13572 |
- if not result.wasSuccessful(): |
13573 |
- return 1 |
13574 |
- return os.EX_OK |
13575 |
- |
13576 |
- |
13577 |
-def my_import(name): |
13578 |
- mod = __import__(name) |
13579 |
- components = name.split(".") |
13580 |
- for comp in components[1:]: |
13581 |
- mod = getattr(mod, comp) |
13582 |
- return mod |
13583 |
- |
13584 |
- |
13585 |
-def getTestFromCommandLine(args, base_path): |
13586 |
- result = [] |
13587 |
- for arg in args: |
13588 |
- realpath = os.path.realpath(arg) |
13589 |
- path = os.path.dirname(realpath) |
13590 |
- f = realpath[len(path) + 1 :] |
13591 |
- |
13592 |
- if not f.startswith("test") or not f.endswith(".py"): |
13593 |
- raise Exception("Invalid argument: '%s'" % arg) |
13594 |
- |
13595 |
- mymodule = f[:-3] |
13596 |
- result.extend(getTestsFromFiles(path, base_path, [mymodule])) |
13597 |
- return result |
13598 |
- |
13599 |
- |
13600 |
-def getTestDirs(base_path): |
13601 |
- TEST_FILE = b"__test__.py" |
13602 |
- testDirs = [] |
13603 |
- |
13604 |
- # the os.walk help mentions relative paths as being quirky |
13605 |
- # I was tired of adding dirs to the list, so now we add __test__.py |
13606 |
- # to each dir we want tested. |
13607 |
- for root, dirs, files in os.walk(base_path): |
13608 |
- try: |
13609 |
- root = _unicode_decode(root, encoding=_encodings["fs"], errors="strict") |
13610 |
- except UnicodeDecodeError: |
13611 |
- continue |
13612 |
- |
13613 |
- if TEST_FILE in files: |
13614 |
- testDirs.append(root) |
13615 |
- |
13616 |
- testDirs.sort() |
13617 |
- return testDirs |
13618 |
- |
13619 |
- |
13620 |
-def getTestNames(path): |
13621 |
- files = os.listdir(path) |
13622 |
- files = [f[:-3] for f in files if f.startswith("test") and f.endswith(".py")] |
13623 |
- files.sort() |
13624 |
- return files |
13625 |
- |
13626 |
- |
13627 |
-def getTestsFromFiles(path, base_path, files): |
13628 |
- parent_path = path[len(base_path) + 1 :] |
13629 |
- parent_module = ".".join(("repoman", "tests", parent_path)) |
13630 |
- parent_module = parent_module.replace("/", ".") |
13631 |
- result = [] |
13632 |
- for mymodule in files: |
13633 |
- # Make the trailing / a . for module importing |
13634 |
- modname = ".".join((parent_module, mymodule)) |
13635 |
- mod = my_import(modname) |
13636 |
- result.append(unittest.TestLoader().loadTestsFromModule(mod)) |
13637 |
- return result |
13638 |
- |
13639 |
- |
13640 |
-def getTests(path, base_path): |
13641 |
- """ |
13642 |
- |
13643 |
- path is the path to a given subdir ( 'portage/' for example) |
13644 |
- This does a simple filter on files in that dir to give us modules |
13645 |
- to import |
13646 |
- |
13647 |
- """ |
13648 |
- return getTestsFromFiles(path, base_path, getTestNames(path)) |
13649 |
- |
13650 |
- |
13651 |
-class TextTestResult(_TextTestResult): |
13652 |
- """ |
13653 |
- We need a subclass of unittest.runner.TextTestResult to handle tests with TODO |
13654 |
- |
13655 |
- This just adds an addTodo method that can be used to add tests |
13656 |
- that are marked TODO; these can be displayed later |
13657 |
- by the test runner. |
13658 |
- """ |
13659 |
- |
13660 |
- def __init__(self, stream, descriptions, verbosity): |
13661 |
- super(TextTestResult, self).__init__(stream, descriptions, verbosity) |
13662 |
- self.todoed = [] |
13663 |
- self.portage_skipped = [] |
13664 |
- |
13665 |
- def addTodo(self, test, info): |
13666 |
- self.todoed.append((test, info)) |
13667 |
- if self.showAll: |
13668 |
- self.stream.writeln("TODO") |
13669 |
- elif self.dots: |
13670 |
- self.stream.write(".") |
13671 |
- |
13672 |
- def addPortageSkip(self, test, info): |
13673 |
- self.portage_skipped.append((test, info)) |
13674 |
- if self.showAll: |
13675 |
- self.stream.writeln("SKIP") |
13676 |
- elif self.dots: |
13677 |
- self.stream.write(".") |
13678 |
- |
13679 |
- def printErrors(self): |
13680 |
- if self.dots or self.showAll: |
13681 |
- self.stream.writeln() |
13682 |
- self.printErrorList("ERROR", self.errors) |
13683 |
- self.printErrorList("FAIL", self.failures) |
13684 |
- self.printErrorList("TODO", self.todoed) |
13685 |
- self.printErrorList("SKIP", self.portage_skipped) |
13686 |
- |
13687 |
- |
13688 |
-class TestCase(unittest.TestCase): |
13689 |
- """ |
13690 |
- We need a way to mark a unit test as "ok to fail" |
13691 |
- This way someone can add a broken test and mark it as failed |
13692 |
- and then fix the code later. This may not be a great approach |
13693 |
- (broken code!!??!11oneone) but it does happen at times. |
13694 |
- """ |
13695 |
- |
13696 |
- def __init__(self, *pargs, **kwargs): |
13697 |
- unittest.TestCase.__init__(self, *pargs, **kwargs) |
13698 |
- self.todo = False |
13699 |
- self.portage_skip = None |
13700 |
- self.cnf_path = cnf_path |
13701 |
- self.cnf_etc_path = cnf_etc_path |
13702 |
- self.bindir = cnf_bindir |
13703 |
- self.sbindir = cnf_sbindir |
13704 |
- |
13705 |
- def defaultTestResult(self): |
13706 |
- return TextTestResult() |
13707 |
- |
13708 |
- def run(self, result=None): |
13709 |
- if result is None: |
13710 |
- result = self.defaultTestResult() |
13711 |
- result.startTest(self) |
13712 |
- testMethod = getattr(self, self._testMethodName) |
13713 |
- try: |
13714 |
- try: |
13715 |
- self.setUp() |
13716 |
- except SystemExit: |
13717 |
- raise |
13718 |
- except KeyboardInterrupt: |
13719 |
- raise |
13720 |
- except: |
13721 |
- result.addError(self, sys.exc_info()) |
13722 |
- return |
13723 |
- |
13724 |
- ok = False |
13725 |
- try: |
13726 |
- testMethod() |
13727 |
- ok = True |
13728 |
- except unittest.SkipTest as e: |
13729 |
- result.addPortageSkip(self, "%s: SKIP: %s" % (testMethod, str(e))) |
13730 |
- except self.failureException: |
13731 |
- if self.portage_skip is not None: |
13732 |
- if self.portage_skip is True: |
13733 |
- result.addPortageSkip(self, "%s: SKIP" % testMethod) |
13734 |
- else: |
13735 |
- result.addPortageSkip( |
13736 |
- self, "%s: SKIP: %s" % (testMethod, self.portage_skip) |
13737 |
- ) |
13738 |
- elif self.todo: |
13739 |
- result.addTodo(self, "%s: TODO" % testMethod) |
13740 |
- else: |
13741 |
- result.addFailure(self, sys.exc_info()) |
13742 |
- except (KeyboardInterrupt, SystemExit): |
13743 |
- raise |
13744 |
- except: |
13745 |
- result.addError(self, sys.exc_info()) |
13746 |
- |
13747 |
- try: |
13748 |
- self.tearDown() |
13749 |
- except SystemExit: |
13750 |
- raise |
13751 |
- except KeyboardInterrupt: |
13752 |
- raise |
13753 |
- except: |
13754 |
- result.addError(self, sys.exc_info()) |
13755 |
- ok = False |
13756 |
- if ok: |
13757 |
- result.addSuccess(self) |
13758 |
- finally: |
13759 |
- result.stopTest(self) |
13760 |
- |
13761 |
- def assertRaisesMsg(self, msg, excClass, callableObj, *args, **kwargs): |
13762 |
- """Fail unless an exception of class excClass is thrown |
13763 |
- by callableObj when invoked with arguments args and keyword |
13764 |
- arguments kwargs. If a different type of exception is |
13765 |
- thrown, it will not be caught, and the test case will be |
13766 |
- deemed to have suffered an error, exactly as for an |
13767 |
- unexpected exception. |
13768 |
- """ |
13769 |
- try: |
13770 |
- callableObj(*args, **kwargs) |
13771 |
- except excClass: |
13772 |
- return |
13773 |
- else: |
13774 |
- if hasattr(excClass, "__name__"): |
13775 |
- excName = excClass.__name__ |
13776 |
- else: |
13777 |
- excName = str(excClass) |
13778 |
- raise self.failureException("%s not raised: %s" % (excName, msg)) |
13779 |
- |
13780 |
- def assertNotExists(self, path): |
13781 |
- """Make sure |path| does not exist""" |
13782 |
- if os.path.exists(path): |
13783 |
- raise self.failureException("path exists when it should not: %s" % path) |
13784 |
- |
13785 |
- |
13786 |
-class TextTestRunner(unittest.TextTestRunner): |
13787 |
- """ |
13788 |
- We subclass unittest.TextTestRunner to output SKIP for tests that fail but are skippable |
13789 |
- """ |
13790 |
- |
13791 |
- def _makeResult(self): |
13792 |
- return TextTestResult(self.stream, self.descriptions, self.verbosity) |
13793 |
- |
13794 |
- def run(self, test): |
13795 |
- """ |
13796 |
- Run the given test case or test suite. |
13797 |
- """ |
13798 |
- result = self._makeResult() |
13799 |
- startTime = time.time() |
13800 |
- test(result) |
13801 |
- stopTime = time.time() |
13802 |
- timeTaken = stopTime - startTime |
13803 |
- result.printErrors() |
13804 |
- self.stream.writeln(result.separator2) |
13805 |
- run = result.testsRun |
13806 |
- self.stream.writeln( |
13807 |
- "Ran %d test%s in %.3fs" % (run, run != 1 and "s" or "", timeTaken) |
13808 |
- ) |
13809 |
- self.stream.writeln() |
13810 |
- if not result.wasSuccessful(): |
13811 |
- self.stream.write("FAILED (") |
13812 |
- failed = len(result.failures) |
13813 |
- errored = len(result.errors) |
13814 |
- if failed: |
13815 |
- self.stream.write("failures=%d" % failed) |
13816 |
- if errored: |
13817 |
- if failed: |
13818 |
- self.stream.write(", ") |
13819 |
- self.stream.write("errors=%d" % errored) |
13820 |
- self.stream.writeln(")") |
13821 |
- else: |
13822 |
- self.stream.writeln("OK") |
13823 |
- return result |
13824 |
- |
13825 |
- |
13826 |
-test_cps = ["sys-apps/portage", "virtual/portage"] |
13827 |
-test_versions = ["1.0", "1.0-r1", "2.3_p4", "1.0_alpha57"] |
13828 |
-test_slots = [None, "1", "gentoo-sources-2.6.17", "spankywashere"] |
13829 |
-test_usedeps = ["foo", "-bar", ("foo", "bar"), ("foo", "-bar"), ("foo?", "!bar?")] |
13830 |
|
13831 |
diff --git a/repoman/lib/repoman/tests/__test__.py b/repoman/lib/repoman/tests/__test__.py |
13832 |
deleted file mode 100644 |
13833 |
index e69de29bb..000000000 |
13834 |
|
13835 |
diff --git a/repoman/lib/repoman/tests/changelog/__init__.py b/repoman/lib/repoman/tests/changelog/__init__.py |
13836 |
deleted file mode 100644 |
13837 |
index 532918b6a..000000000 |
13838 |
--- a/repoman/lib/repoman/tests/changelog/__init__.py |
13839 |
+++ /dev/null |
13840 |
@@ -1,2 +0,0 @@ |
13841 |
-# Copyright 2011 Gentoo Foundation |
13842 |
-# Distributed under the terms of the GNU General Public License v2 |
13843 |
|
13844 |
diff --git a/repoman/lib/repoman/tests/changelog/__test__.py b/repoman/lib/repoman/tests/changelog/__test__.py |
13845 |
deleted file mode 100644 |
13846 |
index e69de29bb..000000000 |
13847 |
|
13848 |
diff --git a/repoman/lib/repoman/tests/changelog/test_echangelog.py b/repoman/lib/repoman/tests/changelog/test_echangelog.py |
13849 |
deleted file mode 100644 |
13850 |
index f0c43e20b..000000000 |
13851 |
--- a/repoman/lib/repoman/tests/changelog/test_echangelog.py |
13852 |
+++ /dev/null |
13853 |
@@ -1,169 +0,0 @@ |
13854 |
-# Copyright 2012 Gentoo Foundation |
13855 |
-# Distributed under the terms of the GNU General Public License v2 |
13856 |
- |
13857 |
-import tempfile |
13858 |
-import time |
13859 |
- |
13860 |
-from portage import os |
13861 |
-from portage import shutil |
13862 |
-from portage.tests import TestCase |
13863 |
-from repoman.utilities import UpdateChangeLog |
13864 |
- |
13865 |
- |
13866 |
-class RepomanEchangelogTestCase(TestCase): |
13867 |
- def setUp(self): |
13868 |
- super(RepomanEchangelogTestCase, self).setUp() |
13869 |
- |
13870 |
- self.tmpdir = tempfile.mkdtemp(prefix="repoman.echangelog.") |
13871 |
- |
13872 |
- self.skel_changelog = os.path.join(self.tmpdir, "skel.ChangeLog") |
13873 |
- skel = [ |
13874 |
- "# ChangeLog for <CATEGORY>/<PACKAGE_NAME>\n", |
13875 |
- "# Copyright 1999-2000 Gentoo Foundation; Distributed under the GPL v2\n", |
13876 |
- "# $Header: $\n", |
13877 |
- ] |
13878 |
- self._writelines(self.skel_changelog, skel) |
13879 |
- |
13880 |
- self.cat = "mycat" |
13881 |
- self.pkg = "mypkg" |
13882 |
- self.pkgdir = os.path.join(self.tmpdir, self.cat, self.pkg) |
13883 |
- os.makedirs(self.pkgdir) |
13884 |
- |
13885 |
- self.header_pkg = "# ChangeLog for %s/%s\n" % (self.cat, self.pkg) |
13886 |
- self.header_copyright = ( |
13887 |
- "# Copyright 1999-%s Gentoo Authors; Distributed under the GPL v2\n" |
13888 |
- % time.strftime("%Y", time.gmtime()) |
13889 |
- ) |
13890 |
- self.header_cvs = "# $Header: $\n" |
13891 |
- |
13892 |
- self.changelog = os.path.join(self.pkgdir, "ChangeLog") |
13893 |
- |
13894 |
- self.user = "Testing User <portage@g.o>" |
13895 |
- |
13896 |
- def tearDown(self): |
13897 |
- super(RepomanEchangelogTestCase, self).tearDown() |
13898 |
- shutil.rmtree(self.tmpdir) |
13899 |
- |
13900 |
- def _readlines(self, file): |
13901 |
- with open(file, "r") as f: |
13902 |
- return f.readlines() |
13903 |
- |
13904 |
- def _writelines(self, file, data): |
13905 |
- with open(file, "w") as f: |
13906 |
- f.writelines(data) |
13907 |
- |
13908 |
- def testRejectRootUser(self): |
13909 |
- self.assertEqual( |
13910 |
- UpdateChangeLog( |
13911 |
- self.pkgdir, "me <root@g.o>", "", "", "", "", quiet=True |
13912 |
- ), |
13913 |
- None, |
13914 |
- ) |
13915 |
- |
13916 |
- def testMissingSkelFile(self): |
13917 |
- # Test missing ChangeLog, but with empty skel (i.e. do nothing). |
13918 |
- UpdateChangeLog( |
13919 |
- self.pkgdir, |
13920 |
- self.user, |
13921 |
- "test!", |
13922 |
- "/does/not/exist", |
13923 |
- self.cat, |
13924 |
- self.pkg, |
13925 |
- quiet=True, |
13926 |
- ) |
13927 |
- actual_cl = self._readlines(self.changelog) |
13928 |
- self.assertTrue(len(actual_cl[0]) > 0) |
13929 |
- |
13930 |
- def testEmptyChangeLog(self): |
13931 |
- # Make sure we do the right thing with a 0-byte ChangeLog |
13932 |
- open(self.changelog, "w").close() |
13933 |
- UpdateChangeLog( |
13934 |
- self.pkgdir, |
13935 |
- self.user, |
13936 |
- "test!", |
13937 |
- self.skel_changelog, |
13938 |
- self.cat, |
13939 |
- self.pkg, |
13940 |
- quiet=True, |
13941 |
- ) |
13942 |
- actual_cl = self._readlines(self.changelog) |
13943 |
- self.assertEqual(actual_cl[0], self.header_pkg) |
13944 |
- self.assertEqual(actual_cl[1], self.header_copyright) |
13945 |
- self.assertEqual(actual_cl[2], self.header_cvs) |
13946 |
- |
13947 |
- def testCopyrightUpdate(self): |
13948 |
- # Make sure updating the copyright line works |
13949 |
- UpdateChangeLog( |
13950 |
- self.pkgdir, |
13951 |
- self.user, |
13952 |
- "test!", |
13953 |
- self.skel_changelog, |
13954 |
- self.cat, |
13955 |
- self.pkg, |
13956 |
- quiet=True, |
13957 |
- ) |
13958 |
- actual_cl = self._readlines(self.changelog) |
13959 |
- self.assertEqual(actual_cl[1], self.header_copyright) |
13960 |
- |
13961 |
- def testSkelHeader(self): |
13962 |
- # Test skel.ChangeLog -> ChangeLog |
13963 |
- UpdateChangeLog( |
13964 |
- self.pkgdir, |
13965 |
- self.user, |
13966 |
- "test!", |
13967 |
- self.skel_changelog, |
13968 |
- self.cat, |
13969 |
- self.pkg, |
13970 |
- quiet=True, |
13971 |
- ) |
13972 |
- actual_cl = self._readlines(self.changelog) |
13973 |
- self.assertEqual(actual_cl[0], self.header_pkg) |
13974 |
- self.assertNotEqual(actual_cl[-1], "\n") |
13975 |
- |
13976 |
- def testExistingGoodHeader(self): |
13977 |
- # Test existing ChangeLog (correct values) |
13978 |
- self._writelines(self.changelog, [self.header_pkg]) |
13979 |
- |
13980 |
- UpdateChangeLog( |
13981 |
- self.pkgdir, |
13982 |
- self.user, |
13983 |
- "test!", |
13984 |
- self.skel_changelog, |
13985 |
- self.cat, |
13986 |
- self.pkg, |
13987 |
- quiet=True, |
13988 |
- ) |
13989 |
- actual_cl = self._readlines(self.changelog) |
13990 |
- self.assertEqual(actual_cl[0], self.header_pkg) |
13991 |
- |
13992 |
- def testExistingBadHeader(self): |
13993 |
- # Test existing ChangeLog (wrong values) |
13994 |
- self._writelines(self.changelog, ["# ChangeLog for \n"]) |
13995 |
- |
13996 |
- UpdateChangeLog( |
13997 |
- self.pkgdir, |
13998 |
- self.user, |
13999 |
- "test!", |
14000 |
- self.skel_changelog, |
14001 |
- self.cat, |
14002 |
- self.pkg, |
14003 |
- quiet=True, |
14004 |
- ) |
14005 |
- actual_cl = self._readlines(self.changelog) |
14006 |
- self.assertEqual(actual_cl[0], self.header_pkg) |
14007 |
- |
14008 |
- def testTrailingNewlines(self): |
14009 |
- # Make sure trailing newlines get chomped. |
14010 |
- self._writelines(self.changelog, ["#\n", "foo\n", "\n", "bar\n", "\n", "\n"]) |
14011 |
- |
14012 |
- UpdateChangeLog( |
14013 |
- self.pkgdir, |
14014 |
- self.user, |
14015 |
- "test!", |
14016 |
- self.skel_changelog, |
14017 |
- self.cat, |
14018 |
- self.pkg, |
14019 |
- quiet=True, |
14020 |
- ) |
14021 |
- actual_cl = self._readlines(self.changelog) |
14022 |
- self.assertNotEqual(actual_cl[-1], "\n") |
14023 |
|
14024 |
diff --git a/repoman/lib/repoman/tests/commit/__init__.py b/repoman/lib/repoman/tests/commit/__init__.py |
14025 |
deleted file mode 100644 |
14026 |
index d74fd94a7..000000000 |
14027 |
--- a/repoman/lib/repoman/tests/commit/__init__.py |
14028 |
+++ /dev/null |
14029 |
@@ -1,2 +0,0 @@ |
14030 |
-# Copyright 2011-2018 Gentoo Foundation |
14031 |
-# Distributed under the terms of the GNU General Public License v2 |
14032 |
|
14033 |
diff --git a/repoman/lib/repoman/tests/commit/__test__.py b/repoman/lib/repoman/tests/commit/__test__.py |
14034 |
deleted file mode 100644 |
14035 |
index e69de29bb..000000000 |
14036 |
|
14037 |
diff --git a/repoman/lib/repoman/tests/commit/test_commitmsg.py b/repoman/lib/repoman/tests/commit/test_commitmsg.py |
14038 |
deleted file mode 100644 |
14039 |
index 392d17cb3..000000000 |
14040 |
--- a/repoman/lib/repoman/tests/commit/test_commitmsg.py |
14041 |
+++ /dev/null |
14042 |
@@ -1,155 +0,0 @@ |
14043 |
-# Copyright 2011-2018 Gentoo Foundation |
14044 |
-# Distributed under the terms of the GNU General Public License v2 |
14045 |
- |
14046 |
-from repoman.actions import Actions |
14047 |
-from repoman.tests import TestCase |
14048 |
- |
14049 |
- |
14050 |
-class CommitMessageVerificationTest(TestCase): |
14051 |
- def assertGood(self, commitmsg): |
14052 |
- res, expl = Actions.verify_commit_message(commitmsg) |
14053 |
- self.assertTrue( |
14054 |
- res, |
14055 |
- """Commit message verification failed for: |
14056 |
-%s |
14057 |
- |
14058 |
-Error: |
14059 |
-%s""" |
14060 |
- % (commitmsg, expl), |
14061 |
- ) |
14062 |
- |
14063 |
- def assertBad(self, commitmsg, reason_re): |
14064 |
- res, expl = Actions.verify_commit_message(commitmsg) |
14065 |
- self.assertFalse( |
14066 |
- res, |
14067 |
- """Commit message verification succeeded unexpectedly, for: |
14068 |
-%s |
14069 |
- |
14070 |
-Expected: /%s/""" |
14071 |
- % (commitmsg, reason_re), |
14072 |
- ) |
14073 |
- self.assertNotIn( |
14074 |
- "\n", |
14075 |
- expl.strip(), |
14076 |
- """Commit message verification returned multiple errors (one expected): |
14077 |
-%s |
14078 |
- |
14079 |
-Expected: /%s/ |
14080 |
-Errors: |
14081 |
-%s""" |
14082 |
- % (commitmsg, reason_re, expl), |
14083 |
- ) |
14084 |
- ( |
14085 |
- self.assertRegex |
14086 |
- if hasattr(self, "assertRegex") |
14087 |
- else self.assertRegexpMatches |
14088 |
- )( |
14089 |
- expl, |
14090 |
- reason_re, |
14091 |
- """Commit message verification did not return expected error, for: |
14092 |
-%s |
14093 |
- |
14094 |
-Expected: /%s/ |
14095 |
-Errors: |
14096 |
-%s""" |
14097 |
- % (commitmsg, reason_re, expl), |
14098 |
- ) |
14099 |
- |
14100 |
- def test_summary_only(self): |
14101 |
- self.assertGood("dev-foo/bar: Actually good commit message") |
14102 |
- |
14103 |
- def test_summary_and_body(self): |
14104 |
- self.assertGood( |
14105 |
- """dev-foo/bar: Good commit message |
14106 |
- |
14107 |
-Extended description goes here and is properly wrapped at 72 characters |
14108 |
-which is very nice and blah blah. |
14109 |
- |
14110 |
-Another paragraph for the sake of having one.""" |
14111 |
- ) |
14112 |
- |
14113 |
- def test_summary_and_footer(self): |
14114 |
- self.assertGood( |
14115 |
- """dev-foo/bar: Good commit message |
14116 |
- |
14117 |
-Closes: https://bugs.gentoo.org/NNNNNN""" |
14118 |
- ) |
14119 |
- |
14120 |
- def test_summary_body_and_footer(self): |
14121 |
- self.assertGood( |
14122 |
- """dev-foo/bar: Good commit message |
14123 |
- |
14124 |
-Extended description goes here and is properly wrapped at 72 characters |
14125 |
-which is very nice and blah blah. |
14126 |
- |
14127 |
-Another paragraph for the sake of having one. |
14128 |
- |
14129 |
-Closes: https://bugs.gentoo.org/NNNNNN""" |
14130 |
- ) |
14131 |
- |
14132 |
- def test_summary_without_unit_name(self): |
14133 |
- self.assertBad("Version bump", r"summary.*logical unit name") |
14134 |
- |
14135 |
- def test_multiline_summary(self): |
14136 |
- self.assertBad( |
14137 |
- """dev-foo/bar: Commit message with very long summary |
14138 |
-that got wrapped because of length""", |
14139 |
- r"single.*line.*summary", |
14140 |
- ) |
14141 |
- |
14142 |
- def test_overlong_summary(self): |
14143 |
- self.assertBad( |
14144 |
- "dev-foo/bar: Commit message with very long summary \ |
14145 |
-in a single line that should trigger an explicit error", |
14146 |
- r"summary.*too long", |
14147 |
- ) |
14148 |
- |
14149 |
- def test_summary_with_very_long_package_name(self): |
14150 |
- self.assertGood( |
14151 |
- "dev-foo/foo-bar-bar-baz-bar-bar-foo-bar-bar-\ |
14152 |
-baz-foo-baz-baz-foo: We do not fail because pkgname was long" |
14153 |
- ) |
14154 |
- |
14155 |
- def test_multiple_footers(self): |
14156 |
- self.assertBad( |
14157 |
- """dev-foo/bar: Good summary |
14158 |
- |
14159 |
-Bug: https://bugs.gentoo.org/NNNNNN |
14160 |
- |
14161 |
-Closes: https://github.com/gentoo/gentoo/pull/NNNN""", |
14162 |
- r"multiple footer", |
14163 |
- ) |
14164 |
- |
14165 |
- def test_gentoo_bug(self): |
14166 |
- self.assertBad( |
14167 |
- """dev-foo/bar: Good summary |
14168 |
- |
14169 |
-Gentoo-Bug: NNNNNN""", |
14170 |
- r"Gentoo-Bug", |
14171 |
- ) |
14172 |
- |
14173 |
- def test_bug_with_number(self): |
14174 |
- self.assertBad( |
14175 |
- """dev-foo/bar: Good summary |
14176 |
- |
14177 |
-Bug: NNNNNN""", |
14178 |
- r"Bug.*full URL", |
14179 |
- ) |
14180 |
- |
14181 |
- def test_closes_with_number(self): |
14182 |
- self.assertBad( |
14183 |
- """dev-foo/bar: Good summary |
14184 |
- |
14185 |
-Closes: NNNNNN""", |
14186 |
- r"Closes.*full URL", |
14187 |
- ) |
14188 |
- |
14189 |
- def test_body_too_long(self): |
14190 |
- self.assertBad( |
14191 |
- """dev-foo/bar: Good summary |
14192 |
- |
14193 |
-But the body is not wrapped properly and has very long lines that are \ |
14194 |
-very hard to read and blah blah blah |
14195 |
-blah blah.""", |
14196 |
- r"body.*wrapped", |
14197 |
- ) |
14198 |
|
14199 |
diff --git a/repoman/lib/repoman/tests/runTests.py b/repoman/lib/repoman/tests/runTests.py |
14200 |
deleted file mode 100644 |
14201 |
index 4a081551e..000000000 |
14202 |
--- a/repoman/lib/repoman/tests/runTests.py |
14203 |
+++ /dev/null |
14204 |
@@ -1,85 +0,0 @@ |
14205 |
-#!/usr/bin/env python |
14206 |
-# runTests.py -- Portage Unit Test Functionality |
14207 |
-# Copyright 2006-2021 Gentoo Authors |
14208 |
-# Distributed under the terms of the GNU General Public License v2 |
14209 |
- |
14210 |
-import os |
14211 |
-import os.path as osp |
14212 |
-import sys |
14213 |
-import grp |
14214 |
-import platform |
14215 |
-import pwd |
14216 |
-import signal |
14217 |
-import tempfile |
14218 |
-from distutils.dir_util import copy_tree |
14219 |
- |
14220 |
- |
14221 |
-def debug_signal(signum, frame): |
14222 |
- import pdb |
14223 |
- |
14224 |
- pdb.set_trace() |
14225 |
- |
14226 |
- |
14227 |
-if platform.python_implementation() == "Jython": |
14228 |
- debug_signum = signal.SIGUSR2 # bug #424259 |
14229 |
-else: |
14230 |
- debug_signum = signal.SIGUSR1 |
14231 |
- |
14232 |
-signal.signal(debug_signum, debug_signal) |
14233 |
- |
14234 |
-# Pretend that the current user's uid/gid are the 'portage' uid/gid, |
14235 |
-# so things go smoothly regardless of the current user and global |
14236 |
-# user/group configuration. |
14237 |
-os.environ["PORTAGE_USERNAME"] = pwd.getpwuid(os.getuid()).pw_name |
14238 |
-os.environ["PORTAGE_GRPNAME"] = grp.getgrgid(os.getgid()).gr_name |
14239 |
- |
14240 |
-# Insert our parent dir so we can do shiny import "tests" |
14241 |
-# This line courtesy of Marienz and Pkgcore ;) |
14242 |
-repoman_pym = osp.dirname(osp.dirname(osp.dirname(osp.realpath(__file__)))) |
14243 |
-sys.path.insert(0, repoman_pym) |
14244 |
- |
14245 |
-# Add in the parent portage python modules |
14246 |
-portage_pym = osp.dirname(osp.dirname(repoman_pym)) + "/lib" |
14247 |
-sys.path.insert(0, portage_pym) |
14248 |
- |
14249 |
-# import our centrally initialized portage instance |
14250 |
-from repoman._portage import portage |
14251 |
- |
14252 |
-portage._internal_caller = True |
14253 |
-import repoman.tests as tests |
14254 |
- |
14255 |
-# Ensure that we don't instantiate portage.settings, so that tests should |
14256 |
-# work the same regardless of global configuration file state/existence. |
14257 |
-portage._disable_legacy_globals() |
14258 |
-from portage.util._eventloop.global_event_loop import global_event_loop |
14259 |
-from portage.const import PORTAGE_BIN_PATH |
14260 |
- |
14261 |
-if os.environ.get("NOCOLOR") in ("yes", "true"): |
14262 |
- portage.output.nocolor() |
14263 |
- |
14264 |
-path = os.environ.get("PATH", "").split(":") |
14265 |
-path = [x for x in path if x] |
14266 |
- |
14267 |
-insert_bin_path = True |
14268 |
-try: |
14269 |
- insert_bin_path = not path or not os.path.samefile(path[0], PORTAGE_BIN_PATH) |
14270 |
-except OSError: |
14271 |
- pass |
14272 |
- |
14273 |
-if insert_bin_path: |
14274 |
- path.insert(0, PORTAGE_BIN_PATH) |
14275 |
- os.environ["PATH"] = ":".join(path) |
14276 |
- |
14277 |
-# Copy GPG test keys to temporary directory |
14278 |
-gpg_path = tempfile.mkdtemp(prefix="gpg_") |
14279 |
- |
14280 |
-copy_tree(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".gnupg"), gpg_path) |
14281 |
- |
14282 |
-os.chmod(gpg_path, 0o700) |
14283 |
-os.environ["PORTAGE_GNUPGHOME"] = gpg_path |
14284 |
- |
14285 |
-if __name__ == "__main__": |
14286 |
- try: |
14287 |
- sys.exit(tests.main()) |
14288 |
- finally: |
14289 |
- global_event_loop().close() |
14290 |
|
14291 |
diff --git a/repoman/lib/repoman/tests/simple/__init__.py b/repoman/lib/repoman/tests/simple/__init__.py |
14292 |
deleted file mode 100644 |
14293 |
index 532918b6a..000000000 |
14294 |
--- a/repoman/lib/repoman/tests/simple/__init__.py |
14295 |
+++ /dev/null |
14296 |
@@ -1,2 +0,0 @@ |
14297 |
-# Copyright 2011 Gentoo Foundation |
14298 |
-# Distributed under the terms of the GNU General Public License v2 |
14299 |
|
14300 |
diff --git a/repoman/lib/repoman/tests/simple/__test__.py b/repoman/lib/repoman/tests/simple/__test__.py |
14301 |
deleted file mode 100644 |
14302 |
index e69de29bb..000000000 |
14303 |
|
14304 |
diff --git a/repoman/lib/repoman/tests/simple/test_simple.py b/repoman/lib/repoman/tests/simple/test_simple.py |
14305 |
deleted file mode 100644 |
14306 |
index 41735b8b4..000000000 |
14307 |
--- a/repoman/lib/repoman/tests/simple/test_simple.py |
14308 |
+++ /dev/null |
14309 |
@@ -1,512 +0,0 @@ |
14310 |
-# Copyright 2011-2021 Gentoo Authors |
14311 |
-# Distributed under the terms of the GNU General Public License v2 |
14312 |
- |
14313 |
-import collections |
14314 |
-import subprocess |
14315 |
-import sys |
14316 |
-import time |
14317 |
-import types |
14318 |
- |
14319 |
-from repoman._portage import portage |
14320 |
-from portage import os |
14321 |
-from portage.process import find_binary |
14322 |
-from portage.tests.resolver.ResolverPlayground import ResolverPlayground |
14323 |
-from portage.util import ensure_dirs |
14324 |
-from portage.util.futures import asyncio |
14325 |
-from portage.util.futures._asyncio.streams import _reader |
14326 |
-from portage.util._async.AsyncFunction import AsyncFunction |
14327 |
- |
14328 |
-# pylint: disable=ungrouped-imports |
14329 |
-from repoman import REPOMAN_BASE_PATH |
14330 |
-from repoman.copyrights import update_copyright_year |
14331 |
-from repoman.main import _repoman_init, _repoman_scan, _handle_result |
14332 |
-from repoman.tests import TestCase |
14333 |
- |
14334 |
- |
14335 |
-class RepomanRun(types.SimpleNamespace): |
14336 |
- async def run(self): |
14337 |
- self.expected = getattr(self, "expected", None) or {"returncode": 0} |
14338 |
- if self.debug: |
14339 |
- fd_pipes = {} |
14340 |
- pr = None |
14341 |
- pw = None |
14342 |
- else: |
14343 |
- pr, pw = os.pipe() |
14344 |
- fd_pipes = {1: pw, 2: pw} |
14345 |
- pr = open(pr, "rb", 0) |
14346 |
- |
14347 |
- proc = AsyncFunction( |
14348 |
- scheduler=asyncio.get_event_loop(), |
14349 |
- target=self._subprocess, |
14350 |
- args=(self.args, self.cwd, self.env, self.expected, self.debug), |
14351 |
- fd_pipes=fd_pipes, |
14352 |
- ) |
14353 |
- |
14354 |
- proc.start() |
14355 |
- if pw is not None: |
14356 |
- os.close(pw) |
14357 |
- |
14358 |
- await proc.async_wait() |
14359 |
- |
14360 |
- if pr is None: |
14361 |
- stdio = None |
14362 |
- else: |
14363 |
- stdio = await _reader(pr) |
14364 |
- |
14365 |
- self.result = { |
14366 |
- "stdio": stdio, |
14367 |
- "result": proc.result, |
14368 |
- } |
14369 |
- |
14370 |
- @staticmethod |
14371 |
- def _subprocess(args, cwd, env, expected, debug): |
14372 |
- os.chdir(cwd) |
14373 |
- os.environ.update(env) |
14374 |
- portage.const.EPREFIX = env["PORTAGE_OVERRIDE_EPREFIX"] |
14375 |
- if debug: |
14376 |
- args = ["-vvvv"] + args |
14377 |
- repoman_vars = _repoman_init(["repoman"] + args) |
14378 |
- if repoman_vars.exitcode is not None: |
14379 |
- return {"returncode": repoman_vars.exitcode} |
14380 |
- result = _repoman_scan(*repoman_vars) |
14381 |
- returncode = _handle_result(*repoman_vars, result) |
14382 |
- qawarnings = repoman_vars.vcs_settings.qatracker.qawarnings |
14383 |
- warns = collections.defaultdict(list) |
14384 |
- fails = collections.defaultdict(list) |
14385 |
- for qacat, issues in repoman_vars.vcs_settings.qatracker.fails.items(): |
14386 |
- if qacat in qawarnings: |
14387 |
- warns[qacat].extend(issues) |
14388 |
- else: |
14389 |
- fails[qacat].extend(issues) |
14390 |
- result = {"returncode": returncode} |
14391 |
- if fails: |
14392 |
- result["fails"] = fails |
14393 |
- if warns: |
14394 |
- result["warns"] = warns |
14395 |
- return result |
14396 |
- |
14397 |
- |
14398 |
-class SimpleRepomanTestCase(TestCase): |
14399 |
- def testCopyrightUpdate(self): |
14400 |
- test_cases = ( |
14401 |
- ( |
14402 |
- "2011", |
14403 |
- "# Copyright 1999-2008 Gentoo Foundation; Distributed under the GPL v2", |
14404 |
- "# Copyright 1999-2011 Gentoo Authors; Distributed under the GPL v2", |
14405 |
- ), |
14406 |
- ( |
14407 |
- "2011", |
14408 |
- "# Copyright 1999 Gentoo Foundation; Distributed under the GPL v2", |
14409 |
- "# Copyright 1999-2011 Gentoo Authors; Distributed under the GPL v2", |
14410 |
- ), |
14411 |
- ( |
14412 |
- "1999", |
14413 |
- "# Copyright 1999 Gentoo Foundation; Distributed under the GPL v2", |
14414 |
- "# Copyright 1999 Gentoo Foundation; Distributed under the GPL v2", |
14415 |
- ), |
14416 |
- ( |
14417 |
- "2018", |
14418 |
- "# Copyright 1999-2008 Gentoo Authors; Distributed under the GPL v2", |
14419 |
- "# Copyright 1999-2018 Gentoo Authors; Distributed under the GPL v2", |
14420 |
- ), |
14421 |
- ( |
14422 |
- "2018", |
14423 |
- "# Copyright 2017 Gentoo Authors; Distributed under the GPL v2", |
14424 |
- "# Copyright 2017-2018 Gentoo Authors; Distributed under the GPL v2", |
14425 |
- ), |
14426 |
- ) |
14427 |
- |
14428 |
- for year, before, after in test_cases: |
14429 |
- self.assertEqual(update_copyright_year(year, before), after) |
14430 |
- |
14431 |
- def _must_skip(self): |
14432 |
- xmllint = find_binary("xmllint") |
14433 |
- if not xmllint: |
14434 |
- return "xmllint not found" |
14435 |
- |
14436 |
- try: |
14437 |
- __import__("xml.etree.ElementTree") |
14438 |
- __import__("xml.parsers.expat").parsers.expat.ExpatError |
14439 |
- except (AttributeError, ImportError): |
14440 |
- return "python is missing xml support" |
14441 |
- |
14442 |
- def testSimple(self): |
14443 |
- debug = False |
14444 |
- |
14445 |
- skip_reason = self._must_skip() |
14446 |
- if skip_reason: |
14447 |
- self.portage_skip = skip_reason |
14448 |
- self.assertFalse(True, skip_reason) |
14449 |
- return |
14450 |
- |
14451 |
- copyright_header = ( |
14452 |
- """# Copyright 1999-%s Gentoo Authors |
14453 |
-# Distributed under the terms of the GNU General Public License v2 |
14454 |
- |
14455 |
-""" |
14456 |
- % time.gmtime().tm_year |
14457 |
- ) |
14458 |
- |
14459 |
- pkg_preinst_references_forbidden_var = """ |
14460 |
-pkg_preinst() { |
14461 |
- echo "This ${A} reference is not allowed. Neither is this $BROOT reference." |
14462 |
-} |
14463 |
-""" |
14464 |
- |
14465 |
- repo_configs = { |
14466 |
- "test_repo": { |
14467 |
- "layout.conf": ("update-changelog = true",), |
14468 |
- } |
14469 |
- } |
14470 |
- |
14471 |
- profiles = ( |
14472 |
- ("x86", "default/linux/x86/test_profile", "stable"), |
14473 |
- ("x86", "default/linux/x86/test_dev", "dev"), |
14474 |
- ("x86", "default/linux/x86/test_exp", "exp"), |
14475 |
- ) |
14476 |
- |
14477 |
- profile = {"eapi": ("5",), "package.use.stable.mask": ("dev-libs/A flag",)} |
14478 |
- |
14479 |
- ebuilds = { |
14480 |
- "dev-libs/A-0": { |
14481 |
- "COPYRIGHT_HEADER": copyright_header, |
14482 |
- "DESCRIPTION": "Desc goes here", |
14483 |
- "EAPI": "5", |
14484 |
- "HOMEPAGE": "https://example.com", |
14485 |
- "IUSE": "flag", |
14486 |
- "KEYWORDS": "x86", |
14487 |
- "LICENSE": "GPL-2", |
14488 |
- "RDEPEND": "flag? ( dev-libs/B[flag] )", |
14489 |
- }, |
14490 |
- "dev-libs/A-1": { |
14491 |
- "COPYRIGHT_HEADER": copyright_header, |
14492 |
- "DESCRIPTION": "Desc goes here", |
14493 |
- "EAPI": "4", |
14494 |
- "HOMEPAGE": "https://example.com", |
14495 |
- "IUSE": "flag", |
14496 |
- "KEYWORDS": "~x86", |
14497 |
- "LICENSE": "GPL-2", |
14498 |
- "RDEPEND": "flag? ( dev-libs/B[flag] )", |
14499 |
- }, |
14500 |
- "dev-libs/B-1": { |
14501 |
- "COPYRIGHT_HEADER": copyright_header, |
14502 |
- "DESCRIPTION": "Desc goes here", |
14503 |
- "EAPI": "4", |
14504 |
- "HOMEPAGE": "https://example.com", |
14505 |
- "IUSE": "flag", |
14506 |
- "KEYWORDS": "~x86", |
14507 |
- "LICENSE": "GPL-2", |
14508 |
- }, |
14509 |
- "dev-libs/C-0": { |
14510 |
- "COPYRIGHT_HEADER": copyright_header, |
14511 |
- "DESCRIPTION": "Desc goes here", |
14512 |
- "EAPI": "7", |
14513 |
- "HOMEPAGE": "https://example.com", |
14514 |
- "IUSE": "flag", |
14515 |
- # must be unstable, since dev-libs/A[flag] is stable masked |
14516 |
- "KEYWORDS": "~x86", |
14517 |
- "LICENSE": "GPL-2", |
14518 |
- "RDEPEND": "flag? ( dev-libs/A[flag] )", |
14519 |
- "MISC_CONTENT": pkg_preinst_references_forbidden_var, |
14520 |
- }, |
14521 |
- } |
14522 |
- licenses = ["GPL-2"] |
14523 |
- arch_list = ["x86"] |
14524 |
- metadata_xsd = os.path.join(REPOMAN_BASE_PATH, "cnf/metadata.xsd") |
14525 |
- metadata_xml_files = ( |
14526 |
- ( |
14527 |
- "dev-libs/A", |
14528 |
- { |
14529 |
- "flags": "<flag name='flag' restrict='>=dev-libs/A-0'>Description of how USE='flag' affects this package</flag>", |
14530 |
- }, |
14531 |
- ), |
14532 |
- ( |
14533 |
- "dev-libs/B", |
14534 |
- { |
14535 |
- "flags": "<flag name='flag'>Description of how USE='flag' affects this package</flag>", |
14536 |
- }, |
14537 |
- ), |
14538 |
- ( |
14539 |
- "dev-libs/C", |
14540 |
- { |
14541 |
- "flags": "<flag name='flag'>Description of how USE='flag' affects this package</flag>", |
14542 |
- }, |
14543 |
- ), |
14544 |
- ) |
14545 |
- |
14546 |
- use_desc = (("flag", "Description of how USE='flag' affects packages"),) |
14547 |
- |
14548 |
- playground = ResolverPlayground( |
14549 |
- ebuilds=ebuilds, profile=profile, repo_configs=repo_configs, debug=debug |
14550 |
- ) |
14551 |
- |
14552 |
- loop = asyncio._wrap_loop() |
14553 |
- loop.run_until_complete( |
14554 |
- asyncio.ensure_future( |
14555 |
- self._async_test_simple( |
14556 |
- playground, |
14557 |
- metadata_xml_files, |
14558 |
- profiles, |
14559 |
- profile, |
14560 |
- licenses, |
14561 |
- arch_list, |
14562 |
- use_desc, |
14563 |
- metadata_xsd, |
14564 |
- copyright_header, |
14565 |
- debug, |
14566 |
- ), |
14567 |
- loop=loop, |
14568 |
- ) |
14569 |
- ) |
14570 |
- |
14571 |
- async def _async_test_simple( |
14572 |
- self, |
14573 |
- playground, |
14574 |
- metadata_xml_files, |
14575 |
- profiles, |
14576 |
- profile, |
14577 |
- licenses, |
14578 |
- arch_list, |
14579 |
- use_desc, |
14580 |
- metadata_xsd, |
14581 |
- copyright_header, |
14582 |
- debug, |
14583 |
- ): |
14584 |
- settings = playground.settings |
14585 |
- eprefix = settings["EPREFIX"] |
14586 |
- eroot = settings["EROOT"] |
14587 |
- portdb = playground.trees[playground.eroot]["porttree"].dbapi |
14588 |
- homedir = os.path.join(eroot, "home") |
14589 |
- distdir = os.path.join(eprefix, "distdir") |
14590 |
- test_repo_location = settings.repositories["test_repo"].location |
14591 |
- profiles_dir = os.path.join(test_repo_location, "profiles") |
14592 |
- license_dir = os.path.join(test_repo_location, "licenses") |
14593 |
- |
14594 |
- repoman_cmd = ( |
14595 |
- portage._python_interpreter, |
14596 |
- "-b", |
14597 |
- "-Wd", |
14598 |
- os.path.join(self.bindir, "repoman"), |
14599 |
- ) |
14600 |
- |
14601 |
- git_binary = find_binary("git") |
14602 |
- git_cmd = (git_binary,) |
14603 |
- |
14604 |
- cp_binary = find_binary("cp") |
14605 |
- self.assertEqual(cp_binary is None, False, "cp command not found") |
14606 |
- cp_cmd = (cp_binary,) |
14607 |
- |
14608 |
- test_ebuild = portdb.findname("dev-libs/A-1") |
14609 |
- self.assertFalse(test_ebuild is None) |
14610 |
- |
14611 |
- committer_name = "Gentoo Dev" |
14612 |
- committer_email = "gentoo-dev@g.o" |
14613 |
- expected_warnings = { |
14614 |
- "returncode": 0, |
14615 |
- "warns": { |
14616 |
- "variable.phase": [ |
14617 |
- "dev-libs/C/C-0.ebuild: line 15: phase pkg_preinst: EAPI 7: variable A: Forbidden reference to variable specified by PMS", |
14618 |
- "dev-libs/C/C-0.ebuild: line 15: phase pkg_preinst: EAPI 7: variable BROOT: Forbidden reference to variable specified by PMS", |
14619 |
- ] |
14620 |
- }, |
14621 |
- } |
14622 |
- |
14623 |
- git_test = ( |
14624 |
- ("", RepomanRun(args=["--version"])), |
14625 |
- ("", RepomanRun(args=["manifest"])), |
14626 |
- ( |
14627 |
- "", |
14628 |
- git_cmd |
14629 |
- + ( |
14630 |
- "config", |
14631 |
- "--global", |
14632 |
- "user.name", |
14633 |
- committer_name, |
14634 |
- ), |
14635 |
- ), |
14636 |
- ( |
14637 |
- "", |
14638 |
- git_cmd |
14639 |
- + ( |
14640 |
- "config", |
14641 |
- "--global", |
14642 |
- "user.email", |
14643 |
- committer_email, |
14644 |
- ), |
14645 |
- ), |
14646 |
- ("", git_cmd + ("init-db",)), |
14647 |
- ("", git_cmd + ("add", ".")), |
14648 |
- ("", git_cmd + ("commit", "-a", "-m", "add whole repo")), |
14649 |
- ("", RepomanRun(args=["full", "-d"], expected=expected_warnings)), |
14650 |
- ( |
14651 |
- "", |
14652 |
- RepomanRun( |
14653 |
- args=[ |
14654 |
- "full", |
14655 |
- "--include-profiles", |
14656 |
- "default/linux/x86/test_profile", |
14657 |
- ], |
14658 |
- expected=expected_warnings, |
14659 |
- ), |
14660 |
- ), |
14661 |
- ("", cp_cmd + (test_ebuild, test_ebuild[:-8] + "2.ebuild")), |
14662 |
- ("", git_cmd + ("add", test_ebuild[:-8] + "2.ebuild")), |
14663 |
- ( |
14664 |
- "", |
14665 |
- RepomanRun( |
14666 |
- args=["commit", "-m", "cat/pkg: bump to version 2"], |
14667 |
- expected=expected_warnings, |
14668 |
- ), |
14669 |
- ), |
14670 |
- ("", cp_cmd + (test_ebuild, test_ebuild[:-8] + "3.ebuild")), |
14671 |
- ("", git_cmd + ("add", test_ebuild[:-8] + "3.ebuild")), |
14672 |
- ( |
14673 |
- "dev-libs", |
14674 |
- RepomanRun( |
14675 |
- args=["commit", "-m", "cat/pkg: bump to version 3"], |
14676 |
- expected=expected_warnings, |
14677 |
- ), |
14678 |
- ), |
14679 |
- ("", cp_cmd + (test_ebuild, test_ebuild[:-8] + "4.ebuild")), |
14680 |
- ("", git_cmd + ("add", test_ebuild[:-8] + "4.ebuild")), |
14681 |
- ( |
14682 |
- "dev-libs/A", |
14683 |
- RepomanRun(args=["commit", "-m", "cat/pkg: bump to version 4"]), |
14684 |
- ), |
14685 |
- ) |
14686 |
- |
14687 |
- env = { |
14688 |
- "PORTAGE_OVERRIDE_EPREFIX": eprefix, |
14689 |
- "DISTDIR": distdir, |
14690 |
- "GENTOO_COMMITTER_NAME": committer_name, |
14691 |
- "GENTOO_COMMITTER_EMAIL": committer_email, |
14692 |
- "HOME": homedir, |
14693 |
- "PATH": os.environ["PATH"], |
14694 |
- "PORTAGE_GRPNAME": os.environ["PORTAGE_GRPNAME"], |
14695 |
- "PORTAGE_USERNAME": os.environ["PORTAGE_USERNAME"], |
14696 |
- "PORTAGE_REPOSITORIES": settings.repositories.config_string(), |
14697 |
- "PYTHONDONTWRITEBYTECODE": os.environ.get("PYTHONDONTWRITEBYTECODE", ""), |
14698 |
- } |
14699 |
- |
14700 |
- if os.environ.get("SANDBOX_ON") == "1": |
14701 |
- # avoid problems from nested sandbox instances |
14702 |
- env["FEATURES"] = "-sandbox -usersandbox" |
14703 |
- |
14704 |
- dirs = [homedir, license_dir, profiles_dir, distdir] |
14705 |
- try: |
14706 |
- for d in dirs: |
14707 |
- ensure_dirs(d) |
14708 |
- with open(os.path.join(test_repo_location, "skel.ChangeLog"), "w") as f: |
14709 |
- f.write(copyright_header) |
14710 |
- with open(os.path.join(profiles_dir, "profiles.desc"), "w") as f: |
14711 |
- for x in profiles: |
14712 |
- f.write("%s %s %s\n" % x) |
14713 |
- |
14714 |
- # ResolverPlayground only created the first profile, |
14715 |
- # so create the remaining ones. |
14716 |
- for x in profiles[1:]: |
14717 |
- sub_profile_dir = os.path.join(profiles_dir, x[1]) |
14718 |
- ensure_dirs(sub_profile_dir) |
14719 |
- for config_file, lines in profile.items(): |
14720 |
- file_name = os.path.join(sub_profile_dir, config_file) |
14721 |
- with open(file_name, "w") as f: |
14722 |
- for line in lines: |
14723 |
- f.write("%s\n" % line) |
14724 |
- |
14725 |
- for x in licenses: |
14726 |
- open(os.path.join(license_dir, x), "wb").close() |
14727 |
- with open(os.path.join(profiles_dir, "arch.list"), "w") as f: |
14728 |
- for x in arch_list: |
14729 |
- f.write("%s\n" % x) |
14730 |
- with open(os.path.join(profiles_dir, "use.desc"), "w") as f: |
14731 |
- for k, v in use_desc: |
14732 |
- f.write("%s - %s\n" % (k, v)) |
14733 |
- for cp, xml_data in metadata_xml_files: |
14734 |
- with open( |
14735 |
- os.path.join(test_repo_location, cp, "metadata.xml"), "w" |
14736 |
- ) as f: |
14737 |
- f.write(playground.metadata_xml_template % xml_data) |
14738 |
- # Use a symlink to test_repo, in order to trigger bugs |
14739 |
- # involving canonical vs. non-canonical paths. |
14740 |
- test_repo_symlink = os.path.join(eroot, "test_repo_symlink") |
14741 |
- os.symlink(test_repo_location, test_repo_symlink) |
14742 |
- metadata_xsd_dest = os.path.join( |
14743 |
- test_repo_location, "metadata/xml-schema/metadata.xsd" |
14744 |
- ) |
14745 |
- os.makedirs(os.path.dirname(metadata_xsd_dest)) |
14746 |
- os.symlink(metadata_xsd, metadata_xsd_dest) |
14747 |
- |
14748 |
- if debug: |
14749 |
- # The subprocess inherits both stdout and stderr, for |
14750 |
- # debugging purposes. |
14751 |
- stdout = None |
14752 |
- else: |
14753 |
- # The subprocess inherits stderr so that any warnings |
14754 |
- # triggered by python -Wd will be visible. |
14755 |
- stdout = subprocess.PIPE |
14756 |
- |
14757 |
- for cwd in ("", "dev-libs", "dev-libs/A", "dev-libs/B", "dev-libs/C"): |
14758 |
- abs_cwd = os.path.join(test_repo_symlink, cwd) |
14759 |
- |
14760 |
- proc = await asyncio.create_subprocess_exec( |
14761 |
- *(repoman_cmd + ("full",)), |
14762 |
- env=env, |
14763 |
- stderr=None, |
14764 |
- stdout=stdout, |
14765 |
- cwd=abs_cwd |
14766 |
- ) |
14767 |
- |
14768 |
- if debug: |
14769 |
- await proc.wait() |
14770 |
- else: |
14771 |
- output, _err = await proc.communicate() |
14772 |
- await proc.wait() |
14773 |
- if proc.returncode != os.EX_OK: |
14774 |
- portage.writemsg(output) |
14775 |
- |
14776 |
- self.assertEqual( |
14777 |
- os.EX_OK, proc.returncode, "repoman failed in %s" % (cwd,) |
14778 |
- ) |
14779 |
- |
14780 |
- if git_binary is not None: |
14781 |
- for cwd, cmd in git_test: |
14782 |
- abs_cwd = os.path.join(test_repo_symlink, cwd) |
14783 |
- if isinstance(cmd, RepomanRun): |
14784 |
- cmd.cwd = abs_cwd |
14785 |
- cmd.env = env |
14786 |
- cmd.debug = debug |
14787 |
- await cmd.run() |
14788 |
- if cmd.result["result"] != cmd.expected and cmd.result.get( |
14789 |
- "stdio" |
14790 |
- ): |
14791 |
- portage.writemsg(cmd.result["stdio"]) |
14792 |
- try: |
14793 |
- self.assertEqual(cmd.result["result"], cmd.expected) |
14794 |
- except Exception: |
14795 |
- print(cmd.result["result"], file=sys.stderr, flush=True) |
14796 |
- raise |
14797 |
- continue |
14798 |
- |
14799 |
- proc = await asyncio.create_subprocess_exec( |
14800 |
- *cmd, env=env, stderr=None, stdout=stdout, cwd=abs_cwd |
14801 |
- ) |
14802 |
- |
14803 |
- if debug: |
14804 |
- await proc.wait() |
14805 |
- else: |
14806 |
- output, _err = await proc.communicate() |
14807 |
- await proc.wait() |
14808 |
- if proc.returncode != os.EX_OK: |
14809 |
- portage.writemsg(output) |
14810 |
- |
14811 |
- self.assertEqual( |
14812 |
- os.EX_OK, |
14813 |
- proc.returncode, |
14814 |
- "%s failed in %s" |
14815 |
- % ( |
14816 |
- cmd, |
14817 |
- cwd, |
14818 |
- ), |
14819 |
- ) |
14820 |
- finally: |
14821 |
- playground.cleanup() |
14822 |
|
14823 |
diff --git a/repoman/lib/repoman/utilities.py b/repoman/lib/repoman/utilities.py |
14824 |
deleted file mode 100644 |
14825 |
index 6c5414470..000000000 |
14826 |
--- a/repoman/lib/repoman/utilities.py |
14827 |
+++ /dev/null |
14828 |
@@ -1,590 +0,0 @@ |
14829 |
-# -*- coding:utf-8 -*- |
14830 |
-# repoman: Utilities |
14831 |
-# Copyright 2007-2021 Gentoo Authors |
14832 |
-# Distributed under the terms of the GNU General Public License v2 |
14833 |
- |
14834 |
-"""This module contains utility functions to help repoman find ebuilds to |
14835 |
-scan""" |
14836 |
- |
14837 |
-__all__ = [ |
14838 |
- "editor_is_executable", |
14839 |
- "FindPackagesToScan", |
14840 |
- "FindPortdir", |
14841 |
- "get_commit_message_with_editor", |
14842 |
- "get_committer_name", |
14843 |
- "have_ebuild_dir", |
14844 |
- "have_profile_dir", |
14845 |
- "UpdateChangeLog", |
14846 |
-] |
14847 |
- |
14848 |
-import errno |
14849 |
-import io |
14850 |
-from itertools import chain |
14851 |
-import logging |
14852 |
-import pwd |
14853 |
-import stat |
14854 |
-import time |
14855 |
-import textwrap |
14856 |
-import difflib |
14857 |
-import tempfile |
14858 |
- |
14859 |
-# import our initialized portage instance |
14860 |
-from repoman._portage import portage |
14861 |
- |
14862 |
-from portage import os |
14863 |
-from portage import shutil |
14864 |
-from portage import _encodings |
14865 |
-from portage import _unicode_decode |
14866 |
-from portage import _unicode_encode |
14867 |
-from portage import util |
14868 |
-from portage.localization import _ |
14869 |
-from portage.process import find_binary |
14870 |
-from portage.output import green |
14871 |
- |
14872 |
-# pylint: disable=ungrouped-imports |
14873 |
-from repoman.copyrights import update_copyright_year |
14874 |
- |
14875 |
- |
14876 |
-normalize_path = util.normalize_path |
14877 |
-util.initialize_logger() |
14878 |
- |
14879 |
- |
14880 |
-def have_profile_dir(path, maxdepth=3, filename="profiles.desc"): |
14881 |
- """ |
14882 |
- Try to figure out if 'path' has a profiles/ |
14883 |
- dir in it by checking for the given filename. |
14884 |
- """ |
14885 |
- while path != "/" and maxdepth: |
14886 |
- if os.path.exists(os.path.join(path, "profiles", filename)): |
14887 |
- return normalize_path(path) |
14888 |
- path = normalize_path(path + "/..") |
14889 |
- maxdepth -= 1 |
14890 |
- |
14891 |
- |
14892 |
-def have_ebuild_dir(path, maxdepth=3): |
14893 |
- """ |
14894 |
- Try to figure out if 'path' or a subdirectory contains one or more |
14895 |
- ebuild files named appropriately for their parent directory. |
14896 |
- """ |
14897 |
- stack = [(normalize_path(path), 1)] |
14898 |
- while stack: |
14899 |
- path, depth = stack.pop() |
14900 |
- basename = os.path.basename(path) |
14901 |
- try: |
14902 |
- listdir = os.listdir(path) |
14903 |
- except OSError: |
14904 |
- continue |
14905 |
- for filename in listdir: |
14906 |
- abs_filename = os.path.join(path, filename) |
14907 |
- try: |
14908 |
- st = os.stat(abs_filename) |
14909 |
- except OSError: |
14910 |
- continue |
14911 |
- if stat.S_ISDIR(st.st_mode): |
14912 |
- if depth < maxdepth: |
14913 |
- stack.append((abs_filename, depth + 1)) |
14914 |
- elif stat.S_ISREG(st.st_mode): |
14915 |
- if filename.endswith(".ebuild") and filename.startswith(basename + "-"): |
14916 |
- return os.path.dirname(os.path.dirname(path)) |
14917 |
- |
14918 |
- |
14919 |
-def FindPackagesToScan(settings, startdir, reposplit): |
14920 |
- """Try to find packages that need to be scanned |
14921 |
- |
14922 |
- Args: |
14923 |
- settings - portage.config instance, preferably repoman_settings |
14924 |
- startdir - directory that repoman was run in |
14925 |
- reposplit - root of the repository |
14926 |
- Returns: |
14927 |
- A list of directories to scan |
14928 |
- """ |
14929 |
- |
14930 |
- def AddPackagesInDir(path): |
14931 |
- """Given a list of dirs, add any packages in it""" |
14932 |
- ret = [] |
14933 |
- pkgdirs = os.listdir(path) |
14934 |
- for d in pkgdirs: |
14935 |
- if d == "CVS" or d.startswith("."): |
14936 |
- continue |
14937 |
- p = os.path.join(path, d) |
14938 |
- |
14939 |
- if os.path.isdir(p): |
14940 |
- cat_pkg_dir = os.path.join(*p.split(os.path.sep)[-2:]) |
14941 |
- logging.debug("adding %s to scanlist" % cat_pkg_dir) |
14942 |
- ret.append(cat_pkg_dir) |
14943 |
- return ret |
14944 |
- |
14945 |
- scanlist = [] |
14946 |
- repolevel = len(reposplit) |
14947 |
- if repolevel == 1: # root of the tree, startdir = repodir |
14948 |
- for cat in settings.categories: |
14949 |
- path = os.path.join(startdir, cat) |
14950 |
- if not os.path.isdir(path): |
14951 |
- continue |
14952 |
- scanlist.extend(AddPackagesInDir(path)) |
14953 |
- elif repolevel == 2: # category level, startdir = catdir |
14954 |
- # We only want 1 segment of the directory, |
14955 |
- # this is why we use catdir instead of startdir. |
14956 |
- catdir = reposplit[-2] |
14957 |
- if catdir not in settings.categories: |
14958 |
- logging.warn( |
14959 |
- "%s is not a valid category according to profiles/categories, " |
14960 |
- "skipping checks in %s" % (catdir, catdir) |
14961 |
- ) |
14962 |
- else: |
14963 |
- scanlist = AddPackagesInDir(catdir) |
14964 |
- elif repolevel == 3: # pkgdir level, startdir = pkgdir |
14965 |
- catdir = reposplit[-2] |
14966 |
- pkgdir = reposplit[-1] |
14967 |
- if catdir not in settings.categories: |
14968 |
- logging.warn( |
14969 |
- "%s is not a valid category according to profiles/categories, " |
14970 |
- "skipping checks in %s" % (catdir, catdir) |
14971 |
- ) |
14972 |
- else: |
14973 |
- path = os.path.join(catdir, pkgdir) |
14974 |
- logging.debug("adding %s to scanlist" % path) |
14975 |
- scanlist.append(path) |
14976 |
- return scanlist |
14977 |
- |
14978 |
- |
14979 |
-def editor_is_executable(editor): |
14980 |
- """ |
14981 |
- Given an EDITOR string, validate that it refers to |
14982 |
- an executable. This uses shlex_split() to split the |
14983 |
- first component and do a PATH lookup if necessary. |
14984 |
- |
14985 |
- @param editor: An EDITOR value from the environment. |
14986 |
- @type: string |
14987 |
- @rtype: bool |
14988 |
- @return: True if an executable is found, False otherwise. |
14989 |
- """ |
14990 |
- editor_split = util.shlex_split(editor) |
14991 |
- if not editor_split: |
14992 |
- return False |
14993 |
- filename = editor_split[0] |
14994 |
- if not os.path.isabs(filename): |
14995 |
- return find_binary(filename) is not None |
14996 |
- return os.access(filename, os.X_OK) and os.path.isfile(filename) |
14997 |
- |
14998 |
- |
14999 |
-def get_commit_message_with_editor(editor, message=None, prefix=""): |
15000 |
- """ |
15001 |
- Execute editor with a temporary file as it's argument |
15002 |
- and return the file content afterwards. |
15003 |
- |
15004 |
- @param editor: An EDITOR value from the environment |
15005 |
- @type: string |
15006 |
- @param message: An iterable of lines to show in the editor. |
15007 |
- @type: iterable |
15008 |
- @param prefix: Suggested prefix for the commit message summary line. |
15009 |
- @type: string |
15010 |
- @rtype: string or None |
15011 |
- @return: A string on success or None if an error occurs. |
15012 |
- """ |
15013 |
- commitmessagedir = tempfile.mkdtemp(".repoman.msg") |
15014 |
- filename = os.path.join(commitmessagedir, "COMMIT_EDITMSG") |
15015 |
- try: |
15016 |
- with open(filename, "wb") as mymsg: |
15017 |
- mymsg.write( |
15018 |
- _unicode_encode( |
15019 |
- _( |
15020 |
- prefix + "\n\n# Please enter the commit message " |
15021 |
- "for your changes.\n# (Comment lines starting " |
15022 |
- "with '#' will not be included)\n" |
15023 |
- ), |
15024 |
- encoding=_encodings["content"], |
15025 |
- errors="backslashreplace", |
15026 |
- ) |
15027 |
- ) |
15028 |
- if message: |
15029 |
- mymsg.write(b"#\n") |
15030 |
- for line in message: |
15031 |
- mymsg.write( |
15032 |
- _unicode_encode( |
15033 |
- "#" + line, |
15034 |
- encoding=_encodings["content"], |
15035 |
- errors="backslashreplace", |
15036 |
- ) |
15037 |
- ) |
15038 |
- retval = os.system(editor + " '%s'" % filename) |
15039 |
- if not (os.WIFEXITED(retval) and os.WEXITSTATUS(retval) == os.EX_OK): |
15040 |
- return None |
15041 |
- try: |
15042 |
- with io.open( |
15043 |
- _unicode_encode(filename, encoding=_encodings["fs"], errors="strict"), |
15044 |
- mode="r", |
15045 |
- encoding=_encodings["content"], |
15046 |
- errors="replace", |
15047 |
- ) as f: |
15048 |
- mylines = f.readlines() |
15049 |
- except OSError as e: |
15050 |
- if e.errno != errno.ENOENT: |
15051 |
- raise |
15052 |
- del e |
15053 |
- return None |
15054 |
- return "".join(line for line in mylines if not line.startswith("#")) |
15055 |
- finally: |
15056 |
- try: |
15057 |
- shutil.rmtree(commitmessagedir) |
15058 |
- except OSError: |
15059 |
- pass |
15060 |
- |
15061 |
- |
15062 |
-def FindPortdir(settings): |
15063 |
- """Try to figure out what repo we are in and whether we are in a regular |
15064 |
- tree or an overlay. |
15065 |
- |
15066 |
- Basic logic is: |
15067 |
- |
15068 |
- 1. Determine what directory we are in (supports symlinks). |
15069 |
- 2. Build a list of directories from / to our current location |
15070 |
- 3. Iterate over PORTDIR_OVERLAY, if we find a match, |
15071 |
- search for a profiles directory in the overlay. If it has one, |
15072 |
- make it portdir, otherwise make it portdir_overlay. |
15073 |
- 4. If we didn't find an overlay in PORTDIR_OVERLAY, |
15074 |
- see if we are in PORTDIR; if so, set portdir_overlay to PORTDIR. |
15075 |
- If we aren't in PORTDIR, see if PWD has a profiles dir, if so, |
15076 |
- set portdir_overlay and portdir to PWD, else make them False. |
15077 |
- 5. If we haven't found portdir_overlay yet, |
15078 |
- it means the user is doing something odd, report an error. |
15079 |
- 6. If we haven't found a portdir yet, set portdir to PORTDIR. |
15080 |
- |
15081 |
- Args: |
15082 |
- settings - portage.config instance, preferably repoman_settings |
15083 |
- Returns: |
15084 |
- list(portdir, portdir_overlay, location) |
15085 |
- """ |
15086 |
- |
15087 |
- portdir = None |
15088 |
- portdir_overlay = None |
15089 |
- location = os.getcwd() |
15090 |
- pwd = _unicode_decode(os.environ.get("PWD", ""), encoding=_encodings["fs"]) |
15091 |
- if pwd and pwd != location and os.path.realpath(pwd) == location: |
15092 |
- # getcwd() returns the canonical path but that makes it hard for repoman to |
15093 |
- # orient itself if the user has symlinks in their repository structure. |
15094 |
- # We use os.environ["PWD"], if available, to get the non-canonical path of |
15095 |
- # the current working directory (from the shell). |
15096 |
- location = pwd |
15097 |
- |
15098 |
- location = normalize_path(location) |
15099 |
- |
15100 |
- path_ids = {} |
15101 |
- p = location |
15102 |
- s = None |
15103 |
- while True: |
15104 |
- s = os.stat(p) |
15105 |
- path_ids[(s.st_dev, s.st_ino)] = p |
15106 |
- if p == "/": |
15107 |
- break |
15108 |
- p = os.path.dirname(p) |
15109 |
- if location[-1] != "/": |
15110 |
- location += "/" |
15111 |
- |
15112 |
- for overlay in portage.util.shlex_split(settings["PORTDIR_OVERLAY"]): |
15113 |
- overlay = os.path.realpath(overlay) |
15114 |
- try: |
15115 |
- s = os.stat(overlay) |
15116 |
- except OSError: |
15117 |
- continue |
15118 |
- overlay = path_ids.get((s.st_dev, s.st_ino)) |
15119 |
- if overlay is None: |
15120 |
- continue |
15121 |
- if overlay[-1] != "/": |
15122 |
- overlay += "/" |
15123 |
- if True: |
15124 |
- portdir_overlay = overlay |
15125 |
- subdir = location[len(overlay) :] |
15126 |
- if subdir and subdir[-1] != "/": |
15127 |
- subdir += "/" |
15128 |
- if have_profile_dir(location, subdir.count("/")): |
15129 |
- portdir = portdir_overlay |
15130 |
- break |
15131 |
- |
15132 |
- # Couldn't match location with anything from PORTDIR_OVERLAY, |
15133 |
- # so fall back to have_profile_dir() checks alone. Assume that |
15134 |
- # an overlay will contain at least a "repo_name" file while a |
15135 |
- # master repo (portdir) will contain at least a "profiles.desc" |
15136 |
- # file. |
15137 |
- if not portdir_overlay: |
15138 |
- portdir_overlay = have_profile_dir(location, filename="repo_name") |
15139 |
- if not portdir_overlay: |
15140 |
- portdir_overlay = have_ebuild_dir(location) |
15141 |
- if portdir_overlay: |
15142 |
- subdir = location[len(portdir_overlay) :] |
15143 |
- if subdir and subdir[-1] != os.sep: |
15144 |
- subdir += os.sep |
15145 |
- if have_profile_dir(location, subdir.count(os.sep)): |
15146 |
- portdir = portdir_overlay |
15147 |
- |
15148 |
- if not portdir_overlay: |
15149 |
- if (settings["PORTDIR"] + os.path.sep).startswith(location): |
15150 |
- portdir_overlay = settings["PORTDIR"] |
15151 |
- else: |
15152 |
- portdir_overlay = have_profile_dir(location) |
15153 |
- portdir = portdir_overlay |
15154 |
- |
15155 |
- if not portdir_overlay: |
15156 |
- msg = ( |
15157 |
- "Repoman is unable to determine PORTDIR or PORTDIR_OVERLAY" |
15158 |
- + " from the current working directory" |
15159 |
- ) |
15160 |
- logging.critical(msg) |
15161 |
- return (None, None, None) |
15162 |
- |
15163 |
- if not portdir: |
15164 |
- portdir = settings["PORTDIR"] |
15165 |
- |
15166 |
- if not portdir_overlay.endswith("/"): |
15167 |
- portdir_overlay += "/" |
15168 |
- |
15169 |
- if not portdir.endswith("/"): |
15170 |
- portdir += "/" |
15171 |
- |
15172 |
- return [normalize_path(x) for x in (portdir, portdir_overlay, location)] |
15173 |
- |
15174 |
- |
15175 |
-def get_committer_name(env=None): |
15176 |
- """Generate a committer string like echangelog does.""" |
15177 |
- if env is None: |
15178 |
- env = os.environ |
15179 |
- if "GENTOO_COMMITTER_NAME" in env and "GENTOO_COMMITTER_EMAIL" in env: |
15180 |
- user = "%s <%s>" % (env["GENTOO_COMMITTER_NAME"], env["GENTOO_COMMITTER_EMAIL"]) |
15181 |
- elif "GENTOO_AUTHOR_NAME" in env and "GENTOO_AUTHOR_EMAIL" in env: |
15182 |
- user = "%s <%s>" % (env["GENTOO_AUTHOR_NAME"], env["GENTOO_AUTHOR_EMAIL"]) |
15183 |
- elif "ECHANGELOG_USER" in env: |
15184 |
- user = env["ECHANGELOG_USER"] |
15185 |
- else: |
15186 |
- pwd_struct = pwd.getpwuid(os.getuid()) |
15187 |
- gecos = pwd_struct.pw_gecos.split(",")[0] # bug #80011 |
15188 |
- user = "%s <%s@g.o>" % (gecos, pwd_struct.pw_name) |
15189 |
- return user |
15190 |
- |
15191 |
- |
15192 |
-def UpdateChangeLog( |
15193 |
- pkgdir, |
15194 |
- user, |
15195 |
- msg, |
15196 |
- skel_path, |
15197 |
- category, |
15198 |
- package, |
15199 |
- new=(), |
15200 |
- removed=(), |
15201 |
- changed=(), |
15202 |
- pretend=False, |
15203 |
- quiet=False, |
15204 |
-): |
15205 |
- """ |
15206 |
- Write an entry to an existing ChangeLog, or create a new one. |
15207 |
- Updates copyright year on changed files, and updates the header of |
15208 |
- ChangeLog with the contents of skel.ChangeLog. |
15209 |
- """ |
15210 |
- |
15211 |
- if "<root@" in user: |
15212 |
- if not quiet: |
15213 |
- logging.critical("Please set ECHANGELOG_USER or run as non-root") |
15214 |
- return None |
15215 |
- |
15216 |
- # ChangeLog times are in UTC |
15217 |
- gmtime = time.gmtime() |
15218 |
- year = time.strftime("%Y", gmtime) |
15219 |
- date = time.strftime("%d %b %Y", gmtime) |
15220 |
- |
15221 |
- cl_path = os.path.join(pkgdir, "ChangeLog") |
15222 |
- clold_lines = [] |
15223 |
- clnew_lines = [] |
15224 |
- old_header_lines = [] |
15225 |
- header_lines = [] |
15226 |
- |
15227 |
- clold_file = None |
15228 |
- try: |
15229 |
- clold_file = io.open( |
15230 |
- _unicode_encode(cl_path, encoding=_encodings["fs"], errors="strict"), |
15231 |
- mode="r", |
15232 |
- encoding=_encodings["repo.content"], |
15233 |
- errors="replace", |
15234 |
- ) |
15235 |
- except EnvironmentError: |
15236 |
- pass |
15237 |
- |
15238 |
- f, clnew_path = tempfile.mkstemp() |
15239 |
- |
15240 |
- # construct correct header first |
15241 |
- try: |
15242 |
- if clold_file is not None: |
15243 |
- # retain header from old ChangeLog |
15244 |
- first_line = True |
15245 |
- for line in clold_file: |
15246 |
- line_strip = line.strip() |
15247 |
- if line_strip and line[:1] != "#": |
15248 |
- clold_lines.append(line) |
15249 |
- break |
15250 |
- # always make sure cat/pkg is up-to-date in case we are |
15251 |
- # moving packages around, or copied from another pkg, or ... |
15252 |
- if first_line: |
15253 |
- if line.startswith("# ChangeLog for"): |
15254 |
- line = "# ChangeLog for %s/%s\n" % (category, package) |
15255 |
- first_line = False |
15256 |
- old_header_lines.append(line) |
15257 |
- header_lines.append(update_copyright_year(year, line)) |
15258 |
- if not line_strip: |
15259 |
- break |
15260 |
- |
15261 |
- clskel_file = None |
15262 |
- if not header_lines: |
15263 |
- # delay opening this until we find we need a header |
15264 |
- try: |
15265 |
- clskel_file = io.open( |
15266 |
- _unicode_encode( |
15267 |
- skel_path, encoding=_encodings["fs"], errors="strict" |
15268 |
- ), |
15269 |
- mode="r", |
15270 |
- encoding=_encodings["repo.content"], |
15271 |
- errors="replace", |
15272 |
- ) |
15273 |
- except EnvironmentError: |
15274 |
- pass |
15275 |
- |
15276 |
- if clskel_file is not None: |
15277 |
- # read skel.ChangeLog up to first empty line |
15278 |
- for line in clskel_file: |
15279 |
- line_strip = line.strip() |
15280 |
- if not line_strip: |
15281 |
- break |
15282 |
- line = line.replace("<CATEGORY>", category) |
15283 |
- line = line.replace("<PACKAGE_NAME>", package) |
15284 |
- line = update_copyright_year(year, line) |
15285 |
- header_lines.append(line) |
15286 |
- header_lines.append("\n") |
15287 |
- clskel_file.close() |
15288 |
- |
15289 |
- # write new ChangeLog entry |
15290 |
- clnew_lines.extend(header_lines) |
15291 |
- newebuild = False |
15292 |
- for fn in new: |
15293 |
- if not fn.endswith(".ebuild"): |
15294 |
- continue |
15295 |
- ebuild = fn.split(os.sep)[-1][0:-7] |
15296 |
- clnew_lines.append("*%s (%s)\n" % (ebuild, date)) |
15297 |
- newebuild = True |
15298 |
- if newebuild: |
15299 |
- clnew_lines.append("\n") |
15300 |
- trivial_files = ("ChangeLog", "Manifest") |
15301 |
- display_new = ["+" + elem for elem in new if elem not in trivial_files] |
15302 |
- display_removed = ["-" + elem for elem in removed] |
15303 |
- display_changed = [elem for elem in changed if elem not in trivial_files] |
15304 |
- if not (display_new or display_removed or display_changed): |
15305 |
- # If there's nothing else to display, show one of the |
15306 |
- # trivial files. |
15307 |
- for fn in trivial_files: |
15308 |
- if fn in new: |
15309 |
- display_new = ["+" + fn] |
15310 |
- break |
15311 |
- elif fn in changed: |
15312 |
- display_changed = [fn] |
15313 |
- break |
15314 |
- |
15315 |
- display_new.sort() |
15316 |
- display_removed.sort() |
15317 |
- display_changed.sort() |
15318 |
- |
15319 |
- mesg = "%s; %s %s:" % ( |
15320 |
- date, |
15321 |
- user, |
15322 |
- ", ".join(chain(display_new, display_removed, display_changed)), |
15323 |
- ) |
15324 |
- for line in textwrap.wrap( |
15325 |
- mesg, |
15326 |
- 80, |
15327 |
- initial_indent=" ", |
15328 |
- subsequent_indent=" ", |
15329 |
- break_on_hyphens=False, |
15330 |
- ): |
15331 |
- clnew_lines.append("%s\n" % line) |
15332 |
- for line in textwrap.wrap(msg, 80, initial_indent=" ", subsequent_indent=" "): |
15333 |
- clnew_lines.append("%s\n" % line) |
15334 |
- # Don't append a trailing newline if the file is new. |
15335 |
- if clold_file is not None: |
15336 |
- clnew_lines.append("\n") |
15337 |
- |
15338 |
- f = io.open( |
15339 |
- f, mode="w", encoding=_encodings["repo.content"], errors="backslashreplace" |
15340 |
- ) |
15341 |
- |
15342 |
- for line in clnew_lines: |
15343 |
- f.write(line) |
15344 |
- |
15345 |
- # append stuff from old ChangeLog |
15346 |
- if clold_file is not None: |
15347 |
- |
15348 |
- if clold_lines: |
15349 |
- # clold_lines may contain a saved non-header line |
15350 |
- # that we want to write first. |
15351 |
- # Also, append this line to clnew_lines so that the |
15352 |
- # unified_diff call doesn't show it as removed. |
15353 |
- for line in clold_lines: |
15354 |
- f.write(line) |
15355 |
- clnew_lines.append(line) |
15356 |
- |
15357 |
- else: |
15358 |
- # ensure that there is no more than one blank |
15359 |
- # line after our new entry |
15360 |
- for line in clold_file: |
15361 |
- if line.strip(): |
15362 |
- f.write(line) |
15363 |
- break |
15364 |
- |
15365 |
- # Now prepend old_header_lines to clold_lines, for use |
15366 |
- # in the unified_diff call below. |
15367 |
- clold_lines = old_header_lines + clold_lines |
15368 |
- |
15369 |
- # Trim any trailing newlines. |
15370 |
- lines = clold_file.readlines() |
15371 |
- clold_file.close() |
15372 |
- while lines and lines[-1] == "\n": |
15373 |
- del lines[-1] |
15374 |
- f.writelines(lines) |
15375 |
- f.close() |
15376 |
- |
15377 |
- # show diff |
15378 |
- if not quiet: |
15379 |
- for line in difflib.unified_diff( |
15380 |
- clold_lines, clnew_lines, fromfile=cl_path, tofile=cl_path, n=0 |
15381 |
- ): |
15382 |
- util.writemsg_stdout(line, noiselevel=-1) |
15383 |
- util.writemsg_stdout("\n", noiselevel=-1) |
15384 |
- |
15385 |
- if pretend: |
15386 |
- # remove what we've done |
15387 |
- os.remove(clnew_path) |
15388 |
- else: |
15389 |
- # rename to ChangeLog, and set permissions |
15390 |
- try: |
15391 |
- clold_stat = os.stat(cl_path) |
15392 |
- except OSError: |
15393 |
- clold_stat = None |
15394 |
- |
15395 |
- shutil.move(clnew_path, cl_path) |
15396 |
- |
15397 |
- if clold_stat is None: |
15398 |
- util.apply_permissions(cl_path, mode=0o644) |
15399 |
- else: |
15400 |
- util.apply_stat_permissions(cl_path, clold_stat) |
15401 |
- |
15402 |
- if clold_file is None: |
15403 |
- return True |
15404 |
- else: |
15405 |
- return False |
15406 |
- except IOError as e: |
15407 |
- err = "Repoman is unable to create/write to Changelog.new file: %s" % (e,) |
15408 |
- logging.critical(err) |
15409 |
- # try to remove if possible |
15410 |
- try: |
15411 |
- os.remove(clnew_path) |
15412 |
- except OSError: |
15413 |
- pass |
15414 |
- return None |
15415 |
- |
15416 |
- |
15417 |
-def repoman_sez(msg): |
15418 |
- print(green("RepoMan sez:"), msg) |
15419 |
|
15420 |
diff --git a/repoman/man/repoman.1 b/repoman/man/repoman.1 |
15421 |
deleted file mode 100644 |
15422 |
index 5dbc41560..000000000 |
15423 |
--- a/repoman/man/repoman.1 |
15424 |
+++ /dev/null |
15425 |
@@ -1,478 +0,0 @@ |
15426 |
-.TH "REPOMAN" "1" "March 2021" "Repoman VERSION" "Repoman" |
15427 |
-.SH NAME |
15428 |
-repoman \- Gentoo's program to enforce a minimal level of quality assurance in |
15429 |
-packages added to the ebuild repository |
15430 |
-.SH SYNOPSIS |
15431 |
-\fBrepoman\fR [\fIoption\fR] [\fImode\fR] |
15432 |
-.SH DESCRIPTION |
15433 |
-.BR "Quality is job zero." |
15434 |
- |
15435 |
-.BR repoman |
15436 |
-checks the quality of ebuild repositories. |
15437 |
- |
15438 |
-Note: \fBrepoman commit\fR only works \fIinside local\fR cvs, git, or |
15439 |
-subversion repositories. |
15440 |
- |
15441 |
-Note: Messages pertaining to specific lines may be inaccurate in the |
15442 |
-prescence of continuation lines from use of the \fI\\\fR character in |
15443 |
-BASH. |
15444 |
-.SH OPTIONS |
15445 |
-.TP |
15446 |
-\fB-a\fR, \fB--ask\fR |
15447 |
-Request a confirmation before commiting |
15448 |
-.TP |
15449 |
-\fB-b\fR, \fB--bug\fR |
15450 |
-Include a bug reference in the commit message footer. The argument can |
15451 |
-be either a Gentoo bug number or a full bug URL (either Gentoo |
15452 |
-or upstream). Gentoo bug URLs are automatically shortened to |
15453 |
-the canonical \fBhttps://bugs.gentoo.org/NNNNNN\fR form, and HTTPS |
15454 |
-is forced for known bug trackers. |
15455 |
- |
15456 |
-When pushing to the Gentoo repository, the reference to the commit |
15457 |
-will be automatically added as a comment on the bug. |
15458 |
-.TP |
15459 |
-\fB-c\fR, \fB--closes\fR |
15460 |
-Include a \fBCloses\fR tag in the commit message footer that can be used |
15461 |
-to close bugs and pull requests. The argument can be either a Gentoo bug |
15462 |
-number or a full PR/bug URL. Gentoo bug URLs are automatically shortened |
15463 |
-to the canonical \fBhttps://bugs.gentoo.org/NNNNNN\fR form, and HTTPS |
15464 |
-is forced for known bug trackers. |
15465 |
- |
15466 |
-When pushing to the Gentoo repository, the referenced bugs will be |
15467 |
-closed as RESOLVED/FIXED automatically with a comment referencing |
15468 |
-the commit. Furthermore, GitHub pull requests will be closed as well |
15469 |
-due to the automatic GitHub mirroring. |
15470 |
- |
15471 |
-Other platforms using the \fBCloses\fR tag include GitLab and Bitbucket. |
15472 |
-.TP |
15473 |
-\fB\-\-digest=<y|n>\fR |
15474 |
-Automatically update Manifest digests for modified files. This |
15475 |
-option triggers a behavior that is very similar to that enabled |
15476 |
-by FEATURES="digest" in \fBmake.conf\fR(5). In order to enable |
15477 |
-this behavior by default for repoman alone, add |
15478 |
-\fB\-\-digest=y\fR to the \fIREPOMAN_DEFAULT_OPTS\fR variable in |
15479 |
-\fBmake.conf\fR(5). The \fBmanifest\-check\fR mode will |
15480 |
-automatically ignore the \-\-digest option. |
15481 |
- |
15482 |
-\fBNOTE:\fR |
15483 |
-This option does not trigger update of digests for Manifest DIST |
15484 |
-entries that already exist. Replacement of existing Manifest |
15485 |
-DIST entries can be forced by using the \fBmanifest\fR mode |
15486 |
-together with the \fB\-\-force\fR option. |
15487 |
-.TP |
15488 |
-\fB-f\fR, \fB--force\fR |
15489 |
-Force commit to proceed, regardless of QA issues. For convenience, this option |
15490 |
-causes the most time consuming QA checks to be skipped. The commit message will |
15491 |
-include an indication that this option has been enabled, together with the |
15492 |
-usual portage version stamp. |
15493 |
- |
15494 |
-When used together with \fBmanifest\fR mode, \fB--force\fR causes existing |
15495 |
-digests to be replaced for any files that exist in ${DISTDIR}. |
15496 |
-Existing digests are assumed to be correct for files that would otherwise |
15497 |
-have to be downloaded in order to recompute digests. \fBWARNING:\fR When |
15498 |
-replacing existing digests, it is the user's responsibility to ensure that |
15499 |
-files contained in ${DISTDIR} have the correct identities. Especially beware |
15500 |
-of partially downloaded files. |
15501 |
-.TP |
15502 |
-\fB-S\fR, \fB--straight-to-stable\fR |
15503 |
-Allow committing straight to stable |
15504 |
-.TP |
15505 |
-\fB-q\fR, \fB--quiet\fR |
15506 |
-Be less verbose about extraneous info |
15507 |
-.TP |
15508 |
-\fB-p\fR, \fB--pretend\fR |
15509 |
-Don't commit or fix anything; just show what would be done |
15510 |
-.TP |
15511 |
-\fB\-j\fR, \fB\-\-jobs\fR |
15512 |
-Specifies the number of jobs (processes) to run simultaneously. |
15513 |
-.TP |
15514 |
-\fB\-l\fR, \fB\-\-load-average\fR |
15515 |
-Specifies that no new jobs (processes) should be started if there are others |
15516 |
-jobs running and the load average is at least load (a floating\-point number). |
15517 |
-.TP |
15518 |
-\fB-x\fR, \fB--xmlparse\fR |
15519 |
-Forces the metadata.xml parse check to be carried out |
15520 |
-.TP |
15521 |
-\fB-v\fR, \fB--verbose\fR |
15522 |
-Displays every package name while checking |
15523 |
-.TP |
15524 |
-\fB\-\-echangelog=<y|n|force>\fR |
15525 |
-For commit mode, call echangelog if ChangeLog is unmodified (or |
15526 |
-regardless of modification if 'force' is specified). This option |
15527 |
-can be enabled by default for a particular repository by setting |
15528 |
-"update\-changelog = true" in metadata/layout.conf (see |
15529 |
-\fBportage\fR(5)). |
15530 |
-.TP |
15531 |
-\fB\-\-experimental\-inherit=<y|n>\fR |
15532 |
-Enable experimental inherit.missing checks which may misbehave when the |
15533 |
-internal eclass database becomes outdated. |
15534 |
-.TP |
15535 |
-\fB\-\-experimental\-repository\-modules=<y|n>\fR |
15536 |
-Enable experimental repository modules: |
15537 |
-\fIhttps://wiki.gentoo.org/wiki/Project:Portage/Repoman-Module-specs\fR |
15538 |
-.TP |
15539 |
-\fB\-\-if\-modified=<y|n>\fR |
15540 |
-Only check packages that have uncommitted modifications |
15541 |
-.TP |
15542 |
-\fB\-i\fR, \fB\-\-ignore\-arches\fR |
15543 |
-Ignore arch-specific failures (where arch != host) |
15544 |
-.TP |
15545 |
-\fB\-\-ignore\-default\-opts\fR |
15546 |
-Do not use the \fIREPOMAN_DEFAULT_OPTS\fR environment variable. |
15547 |
-.TP |
15548 |
-\fB\-I\fR, \fB\-\-ignore\-masked\fR |
15549 |
-Ignore masked packages (not allowed with commit mode) |
15550 |
-.TP |
15551 |
-.BR "\-\-include\-arches " ARCHES |
15552 |
-A space separated list of arches used to filter the selection of |
15553 |
-profiles for dependency checks. |
15554 |
-.TP |
15555 |
-.BR "\-\-include\-profiles " PROFILES |
15556 |
-A space separated list of profiles used to |
15557 |
-define the selection of profiles for dependency checks. |
15558 |
-.TP |
15559 |
-\fB\-d\fR, \fB\-\-include\-dev\fR |
15560 |
-Include dev profiles in dependency checks. |
15561 |
-.TP |
15562 |
-\fB\-e <y|n>\fR, \fB\-\-include\-exp\-profiles=<y|n>\fR |
15563 |
-Include exp profiles in dependency checks. |
15564 |
-.TP |
15565 |
-\fB\-\-unmatched\-removal\fR |
15566 |
-Enable strict checking of package.mask and package.unmask files for |
15567 |
-unmatched removal atoms. |
15568 |
-.TP |
15569 |
-\fB\-\-without\-mask\fR |
15570 |
-Behave as if no package.mask entries exist (not allowed with commit mode) |
15571 |
-.TP |
15572 |
-\fB-m\fR, \fB--commitmsg\fR |
15573 |
-Adds a commit message via the command line |
15574 |
-.TP |
15575 |
-\fB-M\fR, \fB--commitmsgfile\fR |
15576 |
-Adds a commit message from the specified file. This option also will perform |
15577 |
-an automatic text substitution of a leading "cat/pkg: " string (upper or lower |
15578 |
-case) with the actual category/package prefix as defined by the required message |
15579 |
-format. Use this option for templating a common commit message for multiple |
15580 |
-package updates. |
15581 |
-.TP |
15582 |
-\fB-V\fR, \fB--version\fR |
15583 |
-Show version info |
15584 |
-.TP |
15585 |
-\fB-h\fR, \fB--help\fR |
15586 |
-Show this screen |
15587 |
-.SH MODES |
15588 |
-.TP |
15589 |
-.B full |
15590 |
-Scan directory tree for QA issues (full listing) |
15591 |
-.TP |
15592 |
-.B help |
15593 |
-Show this screen |
15594 |
-.TP |
15595 |
-.B scan |
15596 |
-Scan directory tree for QA issues (short listing) |
15597 |
-.TP |
15598 |
-.B fix |
15599 |
-Fix simple QA issues (stray digests, missing digests) |
15600 |
-.TP |
15601 |
-.B manifest |
15602 |
-Generate a Manifest (fetches distfiles if necessary). See the \fB\-\-force\fR |
15603 |
-option if you would like to replace existing distfiles digests. |
15604 |
-.TP |
15605 |
-.B manifest-check |
15606 |
-Check Manifests for missing or incorrect digests |
15607 |
-.TP |
15608 |
-.B commit |
15609 |
-Scan directory tree for QA issues; if OK, commit via VCS |
15610 |
-.TP |
15611 |
-.B ci |
15612 |
-Synonym for commit |
15613 |
-.SH QA KEYWORDS |
15614 |
-.TP |
15615 |
-.B CVS/Entries.IO_error |
15616 |
-Attempting to commit, and an IO error was encountered access the Entries file |
15617 |
-.TP |
15618 |
-.B DESCRIPTION.missing |
15619 |
-Ebuilds that have a missing or empty DESCRIPTION variable |
15620 |
-.TP |
15621 |
-.B EAPI.definition |
15622 |
-EAPI definition does not conform to PMS section 7.3.1 (first |
15623 |
-non\-comment, non\-blank line). See bug #402167. |
15624 |
-.TP |
15625 |
-.B EAPI.deprecated |
15626 |
-Ebuilds that use features that are deprecated in the current EAPI |
15627 |
-.TP |
15628 |
-.B EAPI.incompatible |
15629 |
-Ebuilds that use features that are only available with a different EAPI |
15630 |
-.TP |
15631 |
-.B EAPI.unsupported |
15632 |
-Ebuilds that have an unsupported EAPI version (you must upgrade portage) |
15633 |
-.TP |
15634 |
-.B HOMEPAGE.missing |
15635 |
-Ebuilds that have a missing or empty HOMEPAGE variable |
15636 |
-.TP |
15637 |
-.B HOMEPAGE.missingurischeme |
15638 |
-HOMEPAGE is missing an URI scheme |
15639 |
-.TP |
15640 |
-.B HOMEPAGE.virtual |
15641 |
-Virtuals that have a non-empty HOMEPAGE variable |
15642 |
-.TP |
15643 |
-.B IUSE.invalid |
15644 |
-This ebuild has a variable in IUSE that is not in the use.desc or its |
15645 |
-metadata.xml file |
15646 |
-.TP |
15647 |
-.B IUSE.missing |
15648 |
-This ebuild has a USE conditional which references a flag that is not listed in |
15649 |
-IUSE |
15650 |
-.TP |
15651 |
-.B KEYWORDS.dropped |
15652 |
-Ebuilds that appear to have dropped KEYWORDS for some arch |
15653 |
-.TP |
15654 |
-.B KEYWORDS.invalid |
15655 |
-This ebuild contains KEYWORDS that are not listed in profiles/arch.list or for |
15656 |
-which no valid profile was found |
15657 |
-.TP |
15658 |
-.B KEYWORDS.missing |
15659 |
-Ebuilds that have a missing or empty KEYWORDS variable |
15660 |
-.TP |
15661 |
-.B KEYWORDS.stable |
15662 |
-Ebuilds that have been added directly with stable KEYWORDS |
15663 |
-.TP |
15664 |
-.B KEYWORDS.stupid |
15665 |
-Ebuilds that use KEYWORDS=-* instead of package.mask |
15666 |
-.TP |
15667 |
-.B KEYWORDS.unsorted |
15668 |
-Ebuilds that contain KEYWORDS which are not sorted alphabetically. |
15669 |
-.TP |
15670 |
-.B LICENSE.deprecated |
15671 |
-This ebuild is listing a deprecated license. |
15672 |
-.TP |
15673 |
-.B LICENSE.invalid |
15674 |
-This ebuild is listing a license that doesnt exist in portages license/ dir. |
15675 |
-.TP |
15676 |
-.B LICENSE.missing |
15677 |
-Ebuilds that have a missing or empty LICENSE variable |
15678 |
-.TP |
15679 |
-.B LICENSE.syntax |
15680 |
-Syntax error in LICENSE (usually an extra/missing space/parenthesis) |
15681 |
-.TP |
15682 |
-.B LICENSE.virtual |
15683 |
-Virtuals that have a non-empty LICENSE variable |
15684 |
-.TP |
15685 |
-.B LIVEVCS.stable |
15686 |
-Ebuild is a live ebuild (cvs, git, darcs, svn, etc) checkout with stable |
15687 |
-keywords. |
15688 |
-.TP |
15689 |
-.B LIVEVCS.unmasked |
15690 |
-Ebuild is a live ebuild (cvs, git, darcs, svn, etc) checkout but has keywords |
15691 |
-and is not masked in the global package.mask. |
15692 |
-.TP |
15693 |
-.B PDEPEND.suspect |
15694 |
-PDEPEND contains a package that usually only belongs in DEPEND |
15695 |
-.TP |
15696 |
-.B RDEPEND.implicit |
15697 |
-RDEPEND is unset in the ebuild which triggers implicit RDEPEND=$DEPEND |
15698 |
-assignment (prior to EAPI 4) |
15699 |
-.TP |
15700 |
-.B RDEPEND.suspect |
15701 |
-RDEPEND contains a package that usually only belongs in DEPEND |
15702 |
-.TP |
15703 |
-.B PROPERTIES.syntax |
15704 |
-Syntax error in PROPERTIES (usually an extra/missing space/parenthesis) |
15705 |
-.TP |
15706 |
-.B RESTRICT.syntax |
15707 |
-Syntax error in RESTRICT (usually an extra/missing space/parenthesis) |
15708 |
-.B SLOT.invalid |
15709 |
-Ebuilds that have a missing or invalid SLOT variable value |
15710 |
-.TP |
15711 |
-.B SRC_URI.mirror |
15712 |
-A uri listed in profiles/thirdpartymirrors is found in SRC_URI |
15713 |
-.TP |
15714 |
-.B changelog.ebuildadded |
15715 |
-An ebuild was added but the ChangeLog was not modified |
15716 |
-.TP |
15717 |
-.B changelog.missing |
15718 |
-Missing ChangeLog files |
15719 |
-.TP |
15720 |
-.B changelog.notadded |
15721 |
-ChangeLogs that exist but have not been added to the vcs |
15722 |
-.TP |
15723 |
-.B dependency.bad |
15724 |
-User-visible ebuilds with unsatisfied dependencies (matched against *visible* |
15725 |
-ebuilds) |
15726 |
-.TP |
15727 |
-.B dependency.badindev |
15728 |
-User-visible ebuilds with unsatisfied dependencies (matched against *visible* |
15729 |
-ebuilds) in developing arch |
15730 |
-.TP |
15731 |
-.B dependency.badinexp |
15732 |
-User-visible ebuilds with unsatisfied dependencies (matched against *visible* |
15733 |
-ebuilds) in experimental arch |
15734 |
-.TP |
15735 |
-.B dependency.badmasked |
15736 |
-Masked ebuilds with unsatisfied dependencies (matched against *all* ebuilds) |
15737 |
-.TP |
15738 |
-.B dependency.badmaskedindev |
15739 |
-Masked ebuilds with unsatisfied dependencies (matched against *all* ebuilds) in |
15740 |
-developing arch |
15741 |
-.TP |
15742 |
-.B dependency.badmaskedinexp |
15743 |
-Masked ebuilds with unsatisfied dependencies (matched against *all* ebuilds) in |
15744 |
-experimental arch |
15745 |
-.TP |
15746 |
-.B dependency.badtilde |
15747 |
-Uses the ~ dep operator with a non-zero revision part, which is useless (the |
15748 |
-revision is ignored) |
15749 |
-.TP |
15750 |
-.B dependency.deprecated |
15751 |
-Ebuild has a dependency that refers to a deprecated package |
15752 |
-.TP |
15753 |
-.B dependency.syntax |
15754 |
-Syntax error in dependency string (usually an extra/missing space/parenthesis) |
15755 |
-.TP |
15756 |
-.B dependency.unknown |
15757 |
-Ebuild has a dependency that refers to an unknown package (which may be |
15758 |
-valid if it is a blocker for a renamed/removed package, or is an |
15759 |
-alternative choice provided by an overlay) |
15760 |
-.TP |
15761 |
-.B digest.assumed |
15762 |
-Existing digest must be assumed correct (Package level only) |
15763 |
-.TP |
15764 |
-.B digest.missing |
15765 |
-Some files listed in SRC_URI aren't referenced in the Manifest |
15766 |
-.TP |
15767 |
-.B digest.unused |
15768 |
-Some files listed in the Manifest aren't referenced in SRC_URI |
15769 |
-.TP |
15770 |
-.B ebuild.absdosym |
15771 |
-Ebuild uses 'dosym' with explicit absolute path where relative path |
15772 |
-could be used |
15773 |
-.TP |
15774 |
-.B ebuild.badheader |
15775 |
-This ebuild has a malformed header |
15776 |
-.TP |
15777 |
-.B ebuild.invalidname |
15778 |
-Ebuild files with a non-parseable or syntactically incorrect name (or using 2.1 |
15779 |
-versioning extensions) |
15780 |
-.TP |
15781 |
-.B ebuild.majorsyn |
15782 |
-This ebuild has a major syntax error that may cause the ebuild to fail |
15783 |
-partially or fully |
15784 |
-.TP |
15785 |
-.B ebuild.minorsyn |
15786 |
-This ebuild has a minor syntax error that contravenes gentoo coding style |
15787 |
-.TP |
15788 |
-.B ebuild.namenomatch |
15789 |
-Ebuild files that do not have the same name as their parent directory |
15790 |
-.TP |
15791 |
-.B ebuild.nesteddie |
15792 |
-Placing 'die' inside ( ) prints an error, but doesn't stop the ebuild. |
15793 |
-.TP |
15794 |
-.B ebuild.notadded |
15795 |
-Ebuilds that exist but have not been added to the vcs |
15796 |
-.TP |
15797 |
-.B ebuild.output |
15798 |
-A simple sourcing of the ebuild produces output; this breaks ebuild policy. |
15799 |
-.TP |
15800 |
-.B ebuild.patches |
15801 |
-PATCHES variable should be a bash array to ensure white space safety |
15802 |
-.TP |
15803 |
-.B ebuild.syntax |
15804 |
-Error generating cache entry for ebuild; typically caused by ebuild syntax |
15805 |
-error or digest verification failure. |
15806 |
-.TP |
15807 |
-.B file.UTF8 |
15808 |
-File is not UTF8 compliant |
15809 |
-.TP |
15810 |
-.B file.empty |
15811 |
-Empty file in the files directory |
15812 |
-.TP |
15813 |
-.B file.executable |
15814 |
-Ebuilds, digests, metadata.xml, Manifest, and ChangeLog do not need the |
15815 |
-executable bit |
15816 |
-.TP |
15817 |
-.B file.name |
15818 |
-File/dir name must be composed of only the following chars: a-zA-Z0-9._-+: |
15819 |
-.TP |
15820 |
-.B file.size |
15821 |
-Files in the files directory must be under 20 KiB |
15822 |
-.TP |
15823 |
-.B inherit.missing |
15824 |
-Ebuild uses functions from an eclass but does not inherit it |
15825 |
-.TP |
15826 |
-.B inherit.unused |
15827 |
-Ebuild inherits an eclass but does not use it |
15828 |
-.TP |
15829 |
-.B inherit.deprecated |
15830 |
-Ebuild inherits a deprecated eclass |
15831 |
-.TP |
15832 |
-.B java.eclassesnotused |
15833 |
-With virtual/jdk in DEPEND you must inherit a java eclass. Refer to |
15834 |
-\fIhttps://wiki.gentoo.org/wiki/Project:Java\fR for more information. |
15835 |
-.TP |
15836 |
-.B manifest.bad |
15837 |
-Manifest has missing or incorrect digests |
15838 |
-.TP |
15839 |
-.B metadata.bad |
15840 |
-Bad metadata.xml files |
15841 |
-.TP |
15842 |
-.B metadata.missing |
15843 |
-Missing metadata.xml files |
15844 |
-.TP |
15845 |
-.B metadata.warning |
15846 |
-Warnings in metadata.xml files |
15847 |
-.TP |
15848 |
-.B repo.eapi.banned |
15849 |
-The ebuild uses an EAPI which is banned by the repository's |
15850 |
-metadata/layout.conf settings. |
15851 |
-.TP |
15852 |
-.B repo.eapi.deprecated |
15853 |
-The ebuild uses an EAPI which is deprecated by the repository's |
15854 |
-metadata/layout.conf settings. |
15855 |
-.TP |
15856 |
-.B IUSE.rubydeprecated |
15857 |
-The ebuild has set a ruby interpreter in USE_RUBY, that is not available as a ruby target anymore |
15858 |
-.TP |
15859 |
-.B portage.internal |
15860 |
-The ebuild uses an internal Portage function or variable |
15861 |
-.TP |
15862 |
-.B upstream.workaround |
15863 |
-The ebuild works around an upstream bug, an upstream bug should be filed and |
15864 |
-tracked in bugs.gentoo.org |
15865 |
-.TP |
15866 |
-.B usage.obsolete |
15867 |
-The ebuild makes use of an obsolete construct |
15868 |
-.TP |
15869 |
-.B variable.invalidchar |
15870 |
-A variable contains an invalid character that is not part of the ASCII |
15871 |
-character set. |
15872 |
-.TP |
15873 |
-.B variable.phase |
15874 |
-Variable referenced found within scope of incorrect ebuild phase as specified by PMS. |
15875 |
-.TP |
15876 |
-.B variable.readonly |
15877 |
-Assigning a readonly variable |
15878 |
-.TP |
15879 |
-.B variable.usedwithhelpers |
15880 |
-Ebuild uses D, ROOT, BROOT, ED, EROOT or EPREFIX with helpers |
15881 |
-.TP |
15882 |
-.B virtual.suspect |
15883 |
-Ebuild contains a package that usually should be pulled via virtual/, |
15884 |
-not directly. |
15885 |
-.TP |
15886 |
-.B wxwidgets.eclassnotused |
15887 |
-Ebuild DEPENDs on x11-libs/wxGTK without inheriting wxwidgets.eclass. Refer to |
15888 |
-bug #305469 for more information. |
15889 |
-.SH "BEHAVIOR" |
15890 |
-When invoked from a level higher than a package directory, \fBrepoman\fR |
15891 |
-will recurse through a directory tree and execute the given command |
15892 |
-on a per\-package basis, e.g. \fBrepoman manifest\fR at the root of |
15893 |
-the repository will generate manifests for every package within the |
15894 |
-repository. |
15895 |
-.SH "REPORTING BUGS" |
15896 |
-Please report bugs via https://bugs.gentoo.org/ |
15897 |
-.SH AUTHORS |
15898 |
-.nf |
15899 |
-Daniel Robbins <drobbins@g.o> |
15900 |
-Saleem Abdulrasool <compnerd@g.o> |
15901 |
-.fi |
15902 |
-.SH "SEE ALSO" |
15903 |
-.BR emerge (1) |
15904 |
|
15905 |
diff --git a/repoman/runtests b/repoman/runtests |
15906 |
deleted file mode 100755 |
15907 |
index f02bfe875..000000000 |
15908 |
--- a/repoman/runtests |
15909 |
+++ /dev/null |
15910 |
@@ -1,189 +0,0 @@ |
15911 |
-#!/usr/bin/env python |
15912 |
-# Copyright 2010-2020 Gentoo Authors |
15913 |
-# Distributed under the terms of the GNU General Public License v2 |
15914 |
-# |
15915 |
-# Note: We don't want to import portage modules directly because we do things |
15916 |
-# like run the testsuite through multiple versions of python. |
15917 |
- |
15918 |
-"""Helper script to run portage unittests against different python versions. |
15919 |
- |
15920 |
-Note: Any additional arguments will be passed down directly to the underlying |
15921 |
-unittest runner. This lets you select specific tests to execute. |
15922 |
-""" |
15923 |
- |
15924 |
-import argparse |
15925 |
-import os |
15926 |
-import shutil |
15927 |
-import subprocess |
15928 |
-import sys |
15929 |
-import tempfile |
15930 |
- |
15931 |
- |
15932 |
-# These are the versions we fully support and require to pass tests. |
15933 |
-PYTHON_SUPPORTED_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] |
15934 |
-# The rest are just "nice to have". |
15935 |
-PYTHON_NICE_VERSIONS = ["pypy3", "3.10"] |
15936 |
- |
15937 |
-EPREFIX = os.environ.get("PORTAGE_OVERRIDE_EPREFIX", "/") |
15938 |
- |
15939 |
- |
15940 |
-class Colors(object): |
15941 |
- """Simple object holding color constants.""" |
15942 |
- |
15943 |
- _COLORS_YES = ("y", "yes", "true") |
15944 |
- _COLORS_NO = ("n", "no", "false") |
15945 |
- |
15946 |
- WARN = GOOD = BAD = NORMAL = "" |
15947 |
- |
15948 |
- def __init__(self, colorize=None): |
15949 |
- if colorize is None: |
15950 |
- nocolors = os.environ.get("NOCOLOR", "false") |
15951 |
- # Ugh, look away, for here we invert the world! |
15952 |
- if nocolors in self._COLORS_YES: |
15953 |
- colorize = False |
15954 |
- elif nocolors in self._COLORS_NO: |
15955 |
- colorize = True |
15956 |
- else: |
15957 |
- raise ValueError("$NOCOLORS is invalid: %s" % nocolors) |
15958 |
- else: |
15959 |
- if colorize in self._COLORS_YES: |
15960 |
- colorize = True |
15961 |
- elif colorize in self._COLORS_NO: |
15962 |
- colorize = False |
15963 |
- else: |
15964 |
- raise ValueError("--colors is invalid: %s" % colorize) |
15965 |
- |
15966 |
- if colorize: |
15967 |
- self.WARN = "\033[1;33m" |
15968 |
- self.GOOD = "\033[1;32m" |
15969 |
- self.BAD = "\033[1;31m" |
15970 |
- self.NORMAL = "\033[0m" |
15971 |
- |
15972 |
- |
15973 |
-def get_python_executable(ver): |
15974 |
- """Find the right python executable for |ver|""" |
15975 |
- if ver in ("pypy", "pypy3"): |
15976 |
- prog = ver |
15977 |
- else: |
15978 |
- prog = "python" + ver |
15979 |
- return os.path.join(EPREFIX, "usr", "bin", prog) |
15980 |
- |
15981 |
- |
15982 |
-def get_parser(): |
15983 |
- """Return a argument parser for this module""" |
15984 |
- epilog = """Examples: |
15985 |
-List all the available unittests. |
15986 |
-$ %(prog)s --list |
15987 |
- |
15988 |
-Run against specific versions of python. |
15989 |
-$ %(prog)s --python-versions '2.7 3.3' |
15990 |
- |
15991 |
-Run just one unittest. |
15992 |
-$ %(prog)s lib/portage/tests/xpak/test_decodeint.py |
15993 |
-""" |
15994 |
- parser = argparse.ArgumentParser( |
15995 |
- description=__doc__, |
15996 |
- formatter_class=argparse.RawDescriptionHelpFormatter, |
15997 |
- epilog=epilog, |
15998 |
- ) |
15999 |
- parser.add_argument( |
16000 |
- "--keep-temp", |
16001 |
- default=False, |
16002 |
- action="store_true", |
16003 |
- help="Do not delete the temporary directory when exiting", |
16004 |
- ) |
16005 |
- parser.add_argument( |
16006 |
- "--color", |
16007 |
- type=str, |
16008 |
- default=None, |
16009 |
- help="Whether to use colorized output (default is auto)", |
16010 |
- ) |
16011 |
- parser.add_argument( |
16012 |
- "--python-versions", |
16013 |
- action="append", |
16014 |
- help="Versions of python to test (default is test available)", |
16015 |
- ) |
16016 |
- return parser |
16017 |
- |
16018 |
- |
16019 |
-def main(argv): |
16020 |
- parser = get_parser() |
16021 |
- opts, args = parser.parse_known_args(argv) |
16022 |
- colors = Colors(colorize=opts.color) |
16023 |
- |
16024 |
- # Figure out all the versions we want to test. |
16025 |
- if opts.python_versions is None: |
16026 |
- ignore_missing = True |
16027 |
- pyversions = PYTHON_SUPPORTED_VERSIONS + PYTHON_NICE_VERSIONS |
16028 |
- else: |
16029 |
- ignore_missing = False |
16030 |
- pyversions = [] |
16031 |
- for ver in opts.python_versions: |
16032 |
- if ver == "supported": |
16033 |
- pyversions.extend(PYTHON_SUPPORTED_VERSIONS) |
16034 |
- else: |
16035 |
- pyversions.extend(ver.split()) |
16036 |
- |
16037 |
- here = os.path.dirname(__file__) |
16038 |
- run_path = os.path.join(here, "lib/repoman/tests/runTests.py") |
16039 |
- tempdir = None |
16040 |
- try: |
16041 |
- # Set up a single tempdir for all the tests to use. |
16042 |
- # This way we know the tests won't leak things on us. |
16043 |
- tempdir = tempfile.mkdtemp(prefix="repoman.runtests.") |
16044 |
- os.environ["TMPDIR"] = tempdir |
16045 |
- |
16046 |
- # Actually test those versions now. |
16047 |
- statuses = [] |
16048 |
- for ver in pyversions: |
16049 |
- prog = get_python_executable(ver) |
16050 |
- cmd = [prog, "-b", "-Wd", run_path] + args |
16051 |
- if os.access(prog, os.X_OK): |
16052 |
- print( |
16053 |
- "%sTesting with Python %s...%s" % (colors.GOOD, ver, colors.NORMAL) |
16054 |
- ) |
16055 |
- statuses.append((ver, subprocess.call(cmd))) |
16056 |
- elif not ignore_missing: |
16057 |
- print( |
16058 |
- "%sCould not find requested Python %s%s" |
16059 |
- % (colors.BAD, ver, colors.NORMAL) |
16060 |
- ) |
16061 |
- statuses.append((ver, 1)) |
16062 |
- else: |
16063 |
- print("%sSkip Python %s...%s" % (colors.WARN, ver, colors.NORMAL)) |
16064 |
- print() |
16065 |
- finally: |
16066 |
- if tempdir is not None: |
16067 |
- if opts.keep_temp: |
16068 |
- print("Temporary directory left behind:\n%s" % tempdir) |
16069 |
- else: |
16070 |
- # Nuke our tempdir and anything that might be under it. |
16071 |
- shutil.rmtree(tempdir, True) |
16072 |
- |
16073 |
- # Then summarize it all. |
16074 |
- print("\nSummary:\n") |
16075 |
- width = 10 |
16076 |
- header = "| %-*s | %s" % (width, "Version", "Status") |
16077 |
- print("%s\n|%s" % (header, "-" * (len(header) - 1))) |
16078 |
- exit_status = 0 |
16079 |
- for ver, status in statuses: |
16080 |
- exit_status += status |
16081 |
- if status: |
16082 |
- color = colors.BAD |
16083 |
- msg = "FAIL" |
16084 |
- else: |
16085 |
- color = colors.GOOD |
16086 |
- msg = "PASS" |
16087 |
- print( |
16088 |
- "| %s%-*s%s | %s%s%s" |
16089 |
- % (color, width, ver, colors.NORMAL, color, msg, colors.NORMAL) |
16090 |
- ) |
16091 |
- exit(exit_status) |
16092 |
- |
16093 |
- |
16094 |
-if __name__ == "__main__": |
16095 |
- try: |
16096 |
- main(sys.argv[1:]) |
16097 |
- except KeyboardInterrupt: |
16098 |
- print("interrupted ...", file=sys.stderr) |
16099 |
- exit(1) |
16100 |
|
16101 |
diff --git a/repoman/setup.py b/repoman/setup.py |
16102 |
deleted file mode 100755 |
16103 |
index 8231c8f75..000000000 |
16104 |
--- a/repoman/setup.py |
16105 |
+++ /dev/null |
16106 |
@@ -1,523 +0,0 @@ |
16107 |
-#!/usr/bin/env python |
16108 |
-# Copyright 1998-2021 Gentoo Authors |
16109 |
-# Distributed under the terms of the GNU General Public License v2 |
16110 |
- |
16111 |
-try: |
16112 |
- from setuptools.core import setup, Command |
16113 |
- from setuptools.command.build import build |
16114 |
- from setuptools.command.build_scripts import build_scripts |
16115 |
- from setuptools.command.clean import clean |
16116 |
- from setuptools.command.install import install |
16117 |
- from setuptools.command.install_data import install_data |
16118 |
- from setuptools.command.install_lib import install_lib |
16119 |
- from setuptools.command.install_scripts import install_scripts |
16120 |
- from setuptools.command.sdist import sdist |
16121 |
- from setuptools.dep_util import newer |
16122 |
- from setuptools.dir_util import mkpath, remove_tree, copy_tree |
16123 |
- from setuptools.util import change_root, subst_vars |
16124 |
-except ImportError: |
16125 |
- from distutils.core import setup, Command |
16126 |
- from distutils.command.build import build |
16127 |
- from distutils.command.build_scripts import build_scripts |
16128 |
- from distutils.command.clean import clean |
16129 |
- from distutils.command.install import install |
16130 |
- from distutils.command.install_data import install_data |
16131 |
- from distutils.command.install_lib import install_lib |
16132 |
- from distutils.command.install_scripts import install_scripts |
16133 |
- from distutils.command.sdist import sdist |
16134 |
- from distutils.dep_util import newer |
16135 |
- from distutils.dir_util import mkpath, remove_tree, copy_tree |
16136 |
- from distutils.util import change_root, subst_vars |
16137 |
- |
16138 |
-import codecs |
16139 |
-import collections |
16140 |
-import os |
16141 |
-import os.path |
16142 |
-import re |
16143 |
-import subprocess |
16144 |
-import sys |
16145 |
- |
16146 |
-# change the cwd to this one |
16147 |
-os.chdir(os.path.dirname(os.path.realpath(__file__))) |
16148 |
- |
16149 |
-# TODO: |
16150 |
-# - smarter rebuilds of docs w/ 'install_docbook' and 'install_epydoc'. |
16151 |
- |
16152 |
-x_scripts = { |
16153 |
- "bin": [ |
16154 |
- "bin/repoman", |
16155 |
- ], |
16156 |
-} |
16157 |
- |
16158 |
- |
16159 |
-class x_build(build): |
16160 |
- """Build command with extra build_man call.""" |
16161 |
- |
16162 |
- def run(self): |
16163 |
- build.run(self) |
16164 |
- self.run_command("build_man") |
16165 |
- |
16166 |
- |
16167 |
-class build_man(Command): |
16168 |
- """Perform substitutions in manpages.""" |
16169 |
- |
16170 |
- user_options = [] |
16171 |
- |
16172 |
- def initialize_options(self): |
16173 |
- self.build_base = None |
16174 |
- |
16175 |
- def finalize_options(self): |
16176 |
- self.set_undefined_options("build", ("build_base", "build_base")) |
16177 |
- |
16178 |
- def run(self): |
16179 |
- for d, files in self.distribution.data_files: |
16180 |
- if not d.startswith("$mandir/"): |
16181 |
- continue |
16182 |
- |
16183 |
- for source in files: |
16184 |
- target = os.path.join(self.build_base, source) |
16185 |
- mkpath(os.path.dirname(target)) |
16186 |
- |
16187 |
- if not newer(source, target) and not newer(__file__, target): |
16188 |
- continue |
16189 |
- |
16190 |
- print("copying and updating %s -> %s" % (source, target)) |
16191 |
- |
16192 |
- with codecs.open(source, "r", "utf8") as f: |
16193 |
- data = f.readlines() |
16194 |
- data[0] = data[0].replace("VERSION", self.distribution.get_version()) |
16195 |
- with codecs.open(target, "w", "utf8") as f: |
16196 |
- f.writelines(data) |
16197 |
- |
16198 |
- |
16199 |
-class x_build_scripts_custom(build_scripts): |
16200 |
- def finalize_options(self): |
16201 |
- build_scripts.finalize_options(self) |
16202 |
- if "dir_name" in dir(self): |
16203 |
- self.build_dir = os.path.join(self.build_dir, self.dir_name) |
16204 |
- if self.dir_name in x_scripts: |
16205 |
- self.scripts = x_scripts[self.dir_name] |
16206 |
- else: |
16207 |
- self.scripts = set(self.scripts) |
16208 |
- for other_files in x_scripts.values(): |
16209 |
- self.scripts.difference_update(other_files) |
16210 |
- |
16211 |
- def run(self): |
16212 |
- # group scripts by subdirectory |
16213 |
- split_scripts = collections.defaultdict(list) |
16214 |
- for f in self.scripts: |
16215 |
- dir_name = os.path.dirname(f[len("bin/") :]) |
16216 |
- split_scripts[dir_name].append(f) |
16217 |
- |
16218 |
- base_dir = self.build_dir |
16219 |
- base_scripts = self.scripts |
16220 |
- for d, files in split_scripts.items(): |
16221 |
- self.build_dir = os.path.join(base_dir, d) |
16222 |
- self.scripts = files |
16223 |
- self.copy_scripts() |
16224 |
- |
16225 |
- # restore previous values |
16226 |
- self.build_dir = base_dir |
16227 |
- self.scripts = base_scripts |
16228 |
- |
16229 |
- |
16230 |
-class x_build_scripts_bin(x_build_scripts_custom): |
16231 |
- dir_name = "bin" |
16232 |
- |
16233 |
- |
16234 |
-class x_build_scripts(build_scripts): |
16235 |
- def initialize_option(self): |
16236 |
- build_scripts.initialize_options(self) |
16237 |
- |
16238 |
- def finalize_options(self): |
16239 |
- build_scripts.finalize_options(self) |
16240 |
- |
16241 |
- def run(self): |
16242 |
- self.run_command("build_scripts_bin") |
16243 |
- |
16244 |
- |
16245 |
-class x_clean(clean): |
16246 |
- """clean extended for doc & post-test cleaning""" |
16247 |
- |
16248 |
- def clean_tests(self): |
16249 |
- # do not remove incorrect dirs accidentally |
16250 |
- top_dir = os.path.normpath(os.path.join(self.build_lib, "..")) |
16251 |
- cprefix = os.path.commonprefix((self.build_base, top_dir)) |
16252 |
- if cprefix != self.build_base: |
16253 |
- return |
16254 |
- |
16255 |
- bin_dir = os.path.join(top_dir, "bin") |
16256 |
- if os.path.exists(bin_dir): |
16257 |
- remove_tree(bin_dir) |
16258 |
- |
16259 |
- conf_dir = os.path.join(top_dir, "cnf") |
16260 |
- if os.path.islink(conf_dir): |
16261 |
- print("removing %s symlink" % repr(conf_dir)) |
16262 |
- os.unlink(conf_dir) |
16263 |
- |
16264 |
- pni_file = os.path.join(top_dir, ".repoman_not_installed") |
16265 |
- if os.path.exists(pni_file): |
16266 |
- print("removing %s" % repr(pni_file)) |
16267 |
- os.unlink(pni_file) |
16268 |
- |
16269 |
- def clean_man(self): |
16270 |
- man_dir = os.path.join(self.build_base, "man") |
16271 |
- if os.path.exists(man_dir): |
16272 |
- remove_tree(man_dir) |
16273 |
- |
16274 |
- def run(self): |
16275 |
- if self.all: |
16276 |
- self.clean_tests() |
16277 |
- self.clean_docs() |
16278 |
- self.clean_man() |
16279 |
- |
16280 |
- clean.run(self) |
16281 |
- |
16282 |
- |
16283 |
-class x_install(install): |
16284 |
- """install command with extra Portage paths""" |
16285 |
- |
16286 |
- user_options = install.user_options + [ |
16287 |
- # note: $prefix and $exec_prefix are reserved for Python install |
16288 |
- ("system-prefix=", None, "Prefix for architecture-independent data"), |
16289 |
- ("system-exec-prefix=", None, "Prefix for architecture-specific data"), |
16290 |
- ("bindir=", None, "Install directory for main executables"), |
16291 |
- ("datarootdir=", None, "Data install root directory"), |
16292 |
- ("docdir=", None, "Documentation install directory"), |
16293 |
- ("htmldir=", None, "HTML documentation install directory"), |
16294 |
- ("mandir=", None, "Manpage root install directory"), |
16295 |
- ("portage-base=", "b", "Portage install base"), |
16296 |
- ( |
16297 |
- "portage-bindir=", |
16298 |
- None, |
16299 |
- "Install directory for Portage internal-use executables", |
16300 |
- ), |
16301 |
- ("portage-datadir=", None, "Install directory for data files"), |
16302 |
- ("sbindir=", None, "Install directory for superuser-intended executables"), |
16303 |
- ("sysconfdir=", None, "System configuration path"), |
16304 |
- ] |
16305 |
- |
16306 |
- # note: the order is important for proper substitution |
16307 |
- paths = [ |
16308 |
- ("system_prefix", "/usr"), |
16309 |
- ("system_exec_prefix", "$system_prefix"), |
16310 |
- ("bindir", "$system_exec_prefix/bin"), |
16311 |
- ("sbindir", "$system_exec_prefix/sbin"), |
16312 |
- ("sysconfdir", "/etc"), |
16313 |
- ("datarootdir", "$system_prefix/share"), |
16314 |
- ("docdir", "$datarootdir/doc/$package-$version"), |
16315 |
- ("htmldir", "$docdir/html"), |
16316 |
- ("mandir", "$datarootdir/man"), |
16317 |
- ("portage_base", "$system_exec_prefix/lib/portage"), |
16318 |
- ("portage_bindir", "$portage_base/bin"), |
16319 |
- ("portage_datadir", "$datarootdir/portage"), |
16320 |
- # not customized at the moment |
16321 |
- ("logrotatedir", "$sysconfdir/logrotate.d"), |
16322 |
- ("portage_confdir", "$portage_datadir/config"), |
16323 |
- ("portage_setsdir", "$portage_confdir/sets"), |
16324 |
- ] |
16325 |
- |
16326 |
- def initialize_options(self): |
16327 |
- install.initialize_options(self) |
16328 |
- |
16329 |
- for key, default in self.paths: |
16330 |
- setattr(self, key, default) |
16331 |
- self.subst_paths = {} |
16332 |
- |
16333 |
- def finalize_options(self): |
16334 |
- install.finalize_options(self) |
16335 |
- |
16336 |
- # substitute variables |
16337 |
- new_paths = { |
16338 |
- "package": self.distribution.get_name(), |
16339 |
- "version": self.distribution.get_version(), |
16340 |
- } |
16341 |
- for key, _default in self.paths: |
16342 |
- new_paths[key] = subst_vars(getattr(self, key), new_paths) |
16343 |
- setattr(self, key, new_paths[key]) |
16344 |
- self.subst_paths = new_paths |
16345 |
- |
16346 |
- |
16347 |
-class x_install_data(install_data): |
16348 |
- """install_data with customized path support""" |
16349 |
- |
16350 |
- user_options = install_data.user_options |
16351 |
- |
16352 |
- def initialize_options(self): |
16353 |
- install_data.initialize_options(self) |
16354 |
- self.build_base = None |
16355 |
- self.paths = None |
16356 |
- |
16357 |
- def finalize_options(self): |
16358 |
- install_data.finalize_options(self) |
16359 |
- self.set_undefined_options("build", ("build_base", "build_base")) |
16360 |
- self.set_undefined_options("install", ("subst_paths", "paths")) |
16361 |
- |
16362 |
- def run(self): |
16363 |
- self.run_command("build_man") |
16364 |
- |
16365 |
- def process_data_files(df): |
16366 |
- for d, files in df: |
16367 |
- # substitute man sources |
16368 |
- if d.startswith("$mandir/"): |
16369 |
- files = [os.path.join(self.build_base, v) for v in files] |
16370 |
- |
16371 |
- # substitute variables in path |
16372 |
- d = subst_vars(d, self.paths) |
16373 |
- yield (d, files) |
16374 |
- |
16375 |
- old_data_files = self.data_files |
16376 |
- self.data_files = process_data_files(self.data_files) |
16377 |
- |
16378 |
- install_data.run(self) |
16379 |
- self.data_files = old_data_files |
16380 |
- |
16381 |
- |
16382 |
-class x_install_lib(install_lib): |
16383 |
- """install_lib command with Portage path substitution""" |
16384 |
- |
16385 |
- user_options = install_lib.user_options |
16386 |
- |
16387 |
- def initialize_options(self): |
16388 |
- install_lib.initialize_options(self) |
16389 |
- |
16390 |
- def finalize_options(self): |
16391 |
- install_lib.finalize_options(self) |
16392 |
- self.set_undefined_options( |
16393 |
- "install", |
16394 |
- ) |
16395 |
- |
16396 |
- def install(self): |
16397 |
- ret = install_lib.install(self) |
16398 |
- |
16399 |
- def rewrite_file(path, val_dict): |
16400 |
- path = os.path.join(self.install_dir, path) |
16401 |
- print("Rewriting %s" % path) |
16402 |
- with codecs.open(path, "r", "utf-8") as f: |
16403 |
- data = f.read() |
16404 |
- |
16405 |
- for varname, val in val_dict.items(): |
16406 |
- regexp = r"(?m)^(%s\s*=).*$" % varname |
16407 |
- repl = r"\1 %s" % repr(val) |
16408 |
- |
16409 |
- data = re.sub(regexp, repl, data) |
16410 |
- |
16411 |
- with codecs.open(path, "w", "utf-8") as f: |
16412 |
- f.write(data) |
16413 |
- |
16414 |
- rewrite_file( |
16415 |
- "repoman/__init__.py", |
16416 |
- { |
16417 |
- "VERSION": self.distribution.get_version(), |
16418 |
- }, |
16419 |
- ) |
16420 |
- |
16421 |
- return ret |
16422 |
- |
16423 |
- |
16424 |
-class x_install_scripts_custom(install_scripts): |
16425 |
- def initialize_options(self): |
16426 |
- install_scripts.initialize_options(self) |
16427 |
- self.root = None |
16428 |
- |
16429 |
- def finalize_options(self): |
16430 |
- self.set_undefined_options( |
16431 |
- "install", ("root", "root"), (self.var_name, "install_dir") |
16432 |
- ) |
16433 |
- install_scripts.finalize_options(self) |
16434 |
- self.build_dir = os.path.join(self.build_dir, self.dir_name) |
16435 |
- |
16436 |
- # prepend root |
16437 |
- if self.root is not None: |
16438 |
- self.install_dir = change_root(self.root, self.install_dir) |
16439 |
- |
16440 |
- |
16441 |
-class x_install_scripts_bin(x_install_scripts_custom): |
16442 |
- dir_name = "bin" |
16443 |
- var_name = "bindir" |
16444 |
- |
16445 |
- |
16446 |
-class x_install_scripts(install_scripts): |
16447 |
- def initialize_option(self): |
16448 |
- pass |
16449 |
- |
16450 |
- def finalize_options(self): |
16451 |
- pass |
16452 |
- |
16453 |
- def run(self): |
16454 |
- self.run_command("install_scripts_bin") |
16455 |
- |
16456 |
- |
16457 |
-class x_sdist(sdist): |
16458 |
- """sdist defaulting to .tar.xz format, and archive files owned by root""" |
16459 |
- |
16460 |
- def initialize_options(self): |
16461 |
- super().initialize_options() |
16462 |
- self.formats = ["xztar"] |
16463 |
- |
16464 |
- def finalize_options(self): |
16465 |
- if self.owner is None: |
16466 |
- self.owner = "root" |
16467 |
- if self.group is None: |
16468 |
- self.group = "root" |
16469 |
- |
16470 |
- sdist.finalize_options(self) |
16471 |
- |
16472 |
- |
16473 |
-class build_tests(x_build_scripts_custom): |
16474 |
- """Prepare build dir for running tests.""" |
16475 |
- |
16476 |
- def initialize_options(self): |
16477 |
- x_build_scripts_custom.initialize_options(self) |
16478 |
- self.build_base = None |
16479 |
- self.build_lib = None |
16480 |
- |
16481 |
- def finalize_options(self): |
16482 |
- x_build_scripts_custom.finalize_options(self) |
16483 |
- self.set_undefined_options( |
16484 |
- "build", ("build_base", "build_base"), ("build_lib", "build_lib") |
16485 |
- ) |
16486 |
- |
16487 |
- # since we will be writing to $build_lib/.., it is important |
16488 |
- # that we do not leave $build_base |
16489 |
- self.top_dir = os.path.normpath(os.path.join(self.build_lib, "..")) |
16490 |
- cprefix = os.path.commonprefix((self.build_base, self.top_dir)) |
16491 |
- if cprefix != self.build_base: |
16492 |
- raise SystemError("build_lib must be a subdirectory of build_base") |
16493 |
- |
16494 |
- self.build_dir = os.path.join(self.top_dir, "bin") |
16495 |
- |
16496 |
- def run(self): |
16497 |
- self.run_command("build_py") |
16498 |
- |
16499 |
- # install all scripts $build_lib/../bin |
16500 |
- # (we can't do a symlink since we want shebangs corrected) |
16501 |
- x_build_scripts_custom.run(self) |
16502 |
- |
16503 |
- # symlink 'cnf' directory |
16504 |
- conf_dir = os.path.join(self.top_dir, "cnf") |
16505 |
- if os.path.exists(conf_dir): |
16506 |
- if not os.path.islink(conf_dir): |
16507 |
- raise SystemError( |
16508 |
- "%s exists and is not a symlink (collision)" % repr(conf_dir) |
16509 |
- ) |
16510 |
- os.unlink(conf_dir) |
16511 |
- conf_src = os.path.relpath("cnf", self.top_dir) |
16512 |
- print("Symlinking %s -> %s" % (conf_dir, conf_src)) |
16513 |
- os.symlink(conf_src, conf_dir) |
16514 |
- |
16515 |
- # create $build_lib/../.repoman_not_installed |
16516 |
- # to enable proper paths in tests |
16517 |
- with open(os.path.join(self.top_dir, ".repoman_not_installed"), "w"): |
16518 |
- pass |
16519 |
- |
16520 |
- |
16521 |
-class test(Command): |
16522 |
- """run tests""" |
16523 |
- |
16524 |
- user_options = [] |
16525 |
- |
16526 |
- def initialize_options(self): |
16527 |
- self.build_lib = None |
16528 |
- |
16529 |
- def finalize_options(self): |
16530 |
- self.set_undefined_options("build", ("build_lib", "build_lib")) |
16531 |
- |
16532 |
- def run(self): |
16533 |
- self.run_command("build_tests") |
16534 |
- # copy GPG test keys |
16535 |
- copy_tree( |
16536 |
- os.path.join( |
16537 |
- self.build_lib, "..", "..", "lib", "repoman", "tests", ".gnupg" |
16538 |
- ), |
16539 |
- os.path.join(self.build_lib, "repoman", "tests", ".gnupg"), |
16540 |
- ) |
16541 |
- os.chmod(os.path.join(self.build_lib, "repoman", "tests", ".gnupg"), 0o700) |
16542 |
- subprocess.check_call( |
16543 |
- [ |
16544 |
- sys.executable, |
16545 |
- "-bWd", |
16546 |
- os.path.join(self.build_lib, "repoman/tests/runTests.py"), |
16547 |
- ] |
16548 |
- ) |
16549 |
- |
16550 |
- |
16551 |
-def find_packages(): |
16552 |
- for dirpath, _dirnames, filenames in os.walk("lib"): |
16553 |
- if "__init__.py" in filenames: |
16554 |
- yield os.path.relpath(dirpath, "lib") |
16555 |
- |
16556 |
- |
16557 |
-def find_scripts(): |
16558 |
- for dirpath, _dirnames, filenames in os.walk("bin"): |
16559 |
- for f in filenames: |
16560 |
- if f not in ["deprecated-path"]: |
16561 |
- yield os.path.join(dirpath, f) |
16562 |
- |
16563 |
- |
16564 |
-def get_manpages(): |
16565 |
- linguas = os.environ.get("LINGUAS") |
16566 |
- if linguas is not None: |
16567 |
- linguas = linguas.split() |
16568 |
- |
16569 |
- for dirpath, _dirnames, filenames in os.walk("man"): |
16570 |
- groups = collections.defaultdict(list) |
16571 |
- for f in filenames: |
16572 |
- _fn, suffix = f.rsplit(".", 1) |
16573 |
- groups[suffix].append(os.path.join(dirpath, f)) |
16574 |
- |
16575 |
- topdir = dirpath[len("man/") :] |
16576 |
- if not topdir or linguas is None or topdir in linguas: |
16577 |
- for g, mans in groups.items(): |
16578 |
- yield [os.path.join("$mandir", topdir, "man%s" % g), mans] |
16579 |
- |
16580 |
- |
16581 |
-setup( |
16582 |
- name="repoman", |
16583 |
- version="3.0.3", |
16584 |
- url="https://wiki.gentoo.org/wiki/Project:Portage", |
16585 |
- author="Gentoo Portage Development Team", |
16586 |
- author_email="dev-portage@g.o", |
16587 |
- package_dir={"": "lib"}, |
16588 |
- packages=list(find_packages()), |
16589 |
- # something to cheat build & install commands |
16590 |
- scripts=list(find_scripts()), |
16591 |
- data_files=list(get_manpages()) |
16592 |
- + [ |
16593 |
- ["$docdir", ["NEWS", "RELEASE-NOTES"]], |
16594 |
- ["share/repoman/qa_data", ["cnf/qa_data/qa_data.yaml"]], |
16595 |
- ["share/repoman/linechecks", ["cnf/linechecks/linechecks.yaml"]], |
16596 |
- [ |
16597 |
- "share/repoman/repository", |
16598 |
- [ |
16599 |
- "cnf/repository/linechecks.yaml", |
16600 |
- "cnf/repository/qa_data.yaml", |
16601 |
- "cnf/repository/repository.yaml", |
16602 |
- ], |
16603 |
- ], |
16604 |
- ], |
16605 |
- cmdclass={ |
16606 |
- "build": x_build, |
16607 |
- "build_man": build_man, |
16608 |
- "build_scripts": x_build_scripts, |
16609 |
- "build_scripts_bin": x_build_scripts_bin, |
16610 |
- "build_tests": build_tests, |
16611 |
- "clean": x_clean, |
16612 |
- "install": x_install, |
16613 |
- "install_data": x_install_data, |
16614 |
- "install_lib": x_install_lib, |
16615 |
- "install_scripts": x_install_scripts, |
16616 |
- "install_scripts_bin": x_install_scripts_bin, |
16617 |
- "sdist": x_sdist, |
16618 |
- "test": test, |
16619 |
- }, |
16620 |
- classifiers=[ |
16621 |
- "Development Status :: 5 - Production/Stable", |
16622 |
- "Environment :: Console", |
16623 |
- "Intended Audience :: System Administrators", |
16624 |
- "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", |
16625 |
- "Operating System :: POSIX", |
16626 |
- "Programming Language :: Python :: 3", |
16627 |
- "Topic :: System :: Installation/Setup", |
16628 |
- ], |
16629 |
-) |
16630 |
|
16631 |
diff --git a/tox.ini b/tox.ini |
16632 |
index 2281dfa24..84c24396e 100644 |
16633 |
--- a/tox.ini |
16634 |
+++ b/tox.ini |
16635 |
@@ -20,6 +20,5 @@ deps = |
16636 |
setenv = |
16637 |
PYTHONPATH={toxinidir}/lib |
16638 |
commands = |
16639 |
- pylint: bash -c 'rm -rf build && PYTHONPATH=$PWD/lib:$PWD/repoman/lib pylint bin/* lib/* repoman/bin/* repoman/lib/*' |
16640 |
+ pylint: bash -c 'rm -rf build && PYTHONPATH=$PWD/lib pylint bin/* lib/*' |
16641 |
python -b -Wd setup.py test |
16642 |
- bash -c 'if python -c "import lxml.etree"; then python -b -Wd repoman/setup.py test; else echo "repoman tests skipped due to lxml breakage"; fi' |