def __init__(self, repos, path, rev, log, ls_tree_info=None, historian=None): self.log = log self.repos = repos self.fs_sha = None # points to either tree or blobs self.fs_perm = None self.fs_type = None self.fs_size = None if rev: rev = repos.normalize_rev(to_unicode(rev)) else: rev = repos.youngest_rev created_rev = rev kind = Node.DIRECTORY p = path.strip('/') if p: # ie. not the root-tree if not rev: raise NoSuchNode(path, rev) if ls_tree_info is None: ls_tree_info = repos.git.ls_tree(rev, p) if ls_tree_info: ls_tree_info = ls_tree_info[0] if not ls_tree_info: raise NoSuchNode(path, rev) self.fs_perm, self.fs_type, self.fs_sha, self.fs_size, fname = \ ls_tree_info # fix-up to the last commit-rev that touched this node created_rev = repos.git.last_change(rev, p, historian) if self.fs_type == 'tree': kind = Node.DIRECTORY elif self.fs_type == 'blob': kind = Node.FILE elif _is_submodule(self.fs_perm): # FIXME: this is a workaround for missing git submodule # support in the plugin kind = Node.DIRECTORY else: self.log.warning('Got unexpected object %r', ls_tree_info) raise TracError( _( "Internal error (got unexpected object " "kind '%(kind)s')", kind=self.fs_type)) self.created_path = path self.created_rev = created_rev Node.__init__(self, repos, path, rev, kind)
def __init__(self, repos, path, rev, log, ls_tree_info=None, historian=None): self.log = log self.repos = repos self.fs_sha = None # points to either tree or blobs self.fs_perm = None self.fs_size = None if rev: rev = repos.normalize_rev(to_unicode(rev)) else: rev = repos.youngest_rev kind = Node.DIRECTORY p = path.strip('/') if p: # ie. not the root-tree if not rev: raise NoSuchNode(path, rev) if not ls_tree_info: ls_tree_info = repos.git.ls_tree(rev, p) or None if ls_tree_info: [ls_tree_info] = ls_tree_info if not ls_tree_info: raise NoSuchNode(path, rev) self.fs_perm, k, self.fs_sha, self.fs_size, _ = ls_tree_info # fix-up to the last commit-rev that touched this node rev = repos.git.last_change(rev, p, historian) if k == 'tree': pass elif k == 'commit': # FIXME: this is a workaround for missing git submodule # support in the plugin pass elif k == 'blob': kind = Node.FILE else: raise TracError("Internal error (got unexpected object " \ "kind '%s')" % k) self.created_path = path self.created_rev = rev Node.__init__(self, repos, path, rev, kind)
def __init__(self, git, path, rev, log, ls_tree_info=None): self.log = log self.git = git self.fs_sha = None # points to either tree or blobs self.fs_perm = None self.fs_size = None rev = rev and str(rev) or 'HEAD' kind = Node.DIRECTORY p = path.strip('/') if p: # ie. not the root-tree if not ls_tree_info: ls_tree_info = git.ls_tree(rev, p) or None if ls_tree_info: [ls_tree_info] = ls_tree_info if not ls_tree_info: raise NoSuchNode(path, rev) (self.fs_perm, k, self.fs_sha, self.fs_size, fn) = ls_tree_info # fix-up to the last commit-rev that touched this node rev = self.git.last_change(rev, p) if k=='tree': pass elif k=='blob': kind = Node.FILE else: raise TracError("internal error (got unexpected object kind '%s')" % k) self.created_path = path self.created_rev = rev Node.__init__(self, path, rev, kind)
def get_node(path, rev): if 'missing' in path: raise NoSuchNode(path, rev) basename = posixpath.basename(path) if 'file' in basename: kind = Node.FILE entries = () else: kind = Node.DIRECTORY if 'dir' in basename: entries = ['file.txt'] else: entries = ['dir1', 'dir2'] entries = [posixpath.join(path, entry) for entry in entries] content = b'Contents for %s' % to_utf8(path) node = Mock(Node, repos, path, rev, kind, created_path=path, created_rev=rev, get_entries=lambda: iter( get_node(entry, rev) for entry in entries), get_properties=lambda: {}, get_content=lambda: io.BytesIO(content), get_content_length=lambda: len(content), get_content_type=lambda: 'application/octet-stream', get_last_modified=lambda: t) return node
def _get_kind(self): if self._node.isDirectory: return Node.DIRECTORY elif self._node.isFile: return Node.FILE else: raise NoSuchNode(self._nodePath.path, self._nodePath.rev)
def get_node(path, rev): if 'missing' in path: raise NoSuchNode(path, rev) kind = Node.FILE if 'file' in path else Node.DIRECTORY node = Mock(Node, repos, path, rev, kind, created_path=path, created_rev=rev, get_entries=lambda: iter([]), get_properties=lambda: {}, get_content=lambda: io.BytesIO('content'), get_content_length=lambda: 7, get_content_type=lambda: 'application/octet-stream') return node
def get_node(self, path, rev=None): class Node: path = '' def get_content(self): class Stream: def read(self): if repo: return 'repo:' + repo return 'test' return Stream() if self.is_incorrect: raise NoSuchNode("1", "1") return Node()
def get_history(self, limit=None): self._log.debug('PerforceNode.get_history(%r)' % limit) if self._node.isFile: # Force population of the filelog history for efficiency from p4trac.repos import _P4FileLogOutputConsumer output = _P4FileLogOutputConsumer(self._repos) if limit is None: self._repos._connection.run( 'filelog', '-i', '-l', self._repos.fromUnicode(self._nodePath.fullPath), output=output) else: self._repos._connection.run( 'filelog', '-i', '-l', '-m', str(limit), self._repos.fromUnicode(self._nodePath.fullPath), output=output) from p4trac.repos import NodePath currentNode = self._node i = 0 while i < limit and currentNode is not None: if currentNode.action in [u'add', u'branch', u'import']: if currentNode.integrations: nodePath, how = currentNode.integrations[0] # TODO: Detect whether the copy was really a move yield (normalisePath(currentNode.nodePath.path), currentNode.change, Changeset.COPY) currentNode = self._repos.getNode(nodePath) else: yield(normalisePath(currentNode.nodePath.path), currentNode.change, Changeset.ADD) if currentNode.fileRevision > 1: # Get the previous revision nodePath = NodePath(currentNode.nodePath.path, '#%i' % (currentNode.rev - 1)) currentNode = self._repos.getNode(nodePath) else: currentNode = None elif currentNode.action in [u'edit', u'integrate']: nextNode = None if currentNode.integrations: nodePath, how = currentNode.integrations[0] if how == 'copy': yield (normalisePath(currentNode.nodePath.path), currentNode.change, Changeset.COPY) nextNode = self._repos.getNode(nodePath) else: yield (normalisePath(currentNode.nodePath.path), currentNode.change, Changeset.EDIT) else: yield (normalisePath(currentNode.nodePath.path), currentNode.change, Changeset.EDIT) if nextNode is None: if currentNode.fileRevision > 1: currentNode = self._repos.getNode( NodePath(currentNode.nodePath.path, '#%i' % (currentNode.fileRevision-1))) else: currentNode = None else: currentNode = nextNode elif currentNode.action in [u'delete']: yield (normalisePath(currentNode.nodePath.path), currentNode.change, Changeset.DELETE) if currentNode.fileRevision > 1: currentNode = self._repos.getNode( NodePath(currentNode.nodePath.path, '#%i' % (currentNode.fileRevision - 1))) else: currentNode = None i += 1 elif self._node.isDirectory: # List all changelists that have affected this directory from p4trac.repos import _P4ChangesOutputConsumer output = _P4ChangesOutputConsumer(self._repos) if self._nodePath.isRoot: queryPath = '//...%s' % self._nodePath.rev else: queryPath = '%s/...%s' % (self._nodePath.path, self._nodePath.rev) if limit is None: self._repos._connection.run( 'changes', '-l', '-s', 'submitted', self._repos.fromUnicode(queryPath), output=output) else: self._repos._connection.run( 'changes', '-l', '-s', 'submitted', '-m', str(limit), self._repos.fromUnicode(queryPath), output=output) if output.errors: raise PerforceError(output.errors) changes = output.changes # And describe the contents of those changelists from p4trac.repos import _P4DescribeOutputConsumer output = _P4DescribeOutputConsumer(self._repos) self._repos._connection.run('describe', '-s', output=output, *[str(c) for c in changes]) from p4trac.repos import NodePath for i in xrange(len(changes)): change = changes[i] nodePath = NodePath(self._nodePath.path, change) if i < len(changes)-1: prevChange = changes[i+1] else: prevChange = change-1 prevNodePath = NodePath(self._nodePath.path, prevChange) node = self._repos.getNode(nodePath) prevNode = self._repos.getNode(prevNodePath) if node.isDirectory: if prevNode.isDirectory: yield (normalisePath(self._nodePath.path), change, Changeset.EDIT) else: yield (normalisePath(self._nodePath.path), change, Changeset.ADD) elif prevNode.isDirectory: yield (normalisePath(self._nodePath.path), change, Changeset.DELETE) else: raise NoSuchNode(self._nodePath.path, self._nodePath.rev)