1 |
--- |
2 |
man/portage.5 | 5 ++ |
3 |
pym/portage/package/ebuild/config.py | 2 + |
4 |
pym/portage/repository/config.py | 10 ++-- |
5 |
pym/portage/sync/modules/rsync/__init__.py | 2 +- |
6 |
pym/portage/sync/modules/rsync/rsync.py | 6 ++- |
7 |
pym/portage/tests/sync/test_sync_local.py | 73 +++++++++++++++++++++++++++--- |
8 |
6 files changed, 85 insertions(+), 13 deletions(-) |
9 |
|
10 |
diff --git a/man/portage.5 b/man/portage.5 |
11 |
index e77fc6e..e84142a 100644 |
12 |
--- a/man/portage.5 |
13 |
+++ b/man/portage.5 |
14 |
@@ -1021,6 +1021,11 @@ group id will be changed. |
15 |
.br |
16 |
This key takes precedence over FEATURES=userpriv. If user or group id |
17 |
is provided, Portage no longer uses owner of the directory. |
18 |
+.TP |
19 |
+.B sync-rsync-extra-opts |
20 |
+Extra options to give to rsync on repository synchronization. It takes |
21 |
+precedence over a declaration in [DEFAULT] section, that takes |
22 |
+precedence over PORTAGE_RSYNC_EXTRA_OPTS. |
23 |
.RE |
24 |
|
25 |
.I Example: |
26 |
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py |
27 |
index 3a4007b..08db363 100644 |
28 |
--- a/pym/portage/package/ebuild/config.py |
29 |
+++ b/pym/portage/package/ebuild/config.py |
30 |
@@ -515,6 +515,8 @@ class config(object): |
31 |
v = confs.get("SYNC") |
32 |
if v is not None: |
33 |
portdir_sync = v |
34 |
+ if 'PORTAGE_RSYNC_EXTRA_OPTS' in confs: |
35 |
+ self['PORTAGE_RSYNC_EXTRA_OPTS'] = confs['PORTAGE_RSYNC_EXTRA_OPTS'] |
36 |
|
37 |
self["PORTDIR"] = portdir |
38 |
self["PORTDIR_OVERLAY"] = portdir_overlay |
39 |
diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py |
40 |
index a461ffb..eb183e2 100644 |
41 |
--- a/pym/portage/repository/config.py |
42 |
+++ b/pym/portage/repository/config.py |
43 |
@@ -545,9 +545,9 @@ class RepoConfigLoader(object): |
44 |
return portdir |
45 |
|
46 |
@staticmethod |
47 |
- def _parse(paths, prepos, ignored_map, ignored_location_map, local_config, portdir): |
48 |
+ def _parse(paths, prepos, ignored_map, ignored_location_map, local_config, portdir, default_opts): |
49 |
"""Parse files in paths to load config""" |
50 |
- parser = SafeConfigParser() |
51 |
+ parser = SafeConfigParser(defaults=default_opts) |
52 |
|
53 |
# use read_file/readfp in order to control decoding of unicode |
54 |
try: |
55 |
@@ -619,6 +619,7 @@ class RepoConfigLoader(object): |
56 |
treemap = {} |
57 |
ignored_map = {} |
58 |
ignored_location_map = {} |
59 |
+ default_opts = {} |
60 |
|
61 |
if "PORTAGE_REPOSITORIES" in settings: |
62 |
portdir = "" |
63 |
@@ -631,10 +632,13 @@ class RepoConfigLoader(object): |
64 |
# deprecated portdir_sync |
65 |
portdir_sync = settings.get("SYNC", "") |
66 |
|
67 |
+ default_opts['sync-rsync-extra-opts'] = \ |
68 |
+ settings.get("PORTAGE_RSYNC_EXTRA_OPTS", None) |
69 |
+ |
70 |
try: |
71 |
self._parse(paths, prepos, ignored_map, |
72 |
ignored_location_map, settings.local_config, |
73 |
- portdir) |
74 |
+ portdir, default_opts) |
75 |
except ConfigParserError as e: |
76 |
writemsg( |
77 |
_("!!! Error while reading repo config file: %s\n") % e, |
78 |
diff --git a/pym/portage/sync/modules/rsync/__init__.py b/pym/portage/sync/modules/rsync/__init__.py |
79 |
index 13832f8..f2bad09 100644 |
80 |
--- a/pym/portage/sync/modules/rsync/__init__.py |
81 |
+++ b/pym/portage/sync/modules/rsync/__init__.py |
82 |
@@ -23,7 +23,7 @@ module_spec = { |
83 |
'exists': 'Returns a boolean if the specified directory exists', |
84 |
}, |
85 |
'validate_config': CheckSyncConfig, |
86 |
- 'module_specific_options': (), |
87 |
+ 'module_specific_options': ('sync-rsync-extra-opts',), |
88 |
} |
89 |
} |
90 |
} |
91 |
diff --git a/pym/portage/sync/modules/rsync/rsync.py b/pym/portage/sync/modules/rsync/rsync.py |
92 |
index d84c36d..8041f07 100644 |
93 |
--- a/pym/portage/sync/modules/rsync/rsync.py |
94 |
+++ b/pym/portage/sync/modules/rsync/rsync.py |
95 |
@@ -72,8 +72,10 @@ class RsyncSync(NewBase): |
96 |
rsync_opts = self._validate_rsync_opts(rsync_opts, syncuri) |
97 |
self.rsync_opts = self._rsync_opts_extend(opts, rsync_opts) |
98 |
|
99 |
- self.extra_rsync_opts = portage.util.shlex_split( |
100 |
- self.settings.get("PORTAGE_RSYNC_EXTRA_OPTS","")) |
101 |
+ self.extra_rsync_opts = list() |
102 |
+ if 'sync-rsync-extra-opts' in self.repo.module_specific_options: |
103 |
+ self.extra_rsync_opts.extend(portage.util.shlex_split( |
104 |
+ self.repo.module_specific_options['sync-rsync-extra-opts'])) |
105 |
|
106 |
# Real local timestamp file. |
107 |
self.servertimestampfile = os.path.join( |
108 |
diff --git a/pym/portage/tests/sync/test_sync_local.py b/pym/portage/tests/sync/test_sync_local.py |
109 |
index 65c20f8..f50caba 100644 |
110 |
--- a/pym/portage/tests/sync/test_sync_local.py |
111 |
+++ b/pym/portage/tests/sync/test_sync_local.py |
112 |
@@ -7,7 +7,7 @@ import textwrap |
113 |
import time |
114 |
|
115 |
import portage |
116 |
-from portage import os, shutil |
117 |
+from portage import os, shutil, _shell_quote |
118 |
from portage import _unicode_decode |
119 |
from portage.const import PORTAGE_PYM_PATH, TIMESTAMP_FORMAT |
120 |
from portage.process import find_binary |
121 |
@@ -36,11 +36,14 @@ class SyncLocalTestCase(TestCase): |
122 |
return |
123 |
|
124 |
repos_conf = textwrap.dedent(""" |
125 |
+ [DEFAULT] |
126 |
+ %(default_keys)s |
127 |
[test_repo] |
128 |
location = %(EPREFIX)s/var/repositories/test_repo |
129 |
sync-type = %(sync-type)s |
130 |
sync-uri = file:/%(EPREFIX)s/var/repositories/test_repo_sync |
131 |
auto-sync = yes |
132 |
+ %(repo_extra_keys)s |
133 |
""") |
134 |
|
135 |
profile = { |
136 |
@@ -73,9 +76,17 @@ class SyncLocalTestCase(TestCase): |
137 |
committer_name = "Gentoo Dev" |
138 |
committer_email = "gentoo-dev@g.o" |
139 |
|
140 |
- def change_sync_type(sync_type): |
141 |
- env["PORTAGE_REPOSITORIES"] = repos_conf % \ |
142 |
- {"EPREFIX": eprefix, "sync-type": sync_type} |
143 |
+ def repos_set_conf(sync_type, dflt_keys=None, xtra_keys=None): |
144 |
+ env["PORTAGE_REPOSITORIES"] = repos_conf % {\ |
145 |
+ "EPREFIX": eprefix, "sync-type": sync_type, |
146 |
+ "default_keys": "" if dflt_keys is None else dflt_keys, |
147 |
+ "repo_extra_keys": "" if xtra_keys is None else xtra_keys} |
148 |
+ |
149 |
+ def alter_ebuild(): |
150 |
+ with open(os.path.join(repo.location + "_sync", |
151 |
+ "dev-libs", "A", "A-0.ebuild"), "a") as f: |
152 |
+ f.write("\n") |
153 |
+ os.unlink(os.path.join(metadata_dir, 'timestamp.chk')) |
154 |
|
155 |
sync_cmds = ( |
156 |
(homedir, cmds["emerge"] + ("--sync",)), |
157 |
@@ -90,6 +101,53 @@ class SyncLocalTestCase(TestCase): |
158 |
repo.location + "_sync")), |
159 |
) |
160 |
|
161 |
+ rsync_opts_repos = ( |
162 |
+ (homedir, alter_ebuild), |
163 |
+ (homedir, lambda: repos_set_conf("rsync", None, |
164 |
+ "sync-rsync-extra-opts = --backup --backup-dir=%s" % |
165 |
+ _shell_quote(repo.location + "_back"))), |
166 |
+ (homedir, cmds['emerge'] + ("--sync",)), |
167 |
+ (homedir, lambda: self.assertTrue(os.path.exists( |
168 |
+ repo.location + "_back"))), |
169 |
+ (homedir, lambda: shutil.rmtree(repo.location + "_back")), |
170 |
+ (homedir, lambda: repos_set_conf("rsync")), |
171 |
+ ) |
172 |
+ |
173 |
+ rsync_opts_repos_default = ( |
174 |
+ (homedir, alter_ebuild), |
175 |
+ (homedir, lambda: repos_set_conf("rsync", |
176 |
+ "sync-rsync-extra-opts = --backup --backup-dir=%s" % |
177 |
+ _shell_quote(repo.location+"_back"))), |
178 |
+ (homedir, cmds['emerge'] + ("--sync",)), |
179 |
+ (homedir, lambda: self.assertTrue(os.path.exists(repo.location + "_back"))), |
180 |
+ (homedir, lambda: shutil.rmtree(repo.location + "_back")), |
181 |
+ (homedir, lambda: repos_set_conf("rsync")), |
182 |
+ ) |
183 |
+ |
184 |
+ rsync_opts_repos_default_ovr = ( |
185 |
+ (homedir, alter_ebuild), |
186 |
+ (homedir, lambda: repos_set_conf("rsync", |
187 |
+ "sync-rsync-extra-opts = --backup --backup-dir=%s" % |
188 |
+ _shell_quote(repo.location + "_back_nowhere"), |
189 |
+ "sync-rsync-extra-opts = --backup --backup-dir=%s" % |
190 |
+ _shell_quote(repo.location + "_back"))), |
191 |
+ (homedir, cmds['emerge'] + ("--sync",)), |
192 |
+ (homedir, lambda: self.assertTrue(os.path.exists(repo.location + "_back"))), |
193 |
+ (homedir, lambda: shutil.rmtree(repo.location + "_back")), |
194 |
+ (homedir, lambda: repos_set_conf("rsync")), |
195 |
+ ) |
196 |
+ |
197 |
+ rsync_opts_repos_default_cancel = ( |
198 |
+ (homedir, alter_ebuild), |
199 |
+ (homedir, lambda: repos_set_conf("rsync", |
200 |
+ "sync-rsync-extra-opts = --backup --backup-dir=%s" % |
201 |
+ _shell_quote(repo.location + "_back_nowhere"), |
202 |
+ "sync-rsync-extra-opts = ")), |
203 |
+ (homedir, cmds['emerge'] + ("--sync",)), |
204 |
+ (homedir, lambda: self.assertFalse(os.path.exists(repo.location + "_back"))), |
205 |
+ (homedir, lambda: repos_set_conf("rsync")), |
206 |
+ ) |
207 |
+ |
208 |
delete_sync_repo = ( |
209 |
(homedir, lambda: shutil.rmtree( |
210 |
repo.location + "_sync")), |
211 |
@@ -107,7 +165,7 @@ class SyncLocalTestCase(TestCase): |
212 |
) |
213 |
|
214 |
sync_type_git = ( |
215 |
- (homedir, lambda: change_sync_type("git")), |
216 |
+ (homedir, lambda: repos_set_conf("git")), |
217 |
) |
218 |
|
219 |
pythonpath = os.environ.get("PYTHONPATH") |
220 |
@@ -132,10 +190,9 @@ class SyncLocalTestCase(TestCase): |
221 |
"PATH" : os.environ["PATH"], |
222 |
"PORTAGE_GRPNAME" : os.environ["PORTAGE_GRPNAME"], |
223 |
"PORTAGE_USERNAME" : os.environ["PORTAGE_USERNAME"], |
224 |
- "PORTAGE_REPOSITORIES" : repos_conf % |
225 |
- {"EPREFIX": eprefix, "sync-type": "rsync"}, |
226 |
"PYTHONPATH" : pythonpath, |
227 |
} |
228 |
+ repos_set_conf("rsync") |
229 |
|
230 |
if os.environ.get("SANDBOX_ON") == "1": |
231 |
# avoid problems from nested sandbox instances |
232 |
@@ -160,6 +217,8 @@ class SyncLocalTestCase(TestCase): |
233 |
stdout = subprocess.PIPE |
234 |
|
235 |
for cwd, cmd in rename_repo + sync_cmds + \ |
236 |
+ rsync_opts_repos + rsync_opts_repos_default + \ |
237 |
+ rsync_opts_repos_default_ovr + rsync_opts_repos_default_cancel + \ |
238 |
delete_sync_repo + git_repo_create + sync_type_git + \ |
239 |
rename_repo + sync_cmds: |
240 |
|
241 |
-- |
242 |
2.0.5 |