1 |
--- |
2 |
pym/portage/emaint/modules/merges/__init__.py | 20 ++++++++ |
3 |
pym/portage/emaint/modules/merges/merges.py | 70 +++++++++++++++++++++++++++ |
4 |
2 files changed, 90 insertions(+) |
5 |
create mode 100644 pym/portage/emaint/modules/merges/__init__.py |
6 |
create mode 100644 pym/portage/emaint/modules/merges/merges.py |
7 |
|
8 |
diff --git a/pym/portage/emaint/modules/merges/__init__.py b/pym/portage/emaint/modules/merges/__init__.py |
9 |
new file mode 100644 |
10 |
index 0000000..2cd79af |
11 |
--- /dev/null |
12 |
+++ b/pym/portage/emaint/modules/merges/__init__.py |
13 |
@@ -0,0 +1,20 @@ |
14 |
+# Copyright 2005-2014 Gentoo Foundation |
15 |
+# Distributed under the terms of the GNU General Public License v2 |
16 |
+ |
17 |
+"""Scan for failed merges and fix them. |
18 |
+""" |
19 |
+ |
20 |
+ |
21 |
+module_spec = { |
22 |
+ 'name': 'merges', |
23 |
+ 'description': __doc__, |
24 |
+ 'provides':{ |
25 |
+ 'module1': { |
26 |
+ 'name': "merges", |
27 |
+ 'class': "MergesHandler", |
28 |
+ 'description': __doc__, |
29 |
+ 'functions': ['check', 'fix',], |
30 |
+ 'func_desc': {} |
31 |
+ } |
32 |
+ } |
33 |
+ } |
34 |
diff --git a/pym/portage/emaint/modules/merges/merges.py b/pym/portage/emaint/modules/merges/merges.py |
35 |
new file mode 100644 |
36 |
index 0000000..b243082 |
37 |
--- /dev/null |
38 |
+++ b/pym/portage/emaint/modules/merges/merges.py |
39 |
@@ -0,0 +1,70 @@ |
40 |
+# Copyright 2005-2014 Gentoo Foundation |
41 |
+# Distributed under the terms of the GNU General Public License v2 |
42 |
+ |
43 |
+import portage |
44 |
+from portage import os |
45 |
+from portage.const import PRIVATE_PATH, VDB_PATH |
46 |
+from portage.util import writemsg |
47 |
+ |
48 |
+import shutil |
49 |
+import sys |
50 |
+ |
51 |
+if sys.hexversion >= 0x3000000: |
52 |
+ # pylint: disable=W0622 |
53 |
+ long = int |
54 |
+ |
55 |
+class MergesHandler(object): |
56 |
+ |
57 |
+ short_desc = "Remove failed merges" |
58 |
+ |
59 |
+ def name(): |
60 |
+ return "merges" |
61 |
+ name = staticmethod(name) |
62 |
+ |
63 |
+ def __init__(self): |
64 |
+ self._eroot = portage.settings['EROOT'] |
65 |
+ self._vardb = portage.db[self._eroot]["vartree"].dbapi |
66 |
+ self._vardb_path = os.path.join(self._eroot, VDB_PATH) + os.path.sep |
67 |
+ |
68 |
+ def can_progressbar(self, func): |
69 |
+ return True |
70 |
+ |
71 |
+ def _failed_packages(self, onProgress): |
72 |
+ for cat in os.listdir(self._vardb_path): |
73 |
+ pkgs = os.listdir(self._vardb_path + cat) |
74 |
+ maxval = len(pkgs) |
75 |
+ for i, pkg in enumerate(pkgs): |
76 |
+ if onProgress: |
77 |
+ onProgress(maxval, i+1) |
78 |
+ |
79 |
+ if '-MERGING-' in pkg: |
80 |
+ yield cat + os.path.sep + pkg |
81 |
+ |
82 |
+ def check(self, **kwargs): |
83 |
+ onProgress = kwargs.get('onProgress', None) |
84 |
+ failed_pkgs = [] |
85 |
+ for pkg in self._failed_packages(onProgress): |
86 |
+ failed_pkgs.append(pkg) |
87 |
+ |
88 |
+ errors = ["'%s' failed to merge." % x for x in failed_pkgs] |
89 |
+ return errors |
90 |
+ |
91 |
+ def fix(self, **kwargs): |
92 |
+ onProgress = kwargs.get('onProgress', None) |
93 |
+ tracking_path = os.path.join(self._eroot, PRIVATE_PATH, 'failed-merges'); |
94 |
+ try: |
95 |
+ with open(tracking_path, 'w') as tracking_file: |
96 |
+ for failed_pkg in self._failed_packages(onProgress): |
97 |
+ tracking_file.write(failed_pkg + '\n') |
98 |
+ pkg_path = self._vardb_path + failed_pkg |
99 |
+ # Delete failed merge directory |
100 |
+ # XXX: Would be a good idea to attempt try removing |
101 |
+ # package contents to prevent orphaned files |
102 |
+ shutil.rmtree(pkg_path) |
103 |
+ # Re-emerge package |
104 |
+ pkg_name = '=' + failed_pkg.replace('-MERGING-', '') |
105 |
+ features='FEATURES="-collision-detect -protect-owned"' |
106 |
+ emerge_cmd="emerge --verbose --oneshot --complete-graph=y" |
107 |
+ os.system('%s %s %s' % (features, emerge_cmd, pkg_name)) |
108 |
+ except Exception as ex: |
109 |
+ writemsg('Unable to fix failed package: %s' % str(ex)) |
110 |
-- |
111 |
1.8.3.2 |