Changeset 2991
- Timestamp:
- 01/06/08 15:54:10 (11 months ago)
- Files:
-
- perforceplugin/trunk/p4trac/api.py (modified) (31 diffs)
- perforceplugin/trunk/p4trac/repos.py (modified) (84 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
perforceplugin/trunk/p4trac/api.py
r2974 r2991 42 42 """ 43 43 44 from p4trac.repos import NodePath45 path = NodePath.normalisePath(path)44 from p4trac.repos import P4NodePath 45 path = P4NodePath.normalisePath(path) 46 46 if path is None: 47 47 return u'/' … … 55 55 returns '@<change>' as an integer value. 56 56 """ 57 from p4trac.repos import NodePath58 rev = NodePath.normaliseRevision(rev)57 from p4trac.repos import P4NodePath 58 rev = P4NodePath.normaliseRevision(rev) 59 59 if rev is None: 60 60 return rev … … 72 72 implements(IRepositoryConnector) 73 73 74 port = Option('perforce', 'port', 'localhost:1666', doc= 75 """Perforce server IP address and port. 76 """) 77 user = Option('perforce', 'user', '', doc= 78 """Perforce user name used to identify requests. 79 """) 80 password = Option('perforce', 'password', '', doc= 81 """Perforce password used to identify requests. 82 """) 83 language = Option('perforce', 'password', '', doc= 84 """Perforce password used to identify requests. 85 """) 86 workspace = Option('perforce', 'workspace', NO_CLIENT, doc= 87 """Perforce workspace used to request server. 88 """) 89 charset = Option('perforce', 'charset', 'none', doc= 90 """Perforce charset used to request server. 91 valid options are 'none', 'utf-8'. 92 """) 93 74 94 branches = ListOption('perforce', 'branches', 'main,branches/*', doc= 75 95 """List of paths categorized as ''branches''. … … 77 97 below that path will be included. 78 98 """) 79 80 99 labels = ListOption('perforce', 'labels', 'labels/*', doc= 81 100 """List of paths categorized as ''labels''. … … 110 129 self.log.debug("get_repository options : %s" % (options)) 111 130 112 if 'port' not in options:113 raise TracError(114 message="Missing 'port' value in [perforce] config section.",115 title="TracPerforce configuration error",116 )117 118 131 # Try to connect to the Perforce server 119 132 from perforce import Connection, ConnectionFailed 120 p4 = Connection(port= options['port'], api='58') # Limit to 2005.2 behaviour133 p4 = Connection(port=self.port, api='58') # Limit to 2005.2 behaviour 121 134 try: 122 135 from trac import __version__ as tracVersion … … 127 140 title="Perforce connection error") 128 141 129 if 'user' not in options:142 if 'user' == '': 130 143 raise TracError( 131 144 message="Missing 'user' value in [perforce] config section.", 132 145 title="Perforce configuration error") 133 p4.user = options['user'] 134 135 p4.password = options.get('password', '') 136 p4.charset = 'none' 137 if 'unicode' in options: 138 if options['unicode'] == '1': 139 p4.charset = 'utf8' 140 elif options['unicode'] == '0': 141 p4.charset = 'none' 142 else: 143 raise TracError( 144 message="Invalid 'unicode' value in [perforce] config " \ 145 "section.", 146 title="Perforce configuration error") 147 148 p4.language = options.get('language', '') 146 p4.user = self.user 147 p4.password = self.password 148 p4.charset = self.charset 149 p4.language = self.language 149 150 jobPrefixLength = len(options.get('job_prefix', 'job')) 150 p4.client = options.get('workspace', NO_CLIENT) 151 152 self.log.debug("get_repository [%s,%s,%s]" % (p4.user, p4.password, p4.client)) 151 p4.client = self.workspace 152 153 153 p4_repos = PerforceRepository(p4, None, self.log, jobPrefixLength, 154 154 {'labels': self.labels, … … 190 190 self.options = options 191 191 self._connection = connection 192 name = 'p4://%s:%s@%s' % (self._connection.user, self._connection.password, self._connection.port) 192 name = 'p4://%s:%s@%s' % (connection.user, 193 connection.password, connection.port) 193 194 Repository.__init__(self, name, authz, log) 194 195 from p4trac.repos import P4Repository … … 241 242 242 243 def get_changeset(self, rev): 243 self.log.debug(' get_changeset(%r)' % rev)244 self.log.debug('PerforceRepository.get_changeset(%r)' % rev) 244 245 if isinstance(rev, int): 245 246 change = rev … … 249 250 if rev.startswith(u'@'): 250 251 rev = rev[1:] 251 252 252 try: 253 253 change = int(rev) 254 254 except ValueError: 255 255 raise TracError(u"Invalid changeset number '%s'" % rev) 256 257 256 return PerforceChangeset(change, self._repos, self.log, self._job_prefix_length) 258 257 259 258 def get_changesets(self, start, stop): 260 261 259 self.log.debug('PerforceRepository.get_changesets(%r,%r)' % (start, 262 260 stop)) … … 264 262 start = datetime.datetime.fromtimestamp(start) 265 263 stop = datetime.datetime.fromtimestamp(stop) 266 267 264 startDate = start.strftime('%Y/%m/%d:%H:%M:%S') 268 265 stopDate = stop.strftime('%Y/%m/%d:%H:%M:%S') 269 266 270 from p4trac.repos import _P4ChangesOutputConsumer271 output = _P4ChangesOutputConsumer(self._repos)267 from p4trac.repos import P4ChangesOutputConsumer 268 output = P4ChangesOutputConsumer(self._repos) 272 269 depot_path = '%s@>=%s,@<=%s' % (rootPath(self._connection), startDate, stopDate) 273 270 self._connection.run('changes', '-l', '-s', 'submitted', … … 281 278 282 279 def has_node(self, path, rev=None): 283 from p4trac.repos import NodePath284 path = NodePath.normalisePath(path)285 return self._repos.getNode( NodePath(path, rev)).exists280 from p4trac.repos import P4NodePath 281 path = P4NodePath.normalisePath(path) 282 return self._repos.getNode(P4NodePath(path, rev)).exists 286 283 287 284 def get_node(self, path, rev=None): 288 285 self.log.debug('get_node(%s, %s) called' % (path, rev)) 289 from p4trac.repos import NodePath290 nodePath = NodePath(NodePath.normalisePath(path), rev)286 from p4trac.repos import P4NodePath 287 nodePath = P4NodePath(P4NodePath.normalisePath(path), rev) 291 288 return PerforceNode(nodePath, self._repos, self.log) 292 289 … … 304 301 raise NoSuchChangeset(rev) 305 302 306 from p4trac.repos import _P4ChangesOutputConsumer307 output = _P4ChangesOutputConsumer(self._repos)303 from p4trac.repos import P4ChangesOutputConsumer 304 output = P4ChangesOutputConsumer(self._repos) 308 305 self._connection.run('changes', '-l', '-s', 'submitted', 309 306 '-m', '1', '@<%i' % rev, output=output) 310 307 if output.errors: 311 from p4trac.repos import Perforc Error312 raise Perforc Error(output.errors)308 from p4trac.repos import PerforceError 309 raise PerforceError(output.errors) 313 310 if output.changes: 314 311 return max(output.changes) … … 326 323 self.log.debug('next_rev(%r,%r)' % (rev, path)) 327 324 328 from p4trac.repos import NodePath325 from p4trac.repos import P4NodePath 329 326 if not path: 330 327 path = u'//' 331 328 else: 332 path = NodePath.normalisePath(path)333 node = self._repos.getNode( NodePath(path, rev))329 path = P4NodePath.normalisePath(path) 330 node = self._repos.getNode(P4NodePath(path, rev)) 334 331 335 332 if node.isDirectory: … … 364 361 batchUpperBound)) 365 362 366 from p4trac.repos import _P4ChangesOutputConsumer367 output = _P4ChangesOutputConsumer(self._repos)363 from p4trac.repos import P4ChangesOutputConsumer 364 output = P4ChangesOutputConsumer(self._repos) 368 365 depot_path = '%s%s@>=%i,@<=%i' % (rootPath(self._connection), 369 366 queryPath, lowerBound, batchUpperBound) … … 373 370 374 371 if output.errors: 375 from p4trac.repos import Perforc Error376 raise Perforc Error(output.errors)372 from p4trac.repos import PerforceError 373 raise PerforceError(output.errors) 377 374 378 375 if output.changes: … … 445 442 # Can't compare these revisions directly, 446 443 # Compare based on the latest change number that affects this revision. 447 from p4trac.repos import NodePath444 from p4trac.repos import P4NodePath 448 445 if not isinstance(rev1, int): 449 rootAtRev1 = NodePath(u'//', rev1)446 rootAtRev1 = P4NodePath(u'//', rev1) 450 447 rev1 = self._repos.getNode(rootAtRev1).change 451 448 if not isinstance(rev2, int): 452 rootAtRev2 = NodePath(u'//', rev2)449 rootAtRev2 = P4NodePath(u'//', rev2) 453 450 rev2 = self._repos.getNode(rootAtRev2).change 454 451 self.log.debug('Comparing by change rev1=%i, rev2=%i' % (rev1, rev2)) … … 458 455 # TODO: This doesn't handle the case where the head node has been 459 456 # deleted or a file has changed to a directory or vica versa. 460 from p4trac.repos import NodePath461 nodePath = NodePath(NodePath.normalisePath(path), rev)457 from p4trac.repos import P4NodePath 458 nodePath = P4NodePath(P4NodePath.normalisePath(path), rev) 462 459 node = PerforceNode(nodePath, self._repos, self.log) 463 460 return node.get_history(limit) … … 483 480 old_path, old_rev, new_path, new_rev)) 484 481 485 from p4trac.repos import NodePath486 oldNodePath = NodePath(NodePath.normalisePath(old_path), old_rev)482 from p4trac.repos import P4NodePath 483 oldNodePath = P4NodePath(P4NodePath.normalisePath(old_path), old_rev) 487 484 oldNode = self._repos.getNode(oldNodePath) 488 485 489 newNodePath = NodePath(NodePath.normalisePath(new_path), new_rev)486 newNodePath = P4NodePath(P4NodePath.normalisePath(new_path), new_rev) 490 487 newNode = self._repos.getNode(newNodePath) 491 488 … … 513 510 raise TracError("Cannot diff two non-existant nodes") 514 511 515 from p4trac.repos import _P4Diff2OutputConsumer516 output = _P4Diff2OutputConsumer(self._repos)512 from p4trac.repos import P4Diff2OutputConsumer 513 output = P4Diff2OutputConsumer(self._repos) 517 514 518 515 self._connection.run('diff2', '-ds', … … 589 586 self._log.debug('PerforceNode.get_history(%r)' % limit) 590 587 if self._node.isFile: 591 592 588 # Force population of the filelog history for efficiency 593 from p4trac.repos import _P4FileLogOutputConsumer 594 output = _P4FileLogOutputConsumer(self._repos) 595 596 if limit is None: 597 self._repos._connection.run( 598 'filelog', 599 '-i', '-l', 600 self._repos.fromUnicode(self._nodePath.fullPath), 601 output=output) 602 else: 603 self._repos._connection.run( 604 'filelog', 605 '-i', '-l', 606 '-m', str(limit), 607 self._repos.fromUnicode(self._nodePath.fullPath), 608 output=output) 609 610 from p4trac.repos import NodePath 589 self._repos._runFileLog(self._nodePath, limit) 590 591 from p4trac.repos import P4NodePath 611 592 612 593 currentNode = self._node … … 621 602 currentNode.change, 622 603 Changeset.COPY) 623 624 604 currentNode = self._repos.getNode(nodePath) 625 605 else: … … 627 607 currentNode.change, 628 608 Changeset.ADD) 629 630 609 if currentNode.fileRevision > 1: 631 610 # Get the previous revision 632 nodePath = NodePath(currentNode.nodePath.path,633 '#%i' % (currentNode.fileRevision - 1))611 nodePath = P4NodePath(currentNode.nodePath.path, 612 '#%i' % (currentNode.fileRevision - 1)) 634 613 currentNode = self._repos.getNode(nodePath) 635 614 else: 636 615 currentNode = None 637 638 616 elif currentNode.action in [u'edit', u'integrate']: 639 640 617 nextNode = None 641 618 if currentNode.integrations: 642 619 nodePath, how = currentNode.integrations[0] 643 644 620 if how == 'copy': 645 621 yield (normalisePath(currentNode.nodePath.path), … … 655 631 currentNode.change, 656 632 Changeset.EDIT) 657 658 633 if nextNode is None: 659 634 if currentNode.fileRevision > 1: 660 635 currentNode = self._repos.getNode( 661 NodePath(currentNode.nodePath.path,662 '#%i' % (currentNode.fileRevision - 1)))636 P4NodePath(currentNode.nodePath.path, 637 '#%i' % (currentNode.fileRevision - 1))) 663 638 else: 664 639 currentNode = None 665 640 else: 666 641 currentNode = nextNode 667 668 642 elif currentNode.action in [u'delete']: 669 643 yield (normalisePath(currentNode.nodePath.path), 670 644 currentNode.change, 671 645 Changeset.DELETE) 672 673 646 if currentNode.fileRevision > 1: 674 647 currentNode = self._repos.getNode( 675 NodePath(currentNode.nodePath.path,676 '#%i' % (currentNode.fileRevision - 1)))648 P4NodePath(currentNode.nodePath.path, 649 '#%i' % (currentNode.fileRevision - 1))) 677 650 else: 678 651 currentNode = None 679 680 652 i += 1 681 682 653 elif self._node.isDirectory: 683 684 654 # List all changelists that have affected this directory 685 from p4trac.repos import _P4ChangesOutputConsumer686 output = _P4ChangesOutputConsumer(self._repos)655 from p4trac.repos import P4ChangesOutputConsumer 656 output = P4ChangesOutputConsumer(self._repos) 687 657 688 658 if self._nodePath.isRoot: … … 702 672 if output.errors: 703 673 raise PerforceError(output.errors) 704 705 674 changes = output.changes 706 675 707 # And describe the contents of those changelists 708 from p4trac.repos import _P4DescribeOutputConsumer 709 output = _P4DescribeOutputConsumer(self._repos) 710 self._repos._connection.run('describe', '-s', 711 output=output, 712 *[str(c) for c in changes]) 713 714 from p4trac.repos import NodePath 715 676 self._repos._runDescribe(changes) 677 678 from p4trac.repos import P4NodePath 716 679 for i in xrange(len(changes)): 717 680 change = changes[i] 718 nodePath = NodePath(self._nodePath.path, change) 719 681 nodePath = P4NodePath(self._nodePath.path, change) 720 682 if i < len(changes)-1: 721 683 prevChange = changes[i+1] … … 723 685 prevChange = change-1 724 686 725 prevNodePath = NodePath(self._nodePath.path, prevChange)687 prevNodePath = P4NodePath(self._nodePath.path, prevChange) 726 688 node = self._repos.getNode(nodePath) 727 689 prevNode = self._repos.getNode(prevNodePath) 728 729 690 if node.isDirectory: 730 691 if prevNode.isDirectory: … … 740 701 change, 741 702 Changeset.DELETE) 742 743 703 else: 744 704 raise NoSuchNode(self._nodePath.path, self._nodePath.rev) 745 705 746 706 def get_annotations(self): 707 self._log.debug('PerforceNode.get_annotations') 747 708 annotations = [] 748 709 if self.isfile: … … 799 760 self._changelist = self._repos.getChangelist(self._change) 800 761 Changeset.__init__(self, self._change, self._changelist.description, 801 self._changelist.user, datetime.fromtimestamp(self._changelist.time, utc)) 762 self._changelist.user, 763 datetime.fromtimestamp(self._changelist.time, utc)) 802 764 803 765 def get_properties(self): … … 814 776 self._log.debug("get_properties %d " % tktid) 815 777 fixes += ' %d' % tktid 816 817 778 if fixes != '': 818 779 props['Tickets'] = to_unicode(fixes) … … 853 814 otherNodePath, how = node.integrations[0] 854 815 otherNode = self._repos.getNode(otherNodePath) 855 816 856 817 # A 'copy from' operation 857 818 yield (normalisePath(nodePath.path), … … 862 823 else: 863 824 if node.fileRevision > 1: 864 from p4trac.repos import NodePath865 otherNode = self._repos.getNode( NodePath(nodePath.path,866 '#%i' % (node.fileRevision - 1)))867 825 from p4trac.repos import P4NodePath 826 otherNode = self._repos.getNode(P4NodePath(nodePath.path, 827 '#%i' % (node.fileRevision - 1))) 828 868 829 # A basic edit operation 869 830 yield (normalisePath(nodePath.path), … … 880 841 elif node.action in [u'delete']: 881 842 # The file was deleted 882 from p4trac.repos import NodePath883 otherNodePath = NodePath(nodePath.path,884 '#%i' % (node.fileRevision - 1))843 from p4trac.repos import P4NodePath 844 otherNodePath = P4NodePath(nodePath.path, 845 '#%i' % (node.fileRevision - 1)) 885 846 otherNode = self._repos.getNode(otherNodePath) 886 887 847 yield (normalisePath(nodePath.path), 888 848 Node.FILE, 889 849 Changeset.DELETE, 890 850 normalisePath(nodePath.path), 891 otherNode.change, 892 ) 851 otherNode.change) perforceplugin/trunk/p4trac/repos.py
r2971 r2991 20 20 NO_CLIENT = '_P4TRAC_DUMMY_CLIENT' 21 21 22 class _ChangeInfo(object): 22 23 class _P4ChangeInfo(object): 23 24 """A data structure for recording info about a changelist. 24 25 … … 44 45 self.files = None 45 46 46 class _FileInfo(object): 47 48 class _P4FileInfo(object): 47 49 """A data structure for recording info about a file. 48 50 … … 73 75 self.attributes = None 74 76 75 class _DirectoryInfo(object): 77 78 class _P4DirectoryInfo(object): 76 79 """A data structure for recording info about a directory. 77 80 … … 93 96 self.change = None 94 97 98 95 99 class PerforceError(Exception): 96 97 100 def __init__(self, errors): 98 101 self.errors = errors … … 101 104 return '\n'.join([e.format() for e in self.errors]) 102 105 106 103 107 class NoSuchChangelist(Exception): 104 105 108 def __init__(self, change): 106 109 self.change = change 107 110 111 108 112 class NoSuchNode(Exception): 109 110 113 def __init__(self, path, rev): 111 114 self.path = path 112 115 self.rev = rev 113 116 117 114 118 class NoSuchFile(NoSuchNode): 115 119 pass 116 120 121 117 122 class NoSuchDirectory(NoSuchNode): 118 123 pass 119 124 120 # Some regular expressions used by NodePath125 # Some regular expressions used by P4NodePath 121 126 _slashDotSlashRE = re.compile(ur'/(\./)+') 122 127 _dirSlashDotDotRE = re.compile(ur'[^/]+/..(/|$)') 123 128 _trailingSlashesRE = re.compile(ur'(?<=[^/])/*$') 124 129 125 class NodePath(object):130 class P4NodePath(object): 126 131 """A path to a node in the Perforce repository. 127 132 … … 220 225 221 226 def __init__(self, path, rev=None): 222 """Construct a NodePath object.227 """Construct a P4NodePath object. 223 228 224 229 @param path: The depot path to the node. 225 This must be a normalised path. Call L{ NodePath.normalisePath} if230 This must be a normalised path. Call L{P4NodePath.normalisePath} if 226 231 normalisation is required. 227 232 @type path: C{unicode} … … 234 239 assert isinstance(path, unicode) 235 240 self._path = path 236 self._rev = NodePath.normaliseRevision(rev)241 self._rev = P4NodePath.normaliseRevision(rev) 237 242 238 243 def _get_path(self): … … 354 359 355 360 def __eq__(self, other): 356 if isinstance(other, NodePath):361 if isinstance(other, P4NodePath): 357 362 return self.path == other.path and self.rev == other.rev 358 363 else: … … 363 368 364 369 365 class Changelist(object):370 class _P4Changelist(object): 366 371 """A proxy object that gives access to details about a particular 367 372 changelist in a Perforce repository. … … 376 381 377 382 def __init__(self, change, repository): 378 """Construct a new Changelist object.383 """Construct a new _P4Changelist object. 379 384 380 385 @param change: The change number of the changelist to query. … … 479 484 Has the value None if the changelist is not submitted. 480 485 481 @type: C{list} of L{ Node} objects or C{None}486 @type: C{list} of L{_P4Node} objects or C{None} 482 487 483 488 @raise NoSuchChangelist: If the changelist doesn't exist in the … … 498 503 nodes = [] 499 504 for path in info.files: 500 nodePath = NodePath(path, self._change)501 node = Node(nodePath, self._repo)505 nodePath = P4NodePath(path, self._change) 506 node = _P4Node(nodePath, self._repo) 502 507 nodes.append(node) 503 504 508 return nodes 505 509 506 class Node(object): 510 511 class _P4Node(object): 507 512 """A Perforce node is a particular revision of a path in the repository. 508 513 """ … … 519 524 """The node path of this node. 520 525 521 @type: L{ NodePath}526 @type: L{P4NodePath} 522 527 """ 523 528 return self._nodePath 524 529 525 530 def _get_isDirectory(self): 526 """Boolean flag indicating whether the L{ Node} is a directory.531 """Boolean flag indicating whether the L{_P4Node} is a directory. 527 532 528 533 @type: C{boolean} … … 536 541 if self._nodePath.rev is None: 537 542 latestChange = self._repo.getLatestChange() 538 self._nodePath = NodePath(self._nodePath.path, latestChange)543 self._nodePath = P4NodePath(self._nodePath.path, latestChange) 539 544 540 545 # Do we already know it's a directory? … … 559 564 560 565 def _get_isFile(self): 561 """Boolean flag indicating whether the L{ Node} is a file.566 """Boolean flag indicating whether the L{_P4Node} is a file. 562 567 563 568 @type: C{boolean} … … 571 576 if self._nodePath.rev is None: 572 577 latestChange = self._repo.getLatestChange() 573 self._nodePath = NodePath(self._nodePath.path, latestChange)578 self._nodePath = P4NodePath(self._nodePath.path, latestChange) 574 579 575 580 # Do we already know it's a file? … … 602 607 603 608 def _get_exists(self): 604 """Boolean flag indicating whether the L{ Node} exists or not.609 """Boolean flag indicating whether the L{_P4Node} exists or not. 605 610 606 611 @type: C{boolean} … … 615 620 @type: C{int} 616 621 617 @raise NoSuchFile: If the L{ Node} isn't a file.622 @raise NoSuchFile: If the L{_P4Node} isn't a file. 618 623 """ 619 624 … … 635 640 @type: C{int} 636 641 637 @raise NoSuchFile: If the L{ Node} isn't a file node.642 @raise NoSuchFile: If the L{_P4Node} isn't a file node. 638 643 """ 639 644 … … 657 662 @type: C{file}-like object 658 663 659 @raise NoSuchFile: If the L{ Node} isn't a file.664 @raise NoSuchFile: If the L{_P4Node} isn't a file. 660 665 """ 661 666 … … 682 687 @type: C{int} 683 688 684 @raise NoSuchNode: If the L{ Node} doesn't exist.689 @raise NoSuchNode: If the L{_P4Node} doesn't exist. 685 690 """ 686 691 … … 688 693 if self._nodePath.rev is None: 689 694 latestChange = self._repo.getLatestChange() 690 self._nodePath = NodePath(self._nodePath.path, latestChange)695 self._nodePath = P4NodePath(self._nodePath.path, latestChange) 691 696 692 697 if not self.exists: … … 818 823 if self._nodePath.isRoot: 819 824 if self._repo._connection.client != NO_CLIENT: 820 nodePath = NodePath(u'//%s/%s' % (self._repo._connection.client, subdir),821 self._nodePath.rev)825 nodePath = P4NodePath(u'//%s/%s' % (self._repo._connection.client, subdir), 826 self._nodePath.rev) 822 827 else: 823 nodePath = NodePath(u'//%s' % subdir,824 self._nodePath.rev)828 nodePath = P4NodePath(u'//%s' % subdir, 829 self._nodePath.rev) 825 830 else: 826 nodePath = NodePath(u'%s/%s' % (self._nodePath.path, subdir),827 self._nodePath.rev)828 829 self._repo._log.debug("_ get_subDirectories '%s '" % (nodePath._path))830 node = Node(nodePath, self._repo)831 nodePath = P4NodePath(u'%s/%s' % (self._nodePath.path, subdir), 832 self._nodePath.rev) 833 834 self._repo._log.debug("_P4Node._get_subDirectories '%s'" % (nodePath._path)) 835 node = _P4Node(nodePath, self._repo) 831 836 subdirNodes.append(node) 832 833 837 return subdirNodes 834 838 … … 840 844 841 845 if not self.isDirectory: 842 raise NoSuchDirectory(self._nodePath.path, 843 self._nodePath.rev) 846 raise NoSuchDirectory(self._nodePath.path, self._nodePath.rev) 844 847 845 848 # The root path never has any files under it … … 854 857 if dirInfo.files is None: 855 858 raise 856 857 859 assert dirInfo.files is not None 858 860 859 861 fileNodes = [] 860 862 for file in dirInfo.files: 861 nodePath = NodePath(u'%s/%s' % (self._nodePath.path, file),862 self._nodePath.rev)863 node = Node(nodePath, self._repo)863 nodePath = P4NodePath(u'%s/%s' % (self._nodePath.path, file), 864 self._nodePath.rev) 865 node = _P4Node(nodePath, self._repo) 864 866 fileNodes.append(node) 865 866 867 return fileNodes 868 867 869 868 870 class P4Repository(object): … … 899 901 self._latestChange = None 900 902 901 # Mapping from change number (int) to _ ChangeInfo object903 # Mapping from change number (int) to _P4ChangeInfo object 902 904 self._changes = {} 903 905 904 # Mapping from node-path (unicode) to _ DirectoryInfo object906 # Mapping from node-path (unicode) to _P4DirectoryInfo object 905 907 self._dirs = {} 906 908 907 # Mapping from node-path (unicode) to _ FileInfo object909 # Mapping from node-path (unicode) to _P4FileInfo object 908 910 self._files = {} 909 911 … … 933 935 934 936 def getChangelist(self, change): 935 """Get the Changelist object corresponding to the change number."""936 return Changelist(change, self)937 """Get the _P4Changelist object corresponding to the change number.""" 938 return _P4Changelist(change, self) 937 939 938 940 def isChangelistCached(self, change): … … 946 948 info.description is not None and 947 949 info.time is not None) 948 950 949 951 def getLatestChange(self): 950 952 """Return the number of the most recently submitted change. … … 953 955 """ 954 956 if self._latestChange is None: 955 output = _P4ChangesOutputConsumer(self)957 output = P4ChangesOutputConsumer(self) 956 958 self._connection.run('changes', 957 959 '-m', '1', … … 1009 1011 batchUpperBound = lowerBound + batchSize 1010 1012 1011 output = _P4ChangesOutputConsumer(self)1013 output = P4ChangesOutputConsumer(self) 1012 1014 self._connection.run('changes', '-l', '-s', 'submitted', 1013 1015 '-m', str(batchSize), … … 1035 1037 1036 1038 def getNode(self, nodePath): 1037 """Get the Node object corresponding to the node path.1038 1039 nodePath is a NodePath object1040 """ 1041 return Node(nodePath, self)1039 """Get the _P4Node object corresponding to the node path. 1040 1041 nodePath is a P4NodePath object 1042 """ 1043 return _P4Node(nodePath, self) 1042 1044 1043 1045 def precacheFileInformationForChanges(self, changes): … … 1068 1070 def filesWithoutCachedHistory(): 1069 1071 for change in changes: 1070 1071 1072 changeInfo = self._getChangeInfo(change) 1072 1073 1073 assert changeInfo is not None 1074 1074 assert changeInfo.files is not None 1075 1075 1076 1076 for file in changeInfo.files: 1077 1078 nodePath = NodePath(file, '@%i' % change) 1077 nodePath = P4NodePath(file, '@%i' % change) 1079 1078 fileInfo = self._getFileInfo(nodePath) 1080 1081 1079 assert fileInfo is not None 1082 1080 1083 1081 if fileInfo.sources is None: 1084 1082 yield nodePath … … 1095 1093 1096 1094 for batch in batchesOfFilesWithoutCachedHistory(1000): 1097 1098 1095 output = _P4FileLogOutputConsumer(self) 1099 1096 self._connection.run('filelog', '-m', '1', … … 1101 1098 *[self.fromUnicode(np.fullPath) 1102 1099 for np in batch]) 1103 1104 1100 if output.errors: 1105 1101 raise PerforceError(output.errors) … … 1130 1126 @return: The changelist info structure or C{None} if the change 1131 1127 doesn't yet exist in the cache. 1132 @rtype: L{_ ChangeInfo} or C{None}1128 @rtype: L{_P4ChangeInfo} or C{None} 1133 1129 """ 1134 1130 … … 1136 1132 return self._changes[change] 1137 1133 elif create: 1138 info = _ ChangeInfo(int(change))1134 info = _P4ChangeInfo(int(change)) 1139 1135 self._changes[change] = info 1140 1136 return info … … 1145 1141 """Get the directory info structure for the set of nodePaths. 1146 1142 1147 @param nodePaths: Either a NodePath or a list ofNodePath objects.1143 @param nodePaths: Either a P4NodePath or a list of P4NodePath objects. 1148 1144 If a list is provided, then you must already know that all of the 1149 NodePaths refer to the same Node (this implies that the path component1145 NodePaths refer to the same _P4Node (this implies that the path component 1150 1146 of the NodePaths are all equal). 1151 1147 1152 1148 @param create: If true and the nodePaths aren't already in existence 1153 then a new empty _ DirectoryInfo object is inserted into the database1149 then a new empty _P4DirectoryInfo object is inserted into the database 1154 1150 and is returned, otherwise None is returned. Should only be set to 1155 1151 True if you already know that the nodePaths are a directory. 1156 1152 1157 @return: The L{_ DirectoryInfo} object for the nodePaths or C{None},1158 @rtype: L{_ DirectoryInfo} or C{None}1153 @return: The L{_P4DirectoryInfo} object for the nodePaths or C{None}, 1154 @rtype: L{_P4DirectoryInfo} or C{None} 1159 1155 """ 1160 1156 … … 1171 1167 for p in fullPaths 1172 1168 if p in self._dirs] 1173 1169 1174 1170 if infos: 1175 1171 # There are existing info objects, pick the first one … … 1179 1175 if other is not info: 1180 1176 assert other.path == info.path 1181 1177 1182 1178 if other.subdirs is not None: 1183 1179 if info.subdirs is None: …
