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