1 |
commit: 6d102b25d75d5b2b5a96242ab2cc9e28b75d13fd |
2 |
Author: Brian Dolbec <dolsen <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sat Jan 30 01:58:36 2016 +0000 |
4 |
Commit: Brian Dolbec <dolsen <AT> gentoo <DOT> org> |
5 |
CommitDate: Sat Jan 30 06:51:59 2016 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=6d102b25 |
7 |
|
8 |
repoman: Migrate actions.py vcs code to the vcs modules |
9 |
|
10 |
Add missing changes code to the existing Changes classes. |
11 |
This removes the duplicated code in the Actions class. |
12 |
It alsosspeeds up the run by not calling the vcs binary to scan for changes a second time. |
13 |
Optimize the code for the vcs modules. |
14 |
|
15 |
pym/repoman/actions.py | 208 ++++--------------------------- |
16 |
pym/repoman/modules/vcs/None/__init__.py | 1 + |
17 |
pym/repoman/modules/vcs/bzr/__init__.py | 1 + |
18 |
pym/repoman/modules/vcs/bzr/changes.py | 15 ++- |
19 |
pym/repoman/modules/vcs/changes.py | 13 ++ |
20 |
pym/repoman/modules/vcs/cvs/__init__.py | 1 + |
21 |
pym/repoman/modules/vcs/cvs/changes.py | 13 +- |
22 |
pym/repoman/modules/vcs/git/__init__.py | 1 + |
23 |
pym/repoman/modules/vcs/git/changes.py | 20 +-- |
24 |
pym/repoman/modules/vcs/hg/__init__.py | 1 + |
25 |
pym/repoman/modules/vcs/hg/changes.py | 27 +++- |
26 |
pym/repoman/modules/vcs/settings.py | 5 +- |
27 |
pym/repoman/modules/vcs/svn/__init__.py | 1 + |
28 |
pym/repoman/modules/vcs/svn/changes.py | 24 +++- |
29 |
14 files changed, 118 insertions(+), 213 deletions(-) |
30 |
|
31 |
diff --git a/pym/repoman/actions.py b/pym/repoman/actions.py |
32 |
index 3fd940c..8cf4a97 100644 |
33 |
--- a/pym/repoman/actions.py |
34 |
+++ b/pym/repoman/actions.py |
35 |
@@ -16,7 +16,6 @@ from itertools import chain |
36 |
from _emerge.UserQuery import UserQuery |
37 |
|
38 |
import portage |
39 |
-from portage import cvstree |
40 |
from portage import os |
41 |
from portage import _encodings |
42 |
from portage import _unicode_encode |
43 |
@@ -26,8 +25,7 @@ from portage.package.ebuild.digestgen import digestgen |
44 |
from portage.process import find_binary, spawn |
45 |
from portage.util import writemsg_level |
46 |
|
47 |
-from repoman._subprocess import repoman_popen, repoman_getstatusoutput |
48 |
-from repoman.errors import err |
49 |
+from repoman._subprocess import repoman_getstatusoutput |
50 |
from repoman.gpg import gpgsign, need_signature |
51 |
from repoman import utilities |
52 |
from repoman.modules.vcs.vcs import vcs_files_to_cps |
53 |
@@ -71,13 +69,11 @@ class Actions(object): |
54 |
|
55 |
|
56 |
def perform(self, qa_output): |
57 |
- myunadded, mydeleted = self._vcs_unadded() |
58 |
+ myautoadd = self._vcs_autoadd() |
59 |
|
60 |
- myautoadd = self._vcs_autoadd(myunadded) |
61 |
+ self._vcs_deleted() |
62 |
|
63 |
- self._vcs_deleted(mydeleted) |
64 |
- |
65 |
- changes = self.get_vcs_changed(mydeleted) |
66 |
+ changes = self.get_vcs_changed() |
67 |
|
68 |
mynew, mychanged, myremoved, no_expansion, expansion = changes |
69 |
|
70 |
@@ -127,8 +123,8 @@ class Actions(object): |
71 |
|
72 |
print("* %s files being committed..." % green(str(len(myupdates))), end=' ') |
73 |
|
74 |
- if self.vcs_settings.vcs not in ('cvs', 'svn'): |
75 |
- # With git, bzr and hg, there's never any keyword expansion, so |
76 |
+ if self.vcs_settings.needs_keyword_expansion: |
77 |
+ # With some VCS types there's never any keyword expansion, so |
78 |
# there's no need to regenerate manifests and all files will be |
79 |
# committed in one big commit at the end. |
80 |
print() |
81 |
@@ -261,62 +257,8 @@ class Actions(object): |
82 |
sys.exit(1) |
83 |
|
84 |
|
85 |
- def _vcs_unadded(self): |
86 |
- myunadded = [] |
87 |
- mydeleted = [] |
88 |
- if self.vcs_settings.vcs == "cvs": |
89 |
- try: |
90 |
- myvcstree = portage.cvstree.getentries("./", recursive=1) |
91 |
- myunadded = portage.cvstree.findunadded( |
92 |
- myvcstree, recursive=1, basedir="./") |
93 |
- except SystemExit: |
94 |
- raise # TODO propagate this |
95 |
- except: |
96 |
- err("Error retrieving CVS tree; exiting.") |
97 |
- if self.vcs_settings.vcs == "svn": |
98 |
- try: |
99 |
- with repoman_popen("svn status --no-ignore") as f: |
100 |
- svnstatus = f.readlines() |
101 |
- myunadded = [ |
102 |
- "./" + elem.rstrip().split()[1] |
103 |
- for elem in svnstatus |
104 |
- if elem.startswith("?") or elem.startswith("I")] |
105 |
- except SystemExit: |
106 |
- raise # TODO propagate this |
107 |
- except: |
108 |
- err("Error retrieving SVN info; exiting.") |
109 |
- if self.vcs_settings.vcs == "git": |
110 |
- # get list of files not under version control or missing |
111 |
- myf = repoman_popen("git ls-files --others") |
112 |
- myunadded = ["./" + elem[:-1] for elem in myf] |
113 |
- myf.close() |
114 |
- if self.vcs_settings.vcs == "bzr": |
115 |
- try: |
116 |
- with repoman_popen("bzr status -S .") as f: |
117 |
- bzrstatus = f.readlines() |
118 |
- myunadded = [ |
119 |
- "./" + elem.rstrip().split()[1].split('/')[-1:][0] |
120 |
- for elem in bzrstatus |
121 |
- if elem.startswith("?") or elem[0:2] == " D"] |
122 |
- except SystemExit: |
123 |
- raise # TODO propagate this |
124 |
- except: |
125 |
- err("Error retrieving bzr info; exiting.") |
126 |
- if self.vcs_settings.vcs == "hg": |
127 |
- with repoman_popen("hg status --no-status --unknown .") as f: |
128 |
- myunadded = f.readlines() |
129 |
- myunadded = ["./" + elem.rstrip() for elem in myunadded] |
130 |
- |
131 |
- # Mercurial doesn't handle manually deleted files as removed from |
132 |
- # the repository, so the user need to remove them before commit, |
133 |
- # using "hg remove [FILES]" |
134 |
- with repoman_popen("hg status --no-status --deleted .") as f: |
135 |
- mydeleted = f.readlines() |
136 |
- mydeleted = ["./" + elem.rstrip() for elem in mydeleted] |
137 |
- return myunadded, mydeleted |
138 |
- |
139 |
- |
140 |
- def _vcs_autoadd(self, myunadded): |
141 |
+ def _vcs_autoadd(self): |
142 |
+ myunadded = self.vcs_settings.changes.unadded |
143 |
myautoadd = [] |
144 |
if myunadded: |
145 |
for x in range(len(myunadded) - 1, -1, -1): |
146 |
@@ -348,137 +290,35 @@ class Actions(object): |
147 |
return myautoadd |
148 |
|
149 |
|
150 |
- def _vcs_deleted(self, mydeleted): |
151 |
- if self.vcs_settings.vcs == "hg" and mydeleted: |
152 |
+ def _vcs_deleted(self): |
153 |
+ if self.vcs_settings.changes.has_deleted(): |
154 |
print(red( |
155 |
"!!! The following files are removed manually" |
156 |
" from your local tree but are not")) |
157 |
print(red( |
158 |
"!!! removed from the repository." |
159 |
- " Please remove them, using \"hg remove [FILES]\".")) |
160 |
- for x in mydeleted: |
161 |
+ " Please remove them, using \"%s remove [FILES]\"." |
162 |
+ % self.vcs_settings.vcs)) |
163 |
+ for x in self.vcs_settings.changes.deleted: |
164 |
print(" ", x) |
165 |
print() |
166 |
print() |
167 |
sys.exit(1) |
168 |
|
169 |
|
170 |
- def get_vcs_changed(self, mydeleted): |
171 |
+ def get_vcs_changed(self): |
172 |
'''Holding function which calls the approriate VCS module for the data''' |
173 |
- changed = ([], [], [], [], []) |
174 |
- if self.vcs_settings.vcs: |
175 |
- vcs_module = getattr(self, '_get_changed_%s_' % self.vcs_settings.vcs) |
176 |
- changed = vcs_module(mydeleted) |
177 |
- mynew, mychanged, myremoved, no_expansion, expansion = changed |
178 |
- |
179 |
- a_file_is_changed = mychanged or mynew or myremoved |
180 |
- a_file_is_deleted_hg = self.vcs_settings.vcs == "hg" and mydeleted |
181 |
- |
182 |
- if not (a_file_is_changed or a_file_is_deleted_hg): |
183 |
- utilities.repoman_sez( |
184 |
- "\"Doing nothing is not always good for QA.\"") |
185 |
- print() |
186 |
- print("(Didn't find any changed files...)") |
187 |
- print() |
188 |
- sys.exit(1) |
189 |
- return changed |
190 |
- |
191 |
- |
192 |
- def _get_changed_cvs_(self, mydeleted): |
193 |
- mycvstree = cvstree.getentries("./", recursive=1) |
194 |
- mychanged = cvstree.findchanged(mycvstree, recursive=1, basedir="./") |
195 |
- mynew = cvstree.findnew(mycvstree, recursive=1, basedir="./") |
196 |
- myremoved = portage.cvstree.findremoved(mycvstree, recursive=1, basedir="./") |
197 |
- bin_blob_pattern = re.compile("^-kb$") |
198 |
- no_expansion = set(portage.cvstree.findoption( |
199 |
- mycvstree, bin_blob_pattern, recursive=1, basedir="./")) |
200 |
- expansion = {} |
201 |
- return (mynew, mychanged, myremoved, no_expansion, expansion) |
202 |
- |
203 |
- def _get_changed_svn_(self, mydeleted): |
204 |
- with repoman_popen("svn status") as f: |
205 |
- svnstatus = f.readlines() |
206 |
- mychanged = [ |
207 |
- "./" + elem.split()[-1:][0] |
208 |
- for elem in svnstatus |
209 |
- if (elem[:1] in "MR" or elem[1:2] in "M")] |
210 |
- mynew = [ |
211 |
- "./" + elem.split()[-1:][0] |
212 |
- for elem in svnstatus |
213 |
- if elem.startswith("A")] |
214 |
- myremoved = [ |
215 |
- "./" + elem.split()[-1:][0] |
216 |
- for elem in svnstatus |
217 |
- if elem.startswith("D")] |
218 |
- # Subversion expands keywords specified in svn:keywords properties. |
219 |
- with repoman_popen("svn propget -R svn:keywords") as f: |
220 |
- props = f.readlines() |
221 |
- expansion = dict( |
222 |
- ("./" + prop.split(" - ")[0], prop.split(" - ")[1].split()) |
223 |
- for prop in props if " - " in prop) |
224 |
- no_expansion = set() |
225 |
- return (mynew, mychanged, myremoved, no_expansion, expansion) |
226 |
- |
227 |
- def _get_changed_git_(self, mydeleted): |
228 |
- with repoman_popen( |
229 |
- "git diff-index --name-only " |
230 |
- "--relative --diff-filter=M HEAD") as f: |
231 |
- mychanged = f.readlines() |
232 |
- mychanged = ["./" + elem[:-1] for elem in mychanged] |
233 |
- with repoman_popen( |
234 |
- "git diff-index --name-only " |
235 |
- "--relative --diff-filter=A HEAD") as f: |
236 |
- mynew = f.readlines() |
237 |
- mynew = ["./" + elem[:-1] for elem in mynew] |
238 |
- with repoman_popen( |
239 |
- "git diff-index --name-only " |
240 |
- "--relative --diff-filter=D HEAD") as f: |
241 |
- myremoved = f.readlines() |
242 |
- myremoved = ["./" + elem[:-1] for elem in myremoved] |
243 |
- no_expansion = set() |
244 |
- expansion = {} |
245 |
- return (mynew, mychanged, myremoved, no_expansion, expansion) |
246 |
- |
247 |
- def _get_changed_bzr_(self, mydeleted): |
248 |
- with repoman_popen("bzr status -S .") as f: |
249 |
- bzrstatus = f.readlines() |
250 |
- mychanged = [ |
251 |
- "./" + elem.split()[-1:][0].split('/')[-1:][0] |
252 |
- for elem in bzrstatus |
253 |
- if elem and elem[1:2] == "M"] |
254 |
- mynew = [ |
255 |
- "./" + elem.split()[-1:][0].split('/')[-1:][0] |
256 |
- for elem in bzrstatus |
257 |
- if elem and (elem[1:2] in "NK" or elem[0:1] == "R")] |
258 |
- myremoved = [ |
259 |
- "./" + elem.split()[-1:][0].split('/')[-1:][0] |
260 |
- for elem in bzrstatus |
261 |
- if elem.startswith("-")] |
262 |
- myremoved = [ |
263 |
- "./" + elem.split()[-3:-2][0].split('/')[-1:][0] |
264 |
- for elem in bzrstatus |
265 |
- if elem and (elem[1:2] == "K" or elem[0:1] == "R")] |
266 |
- # Bazaar expands nothing. |
267 |
- no_expansion = set() |
268 |
- expansion = {} |
269 |
- return (mynew, mychanged, myremoved, no_expansion, expansion) |
270 |
- |
271 |
- def _get_changed_hg_(self, mydeleted): |
272 |
- with repoman_popen("hg status --no-status --modified .") as f: |
273 |
- mychanged = f.readlines() |
274 |
- mychanged = ["./" + elem.rstrip() for elem in mychanged] |
275 |
- |
276 |
- with repoman_popen("hg status --no-status --added .") as f: |
277 |
- mynew = f.readlines() |
278 |
- mynew = ["./" + elem.rstrip() for elem in mynew] |
279 |
- |
280 |
- with repoman_popen("hg status --no-status --removed .") as f: |
281 |
- myremoved = f.readlines() |
282 |
- myremoved = ["./" + elem.rstrip() for elem in myremoved] |
283 |
- no_expansion = set() |
284 |
- expansion = {} |
285 |
- return (mynew, mychanged, myremoved, no_expansion, expansion) |
286 |
+ changes = self.vcs_settings.vcs.changes |
287 |
|
288 |
+ if not changes.has_changes: |
289 |
+ utilities.repoman_sez( |
290 |
+ "\"Doing nothing is not always good for QA.\"") |
291 |
+ print() |
292 |
+ print("(Didn't find any changed files...)") |
293 |
+ print() |
294 |
+ sys.exit(1) |
295 |
+ return (changes.new, changes.changed, changes.removed, |
296 |
+ changes.no_expansion, changes.expansion) |
297 |
|
298 |
def get_commit_footer(self): |
299 |
portage_version = getattr(portage, "VERSION", None) |
300 |
|
301 |
diff --git a/pym/repoman/modules/vcs/None/__init__.py b/pym/repoman/modules/vcs/None/__init__.py |
302 |
index 4146e1e..2859325 100644 |
303 |
--- a/pym/repoman/modules/vcs/None/__init__.py |
304 |
+++ b/pym/repoman/modules/vcs/None/__init__.py |
305 |
@@ -19,6 +19,7 @@ module_spec = { |
306 |
'func_desc': { |
307 |
}, |
308 |
'vcs_preserves_mtime': False, |
309 |
+ 'needs_keyword_expansion': False, |
310 |
}, |
311 |
'None-changes': { |
312 |
'name': "None_changes", |
313 |
|
314 |
diff --git a/pym/repoman/modules/vcs/bzr/__init__.py b/pym/repoman/modules/vcs/bzr/__init__.py |
315 |
index ccdbddf..1192782 100644 |
316 |
--- a/pym/repoman/modules/vcs/bzr/__init__.py |
317 |
+++ b/pym/repoman/modules/vcs/bzr/__init__.py |
318 |
@@ -19,6 +19,7 @@ module_spec = { |
319 |
'func_desc': { |
320 |
}, |
321 |
'vcs_preserves_mtime': True, |
322 |
+ 'needs_keyword_expansion': False, |
323 |
}, |
324 |
'bzr-changes': { |
325 |
'name': "bzr_changes", |
326 |
|
327 |
diff --git a/pym/repoman/modules/vcs/bzr/changes.py b/pym/repoman/modules/vcs/bzr/changes.py |
328 |
index 0f70613..dab5d73 100644 |
329 |
--- a/pym/repoman/modules/vcs/bzr/changes.py |
330 |
+++ b/pym/repoman/modules/vcs/bzr/changes.py |
331 |
@@ -25,8 +25,13 @@ class Changes(ChangesBase): |
332 |
"./" + elem.split()[-1:][0].split('/')[-1:][0] |
333 |
for elem in bzrstatus |
334 |
if elem and (elem[1:2] == "NK" or elem[0:1] == "R")] |
335 |
- if self.options.if_modified == "y": |
336 |
- self.removed = [ |
337 |
- "./" + elem.split()[-3:-2][0].split('/')[-1:][0] |
338 |
- for elem in bzrstatus |
339 |
- if elem and (elem[1:2] == "K" or elem[0:1] == "R")] |
340 |
+ #if self.options.if_modified == "y": |
341 |
+ self.removed = [ |
342 |
+ "./" + elem.split()[-3:-2][0].split('/')[-1:][0] |
343 |
+ for elem in bzrstatus |
344 |
+ if elem and (elem[1:2] == "K" or elem[0:1] == "R")] |
345 |
+ self.unadded = [ |
346 |
+ "./" + elem.rstrip().split()[1].split('/')[-1:][0] |
347 |
+ for elem in bzrstatus |
348 |
+ if elem.startswith("?") or elem[0:2] == " D"] |
349 |
+ # Bazaar expands nothing. |
350 |
|
351 |
diff --git a/pym/repoman/modules/vcs/changes.py b/pym/repoman/modules/vcs/changes.py |
352 |
index 6553ac9..b677964 100644 |
353 |
--- a/pym/repoman/modules/vcs/changes.py |
354 |
+++ b/pym/repoman/modules/vcs/changes.py |
355 |
@@ -21,6 +21,10 @@ class ChangesBase(object): |
356 |
self.changed = [] |
357 |
self.new = [] |
358 |
self.removed = [] |
359 |
+ self.no_expansion = set() |
360 |
+ self.expansion = {} |
361 |
+ self.deleted = [] |
362 |
+ self.unadded = [] |
363 |
|
364 |
def scan(self): |
365 |
self._reset() |
366 |
@@ -37,3 +41,12 @@ class ChangesBase(object): |
367 |
'''Placeholder for subclassing''' |
368 |
pass |
369 |
|
370 |
+ @property |
371 |
+ def has_deleted(self): |
372 |
+ '''Placeholder for VCS that requires manual deletion of files''' |
373 |
+ return self.deleted != [] |
374 |
+ |
375 |
+ @property |
376 |
+ def has_changes(self): |
377 |
+ '''Placeholder for VCS repo common has changes result''' |
378 |
+ return (self.changed or self.new or self.removed or self.deleted) == [] |
379 |
|
380 |
diff --git a/pym/repoman/modules/vcs/cvs/__init__.py b/pym/repoman/modules/vcs/cvs/__init__.py |
381 |
index 6db6078..ba60e2c 100644 |
382 |
--- a/pym/repoman/modules/vcs/cvs/__init__.py |
383 |
+++ b/pym/repoman/modules/vcs/cvs/__init__.py |
384 |
@@ -19,6 +19,7 @@ module_spec = { |
385 |
'func_desc': { |
386 |
}, |
387 |
'vcs_preserves_mtime': True, |
388 |
+ 'needs_keyword_expansion': True, |
389 |
}, |
390 |
'cvs-changes': { |
391 |
'name': "cvs_changes", |
392 |
|
393 |
diff --git a/pym/repoman/modules/vcs/cvs/changes.py b/pym/repoman/modules/vcs/cvs/changes.py |
394 |
index f0893a1..ca07f1f 100644 |
395 |
--- a/pym/repoman/modules/vcs/cvs/changes.py |
396 |
+++ b/pym/repoman/modules/vcs/cvs/changes.py |
397 |
@@ -1,7 +1,9 @@ |
398 |
|
399 |
|
400 |
-from portage import cvstree |
401 |
+from repoman._portage import portage |
402 |
from repoman.modules.vcs.changes import ChangesBase |
403 |
+from portage import cvstree |
404 |
+ |
405 |
|
406 |
class Changes(ChangesBase): |
407 |
'''Class object to scan and hold the resultant data |
408 |
@@ -14,9 +16,12 @@ class Changes(ChangesBase): |
409 |
super(Changes, self).__init__(options) |
410 |
|
411 |
def _scan(self): |
412 |
- tree = cvstree.getentries("./", recursive=1) |
413 |
+ tree = portage.cvstree.getentries("./", recursive=1) |
414 |
self.changed = cvstree.findchanged(tree, recursive=1, basedir="./") |
415 |
self.new = cvstree.findnew(tree, recursive=1, basedir="./") |
416 |
- if self.options.if_modified == "y": |
417 |
- self.removed = cvstree.findremoved(tree, recursive=1, basedir="./") |
418 |
+ self.removed = cvstree.findremoved(tree, recursive=1, basedir="./") |
419 |
+ myunadded = portage.cvstree.findunadded(myvcstree, recursive=1, basedir="./") |
420 |
+ bin_blob_pattern = re.compile("^-kb$") |
421 |
+ self.no_expansion = set(portage.cvstree.findoption( |
422 |
+ mycvstree, bin_blob_pattern, recursive=1, basedir="./")) |
423 |
del tree |
424 |
|
425 |
diff --git a/pym/repoman/modules/vcs/git/__init__.py b/pym/repoman/modules/vcs/git/__init__.py |
426 |
index 4e1d599..e077767 100644 |
427 |
--- a/pym/repoman/modules/vcs/git/__init__.py |
428 |
+++ b/pym/repoman/modules/vcs/git/__init__.py |
429 |
@@ -19,6 +19,7 @@ module_spec = { |
430 |
'func_desc': { |
431 |
}, |
432 |
'vcs_preserves_mtime': False, |
433 |
+ 'needs_keyword_expansion': False, |
434 |
}, |
435 |
'git-changes': { |
436 |
'name': "git_changes", |
437 |
|
438 |
diff --git a/pym/repoman/modules/vcs/git/changes.py b/pym/repoman/modules/vcs/git/changes.py |
439 |
index 6ee39a0..26ffff3 100644 |
440 |
--- a/pym/repoman/modules/vcs/git/changes.py |
441 |
+++ b/pym/repoman/modules/vcs/git/changes.py |
442 |
@@ -27,11 +27,17 @@ class Changes(ChangesBase): |
443 |
"--relative --diff-filter=A HEAD") as f: |
444 |
new = f.readlines() |
445 |
self.new = ["./" + elem[:-1] for elem in new] |
446 |
- if self.options.if_modified == "y": |
447 |
- with repoman_popen( |
448 |
- "git diff-index --name-only " |
449 |
- "--relative --diff-filter=D HEAD") as f: |
450 |
- removed = f.readlines() |
451 |
- self.removed = ["./" + elem[:-1] for elem in removed] |
452 |
- del removed |
453 |
+ del new |
454 |
|
455 |
+ with repoman_popen( |
456 |
+ "git diff-index --name-only " |
457 |
+ "--relative --diff-filter=D HEAD") as f: |
458 |
+ removed = f.readlines() |
459 |
+ self.removed = ["./" + elem[:-1] for elem in removed] |
460 |
+ del removed |
461 |
+ |
462 |
+ # get list of files not under version control or missing |
463 |
+ with repoman_popen("git ls-files --others") as f: |
464 |
+ unadded = f.readlines() |
465 |
+ self.unadded = ["./" + elem[:-1] for elem in unadded] |
466 |
+ del unadded |
467 |
|
468 |
diff --git a/pym/repoman/modules/vcs/hg/__init__.py b/pym/repoman/modules/vcs/hg/__init__.py |
469 |
index 6f8a376..6737dfb 100644 |
470 |
--- a/pym/repoman/modules/vcs/hg/__init__.py |
471 |
+++ b/pym/repoman/modules/vcs/hg/__init__.py |
472 |
@@ -19,6 +19,7 @@ module_spec = { |
473 |
'func_desc': { |
474 |
}, |
475 |
'vcs_preserves_mtime': False, |
476 |
+ 'needs_keyword_expansion': False, |
477 |
}, |
478 |
'hg-changes': { |
479 |
'name': "hg_changes", |
480 |
|
481 |
diff --git a/pym/repoman/modules/vcs/hg/changes.py b/pym/repoman/modules/vcs/hg/changes.py |
482 |
index 86dffff..621b0d4 100644 |
483 |
--- a/pym/repoman/modules/vcs/hg/changes.py |
484 |
+++ b/pym/repoman/modules/vcs/hg/changes.py |
485 |
@@ -18,12 +18,27 @@ class Changes(ChangesBase): |
486 |
with repoman_popen("hg status --no-status --modified .") as f: |
487 |
changed = f.readlines() |
488 |
self.changed = ["./" + elem.rstrip() for elem in changed] |
489 |
+ del changed |
490 |
+ |
491 |
with repoman_popen("hg status --no-status --added .") as f: |
492 |
new = f.readlines() |
493 |
self.new = ["./" + elem.rstrip() for elem in new] |
494 |
- if self.options.if_modified == "y": |
495 |
- with repoman_popen("hg status --no-status --removed .") as f: |
496 |
- removed = f.readlines() |
497 |
- self.removed = ["./" + elem.rstrip() for elem in removed] |
498 |
- del removed |
499 |
- del changed, new |
500 |
+ del new |
501 |
+ |
502 |
+ with repoman_popen("hg status --no-status --removed .") as f: |
503 |
+ removed = f.readlines() |
504 |
+ self.removed = ["./" + elem.rstrip() for elem in removed] |
505 |
+ del removed |
506 |
+ |
507 |
+ with repoman_popen("hg status --no-status --unknown .") as f: |
508 |
+ unadded = f.readlines() |
509 |
+ self.unadded = ["./" + elem.rstrip() for elem in unadded] |
510 |
+ del unadded |
511 |
+ |
512 |
+ # Mercurial doesn't handle manually deleted files as removed from |
513 |
+ # the repository, so the user need to remove them before commit, |
514 |
+ # using "hg remove [FILES]" |
515 |
+ with repoman_popen("hg status --no-status --deleted .") as f: |
516 |
+ deleted = f.readlines() |
517 |
+ self.deleted = ["./" + elem.rstrip() for elem in deleted] |
518 |
+ del deleted |
519 |
|
520 |
diff --git a/pym/repoman/modules/vcs/settings.py b/pym/repoman/modules/vcs/settings.py |
521 |
index 34f1c78..bcd5f18 100644 |
522 |
--- a/pym/repoman/modules/vcs/settings.py |
523 |
+++ b/pym/repoman/modules/vcs/settings.py |
524 |
@@ -4,7 +4,6 @@ from __future__ import print_function, unicode_literals |
525 |
import logging |
526 |
import sys |
527 |
|
528 |
-from repoman._portage import portage |
529 |
from portage.output import red |
530 |
from repoman.modules.vcs import module_controller, module_names |
531 |
from repoman.modules.vcs.vcs import FindVCS |
532 |
@@ -58,6 +57,8 @@ class VCSSettings(object): |
533 |
logging.error("VCSSettings: Unknown VCS type: %s", self.vcs) |
534 |
logging.error("Available modules: %s", module_controller.parents) |
535 |
|
536 |
+ self.needs_keyword_expansion = module_controller.modules[ |
537 |
+ "%s_status" % self.vcs]['needs_keyword_expansion'] |
538 |
self.vcs_local_opts = repoman_settings.get( |
539 |
"REPOMAN_VCS_LOCAL_OPTS", "").split() |
540 |
self.vcs_global_opts = repoman_settings.get( |
541 |
@@ -88,5 +89,5 @@ class VCSSettings(object): |
542 |
def changes(self): |
543 |
if not self._changes: |
544 |
changes = self.module_controller.get_class('%s_changes' % self.vcs) |
545 |
- self._changes = changes(self.options) |
546 |
+ self._changes = changes(self.options, self.vcs) |
547 |
return self._changes |
548 |
|
549 |
diff --git a/pym/repoman/modules/vcs/svn/__init__.py b/pym/repoman/modules/vcs/svn/__init__.py |
550 |
index 41e481a..becb93e 100644 |
551 |
--- a/pym/repoman/modules/vcs/svn/__init__.py |
552 |
+++ b/pym/repoman/modules/vcs/svn/__init__.py |
553 |
@@ -19,6 +19,7 @@ module_spec = { |
554 |
'func_desc': { |
555 |
}, |
556 |
'vcs_preserves_mtime': False, |
557 |
+ 'needs_keyword_expansion': True, |
558 |
}, |
559 |
'svn-changes': { |
560 |
'name': "svn_changes", |
561 |
|
562 |
diff --git a/pym/repoman/modules/vcs/svn/changes.py b/pym/repoman/modules/vcs/svn/changes.py |
563 |
index 3567b61..f12b47d 100644 |
564 |
--- a/pym/repoman/modules/vcs/svn/changes.py |
565 |
+++ b/pym/repoman/modules/vcs/svn/changes.py |
566 |
@@ -25,9 +25,23 @@ class Changes(ChangesBase): |
567 |
"./" + elem.split()[-1:][0] |
568 |
for elem in svnstatus |
569 |
if elem.startswith("A")] |
570 |
- if self.options.if_modified == "y": |
571 |
- self.removed = [ |
572 |
- "./" + elem.split()[-1:][0] |
573 |
- for elem in svnstatus |
574 |
- if elem.startswith("D")] |
575 |
+ self.removed = [ |
576 |
+ "./" + elem.split()[-1:][0] |
577 |
+ for elem in svnstatus |
578 |
+ if elem.startswith("D")] |
579 |
+ |
580 |
+ # Subversion expands keywords specified in svn:keywords properties. |
581 |
+ with repoman_popen("svn propget -R svn:keywords") as f: |
582 |
+ props = f.readlines() |
583 |
+ self.expansion = dict( |
584 |
+ ("./" + prop.split(" - ")[0], prop.split(" - ")[1].split()) |
585 |
+ for prop in props if " - " in prop) |
586 |
+ del props |
587 |
|
588 |
+ with repoman_popen("svn status --no-ignore") as f: |
589 |
+ svnstatus = f.readlines() |
590 |
+ self.unadded = [ |
591 |
+ "./" + elem.rstrip().split()[1] |
592 |
+ for elem in svnstatus |
593 |
+ if elem.startswith("?") or elem.startswith("I")] |
594 |
+ del svnstatus |