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