##// END OF EJS Templates
user-groups: fix potential problem with group sync of external plugins....
user-groups: fix potential problem with group sync of external plugins. - when using external plugin we used to check for a parameter that set the sync mode. The problem is we only checked if the flag was there. So toggling sync on and off set the value and then left the key still set but with None. This confused the sync and thought the group should be synced !

File last commit:

r1926:f9d07533 default
r2143:4314e88b default
Show More
commit.py
236 lines | 7.8 KiB | text/x-python | PythonLexer
project: added all source files and assets
r1 # -*- coding: utf-8 -*-
license: updated copyright year to 2017
r1271 # Copyright (C) 2014-2017 RhodeCode GmbH
project: added all source files and assets
r1 #
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License, version 3
# (only), as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This program is dual-licensed. If you wish to learn more about the
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/
"""
SVN commit module
"""
import dateutil.parser
from zope.cachedescriptors.property import Lazy as LazyProperty
from rhodecode.lib.utils import safe_str, safe_unicode
from rhodecode.lib.vcs import nodes, path as vcspath
from rhodecode.lib.vcs.backends import base
from rhodecode.lib.vcs.exceptions import CommitError, NodeDoesNotExistError
_SVN_PROP_TRUE = '*'
class SubversionCommit(base.BaseCommit):
"""
Subversion specific implementation of commits
.. attribute:: branch
The Subversion backend does not support to assign branches to
specific commits. This attribute has always the value `None`.
"""
def __init__(self, repository, commit_id):
self.repository = repository
self.idx = self.repository._get_commit_idx(commit_id)
self._svn_rev = self.idx + 1
self._remote = repository._remote
# TODO: handling of raw_id should be a method on repository itself,
# which knows how to translate commit index and commit id
self.raw_id = commit_id
self.short_id = commit_id
self.id = 'r%s' % (commit_id, )
# TODO: Implement the following placeholder attributes
self.nodes = {}
self.tags = []
@property
def author(self):
return safe_unicode(self._properties.get('svn:author'))
@property
def date(self):
return _date_from_svn_properties(self._properties)
@property
def message(self):
return safe_unicode(self._properties.get('svn:log'))
@LazyProperty
def _properties(self):
return self._remote.revision_properties(self._svn_rev)
@LazyProperty
def parents(self):
parent_idx = self.idx - 1
if parent_idx >= 0:
parent = self.repository.get_commit(commit_idx=parent_idx)
return [parent]
return []
@LazyProperty
def children(self):
child_idx = self.idx + 1
if child_idx < len(self.repository.commit_ids):
child = self.repository.get_commit(commit_idx=child_idx)
return [child]
return []
def get_file_mode(self, path):
# Note: Subversion flags files which are executable with a special
# property `svn:executable` which is set to the value ``"*"``.
if self._get_file_property(path, 'svn:executable') == _SVN_PROP_TRUE:
return base.FILEMODE_EXECUTABLE
else:
return base.FILEMODE_DEFAULT
def is_link(self, path):
# Note: Subversion has a flag for special files, the content of the
# file contains the type of that file.
if self._get_file_property(path, 'svn:special') == _SVN_PROP_TRUE:
return self.get_file_content(path).startswith('link')
return False
def _get_file_property(self, path, name):
file_properties = self._remote.node_properties(
safe_str(path), self._svn_rev)
return file_properties.get(name)
def get_file_content(self, path):
path = self._fix_path(path)
return self._remote.get_file_content(safe_str(path), self._svn_rev)
def get_file_size(self, path):
path = self._fix_path(path)
return self._remote.get_file_size(safe_str(path), self._svn_rev)
def get_file_history(self, path, limit=None, pre_load=None):
path = safe_str(self._fix_path(path))
history = self._remote.node_history(path, self._svn_rev, limit)
return [
self.repository.get_commit(commit_id=str(svn_rev))
for svn_rev in history]
def get_file_annotate(self, path, pre_load=None):
result = self._remote.file_annotate(safe_str(path), self._svn_rev)
for zero_based_line_no, svn_rev, content in result:
commit_id = str(svn_rev)
line_no = zero_based_line_no + 1
yield (
line_no,
commit_id,
lambda: self.repository.get_commit(commit_id=commit_id),
content)
vcs: added possibility to pre-load attributes for FileNodes.
r1355 def get_node(self, path, pre_load=None):
project: added all source files and assets
r1 path = self._fix_path(path)
if path not in self.nodes:
if path == '':
node = nodes.RootNode(commit=self)
else:
node_type = self._remote.get_node_type(
safe_str(path), self._svn_rev)
if node_type == 'dir':
node = nodes.DirNode(path, commit=self)
elif node_type == 'file':
vcs: added possibility to pre-load attributes for FileNodes.
r1355 node = nodes.FileNode(path, commit=self, pre_load=pre_load)
project: added all source files and assets
r1 else:
svn: don't raise duplicate exception. The function already does that.
r1926 raise self.no_node_at_path(path)
project: added all source files and assets
r1
self.nodes[path] = node
return self.nodes[path]
def get_nodes(self, path):
if self._get_kind(path) != nodes.NodeKind.DIR:
raise CommitError(
"Directory does not exist for commit %s at "
" '%s'" % (self.raw_id, path))
path = self._fix_path(path)
path_nodes = []
for name, kind in self._remote.get_nodes(
safe_str(path), revision=self._svn_rev):
node_path = vcspath.join(path, name)
if kind == 'dir':
node = nodes.DirNode(node_path, commit=self)
elif kind == 'file':
node = nodes.FileNode(node_path, commit=self)
else:
raise ValueError("Node kind %s not supported." % (kind, ))
self.nodes[node_path] = node
path_nodes.append(node)
return path_nodes
def _get_kind(self, path):
path = self._fix_path(path)
kind = self._remote.get_node_type(path, self._svn_rev)
if kind == 'file':
return nodes.NodeKind.FILE
elif kind == 'dir':
return nodes.NodeKind.DIR
else:
raise CommitError(
"Node does not exist at the given path '%s'" % (path, ))
@LazyProperty
def _changes_cache(self):
return self._remote.revision_changes(self._svn_rev)
@LazyProperty
def affected_files(self):
changed_files = set()
for files in self._changes_cache.itervalues():
changed_files.update(files)
return list(changed_files)
vcs: implement id for svn commit and EmptyCommit fixes #4136
r621 @LazyProperty
def id(self):
return self.raw_id
project: added all source files and assets
r1 @property
def added(self):
return nodes.AddedFileNodesGenerator(
self._changes_cache['added'], self)
@property
def changed(self):
return nodes.ChangedFileNodesGenerator(
self._changes_cache['changed'], self)
@property
def removed(self):
return nodes.RemovedFileNodesGenerator(
self._changes_cache['removed'], self)
def _date_from_svn_properties(properties):
"""
Parses the date out of given svn properties.
:return: :class:`datetime.datetime` instance. The object is naive.
"""
svn: date-parser should use UTC dates to be consistent with other backends.
r1348
project: added all source files and assets
r1 aware_date = dateutil.parser.parse(properties.get('svn:date'))
svn: date-parser should use UTC dates to be consistent with other backends.
r1348 # final_date = aware_date.astimezone(dateutil.tz.tzlocal())
final_date = aware_date
return final_date.replace(tzinfo=None)