Changeset 1241 in tailor
- Timestamp:
- 08/15/06 00:11:26 (7 years ago)
- Hash name:
- 20060814221126-97f81-d54d76cb84ff96793c96fa5b09a762fd389cdc18
- Location:
- vcpx
- Files:
-
- 2 edited
-
tests/darcs.py (modified) (4 diffs)
-
repository/darcs/source.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
vcpx/tests/darcs.py
r1223 r1241 169 169 cset = csets[2] 170 170 self.assertEqual(cset.revision, 'moved') 171 self.assertEqual(len(cset.entries), 2) 172 173 entry = cset.entries[0] 174 self.assertEqual(entry.name, 'bdir') 175 self.assertEqual(entry.action_kind, entry.ADDED) 176 177 entry = cset.entries[1] 171 self.assertEqual(len(cset.entries), 1) 172 173 entry = cset.entries[0] 178 174 self.assertEqual(entry.name, 'dir') 179 self.assertEqual(entry.action_kind, entry. RENAMED)175 self.assertEqual(entry.action_kind, entry.ADDED) 180 176 181 177 cset = csets[3] … … 358 354 if ((e.name.startswith(n.name+'/') or (e.old_name==n.name)) and 359 355 (n.action_kind==n.ADDED or n.action_kind==n.RENAMED))] 360 for ee in postadds:361 print ee362 356 self.assertEqual(postadds, []) 363 357 … … 398 392 """ 399 393 394 MIXED_TEST = """ 395 <changelog> 396 <patch author='esj@harvee.org' date='20050104213401' local_date='Tue Jan 4 22:34:01 CET 2005' inverted='False' hash='20050104213401-fab45-49c3d772521e523fa84be43883b235dbcbf9d61c.gz'> 397 <name>feedback and logging </name> 398 <comment>this patch has three major changes. First is the addition of the 399 false negative feedback so that spam that leaks through 400 can be identified and corrected. 401 402 second is the logging changes minimizing information 403 dumped at the highest levels (1) in order to speed up message processing 404 405 third is updating portalocker for modern pythons. 406 </comment> 407 <summary> 408 <move from="ancillary/mbox2rpc.py" to="ancillary/fnsource.py"/> 409 <move from="ancillary/rpc2mbox.py" to="web-ui/cgi-exec/fnsink.py"/> 410 <modify_file> 411 ancillary/fnsource.py<added_lines num='335'/> 412 </modify_file> 413 <modify_file> 414 ancillary/global_configuration<added_lines num='8'/> 415 </modify_file> 416 <add_file> 417 ancillary/mbox2rpc.py 418 </add_file> 419 <modify_file> 420 ancillary/mbox2spamtrap.py<removed_lines num='1'/><added_lines num='1'/> 421 </modify_file> 422 <add_file> 423 ancillary/rpc2mbox.py 424 </add_file> 425 <modify_file> 426 modules/camram_email.py<removed_lines num='17'/><added_lines num='33'/> 427 </modify_file> 428 <modify_file> 429 modules/camram_utils.py<removed_lines num='2'/><added_lines num='5'/> 430 </modify_file> 431 <modify_file> 432 modules/configuration.py<removed_lines num='15'/><added_lines num='15'/> 433 </modify_file> 434 <modify_file> 435 modules/dbm_utils.py<removed_lines num='4'/><added_lines num='4'/> 436 </modify_file> 437 <modify_file> 438 modules/log.py<removed_lines num='1'/><added_lines num='1'/> 439 </modify_file> 440 <modify_file> 441 modules/portalocker.py<removed_lines num='2'/><added_lines num='2'/> 442 </modify_file> 443 <modify_file> 444 sgid/build.sh<removed_lines num='1'/><added_lines num='4'/> 445 </modify_file> 446 <modify_file> 447 src/core_filter.py<removed_lines num='50'/><added_lines num='55'/> 448 </modify_file> 449 <modify_file> 450 src/postfix_filter.py<removed_lines num='35'/><added_lines num='49'/> 451 </modify_file> 452 <modify_file> 453 src/postfix_stamper.py<removed_lines num='17'/><added_lines num='18'/> 454 </modify_file> 455 <modify_file> 456 web-ui/cgi-exec/correct.py<removed_lines num='17'/><added_lines num='17'/> 457 </modify_file> 458 <modify_file> 459 web-ui/cgi-exec/edit_config.py<removed_lines num='23'/><added_lines num='26'/> 460 </modify_file> 461 <modify_file> 462 web-ui/cgi-exec/fnsink.py<added_lines num='154'/> 463 </modify_file> 464 <modify_file> 465 web-ui/cgi-exec/recover.py<removed_lines num='5'/><added_lines num='5'/> 466 </modify_file> 467 <modify_file> 468 web-ui/cgi-exec/spamtrap_display.py<removed_lines num='4'/><added_lines num='4'/> 469 </modify_file> 470 <modify_file> 471 web-ui/templates/correct.html<removed_lines num='1'/><added_lines num='1'/> 472 </modify_file> 473 </summary> 474 </patch> 475 </changelog> 476 """ 477 400 478 def testAddAndRename(self): 401 479 "Verify if the parser degrades (add A)+(rename A B) to (add B)" … … 405 483 406 484 cset = csets.next() 407 for e in cset.entries: print e408 485 409 486 entry = cset.entries[2] 410 487 self.assertEqual(entry.name, 'vcpx/repository/git/__init__.py') 411 self.assertEqual(entry.action_kind, entry.ADD) 488 self.assertEqual(entry.action_kind, entry.ADDED) 489 490 log = StringIO(self.MIXED_TEST) 491 csets = changesets_from_darcschanges(log) 492 493 cset = csets.next() 494 self.assertEqual([], [e for e in cset.entries if e.name == 'ancillary/mbox2rpc.py']) 495 self.assertEqual([], [e for e in cset.entries if e.action_kind == e.RENAMED]) -
vcpx/repository/darcs/source.py
r1222 r1241 14 14 import re 15 15 16 from vcpx.changes import ChangesetEntry, Changeset 16 17 from vcpx.shwrap import ExternalCommand, PIPE, STDOUT 17 18 from vcpx.source import UpdatableSourceWorkingDir, ChangesetApplicationFailure, \ … … 21 22 22 23 24 class DarcsChangeset(Changeset): 25 """ 26 Fixup darcs idiosyncrasies: 27 28 - collapse "add A; rename A B" into "add B" 29 - collapse "rename A B; remove B" into "remove A" 30 """ 31 32 def __init__(self, revision, date, author, log, entries=None, **other): 33 """ 34 Initialize a new DarcsChangeset. 35 """ 36 37 super(DarcsChangeset, self).__init__(revision, date, author, log, entries=None, **other) 38 if entries is not None: 39 for e in entries: 40 self.addEntry(e, revision) 41 42 def addEntry(self, entry, revision): 43 """ 44 Fixup darcs idiosyncrasies: 45 46 - collapse "add A; rename A B" into "add B" 47 - collapse "rename A B; remove B" into "remove A" 48 """ 49 50 # This should not happen, since the parser feeds us an already built 51 # list of ChangesetEntries, anyway... 52 if not isinstance(entry, ChangesetEntry): 53 return super(DarcsChangeset, self).addEntry(entry, revision) 54 55 # Ok, before adding this entry, check it against already 56 # known: if this is an add, and there's a rename (such as "add 57 # A; rename A B; ") then... 58 59 if entry.action_kind == entry.ADDED: 60 # ... we have to check existings, because of a bug in 61 # darcs: `changes --xml` (as of 1.0.7) emits the changes 62 # in the wrong order, that is, it prefers to start with 63 # renames, *always*, even when they obviously follows the 64 # add of the same entry (even, it should apply this "fix" 65 # by its own). 66 # 67 # So, if there's a rename of this entry there, change that 68 # to an addition instead, and don't insert any other entry 69 70 dirname = entry.name+'/' # darcs hopefully use forward slashes also under win 71 72 for i,e in enumerate(self.entries): 73 if e.action_kind == e.RENAMED and e.old_name == entry.name: 74 # Luckily enough (since removes are the first entries 75 # in the list, that is) by anticipating the add we 76 # cure also the case below, when addition follows 77 # edit. 78 e.action_kind = e.ADDED 79 e.old_name = None 80 return e 81 82 # Assert also that add_dir events must preceeds any 83 # add_file and ren_file that have that dir as target, 84 # and that add_file preceeds any edit. 85 86 if ((e.name == entry.name or e.name.startswith(dirname)) 87 or (e.action_kind == e.RENAMED and e.old_name.startswith(dirname))): 88 self.entries.insert(i, entry) 89 return entry 90 91 # Likewise, if this is a deletion, and there is a rename of this 92 # entry (such as "rename A B; remove B") then ... 93 94 elif entry.action_kind == entry.DELETED: 95 # turn the existing rename into a deletion instead 96 97 for i,e in enumerate(self.entries): 98 if e.action_kind == e.RENAMED and e.name == entry.name: 99 e.action_kind = e.DELETED 100 e.name = e.old_name 101 e.old_name = None 102 return e 103 104 # Ok, it must be either an edit or a rename: the former goes 105 # obviously to the end, and since the latter, as said, come 106 # in very early, appending is just good. 107 self.entries.append(entry) 108 return entry 109 110 23 111 def changesets_from_darcschanges(changes, unidiff=False, repodir=None, 24 112 chunksize=2**15): … … 55 143 from xml.sax.handler import ContentHandler, ErrorHandler 56 144 from datetime import datetime 57 from vcpx.changes import ChangesetEntry, Changeset58 145 59 146 class DarcsXMLChangesHandler(ContentHandler): … … 97 184 def endElement(self, name): 98 185 if name == 'patch': 99 entries = [] 100 todo = self.current['entries'] 101 # Darcs allows "rename A B; remove B": collapse those 102 # into "remove A" 103 while todo: 104 e = todo.pop(0) 105 if e.action_kind == e.RENAMED: 106 lookfor = e.name 107 forget = [] 108 for i,n in enumerate(todo): 109 if n.action_kind == n.DELETED and n.name == lookfor: 110 e.action_kind = e.DELETED 111 e.name = e.old_name 112 e.old_name = None 113 entries.append(e) 114 forget.append(i) 115 forget.reverse() 116 for i in forget: 117 del todo[i] 118 break 119 elif n.action_kind == n.RENAMED and n.old_name == lookfor: 120 forget.append(i) 121 lookfor = n.name 122 if not forget: 123 entries.append(e) 124 else: 125 entries.append(e) 126 127 # Darcs changes --xml (as of 1.0.7) emits bad ordered hunks: it 128 # begins with file moves, apparently for no good reason. Do as 129 # little reordering as needed to adjust the meaning, ie moving all 130 # add_dirs before add_file and ren_file that have that dir as 131 # target 132 133 sorted = False 134 while not sorted: 135 sorted = True 136 for i,e in enumerate(entries): 137 if e.action_kind == e.RENAMED: 138 for j,n in enumerate(entries[i+1:]): 139 if ((e.name.startswith(n.name+'/') or e.old_name==n.name) and 140 (n.action_kind == n.ADDED or n.action_kind == n.RENAMED)): 141 m = entries.pop(i+1+j) 142 entries.insert(i, m) 143 sorted = False 144 145 cset = Changeset(self.current['name'], 146 self.current['date'], 147 self.current['author'], 148 self.current['comment'], 149 entries, 150 tags=self.current.get('tags',[])) 186 cset = DarcsChangeset(self.current['name'], 187 self.current['date'], 188 self.current['author'], 189 self.current['comment'], 190 self.current['entries'], 191 tags=self.current.get('tags',[])) 151 192 cset.darcs_hash = self.current['hash'] 152 193 if self.darcsdiff:
Note: See TracChangeset
for help on using the changeset viewer.
