Changeset - d7488551578e
[Not reviewed]
beta
1 58 1
Marcin Kuzminski - 13 years ago 2013-04-27 11:24:25
marcin@python-works.com
synced vcs with upstream

- moved subprocessio module to VCS
- many small changes to make embedded vcs as similar to to external lib
- use only absolute imports
- patch vcs config during load pylons env
58 files changed:
Changeset was too big and was cut off... Show full diff anyway
0 comments (0 inline, 0 general)
rhodecode/__init__.py
Show inline comments
 
@@ -27,6 +27,19 @@ import sys
 
import platform
 

	
 
VERSION = (1, 7, 0, 'dev')
 
BACKENDS = {
 
    'hg': 'Mercurial repository',
 
    'git': 'Git repository',
 
}
 

	
 
CELERY_ON = False
 
CELERY_EAGER = False
 

	
 
# link to config for pylons
 
CONFIG = {}
 

	
 
# Linked module for extensions
 
EXTENSIONS = {}
 

	
 
try:
 
    from rhodecode.lib import get_current_revision
 
@@ -45,23 +58,5 @@ __py_version__ = sys.version_info
 
__author__ = 'Marcin Kuzminski'
 
__url__ = 'http://rhodecode.org'
 

	
 
PLATFORM_WIN = ('Windows')
 
PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD', 'SunOS') #depracated
 

	
 
is_windows = __platform__ in PLATFORM_WIN
 
is_windows = __platform__ in ('Windows')
 
is_unix = not is_windows
 

	
 

	
 
BACKENDS = {
 
    'hg': 'Mercurial repository',
 
    'git': 'Git repository',
 
}
 

	
 
CELERY_ON = False
 
CELERY_EAGER = False
 

	
 
# link to config for pylons
 
CONFIG = {}
 

	
 
# Linked module for extensions
 
EXTENSIONS = {}
rhodecode/config/environment.py
Show inline comments
 
@@ -18,7 +18,7 @@ from rhodecode.config.routing import mak
 
from rhodecode.lib import helpers
 
from rhodecode.lib.auth import set_available_permissions
 
from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config,\
 
    load_rcextensions, check_git_version
 
    load_rcextensions, check_git_version, set_vcs_config
 
from rhodecode.lib.utils2 import engine_from_config, str2bool
 
from rhodecode.lib.db_manage import DbManage
 
from rhodecode.model import init_model
 
@@ -114,4 +114,6 @@ def load_environment(global_conf, app_co
 
    # store config reference into our module to skip import magic of
 
    # pylons
 
    rhodecode.CONFIG.update(config)
 

	
 
    set_vcs_config(rhodecode.CONFIG)
 
    return config
rhodecode/lib/__init__.py
Show inline comments
 
@@ -12,7 +12,8 @@ def get_current_revision(quiet=False):
 
    try:
 
        from rhodecode.lib.vcs import get_repo
 
        from rhodecode.lib.vcs.utils.helpers import get_scm
 
        repopath = os.path.join(os.path.dirname(__file__), '..', '..')
 
        repopath = os.path.abspath(os.path.join(os.path.dirname(__file__),
 
                                                '..', '..'))
 
        scm = get_scm(repopath)[0]
 
        repo = get_repo(path=repopath, alias=scm)
 
        wk_dir = repo.workdir
rhodecode/lib/compat.py
Show inline comments
 
@@ -25,13 +25,12 @@
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import os
 
from rhodecode import __platform__, PLATFORM_WIN, __py_version__
 
from rhodecode import __py_version__, is_windows
 

	
 
#==============================================================================
 
# json
 
#==============================================================================
 
from rhodecode.lib.ext_json import json
 
import array
 

	
 

	
 
#==============================================================================
 
@@ -366,7 +365,7 @@ from sqlalchemy.util import OrderedSet
 
#==============================================================================
 
# kill FUNCTIONS
 
#==============================================================================
 
if __platform__ in PLATFORM_WIN:
 
if is_windows:
 
    import ctypes
 

	
 
    def kill(pid, sig):
 
@@ -419,6 +418,7 @@ else:
 
if __py_version__ >= (2, 6):
 
    _bytearray = bytearray
 
else:
 
    import array
 
    # no idea if this is correct but all integration tests are passing
 
    # i think we never use bytearray anyway
 
    _bytearray = array
 
@@ -548,173 +548,3 @@ else:
 
            memo[id(self)] = result
 
            result.__init__(deepcopy(tuple(self), memo))
 
            return result
 

	
 

	
 
#==============================================================================
 
# threading.Event
 
#==============================================================================
 

	
 
if __py_version__ >= (2, 6):
 
    from threading import Event, Thread
 
else:
 
    from threading import _Verbose, Condition, Lock, Thread, _time, \
 
        _allocate_lock, RLock, _sleep
 

	
 
    def Condition(*args, **kwargs):
 
        return _Condition(*args, **kwargs)
 

	
 
    class _Condition(_Verbose):
 

	
 
        def __init__(self, lock=None, verbose=None):
 
            _Verbose.__init__(self, verbose)
 
            if lock is None:
 
                lock = RLock()
 
            self.__lock = lock
 
            # Export the lock's acquire() and release() methods
 
            self.acquire = lock.acquire
 
            self.release = lock.release
 
            # If the lock defines _release_save() and/or _acquire_restore(),
 
            # these override the default implementations (which just call
 
            # release() and acquire() on the lock).  Ditto for _is_owned().
 
            try:
 
                self._release_save = lock._release_save
 
            except AttributeError:
 
                pass
 
            try:
 
                self._acquire_restore = lock._acquire_restore
 
            except AttributeError:
 
                pass
 
            try:
 
                self._is_owned = lock._is_owned
 
            except AttributeError:
 
                pass
 
            self.__waiters = []
 

	
 
        def __enter__(self):
 
            return self.__lock.__enter__()
 

	
 
        def __exit__(self, *args):
 
            return self.__lock.__exit__(*args)
 

	
 
        def __repr__(self):
 
            return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
 

	
 
        def _release_save(self):
 
            self.__lock.release()           # No state to save
 

	
 
        def _acquire_restore(self, x):
 
            self.__lock.acquire()           # Ignore saved state
 

	
 
        def _is_owned(self):
 
            # Return True if lock is owned by current_thread.
 
            # This method is called only if __lock doesn't have _is_owned().
 
            if self.__lock.acquire(0):
 
                self.__lock.release()
 
                return False
 
            else:
 
                return True
 

	
 
        def wait(self, timeout=None):
 
            if not self._is_owned():
 
                raise RuntimeError("cannot wait on un-acquired lock")
 
            waiter = _allocate_lock()
 
            waiter.acquire()
 
            self.__waiters.append(waiter)
 
            saved_state = self._release_save()
 
            try:    # restore state no matter what (e.g., KeyboardInterrupt)
 
                if timeout is None:
 
                    waiter.acquire()
 
                    if __debug__:
 
                        self._note("%s.wait(): got it", self)
 
                else:
 
                    # Balancing act:  We can't afford a pure busy loop, so we
 
                    # have to sleep; but if we sleep the whole timeout time,
 
                    # we'll be unresponsive.  The scheme here sleeps very
 
                    # little at first, longer as time goes on, but never longer
 
                    # than 20 times per second (or the timeout time remaining).
 
                    endtime = _time() + timeout
 
                    delay = 0.0005 # 500 us -> initial delay of 1 ms
 
                    while True:
 
                        gotit = waiter.acquire(0)
 
                        if gotit:
 
                            break
 
                        remaining = endtime - _time()
 
                        if remaining <= 0:
 
                            break
 
                        delay = min(delay * 2, remaining, .05)
 
                        _sleep(delay)
 
                    if not gotit:
 
                        if __debug__:
 
                            self._note("%s.wait(%s): timed out", self, timeout)
 
                        try:
 
                            self.__waiters.remove(waiter)
 
                        except ValueError:
 
                            pass
 
                    else:
 
                        if __debug__:
 
                            self._note("%s.wait(%s): got it", self, timeout)
 
            finally:
 
                self._acquire_restore(saved_state)
 

	
 
        def notify(self, n=1):
 
            if not self._is_owned():
 
                raise RuntimeError("cannot notify on un-acquired lock")
 
            __waiters = self.__waiters
 
            waiters = __waiters[:n]
 
            if not waiters:
 
                if __debug__:
 
                    self._note("%s.notify(): no waiters", self)
 
                return
 
            self._note("%s.notify(): notifying %d waiter%s", self, n,
 
                       n != 1 and "s" or "")
 
            for waiter in waiters:
 
                waiter.release()
 
                try:
 
                    __waiters.remove(waiter)
 
                except ValueError:
 
                    pass
 

	
 
        def notifyAll(self):
 
            self.notify(len(self.__waiters))
 

	
 
        notify_all = notifyAll
 

	
 
    def Event(*args, **kwargs):
 
        return _Event(*args, **kwargs)
 

	
 
    class _Event(_Verbose):
 

	
 
        # After Tim Peters' event class (without is_posted())
 

	
 
        def __init__(self, verbose=None):
 
            _Verbose.__init__(self, verbose)
 
            self.__cond = Condition(Lock())
 
            self.__flag = False
 

	
 
        def isSet(self):
 
            return self.__flag
 

	
 
        is_set = isSet
 

	
 
        def set(self):
 
            self.__cond.acquire()
 
            try:
 
                self.__flag = True
 
                self.__cond.notify_all()
 
            finally:
 
                self.__cond.release()
 

	
 
        def clear(self):
 
            self.__cond.acquire()
 
            try:
 
                self.__flag = False
 
            finally:
 
                self.__cond.release()
 

	
 
        def wait(self, timeout=None):
 
            self.__cond.acquire()
 
            try:
 
                if not self.__flag:
 
                    self.__cond.wait(timeout)
 
            finally:
 
                self.__cond.release()
rhodecode/lib/middleware/pygrack.py
Show inline comments
 
@@ -7,7 +7,7 @@ import traceback
 
from webob import Request, Response, exc
 

	
 
import rhodecode
 
from rhodecode.lib import subprocessio
 
from rhodecode.lib.vcs import subprocessio
 

	
 
log = logging.getLogger(__name__)
 

	
rhodecode/lib/subprocessio.py
Show inline comments
 
deleted file
rhodecode/lib/utils.py
Show inline comments
 
@@ -374,6 +374,26 @@ def set_rhodecode_config(config):
 
        config[k] = v
 

	
 

	
 
def set_vcs_config(config):
 
    """
 
    Patch VCS config with some RhodeCode specific stuff
 

	
 
    :param config: rhodecode.CONFIG
 
    """
 
    import rhodecode
 
    from rhodecode.lib.vcs import conf
 
    from rhodecode.lib.utils2 import aslist
 
    conf.settings.BACKENDS = {
 
        'hg': 'rhodecode.lib.vcs.backends.hg.MercurialRepository',
 
        'git': 'rhodecode.lib.vcs.backends.git.GitRepository',
 
    }
 

	
 
    conf.settings.GIT_EXECUTABLE_PATH = config.get('git_path', 'git')
 
    conf.settings.GIT_REV_FILTER = config.get('git_rev_filter', '--all').strip()
 
    conf.settings.DEFAULT_ENCODINGS = aslist(config.get('default_encoding',
 
                                                        'utf8'), sep=',')
 

	
 

	
 
def map_groups(path):
 
    """
 
    Given a full path to a repository, create all nested groups that this
 
@@ -739,6 +759,7 @@ def check_git_version():
 
    """
 
    from rhodecode import BACKENDS
 
    from rhodecode.lib.vcs.backends.git.repository import GitRepository
 
    from rhodecode.lib.vcs.conf import settings
 
    from distutils.version import StrictVersion
 

	
 
    stdout, stderr = GitRepository._run_git_command('--version', _bare=True,
 
@@ -760,7 +781,8 @@ def check_git_version():
 
        to_old_git = True
 

	
 
    if 'git' in BACKENDS:
 
        log.debug('GIT version detected: %s' % stdout)
 
        log.debug('GIT executable: "%s" version detected: %s'
 
                  % (settings.GIT_EXECUTABLE_PATH, stdout))
 
        if stderr:
 
            log.warning('Unable to detect git version, org error was: %r' % stderr)
 
        elif to_old_git:
rhodecode/lib/vcs/__init__.py
Show inline comments
 
@@ -10,13 +10,14 @@
 
    :copyright: (c) 2010-2011 by Marcin Kuzminski, Lukasz Balcerzak.
 
"""
 

	
 
VERSION = (0, 3, 0, 'dev')
 
VERSION = (0, 4, 0, 'dev')
 

	
 
__version__ = '.'.join((str(each) for each in VERSION[:4]))
 

	
 
__all__ = [
 
    'get_version', 'get_repo', 'get_backend',
 
    'VCSError', 'RepositoryError', 'ChangesetError']
 
    'VCSError', 'RepositoryError', 'ChangesetError'
 
]
 

	
 
import sys
 
from rhodecode.lib.vcs.backends import get_repo, get_backend
 
@@ -29,6 +30,7 @@ def get_version():
 
    """
 
    return '.'.join((str(each) for each in VERSION[:3]))
 

	
 

	
 
def main(argv=None):
 
    if argv is None:
 
        argv = sys.argv
rhodecode/lib/vcs/backends/base.py
Show inline comments
 
@@ -10,16 +10,18 @@
 
"""
 

	
 
import datetime
 
from itertools import chain
 
import itertools
 

	
 
from rhodecode.lib.vcs.utils import author_name, author_email
 
from rhodecode.lib.vcs.utils.lazy import LazyProperty
 
from rhodecode.lib.vcs.utils.helpers import get_dict_for_attrs
 
from rhodecode.lib.vcs.conf import settings
 

	
 
from rhodecode.lib.vcs.exceptions import ChangesetError, EmptyRepositoryError, \
 
    NodeAlreadyAddedError, NodeAlreadyChangedError, NodeAlreadyExistsError, \
 
    NodeAlreadyRemovedError, NodeDoesNotExistError, NodeNotChangedError, \
 
    RepositoryError
 
from rhodecode.lib.vcs.exceptions import (
 
    ChangesetError, EmptyRepositoryError, NodeAlreadyAddedError,
 
    NodeAlreadyChangedError, NodeAlreadyExistsError, NodeAlreadyRemovedError,
 
    NodeDoesNotExistError, NodeNotChangedError, RepositoryError
 
)
 

	
 

	
 
class BaseRepository(object):
 
@@ -851,7 +853,7 @@ class BaseInMemoryChangeset(object):
 
        Returns generator of paths from nodes marked as added, changed or
 
        removed.
 
        """
 
        for node in chain(self.added, self.changed, self.removed):
 
        for node in itertools.chain(self.added, self.changed, self.removed):
 
            yield node.path
 

	
 
    def get_paths(self):
rhodecode/lib/vcs/backends/git/changeset.py
Show inline comments
 
@@ -2,22 +2,21 @@ import re
 
from itertools import chain
 
from dulwich import objects
 
from subprocess import Popen, PIPE
 
import rhodecode
 

	
 
from rhodecode.lib.vcs.conf import settings
 
from rhodecode.lib.vcs.exceptions import RepositoryError
 
from rhodecode.lib.vcs.exceptions import ChangesetError
 
from rhodecode.lib.vcs.exceptions import NodeDoesNotExistError
 
from rhodecode.lib.vcs.exceptions import VCSError
 
from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
 
from rhodecode.lib.vcs.exceptions import ImproperArchiveTypeError
 
from rhodecode.lib.vcs.backends.base import BaseChangeset, EmptyChangeset
 
from rhodecode.lib.vcs.nodes import FileNode, DirNode, NodeKind, RootNode, \
 
    RemovedFileNode, SubModuleNode, ChangedFileNodesGenerator,\
 
    AddedFileNodesGenerator, RemovedFileNodesGenerator
 
from rhodecode.lib.vcs.utils import safe_unicode
 
from rhodecode.lib.vcs.utils import date_fromtimestamp
 
from rhodecode.lib.vcs.exceptions import (
 
    RepositoryError, ChangesetError, NodeDoesNotExistError, VCSError,
 
    ChangesetDoesNotExistError, ImproperArchiveTypeError
 
)
 
from rhodecode.lib.vcs.nodes import (
 
    FileNode, DirNode, NodeKind, RootNode, RemovedFileNode, SubModuleNode,
 
    ChangedFileNodesGenerator, AddedFileNodesGenerator, RemovedFileNodesGenerator
 
)
 
from rhodecode.lib.vcs.utils import (
 
    safe_unicode, safe_str, safe_int, date_fromtimestamp
 
)
 
from rhodecode.lib.vcs.utils.lazy import LazyProperty
 
from rhodecode.lib.utils2 import safe_int, safe_str
 

	
 

	
 
class GitChangeset(BaseChangeset):
 
@@ -187,8 +186,7 @@ class GitChangeset(BaseChangeset):
 
        """
 
        Returns list of children changesets.
 
        """
 
        rev_filter = _git_path = rhodecode.CONFIG.get('git_rev_filter',
 
                                              '--all').strip()
 
        rev_filter = _git_path = settings.GIT_REV_FILTER
 
        so, se = self.repository.run_git_command(
 
            "rev-list %s --children | grep '^%s'" % (rev_filter, self.raw_id)
 
        )
 
@@ -373,7 +371,7 @@ class GitChangeset(BaseChangeset):
 
            frmt = 'zip'
 
        else:
 
            frmt = 'tar'
 
        _git_path = rhodecode.CONFIG.get('git_path', 'git')
 
        _git_path = settings.GIT_EXECUTABLE_PATH
 
        cmd = '%s archive --format=%s --prefix=%s/ %s' % (_git_path,
 
                                                frmt, prefix, self.raw_id)
 
        if kind == 'tgz':
 
@@ -472,8 +470,8 @@ class GitChangeset(BaseChangeset):
 
        """
 
        Get's a fast accessible file changes for given changeset
 
        """
 
        a, m, d = self._changes_cache
 
        return list(a.union(m).union(d))
 
        added, modified, deleted = self._changes_cache
 
        return list(added.union(modified).union(deleted))
 

	
 
    @LazyProperty
 
    def _diff_name_status(self):
 
@@ -516,11 +514,11 @@ class GitChangeset(BaseChangeset):
 

	
 
        :param status: one of: *added*, *modified* or *deleted*
 
        """
 
        a, m, d = self._changes_cache
 
        added, modified, deleted = self._changes_cache
 
        return sorted({
 
            'added': list(a),
 
            'modified': list(m),
 
            'deleted': list(d)}[status]
 
            'added': list(added),
 
            'modified': list(modified),
 
            'deleted': list(deleted)}[status]
 
        )
 

	
 
    @LazyProperty
rhodecode/lib/vcs/backends/git/inmemory.py
Show inline comments
 
@@ -150,7 +150,6 @@ class GitInMemoryChangeset(BaseInMemoryC
 

	
 
        ref = 'refs/heads/%s' % branch
 
        repo.refs[ref] = commit.id
 
        repo.refs.set_symbolic_ref('HEAD', ref)
 

	
 
        # Update vcs repository object & recreate dulwich repo
 
        self.repository.revisions.append(commit.id)
rhodecode/lib/vcs/backends/git/repository.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    vcs.backends.git
 
    ~~~~~~~~~~~~~~~~
 
    vcs.backends.git.repository
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    Git backend implementation.
 
    Git repository implementation.
 

	
 
    :created_on: Apr 8, 2010
 
    :copyright: (c) 2010-2011 by Marcin Kuzminski, Lukasz Balcerzak.
 
@@ -12,34 +12,36 @@
 
import os
 
import re
 
import time
 
import posixpath
 
import logging
 
import traceback
 
import urllib
 
import urllib2
 
from dulwich.repo import Repo, NotGitRepository
 
import logging
 
import posixpath
 
import string
 

	
 
from dulwich.objects import Tag
 
from string import Template
 
from dulwich.repo import Repo, NotGitRepository
 

	
 
import rhodecode
 
from rhodecode.lib.vcs import subprocessio
 
from rhodecode.lib.vcs.backends.base import BaseRepository, CollectionGenerator
 
from rhodecode.lib.vcs.exceptions import BranchDoesNotExistError
 
from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
 
from rhodecode.lib.vcs.exceptions import EmptyRepositoryError
 
from rhodecode.lib.vcs.exceptions import RepositoryError
 
from rhodecode.lib.vcs.exceptions import TagAlreadyExistError
 
from rhodecode.lib.vcs.exceptions import TagDoesNotExistError
 
from rhodecode.lib.vcs.conf import settings
 

	
 
from rhodecode.lib.vcs.exceptions import (
 
    BranchDoesNotExistError, ChangesetDoesNotExistError, EmptyRepositoryError,
 
    RepositoryError, TagAlreadyExistError, TagDoesNotExistError
 
)
 
from rhodecode.lib.vcs.utils import safe_unicode, makedate, date_fromtimestamp
 
from rhodecode.lib.vcs.utils.lazy import LazyProperty, ThreadLocalLazyProperty
 
from rhodecode.lib.vcs.utils.lazy import LazyProperty
 
from rhodecode.lib.vcs.utils.ordered_dict import OrderedDict
 
from rhodecode.lib.vcs.utils.paths import abspath
 
from rhodecode.lib.vcs.utils.paths import get_user_home
 
from .workdir import GitWorkdir
 
from rhodecode.lib.vcs.utils.paths import abspath, get_user_home
 

	
 
from rhodecode.lib.vcs.utils.hgcompat import (
 
    hg_url, httpbasicauthhandler, httpdigestauthhandler
 
)
 

	
 
from .changeset import GitChangeset
 
from .config import ConfigFile
 
from .inmemory import GitInMemoryChangeset
 
from .config import ConfigFile
 
from rhodecode.lib import subprocessio
 

	
 
from .workdir import GitWorkdir
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -115,7 +117,7 @@ class GitRepository(BaseRepository):
 
            del gitenv['GIT_DIR']
 
        gitenv['GIT_CONFIG_NOGLOBAL'] = '1'
 

	
 
        _git_path = rhodecode.CONFIG.get('git_path', 'git')
 
        _git_path = settings.GIT_EXECUTABLE_PATH
 
        cmd = [_git_path] + _copts + cmd
 
        if _str_cmd:
 
            cmd = ' '.join(cmd)
 
@@ -153,11 +155,6 @@ class GitRepository(BaseRepository):
 

	
 
        On failures it'll raise urllib2.HTTPError
 
        """
 
        from mercurial.util import url as Url
 

	
 
        # those authnadlers are patched for python 2.6.5 bug an
 
        # infinit looping when given invalid resources
 
        from mercurial.url import httpbasicauthhandler, httpdigestauthhandler
 

	
 
        # check first if it's not an local url
 
        if os.path.isdir(url) or url.startswith('file:'):
 
@@ -167,7 +164,7 @@ class GitRepository(BaseRepository):
 
            url = url[url.find('+') + 1:]
 

	
 
        handlers = []
 
        test_uri, authinfo = Url(url).authinfo()
 
        test_uri, authinfo = hg_url(url).authinfo()
 
        if not test_uri.endswith('info/refs'):
 
            test_uri = test_uri.rstrip('/') + '/info/refs'
 
        if authinfo:
 
@@ -224,8 +221,8 @@ class GitRepository(BaseRepository):
 
            self._repo.head()
 
        except KeyError:
 
            return []
 
        rev_filter = _git_path = rhodecode.CONFIG.get('git_rev_filter',
 
                                                      '--all').strip()
 

	
 
        rev_filter = _git_path = settings.GIT_REV_FILTER
 
        cmd = 'rev-list %s --reverse --date-order' % (rev_filter)
 
        try:
 
            so, se = self.run_git_command(cmd)
 
@@ -502,11 +499,10 @@ class GitRepository(BaseRepository):
 
            cmd_template += ' $branch_name'
 
            cmd_params['branch_name'] = branch_name
 
        else:
 
            rev_filter = _git_path = rhodecode.CONFIG.get('git_rev_filter',
 
                                                          '--all').strip()
 
            rev_filter = _git_path = settings.GIT_REV_FILTER
 
            cmd_template += ' %s' % (rev_filter)
 

	
 
        cmd = Template(cmd_template).safe_substitute(**cmd_params)
 
        cmd = string.Template(cmd_template).safe_substitute(**cmd_params)
 
        revs = self.run_git_command(cmd)[0].splitlines()
 
        start_pos = 0
 
        end_pos = len(revs)
rhodecode/lib/vcs/backends/hg/changeset.py
Show inline comments
 
import os
 
import posixpath
 

	
 
from rhodecode.lib.vcs.conf import settings
 
from rhodecode.lib.vcs.backends.base import BaseChangeset
 
from rhodecode.lib.vcs.conf import settings
 
from rhodecode.lib.vcs.exceptions import  ChangesetDoesNotExistError, \
 
    ChangesetError, ImproperArchiveTypeError, NodeDoesNotExistError, VCSError
 
from rhodecode.lib.vcs.nodes import AddedFileNodesGenerator, \
 
    ChangedFileNodesGenerator, DirNode, FileNode, NodeKind, \
 
    RemovedFileNodesGenerator, RootNode, SubModuleNode
 

	
 
from rhodecode.lib.vcs.exceptions import (
 
    ChangesetDoesNotExistError, ChangesetError, ImproperArchiveTypeError,
 
    NodeDoesNotExistError, VCSError
 
)
 
from rhodecode.lib.vcs.nodes import (
 
    AddedFileNodesGenerator, ChangedFileNodesGenerator, DirNode, FileNode,
 
    NodeKind, RemovedFileNodesGenerator, RootNode, SubModuleNode
 
)
 
from rhodecode.lib.vcs.utils import safe_str, safe_unicode, date_fromtimestamp
 
from rhodecode.lib.vcs.utils.lazy import LazyProperty
 
from rhodecode.lib.vcs.utils.paths import get_dirs_for_path
rhodecode/lib/vcs/backends/hg/repository.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    vcs.backends.hg.repository
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    Mercurial repository implementation.
 

	
 
    :created_on: Apr 8, 2010
 
    :copyright: (c) 2010-2011 by Marcin Kuzminski, Lukasz Balcerzak.
 
"""
 

	
 
import os
 
import time
 
import datetime
 
import urllib
 
import urllib2
 
import logging
 
import datetime
 

	
 

	
 
from rhodecode.lib.vcs.backends.base import BaseRepository, CollectionGenerator
 
from .workdir import MercurialWorkdir
 
from .changeset import MercurialChangeset
 
from .inmemory import MercurialInMemoryChangeset
 
from rhodecode.lib.vcs.conf import settings
 

	
 
from rhodecode.lib.vcs.exceptions import BranchDoesNotExistError, \
 
    ChangesetDoesNotExistError, EmptyRepositoryError, RepositoryError, \
 
    VCSError, TagAlreadyExistError, TagDoesNotExistError
 
from rhodecode.lib.vcs.utils import author_email, author_name, date_fromtimestamp, \
 
    makedate, safe_unicode
 
from rhodecode.lib.vcs.exceptions import (
 
    BranchDoesNotExistError, ChangesetDoesNotExistError, EmptyRepositoryError,
 
    RepositoryError, VCSError, TagAlreadyExistError, TagDoesNotExistError
 
)
 
from rhodecode.lib.vcs.utils import (
 
    author_email, author_name, date_fromtimestamp, makedate, safe_unicode
 
)
 
from rhodecode.lib.vcs.utils.lazy import LazyProperty
 
from rhodecode.lib.vcs.utils.ordered_dict import OrderedDict
 
from rhodecode.lib.vcs.utils.paths import abspath
 
from rhodecode.lib.vcs.utils.hgcompat import (
 
    ui, nullid, match, patch, diffopts, clone, get_contact, pull,
 
    localrepository, RepoLookupError, Abort, RepoError, hex, scmutil, hg_url,
 
    httpbasicauthhandler, httpdigestauthhandler
 
)
 

	
 
from rhodecode.lib.vcs.utils.hgcompat import ui, nullid, match, patch, \
 
    diffopts, clone, get_contact, pull, localrepository, RepoLookupError, \
 
    Abort, RepoError, hex, scmutil
 
from .changeset import MercurialChangeset
 
from .inmemory import MercurialInMemoryChangeset
 
from .workdir import MercurialWorkdir
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class MercurialRepository(BaseRepository):
 
@@ -272,12 +292,6 @@ class MercurialRepository(BaseRepository
 
        is valid or True if it's a local path
 
        """
 

	
 
        from mercurial.util import url as Url
 

	
 
        # those authnadlers are patched for python 2.6.5 bug an
 
        # infinit looping when given invalid resources
 
        from mercurial.url import httpbasicauthhandler, httpdigestauthhandler
 

	
 
        # check first if it's not an local url
 
        if os.path.isdir(url) or url.startswith('file:'):
 
            return True
 
@@ -286,7 +300,7 @@ class MercurialRepository(BaseRepository
 
            url = url[url.find('+') + 1:]
 

	
 
        handlers = []
 
        test_uri, authinfo = Url(url).authinfo()
 
        test_uri, authinfo = hg_url(url).authinfo()
 

	
 
        if authinfo:
 
            #create a password manager
 
@@ -486,8 +500,10 @@ class MercurialRepository(BaseRepository
 
            revisions = scmutil.revrange(self._repo, filter_)
 
        else:
 
            revisions = self.revisions
 
        revs = reversed(revisions[start_pos:end_pos]) if reverse else \
 
                revisions[start_pos:end_pos]
 

	
 
        revs = revisions[start_pos:end_pos]
 
        if reverse:
 
            revs = reversed(revs)
 

	
 
        return CollectionGenerator(self, revs)
 

	
rhodecode/lib/vcs/conf/settings.py
Show inline comments
 
import os
 
import tempfile
 
from rhodecode.lib.vcs.utils import aslist
 
from rhodecode.lib.vcs.utils.paths import get_user_home
 

	
 
abspath = lambda * p: os.path.abspath(os.path.join(*p))
 
@@ -15,9 +16,17 @@ VCSRC_PATH = VCSRC_PATH or abspath(HOME_
 
if os.path.isdir(VCSRC_PATH):
 
    VCSRC_PATH = os.path.join(VCSRC_PATH, '__init__.py')
 

	
 
# list of default encoding used in safe_unicode/safe_str methods
 
DEFAULT_ENCODINGS = aslist('utf8')
 

	
 
# path to git executable runned by run_git_command function
 
GIT_EXECUTABLE_PATH = 'git'
 
# can be also --branches --tags
 
GIT_REV_FILTER = '--all'
 

	
 
BACKENDS = {
 
    'hg': 'vcs.backends.hg.MercurialRepository',
 
    'git': 'vcs.backends.git.GitRepository',
 
    'hg': 'rhodecode.lib.vcs.backends.hg.MercurialRepository',
 
    'git': 'rhodecode.lib.vcs.backends.git.GitRepository',
 
}
 

	
 
ARCHIVE_SPECS = {
 
@@ -26,8 +35,3 @@ ARCHIVE_SPECS = {
 
    'tgz': ('application/x-gzip', '.tar.gz'),
 
    'zip': ('application/zip', '.zip'),
 
}
 

	
 
BACKENDS = {
 
    'hg': 'rhodecode.lib.vcs.backends.hg.MercurialRepository',
 
    'git': 'rhodecode.lib.vcs.backends.git.GitRepository',
 
}
rhodecode/lib/vcs/nodes.py
Show inline comments
 
@@ -15,11 +15,10 @@ import mimetypes
 

	
 
from pygments import lexers
 

	
 
from rhodecode.lib.vcs.backends.base import EmptyChangeset
 
from rhodecode.lib.vcs.exceptions import NodeError, RemovedFileNodeError
 
from rhodecode.lib.vcs.utils.lazy import LazyProperty
 
from rhodecode.lib.vcs.utils import safe_unicode
 
from rhodecode.lib.vcs.exceptions import NodeError
 
from rhodecode.lib.vcs.exceptions import RemovedFileNodeError
 
from rhodecode.lib.vcs.backends.base import EmptyChangeset
 

	
 

	
 
class NodeKind:
 
@@ -353,7 +352,6 @@ class FileNode(Node):
 

	
 
    @LazyProperty
 
    def mimetype_main(self):
 
        return ['', '']
 
        return self.mimetype.split('/')[0]
 

	
 
    @LazyProperty
rhodecode/lib/vcs/subprocessio.py
Show inline comments
 
new file 100644
 
'''
 
Module provides a class allowing to wrap communication over subprocess.Popen
 
input, output, error streams into a meaningfull, non-blocking, concurrent
 
stream processor exposing the output data as an iterator fitting to be a
 
return value passed by a WSGI applicaiton to a WSGI server per PEP 3333.
 

	
 
Copyright (c) 2011  Daniel Dotsenko <dotsa@hotmail.com>
 

	
 
This file is part of git_http_backend.py Project.
 

	
 
git_http_backend.py Project is free software: you can redistribute it and/or
 
modify it under the terms of the GNU Lesser General Public License as
 
published by the Free Software Foundation, either version 2.1 of the License,
 
or (at your option) any later version.
 

	
 
git_http_backend.py Project 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 Lesser General Public License for more details.
 

	
 
You should have received a copy of the GNU Lesser General Public License
 
along with git_http_backend.py Project.
 
If not, see <http://www.gnu.org/licenses/>.
 
'''
 
import os
 
import subprocess
 
from rhodecode.lib.vcs.utils.compat import deque, Event, Thread, _bytes, _bytearray
 

	
 

	
 
class StreamFeeder(Thread):
 
    """
 
    Normal writing into pipe-like is blocking once the buffer is filled.
 
    This thread allows a thread to seep data from a file-like into a pipe
 
    without blocking the main thread.
 
    We close inpipe once the end of the source stream is reached.
 
    """
 
    def __init__(self, source):
 
        super(StreamFeeder, self).__init__()
 
        self.daemon = True
 
        filelike = False
 
        self.bytes = _bytes()
 
        if type(source) in (type(''), _bytes, _bytearray):  # string-like
 
            self.bytes = _bytes(source)
 
        else:  # can be either file pointer or file-like
 
            if type(source) in (int, long):  # file pointer it is
 
                ## converting file descriptor (int) stdin into file-like
 
                try:
 
                    source = os.fdopen(source, 'rb', 16384)
 
                except Exception:
 
                    pass
 
            # let's see if source is file-like by now
 
            try:
 
                filelike = source.read
 
            except Exception:
 
                pass
 
        if not filelike and not self.bytes:
 
            raise TypeError("StreamFeeder's source object must be a readable "
 
                            "file-like, a file descriptor, or a string-like.")
 
        self.source = source
 
        self.readiface, self.writeiface = os.pipe()
 

	
 
    def run(self):
 
        t = self.writeiface
 
        if self.bytes:
 
            os.write(t, self.bytes)
 
        else:
 
            s = self.source
 
            b = s.read(4096)
 
            while b:
 
                os.write(t, b)
 
                b = s.read(4096)
 
        os.close(t)
 

	
 
    @property
 
    def output(self):
 
        return self.readiface
 

	
 

	
 
class InputStreamChunker(Thread):
 
    def __init__(self, source, target, buffer_size, chunk_size):
 

	
 
        super(InputStreamChunker, self).__init__()
 

	
 
        self.daemon = True  # die die die.
 

	
 
        self.source = source
 
        self.target = target
 
        self.chunk_count_max = int(buffer_size / chunk_size) + 1
 
        self.chunk_size = chunk_size
 

	
 
        self.data_added = Event()
 
        self.data_added.clear()
 

	
 
        self.keep_reading = Event()
 
        self.keep_reading.set()
 

	
 
        self.EOF = Event()
 
        self.EOF.clear()
 

	
 
        self.go = Event()
 
        self.go.set()
 

	
 
    def stop(self):
 
        self.go.clear()
 
        self.EOF.set()
 
        try:
 
            # this is not proper, but is done to force the reader thread let
 
            # go of the input because, if successful, .close() will send EOF
 
            # down the pipe.
 
            self.source.close()
 
        except:
 
            pass
 

	
 
    def run(self):
 
        s = self.source
 
        t = self.target
 
        cs = self.chunk_size
 
        ccm = self.chunk_count_max
 
        kr = self.keep_reading
 
        da = self.data_added
 
        go = self.go
 

	
 
        try:
 
            b = s.read(cs)
 
        except ValueError:
 
            b = ''
 

	
 
        while b and go.is_set():
 
            if len(t) > ccm:
 
                kr.clear()
 
                kr.wait(2)
 
#                # this only works on 2.7.x and up
 
#                if not kr.wait(10):
 
#                    raise Exception("Timed out while waiting for input to be read.")
 
                # instead we'll use this
 
                if len(t) > ccm + 3:
 
                    raise IOError("Timed out while waiting for input from subprocess.")
 
            t.append(b)
 
            da.set()
 
            b = s.read(cs)
 
        self.EOF.set()
 
        da.set()  # for cases when done but there was no input.
 

	
 

	
 
class BufferedGenerator():
 
    '''
 
    Class behaves as a non-blocking, buffered pipe reader.
 
    Reads chunks of data (through a thread)
 
    from a blocking pipe, and attaches these to an array (Deque) of chunks.
 
    Reading is halted in the thread when max chunks is internally buffered.
 
    The .next() may operate in blocking or non-blocking fashion by yielding
 
    '' if no data is ready
 
    to be sent or by not returning until there is some data to send
 
    When we get EOF from underlying source pipe we raise the marker to raise
 
    StopIteration after the last chunk of data is yielded.
 
    '''
 

	
 
    def __init__(self, source, buffer_size=65536, chunk_size=4096,
 
                 starting_values=[], bottomless=False):
 

	
 
        if bottomless:
 
            maxlen = int(buffer_size / chunk_size)
 
        else:
 
            maxlen = None
 

	
 
        self.data = deque(starting_values, maxlen)
 

	
 
        self.worker = InputStreamChunker(source, self.data, buffer_size,
 
                                         chunk_size)
 
        if starting_values:
 
            self.worker.data_added.set()
 
        self.worker.start()
 

	
 
    ####################
 
    # Generator's methods
 
    ####################
 

	
 
    def __iter__(self):
 
        return self
 

	
 
    def next(self):
 
        while not len(self.data) and not self.worker.EOF.is_set():
 
            self.worker.data_added.clear()
 
            self.worker.data_added.wait(0.2)
 
        if len(self.data):
 
            self.worker.keep_reading.set()
 
            return _bytes(self.data.popleft())
 
        elif self.worker.EOF.is_set():
 
            raise StopIteration
 

	
 
    def throw(self, type, value=None, traceback=None):
 
        if not self.worker.EOF.is_set():
 
            raise type(value)
 

	
 
    def start(self):
 
        self.worker.start()
 

	
 
    def stop(self):
 
        self.worker.stop()
 

	
 
    def close(self):
 
        try:
 
            self.worker.stop()
 
            self.throw(GeneratorExit)
 
        except (GeneratorExit, StopIteration):
 
            pass
 

	
 
    def __del__(self):
 
        self.close()
 

	
 
    ####################
 
    # Threaded reader's infrastructure.
 
    ####################
 
    @property
 
    def input(self):
 
        return self.worker.w
 

	
 
    @property
 
    def data_added_event(self):
 
        return self.worker.data_added
 

	
 
    @property
 
    def data_added(self):
 
        return self.worker.data_added.is_set()
 

	
 
    @property
 
    def reading_paused(self):
 
        return not self.worker.keep_reading.is_set()
 

	
 
    @property
 
    def done_reading_event(self):
 
        '''
 
        Done_reding does not mean that the iterator's buffer is empty.
 
        Iterator might have done reading from underlying source, but the read
 
        chunks might still be available for serving through .next() method.
 

	
 
        @return An Event class instance.
 
        '''
 
        return self.worker.EOF
 

	
 
    @property
 
    def done_reading(self):
 
        '''
 
        Done_reding does not mean that the iterator's buffer is empty.
 
        Iterator might have done reading from underlying source, but the read
 
        chunks might still be available for serving through .next() method.
 

	
 
        @return An Bool value.
 
        '''
 
        return self.worker.EOF.is_set()
 

	
 
    @property
 
    def length(self):
 
        '''
 
        returns int.
 

	
 
        This is the lenght of the que of chunks, not the length of
 
        the combined contents in those chunks.
 

	
 
        __len__() cannot be meaningfully implemented because this
 
        reader is just flying throuh a bottomless pit content and
 
        can only know the lenght of what it already saw.
 

	
 
        If __len__() on WSGI server per PEP 3333 returns a value,
 
        the responce's length will be set to that. In order not to
 
        confuse WSGI PEP3333 servers, we will not implement __len__
 
        at all.
 
        '''
 
        return len(self.data)
 

	
 
    def prepend(self, x):
 
        self.data.appendleft(x)
 

	
 
    def append(self, x):
 
        self.data.append(x)
 

	
 
    def extend(self, o):
 
        self.data.extend(o)
 

	
 
    def __getitem__(self, i):
 
        return self.data[i]
 

	
 

	
 
class SubprocessIOChunker(object):
 
    '''
 
    Processor class wrapping handling of subprocess IO.
 

	
 
    In a way, this is a "communicate()" replacement with a twist.
 

	
 
    - We are multithreaded. Writing in and reading out, err are all sep threads.
 
    - We support concurrent (in and out) stream processing.
 
    - The output is not a stream. It's a queue of read string (bytes, not unicode)
 
      chunks. The object behaves as an iterable. You can "for chunk in obj:" us.
 
    - We are non-blocking in more respects than communicate()
 
      (reading from subprocess out pauses when internal buffer is full, but
 
       does not block the parent calling code. On the flip side, reading from
 
       slow-yielding subprocess may block the iteration until data shows up. This
 
       does not block the parallel inpipe reading occurring parallel thread.)
 

	
 
    The purpose of the object is to allow us to wrap subprocess interactions into
 
    and interable that can be passed to a WSGI server as the application's return
 
    value. Because of stream-processing-ability, WSGI does not have to read ALL
 
    of the subprocess's output and buffer it, before handing it to WSGI server for
 
    HTTP response. Instead, the class initializer reads just a bit of the stream
 
    to figure out if error ocurred or likely to occur and if not, just hands the
 
    further iteration over subprocess output to the server for completion of HTTP
 
    response.
 

	
 
    The real or perceived subprocess error is trapped and raised as one of
 
    EnvironmentError family of exceptions
 

	
 
    Example usage:
 
    #    try:
 
    #        answer = SubprocessIOChunker(
 
    #            cmd,
 
    #            input,
 
    #            buffer_size = 65536,
 
    #            chunk_size = 4096
 
    #            )
 
    #    except (EnvironmentError) as e:
 
    #        print str(e)
 
    #        raise e
 
    #
 
    #    return answer
 

	
 

	
 
    '''
 
    def __init__(self, cmd, inputstream=None, buffer_size=65536,
 
                 chunk_size=4096, starting_values=[], **kwargs):
 
        '''
 
        Initializes SubprocessIOChunker
 

	
 
        :param cmd: A Subprocess.Popen style "cmd". Can be string or array of strings
 
        :param inputstream: (Default: None) A file-like, string, or file pointer.
 
        :param buffer_size: (Default: 65536) A size of total buffer per stream in bytes.
 
        :param chunk_size: (Default: 4096) A max size of a chunk. Actual chunk may be smaller.
 
        :param starting_values: (Default: []) An array of strings to put in front of output que.
 
        '''
 

	
 
        if inputstream:
 
            input_streamer = StreamFeeder(inputstream)
 
            input_streamer.start()
 
            inputstream = input_streamer.output
 

	
 
        if isinstance(cmd, (list, tuple)):
 
            cmd = ' '.join(cmd)
 

	
 
        _shell = kwargs.get('shell') or True
 
        kwargs['shell'] = _shell
 
        _p = subprocess.Popen(cmd,
 
            bufsize=-1,
 
            stdin=inputstream,
 
            stdout=subprocess.PIPE,
 
            stderr=subprocess.PIPE,
 
            **kwargs
 
            )
 

	
 
        bg_out = BufferedGenerator(_p.stdout, buffer_size, chunk_size, starting_values)
 
        bg_err = BufferedGenerator(_p.stderr, 16000, 1, bottomless=True)
 

	
 
        while not bg_out.done_reading and not bg_out.reading_paused and not bg_err.length:
 
            # doing this until we reach either end of file, or end of buffer.
 
            bg_out.data_added_event.wait(1)
 
            bg_out.data_added_event.clear()
 

	
 
        # at this point it's still ambiguous if we are done reading or just full buffer.
 
        # Either way, if error (returned by ended process, or implied based on
 
        # presence of stuff in stderr output) we error out.
 
        # Else, we are happy.
 
        _returncode = _p.poll()
 
        if _returncode or (_returncode == None and bg_err.length):
 
            try:
 
                _p.terminate()
 
            except:
 
                pass
 
            bg_out.stop()
 
            bg_err.stop()
 
            err = '%s' % ''.join(bg_err)
 
            if err:
 
                raise EnvironmentError("Subprocess exited due to an error:\n" + err)
 
            raise EnvironmentError("Subprocess exited with non 0 ret code:%s" % _returncode)
 

	
 
        self.process = _p
 
        self.output = bg_out
 
        self.error = bg_err
 

	
 
    def __iter__(self):
 
        return self
 

	
 
    def next(self):
 
        if self.process.poll():
 
            err = '%s' % ''.join(self.error)
 
            raise EnvironmentError("Subprocess exited due to an error:\n" + err)
 
        return self.output.next()
 

	
 
    def throw(self, type, value=None, traceback=None):
 
        if self.output.length or not self.output.done_reading:
 
            raise type(value)
 

	
 
    def close(self):
 
        try:
 
            self.process.terminate()
 
        except:
 
            pass
 
        try:
 
            self.output.close()
 
        except:
 
            pass
 
        try:
 
            self.error.close()
 
        except:
 
            pass
 

	
 
    def __del__(self):
 
        self.close()
rhodecode/lib/vcs/utils/__init__.py
Show inline comments
 
@@ -16,6 +16,27 @@ def makedate():
 
    return time.mktime(lt), tz
 

	
 

	
 
def aslist(obj, sep=None, strip=True):
 
    """
 
    Returns given string separated by sep as list
 

	
 
    :param obj:
 
    :param sep:
 
    :param strip:
 
    """
 
    if isinstance(obj, (basestring)):
 
        lst = obj.split(sep)
 
        if strip:
 
            lst = [v.strip() for v in lst]
 
        return lst
 
    elif isinstance(obj, (list, tuple)):
 
        return obj
 
    elif obj is None:
 
        return []
 
    else:
 
        return [obj]
 

	
 

	
 
def date_fromtimestamp(unixts, tzoffset=0):
 
    """
 
    Makes a local datetime object out of unix timestamp
 
@@ -27,6 +48,23 @@ def date_fromtimestamp(unixts, tzoffset=
 
    return datetime.datetime.fromtimestamp(float(unixts))
 

	
 

	
 
def safe_int(val, default=None):
 
    """
 
    Returns int() of val if val is not convertable to int use default
 
    instead
 

	
 
    :param val:
 
    :param default:
 
    """
 

	
 
    try:
 
        val = int(val)
 
    except (ValueError, TypeError):
 
        val = default
 

	
 
    return val
 

	
 

	
 
def safe_unicode(str_, from_encoding=None):
 
    """
 
    safe unicode function. Does few trick to turn str_ into unicode
 
@@ -38,21 +76,26 @@ def safe_unicode(str_, from_encoding=Non
 
    :rtype: unicode
 
    :returns: unicode object
 
    """
 
    from rhodecode.lib.utils2 import safe_unicode
 
    return safe_unicode(str_, from_encoding)
 

	
 
    if isinstance(str_, unicode):
 
        return str_
 

	
 
    if not from_encoding:
 
        from rhodecode.lib.vcs.conf import settings
 
        from_encoding = settings.DEFAULT_ENCODINGS
 

	
 
    if not isinstance(from_encoding, (list, tuple)):
 
        from_encoding = [from_encoding]
 

	
 
    try:
 
        return unicode(str_)
 
    except UnicodeDecodeError:
 
        pass
 

	
 
    try:
 
        return unicode(str_, from_encoding)
 
    except UnicodeDecodeError:
 
        pass
 
    for enc in from_encoding:
 
        try:
 
            return unicode(str_, enc)
 
        except UnicodeDecodeError:
 
            pass
 

	
 
    try:
 
        import chardet
 
@@ -61,7 +104,7 @@ def safe_unicode(str_, from_encoding=Non
 
            raise Exception()
 
        return str_.decode(encoding)
 
    except (ImportError, UnicodeDecodeError, Exception):
 
        return unicode(str_, from_encoding, 'replace')
 
        return unicode(str_, from_encoding[0], 'replace')
 

	
 

	
 
def safe_str(unicode_, to_encoding=None):
 
@@ -75,16 +118,26 @@ def safe_str(unicode_, to_encoding=None)
 
    :rtype: str
 
    :returns: str object
 
    """
 
    from rhodecode.lib.utils2 import safe_str
 
    return safe_str(unicode_, to_encoding)
 

	
 
    # if it's not basestr cast to str
 
    if not isinstance(unicode_, basestring):
 
        return str(unicode_)
 

	
 
    if isinstance(unicode_, str):
 
        return unicode_
 

	
 
    try:
 
        return unicode_.encode(to_encoding)
 
    except UnicodeEncodeError:
 
        pass
 
    if not to_encoding:
 
        from rhodecode.lib.vcs.conf import settings
 
        to_encoding = settings.DEFAULT_ENCODINGS
 

	
 
    if not isinstance(to_encoding, (list, tuple)):
 
        to_encoding = [to_encoding]
 

	
 
    for enc in to_encoding:
 
        try:
 
            return unicode_.encode(enc)
 
        except UnicodeEncodeError:
 
            pass
 

	
 
    try:
 
        import chardet
 
@@ -94,7 +147,7 @@ def safe_str(unicode_, to_encoding=None)
 

	
 
        return unicode_.encode(encoding)
 
    except (ImportError, UnicodeEncodeError):
 
        return unicode_.encode(to_encoding, 'replace')
 
        return unicode_.encode(to_encoding[0], 'replace')
 

	
 
    return safe_str
 

	
rhodecode/lib/vcs/utils/annotate.py
Show inline comments
 
from rhodecode.lib.vcs.exceptions import VCSError
 
from rhodecode.lib.vcs.nodes import FileNode
 
import StringIO
 

	
 
from pygments.formatters import HtmlFormatter
 
from pygments import highlight
 

	
 
import StringIO
 
from rhodecode.lib.vcs.exceptions import VCSError
 
from rhodecode.lib.vcs.nodes import FileNode
 

	
 

	
 
def annotate_highlight(filenode, annotate_from_changeset_func=None,
rhodecode/lib/vcs/utils/compat.py
Show inline comments
 
@@ -5,9 +5,314 @@ Those utilities may be deleted once ``vc
 
versions.
 
"""
 
import sys
 

	
 
import array
 

	
 
if sys.version_info >= (2, 7):
 
    unittest = __import__('unittest')
 
else:
 
    unittest = __import__('unittest2')
 

	
 

	
 
if sys.version_info >= (2, 6):
 
    _bytes = bytes
 
else:
 
    # in py2.6 bytes is a synonim for str
 
    _bytes = str
 

	
 
if sys.version_info >= (2, 6):
 
    _bytearray = bytearray
 
else:
 
    # no idea if this is correct but all integration tests are passing
 
    # i think we never use bytearray anyway
 
    _bytearray = array
 

	
 
if sys.version_info >= (2, 6):
 
    from collections import deque
 
else:
 
    #need to implement our own deque with maxlen
 
    class deque(object):
 

	
 
        def __init__(self, iterable=(), maxlen= -1):
 
            if not hasattr(self, 'data'):
 
                self.left = self.right = 0
 
                self.data = {}
 
            self.maxlen = maxlen or -1
 
            self.extend(iterable)
 

	
 
        def append(self, x):
 
            self.data[self.right] = x
 
            self.right += 1
 
            if self.maxlen != -1 and len(self) > self.maxlen:
 
                self.popleft()
 

	
 
        def appendleft(self, x):
 
            self.left -= 1
 
            self.data[self.left] = x
 
            if self.maxlen != -1 and len(self) > self.maxlen:
 
                self.pop()
 

	
 
        def pop(self):
 
            if self.left == self.right:
 
                raise IndexError('cannot pop from empty deque')
 
            self.right -= 1
 
            elem = self.data[self.right]
 
            del self.data[self.right]
 
            return elem
 

	
 
        def popleft(self):
 
            if self.left == self.right:
 
                raise IndexError('cannot pop from empty deque')
 
            elem = self.data[self.left]
 
            del self.data[self.left]
 
            self.left += 1
 
            return elem
 

	
 
        def clear(self):
 
            self.data.clear()
 
            self.left = self.right = 0
 

	
 
        def extend(self, iterable):
 
            for elem in iterable:
 
                self.append(elem)
 

	
 
        def extendleft(self, iterable):
 
            for elem in iterable:
 
                self.appendleft(elem)
 

	
 
        def rotate(self, n=1):
 
            if self:
 
                n %= len(self)
 
                for i in xrange(n):
 
                    self.appendleft(self.pop())
 

	
 
        def __getitem__(self, i):
 
            if i < 0:
 
                i += len(self)
 
            try:
 
                return self.data[i + self.left]
 
            except KeyError:
 
                raise IndexError
 

	
 
        def __setitem__(self, i, value):
 
            if i < 0:
 
                i += len(self)
 
            try:
 
                self.data[i + self.left] = value
 
            except KeyError:
 
                raise IndexError
 

	
 
        def __delitem__(self, i):
 
            size = len(self)
 
            if not (-size <= i < size):
 
                raise IndexError
 
            data = self.data
 
            if i < 0:
 
                i += size
 
            for j in xrange(self.left + i, self.right - 1):
 
                data[j] = data[j + 1]
 
            self.pop()
 

	
 
        def __len__(self):
 
            return self.right - self.left
 

	
 
        def __cmp__(self, other):
 
            if type(self) != type(other):
 
                return cmp(type(self), type(other))
 
            return cmp(list(self), list(other))
 

	
 
        def __repr__(self, _track=[]):
 
            if id(self) in _track:
 
                return '...'
 
            _track.append(id(self))
 
            r = 'deque(%r, maxlen=%s)' % (list(self), self.maxlen)
 
            _track.remove(id(self))
 
            return r
 

	
 
        def __getstate__(self):
 
            return (tuple(self),)
 

	
 
        def __setstate__(self, s):
 
            self.__init__(s[0])
 

	
 
        def __hash__(self):
 
            raise TypeError
 

	
 
        def __copy__(self):
 
            return self.__class__(self)
 

	
 
        def __deepcopy__(self, memo={}):
 
            from copy import deepcopy
 
            result = self.__class__()
 
            memo[id(self)] = result
 
            result.__init__(deepcopy(tuple(self), memo))
 
            return result
 

	
 

	
 
#==============================================================================
 
# threading.Event
 
#==============================================================================
 

	
 
if sys.version_info >= (2, 6):
 
    from threading import Event, Thread
 
else:
 
    from threading import _Verbose, Lock, Thread, _time, \
 
        _allocate_lock, RLock, _sleep
 

	
 
    def Condition(*args, **kwargs):
 
        return _Condition(*args, **kwargs)
 

	
 
    class _Condition(_Verbose):
 

	
 
        def __init__(self, lock=None, verbose=None):
 
            _Verbose.__init__(self, verbose)
 
            if lock is None:
 
                lock = RLock()
 
            self.__lock = lock
 
            # Export the lock's acquire() and release() methods
 
            self.acquire = lock.acquire
 
            self.release = lock.release
 
            # If the lock defines _release_save() and/or _acquire_restore(),
 
            # these override the default implementations (which just call
 
            # release() and acquire() on the lock).  Ditto for _is_owned().
 
            try:
 
                self._release_save = lock._release_save
 
            except AttributeError:
 
                pass
 
            try:
 
                self._acquire_restore = lock._acquire_restore
 
            except AttributeError:
 
                pass
 
            try:
 
                self._is_owned = lock._is_owned
 
            except AttributeError:
 
                pass
 
            self.__waiters = []
 

	
 
        def __enter__(self):
 
            return self.__lock.__enter__()
 

	
 
        def __exit__(self, *args):
 
            return self.__lock.__exit__(*args)
 

	
 
        def __repr__(self):
 
            return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
 

	
 
        def _release_save(self):
 
            self.__lock.release()           # No state to save
 

	
 
        def _acquire_restore(self, x):
 
            self.__lock.acquire()           # Ignore saved state
 

	
 
        def _is_owned(self):
 
            # Return True if lock is owned by current_thread.
 
            # This method is called only if __lock doesn't have _is_owned().
 
            if self.__lock.acquire(0):
 
                self.__lock.release()
 
                return False
 
            else:
 
                return True
 

	
 
        def wait(self, timeout=None):
 
            if not self._is_owned():
 
                raise RuntimeError("cannot wait on un-acquired lock")
 
            waiter = _allocate_lock()
 
            waiter.acquire()
 
            self.__waiters.append(waiter)
 
            saved_state = self._release_save()
 
            try:    # restore state no matter what (e.g., KeyboardInterrupt)
 
                if timeout is None:
 
                    waiter.acquire()
 
                    if __debug__:
 
                        self._note("%s.wait(): got it", self)
 
                else:
 
                    # Balancing act:  We can't afford a pure busy loop, so we
 
                    # have to sleep; but if we sleep the whole timeout time,
 
                    # we'll be unresponsive.  The scheme here sleeps very
 
                    # little at first, longer as time goes on, but never longer
 
                    # than 20 times per second (or the timeout time remaining).
 
                    endtime = _time() + timeout
 
                    delay = 0.0005 # 500 us -> initial delay of 1 ms
 
                    while True:
 
                        gotit = waiter.acquire(0)
 
                        if gotit:
 
                            break
 
                        remaining = endtime - _time()
 
                        if remaining <= 0:
 
                            break
 
                        delay = min(delay * 2, remaining, .05)
 
                        _sleep(delay)
 
                    if not gotit:
 
                        if __debug__:
 
                            self._note("%s.wait(%s): timed out", self, timeout)
 
                        try:
 
                            self.__waiters.remove(waiter)
 
                        except ValueError:
 
                            pass
 
                    else:
 
                        if __debug__:
 
                            self._note("%s.wait(%s): got it", self, timeout)
 
            finally:
 
                self._acquire_restore(saved_state)
 

	
 
        def notify(self, n=1):
 
            if not self._is_owned():
 
                raise RuntimeError("cannot notify on un-acquired lock")
 
            __waiters = self.__waiters
 
            waiters = __waiters[:n]
 
            if not waiters:
 
                if __debug__:
 
                    self._note("%s.notify(): no waiters", self)
 
                return
 
            self._note("%s.notify(): notifying %d waiter%s", self, n,
 
                       n != 1 and "s" or "")
 
            for waiter in waiters:
 
                waiter.release()
 
                try:
 
                    __waiters.remove(waiter)
 
                except ValueError:
 
                    pass
 

	
 
        def notifyAll(self):
 
            self.notify(len(self.__waiters))
 

	
 
        notify_all = notifyAll
 

	
 
    def Event(*args, **kwargs):
 
        return _Event(*args, **kwargs)
 

	
 
    class _Event(_Verbose):
 

	
 
        # After Tim Peters' event class (without is_posted())
 

	
 
        def __init__(self, verbose=None):
 
            _Verbose.__init__(self, verbose)
 
            self.__cond = Condition(Lock())
 
            self.__flag = False
 

	
 
        def isSet(self):
 
            return self.__flag
 

	
 
        is_set = isSet
 

	
 
        def set(self):
 
            self.__cond.acquire()
 
            try:
 
                self.__flag = True
 
                self.__cond.notify_all()
 
            finally:
 
                self.__cond.release()
 

	
 
        def clear(self):
 
            self.__cond.acquire()
 
            try:
 
                self.__flag = False
 
            finally:
 
                self.__cond.release()
 

	
 
        def wait(self, timeout=None):
 
            self.__cond.acquire()
 
            try:
 
                if not self.__flag:
 
                    self.__cond.wait(timeout)
 
            finally:
 
                self.__cond.release()
rhodecode/lib/vcs/utils/diffs.py
Show inline comments
 
@@ -5,11 +5,9 @@
 
import re
 
import difflib
 
import logging
 
import itertools
 

	
 
from difflib import unified_diff
 
from itertools import tee, imap
 

	
 
from mercurial.match import match
 

	
 
from rhodecode.lib.vcs.exceptions import VCSError
 
from rhodecode.lib.vcs.nodes import FileNode, NodeError
 
@@ -65,7 +63,7 @@ def get_gitdiff(filenode_old, filenode_n
 
    new_raw_id = getattr(filenode_new.changeset, 'raw_id', '0' * 40)
 

	
 
    repo = filenode_new.changeset.repository
 
    vcs_gitdiff = repo._get_diff(old_raw_id, new_raw_id, filenode_new.path,
 
    vcs_gitdiff = repo.get_diff(old_raw_id, new_raw_id, filenode_new.path,
 
                                 ignore_whitespace)
 

	
 
    return vcs_gitdiff
 
@@ -97,10 +95,11 @@ class DiffProcessor(object):
 

	
 
        elif self.__format == 'gitdiff':
 
            udiff_copy = self.copy_iterator()
 
            self.lines = imap(self.escaper, self._parse_gitdiff(udiff_copy))
 
            self.lines = itertools.imap(self.escaper,
 
                                        self._parse_gitdiff(udiff_copy))
 
        else:
 
            udiff_copy = self.copy_iterator()
 
            self.lines = imap(self.escaper, udiff_copy)
 
            self.lines = itertools.imap(self.escaper, udiff_copy)
 

	
 
        # Select a differ.
 
        if differ == 'difflib':
 
@@ -117,7 +116,7 @@ class DiffProcessor(object):
 
        an original as it's needed for repeating operations on
 
        this instance of DiffProcessor
 
        """
 
        self.__udiff, iterator_copy = tee(self.__udiff)
 
        self.__udiff, iterator_copy = itertools.tee(self.__udiff)
 
        return iterator_copy
 

	
 
    def _extract_rev(self, line1, line2):
rhodecode/lib/vcs/utils/helpers.py
Show inline comments
 
@@ -4,10 +4,11 @@ Utitlites aimed to help achieve mostly b
 
from __future__ import division
 

	
 
import re
 
import os
 
import time
 
import datetime
 
import os.path
 
from subprocess import Popen, PIPE
 

	
 
from rhodecode.lib.vcs.exceptions import VCSError
 
from rhodecode.lib.vcs.exceptions import RepositoryError
 
from rhodecode.lib.vcs.utils.paths import abspath
 
@@ -163,6 +164,7 @@ def parse_changesets(text):
 
            return result
 
    raise ValueError("IDs not recognized")
 

	
 

	
 
def parse_datetime(text):
 
    """
 
    Parses given text and returns ``datetime.datetime`` instance or raises
rhodecode/lib/vcs/utils/hgcompat.py
Show inline comments
 
@@ -16,3 +16,9 @@ from mercurial import discovery
 
from mercurial import localrepo
 
from mercurial import scmutil
 
from mercurial.discovery import findcommonoutgoing
 

	
 
from mercurial.util import url as hg_url
 

	
 
# those authnadlers are patched for python 2.6.5 bug an
 
# infinit looping when given invalid resources
 
from mercurial.url import httpbasicauthhandler, httpdigestauthhandler
rhodecode/lib/vcs/utils/progressbar.py
Show inline comments
 
# encoding: UTF-8
 
import sys
 
import datetime
 
from string import Template
 
import string
 

	
 
from rhodecode.lib.vcs.utils.filesize import filesizeformat
 
from rhodecode.lib.vcs.utils.helpers import get_total_seconds
 

	
 
@@ -63,7 +64,7 @@ class ProgressBar(object):
 
    def get_template(self):
 
        separator = self.get_separator()
 
        elements = self.get_elements()
 
        return Template(separator.join((('$%s' % e) for e in elements)))
 
        return string.Template(separator.join((('$%s' % e) for e in elements)))
 

	
 
    def get_total_time(self, current_time=None):
 
        if current_time is None:
rhodecode/tests/__init__.py
Show inline comments
 
@@ -30,7 +30,12 @@ from tempfile import _RandomNameSequence
 

	
 
from paste.deploy import loadapp
 
from paste.script.appinstall import SetupCommand
 

	
 
import pylons
 
import pylons.test
 
from pylons import config, url
 
from pylons.i18n.translation import _get_translator
 

	
 
from routes.util import URLGenerator
 
from webtest import TestApp
 
from nose.plugins.skip import SkipTest
 
@@ -39,8 +44,6 @@ from rhodecode import is_windows
 
from rhodecode.model.meta import Session
 
from rhodecode.model.db import User
 
from rhodecode.tests.nose_parametrized import parameterized
 

	
 
import pylons.test
 
from rhodecode.lib.utils2 import safe_unicode, safe_str
 

	
 

	
 
@@ -149,7 +152,13 @@ class TestController(TestCase):
 

	
 
        self.app = TestApp(wsgiapp)
 
        url._push_object(URLGenerator(config['routes.map'], environ))
 
        self.Session = Session
 
        pylons.app_globals._push_object(config['pylons.app_globals'])
 
        pylons.config._push_object(config)
 

	
 
        # Initialize a translator for tests that utilize i18n
 
        translator = _get_translator(pylons.config.get('lang'))
 
        pylons.translator._push_object(translator)
 

	
 
        self.index_location = config['app_conf']['index_dir']
 
        TestCase.__init__(self, *args, **kwargs)
 

	
rhodecode/tests/functional/test_admin_notifications.py
Show inline comments
 
@@ -3,6 +3,7 @@ from rhodecode.model.db import Notificat
 

	
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.notification import NotificationModel
 
from rhodecode.model.meta import Session
 

	
 

	
 
class TestNotificationsController(TestController):
 
@@ -10,8 +11,8 @@ class TestNotificationsController(TestCo
 
    def tearDown(self):
 
        for n in Notification.query().all():
 
            inst = Notification.get(n.notification_id)
 
            self.Session().delete(inst)
 
        self.Session().commit()
 
            Session().delete(inst)
 
        Session().commit()
 

	
 
    def test_index(self):
 
        self.log_user()
 
@@ -29,7 +30,7 @@ class TestNotificationsController(TestCo
 
        NotificationModel().create(created_by=u1, subject=u'test_notification_1',
 
                                   body=u'notification_1',
 
                                   recipients=[cur_user])
 
        self.Session().commit()
 
        Session().commit()
 
        response = self.app.get(url('notifications'))
 
        response.mustcontain(u'test_notification_1')
 

	
 
@@ -67,7 +68,7 @@ class TestNotificationsController(TestCo
 
                                                  subject=u'test',
 
                                                  body=u'hi there',
 
                                                  recipients=[cur_user, u1, u2])
 
        self.Session().commit()
 
        Session().commit()
 
        u1 = User.get(u1.user_id)
 
        u2 = User.get(u2.user_id)
 

	
rhodecode/tests/functional/test_admin_repos.py
Show inline comments
 
@@ -47,7 +47,7 @@ class TestAdminReposController(TestContr
 
                               % (repo_name, repo_name))
 

	
 
        #test if the repo was created in the database
 
        new_repo = self.Session().query(Repository)\
 
        new_repo = Session().query(Repository)\
 
            .filter(Repository.repo_name == repo_name).one()
 

	
 
        self.assertEqual(new_repo.repo_name, repo_name)
 
@@ -80,7 +80,7 @@ class TestAdminReposController(TestContr
 
                               u'Created repository <a href="/%s">%s</a>'
 
                               % (urllib.quote(repo_name), repo_name_unicode))
 
        #test if the repo was created in the database
 
        new_repo = self.Session().query(Repository)\
 
        new_repo = Session().query(Repository)\
 
            .filter(Repository.repo_name == repo_name_unicode).one()
 

	
 
        self.assertEqual(new_repo.repo_name, repo_name_unicode)
 
@@ -105,7 +105,7 @@ class TestAdminReposController(TestContr
 
        gr = ReposGroupModel().create(group_name=group_name,
 
                                      group_description='test',
 
                                      owner=TEST_USER_ADMIN_LOGIN)
 
        self.Session().commit()
 
        Session().commit()
 

	
 
        repo_name = 'ingroup'
 
        repo_name_full = RepoGroup.url_sep().join([group_name, repo_name])
 
@@ -120,7 +120,7 @@ class TestAdminReposController(TestContr
 
                               'Created repository <a href="/%s">%s</a>'
 
                               % (repo_name_full, repo_name))
 
        #test if the repo was created in the database
 
        new_repo = self.Session().query(Repository)\
 
        new_repo = Session().query(Repository)\
 
            .filter(Repository.repo_name == repo_name_full).one()
 

	
 
        self.assertEqual(new_repo.repo_name, repo_name_full)
 
@@ -136,12 +136,12 @@ class TestAdminReposController(TestContr
 
            vcs.get_repo(os.path.join(TESTS_TMP_PATH, repo_name_full))
 
        except Exception:
 
            ReposGroupModel().delete(group_name)
 
            self.Session().commit()
 
            Session().commit()
 
            self.fail('no repo %s in filesystem' % repo_name)
 

	
 
        RepoModel().delete(repo_name_full)
 
        ReposGroupModel().delete(group_name)
 
        self.Session().commit()
 
        Session().commit()
 

	
 
    def test_create_git(self):
 
        self.log_user()
 
@@ -158,7 +158,7 @@ class TestAdminReposController(TestContr
 
                               % (repo_name, repo_name))
 

	
 
        #test if the repo was created in the database
 
        new_repo = self.Session().query(Repository)\
 
        new_repo = Session().query(Repository)\
 
            .filter(Repository.repo_name == repo_name).one()
 

	
 
        self.assertEqual(new_repo.repo_name, repo_name)
 
@@ -194,7 +194,7 @@ class TestAdminReposController(TestContr
 
                               % (urllib.quote(repo_name), repo_name_unicode))
 

	
 
        #test if the repo was created in the database
 
        new_repo = self.Session().query(Repository)\
 
        new_repo = Session().query(Repository)\
 
            .filter(Repository.repo_name == repo_name_unicode).one()
 

	
 
        self.assertEqual(new_repo.repo_name, repo_name_unicode)
 
@@ -232,7 +232,7 @@ class TestAdminReposController(TestContr
 
                               'Created repository <a href="/%s">%s</a>'
 
                               % (repo_name, repo_name))
 
        #test if the repo was created in the database
 
        new_repo = self.Session().query(Repository)\
 
        new_repo = Session().query(Repository)\
 
            .filter(Repository.repo_name == repo_name).one()
 

	
 
        self.assertEqual(new_repo.repo_name, repo_name)
 
@@ -256,7 +256,7 @@ class TestAdminReposController(TestContr
 
        response.follow()
 

	
 
        #check if repo was deleted from db
 
        deleted_repo = self.Session().query(Repository)\
 
        deleted_repo = Session().query(Repository)\
 
            .filter(Repository.repo_name == repo_name).scalar()
 

	
 
        self.assertEqual(deleted_repo, None)
 
@@ -279,7 +279,7 @@ class TestAdminReposController(TestContr
 
                               'Created repository <a href="/%s">%s</a>'
 
                               % (repo_name, repo_name))
 
        #test if the repo was created in the database
 
        new_repo = self.Session().query(Repository)\
 
        new_repo = Session().query(Repository)\
 
            .filter(Repository.repo_name == repo_name).one()
 

	
 
        self.assertEqual(new_repo.repo_name, repo_name)
 
@@ -303,7 +303,7 @@ class TestAdminReposController(TestContr
 
        response.follow()
 

	
 
        #check if repo was deleted from db
 
        deleted_repo = self.Session().query(Repository)\
 
        deleted_repo = Session().query(Repository)\
 
            .filter(Repository.repo_name == repo_name).scalar()
 

	
 
        self.assertEqual(deleted_repo, None)
rhodecode/tests/functional/test_admin_settings.py
Show inline comments
 
@@ -6,6 +6,7 @@ from rhodecode.tests import *
 
from rhodecode.lib import helpers as h
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.model.meta import Session
 

	
 

	
 
class TestAdminSettingsController(TestController):
 
@@ -135,7 +136,7 @@ class TestAdminSettingsController(TestCo
 
        uname = 'testme'
 
        usr = UserModel().create_or_update(username=uname, password='qweqwe',
 
                                           email='testme@rhodecod.org')
 
        self.Session().commit()
 
        Session().commit()
 
        params = usr.get_api_data()
 
        user_id = usr.user_id
 
        self.log_user(username=uname, password='qweqwe')
rhodecode/tests/functional/test_admin_users.py
Show inline comments
 
@@ -39,7 +39,7 @@ class TestAdminUsersController(TestContr
 

	
 
        self.checkSessionFlash(response, '''Created user %s''' % (username))
 

	
 
        new_user = self.Session.query(User).\
 
        new_user = Session().query(User).\
 
            filter(User.username == username).one()
 

	
 
        self.assertEqual(new_user.username, username)
 
@@ -74,7 +74,7 @@ class TestAdminUsersController(TestContr
 
        response.mustcontain("""<span class="error-message">An email address must contain a single @</span>""")
 

	
 
        def get_user():
 
            self.Session.query(User).filter(User.username == username).one()
 
            Session().query(User).filter(User.username == username).one()
 

	
 
        self.assertRaises(NoResultFound, get_user), 'found user in database'
 

	
 
@@ -100,7 +100,7 @@ class TestAdminUsersController(TestContr
 
        uname = 'testme'
 
        usr = UserModel().create_or_update(username=uname, password='qweqwe',
 
                                           email='testme@rhodecod.org')
 
        self.Session().commit()
 
        Session().commit()
 
        params = usr.get_api_data()
 
        params.update({name: expected})
 
        params.update({'password_confirmation': ''})
 
@@ -146,7 +146,7 @@ class TestAdminUsersController(TestContr
 

	
 
        response = response.follow()
 

	
 
        new_user = self.Session.query(User)\
 
        new_user = Session().query(User)\
 
            .filter(User.username == username).one()
 
        response = self.app.delete(url('user', id=new_user.user_id))
 

	
rhodecode/tests/functional/test_admin_users_groups.py
Show inline comments
 
from rhodecode.tests import *
 
from rhodecode.model.db import UserGroup, UserGroupToPerm, Permission
 
from rhodecode.model.meta import Session
 

	
 
TEST_USER_GROUP = 'admins_test'
 

	
 
@@ -48,13 +49,13 @@ class TestAdminUsersGroupsController(Tes
 
        self.checkSessionFlash(response,
 
                               'Created user group %s' % users_group_name)
 

	
 
        gr = self.Session.query(UserGroup)\
 
        gr = Session().query(UserGroup)\
 
                           .filter(UserGroup.users_group_name ==
 
                                   users_group_name).one()
 

	
 
        response = self.app.delete(url('users_group', id=gr.users_group_id))
 

	
 
        gr = self.Session.query(UserGroup)\
 
        gr = Session().query(UserGroup)\
 
                           .filter(UserGroup.users_group_name ==
 
                                   users_group_name).scalar()
 

	
 
@@ -119,7 +120,7 @@ class TestAdminUsersGroupsController(Tes
 
        ugid = ug.users_group_id
 
        response = self.app.delete(url('users_group', id=ug.users_group_id))
 
        response = response.follow()
 
        gr = self.Session.query(UserGroup)\
 
        gr = Session().query(UserGroup)\
 
                           .filter(UserGroup.users_group_name ==
 
                                   users_group_name).scalar()
 

	
 
@@ -192,7 +193,7 @@ class TestAdminUsersGroupsController(Tes
 
        ugid = ug.users_group_id
 
        response = self.app.delete(url('users_group', id=ug.users_group_id))
 
        response = response.follow()
 
        gr = self.Session.query(UserGroup)\
 
        gr = Session().query(UserGroup)\
 
                           .filter(UserGroup.users_group_name ==
 
                                   users_group_name).scalar()
 

	
rhodecode/tests/functional/test_branches.py
Show inline comments
 
from rhodecode.tests import *
 

	
 

	
 
class TestBranchesController(TestController):
 

	
 
    def test_index(self):
 
    def test_index_hg(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='branches',
 
                                    action='index', repo_name=HG_REPO))
 
        response.mustcontain("""<a href="/%s/files/27cd5cce30c96924232dffcd24178a07ffeb5dfc/">default</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/97e8b885c04894463c51898e14387d80c30ed1ee/">git</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/2e6a2bf9356ca56df08807f4ad86d480da72a8f4/">web</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/">default</a>""" % HG_REPO)
 

	
 
        # closed branches
 
        response.mustcontain("""<a href="/%s/changeset/95ca6417ec0de6ac3bd19b336d7b608f27b88711">git [closed]</a><""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/changeset/0dd5fd7b37a4eea4dd9b662af63cee743b4ccce2">web [closed]</a>""" % HG_REPO)
 

	
 
    def test_index_git(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='branches',
 
                                    action='index', repo_name=GIT_REPO))
 
        response.mustcontain("""<a href="/%s/files/5f2c6ee195929b0be80749243c18121c9864a3b3/">master</a>""" % GIT_REPO)
rhodecode/tests/functional/test_changelog.py
Show inline comments
 
@@ -11,23 +11,15 @@ class TestChangelogController(TestContro
 
        response.mustcontain('''id="chg_20" class="container tablerow1"''')
 
        response.mustcontain(
 
            """<input class="changeset_range" """
 
            """id="5e204e7583b9c8e7b93a020bd036564b1e731dae" """
 
            """name="5e204e7583b9c8e7b93a020bd036564b1e731dae" """
 
            """id="7b22a518347bb9bc19679f6af07cd0a61bfe16e7" """
 
            """name="7b22a518347bb9bc19679f6af07cd0a61bfe16e7" """
 
            """type="checkbox" value="1" />"""
 
        )
 

	
 
        #rev 640: code garden
 
        response.mustcontain(
 
            """<span class="changeset_hash">r154:5e204e7583b9</span>"""
 
            """<span class="changeset_hash">r640:0a4e54a44604</span>"""
 
        )
 

	
 
        response.mustcontain("""Small update at simplevcs app""")
 

	
 
#        response.mustcontain(
 
#            """<div id="changed_total_5e204e7583b9c8e7b93a020bd036564b1e731dae" """
 
#            """style="float:right;" class="changed_total tooltip" """
 
#            """title="Affected number of files, click to show """
 
#            """more details">3</div>"""
 
#        )
 
        response.mustcontain("""code garden""")
 

	
 
    def test_index_pagination_hg(self):
 
        self.log_user()
 
@@ -48,29 +40,15 @@ class TestChangelogController(TestContro
 
        # Test response after pagination...
 
        response.mustcontain(
 
            """<input class="changeset_range" """
 
            """id="46ad32a4f974e45472a898c6b0acb600320579b1" """
 
            """name="46ad32a4f974e45472a898c6b0acb600320579b1" """
 
            """id="22baf968d547386b9516965ce89d189665003a31" """
 
            """name="22baf968d547386b9516965ce89d189665003a31" """
 
            """type="checkbox" value="1" />"""
 
        )
 

	
 
        response.mustcontain(
 
            """<span class="changeset_hash">r64:46ad32a4f974</span>"""
 
            """<span class="changeset_hash">r539:22baf968d547</span>"""
 
        )
 

	
 
#        response.mustcontain(
 
#            """<div id="changed_total_46ad32a4f974e45472a898c6b0acb600320579b1" """
 
#            """style="float:right;" class="changed_total tooltip" """
 
#            """title="Affected number of files, click to show """
 
#            """more details">21</div>"""
 
#        )
 
#
 
#        response.mustcontain(
 
#            """<a href="/%s/changeset/"""
 
#            """46ad32a4f974e45472a898c6b0acb600320579b1" """
 
#            """title="Merge with 2e6a2bf9356ca56df08807f4ad86d480da72a8f4">"""
 
#            """46ad32a4f974</a>""" % HG_REPO
 
#        )
 

	
 
    def test_index_git(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='changelog', action='index',
rhodecode/tests/functional/test_changeset_comments.py
Show inline comments
 
from rhodecode.tests import *
 
from rhodecode.model.db import ChangesetComment, Notification, User, \
 
    UserNotification
 
from rhodecode.model.meta import Session
 

	
 

	
 
class TestChangeSetCommentsController(TestController):
 

	
 
    def setUp(self):
 
        for x in ChangesetComment.query().all():
 
            self.Session.delete(x)
 
        self.Session.commit()
 
            Session().delete(x)
 
        Session().commit()
 

	
 
        for x in Notification.query().all():
 
            self.Session.delete(x)
 
        self.Session.commit()
 
            Session().delete(x)
 
        Session().commit()
 

	
 
    def tearDown(self):
 
        for x in ChangesetComment.query().all():
 
            self.Session.delete(x)
 
        self.Session.commit()
 
            Session().delete(x)
 
        Session().commit()
 

	
 
        for x in Notification.query().all():
 
            self.Session.delete(x)
 
        self.Session.commit()
 
            Session().delete(x)
 
        Session().commit()
 

	
 
    def test_create(self):
 
        self.log_user()
rhodecode/tests/functional/test_compare_local.py
Show inline comments
 
@@ -10,16 +10,17 @@ class TestCompareController(TestControll
 

	
 
    def test_compare_tag_hg(self):
 
        self.log_user()
 
        tag1 = '0.1.2'
 
        tag2 = '0.1.3'
 
        tag1 = 'v0.1.2'
 
        tag2 = 'v0.1.3'
 
        response = self.app.get(url(controller='compare', action='index',
 
                                    repo_name=HG_REPO,
 
                                    org_ref_type="tag",
 
                                    org_ref=tag1,
 
                                    other_ref_type="tag",
 
                                    other_ref=tag2,
 
                                    ))
 
                                    ), status=200)
 
        response.mustcontain('%s@%s -&gt; %s@%s' % (HG_REPO, tag1, HG_REPO, tag2))
 

	
 
        ## outgoing changesets between tags
 
        response.mustcontain('''<a href="/%s/changeset/c5ddebc06eaaba3010c2d66ea6ec9d074eb0f678">r112:c5ddebc06eaa</a>''' % HG_REPO)
 
        response.mustcontain('''<a href="/%s/changeset/70d4cef8a37657ee4cf5aabb3bd9f68879769816">r115:70d4cef8a376</a>''' % HG_REPO)
 
@@ -54,7 +55,7 @@ class TestCompareController(TestControll
 
                                    org_ref=tag1,
 
                                    other_ref_type="tag",
 
                                    other_ref=tag2,
 
                                    ))
 
                                    ), status=200)
 
        response.mustcontain('%s@%s -&gt; %s@%s' % (GIT_REPO, tag1, GIT_REPO, tag2))
 

	
 
        ## outgoing changesets between tags
rhodecode/tests/functional/test_files.py
Show inline comments
 
@@ -25,11 +25,19 @@ class TestFilesController(TestController
 
                                    revision='tip',
 
                                    f_path='/'))
 
        # Test response...
 
        response.mustcontain('<a class="browser-dir ypjax-link" href="/vcs_test_hg/files/27cd5cce30c96924232dffcd24178a07ffeb5dfc/docs">docs</a>')
 
        response.mustcontain('<a class="browser-dir ypjax-link" href="/vcs_test_hg/files/27cd5cce30c96924232dffcd24178a07ffeb5dfc/tests">tests</a>')
 
        response.mustcontain('<a class="browser-dir ypjax-link" href="/vcs_test_hg/files/27cd5cce30c96924232dffcd24178a07ffeb5dfc/vcs">vcs</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/27cd5cce30c96924232dffcd24178a07ffeb5dfc/.hgignore">.hgignore</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/27cd5cce30c96924232dffcd24178a07ffeb5dfc/MANIFEST.in">MANIFEST.in</a>')
 
        response.mustcontain('<a class="browser-dir ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/docs">docs</a>')
 
        response.mustcontain('<a class="browser-dir ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/vcs">vcs</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/.gitignore">.gitignore</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/.hgignore">.hgignore</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/.hgtags">.hgtags</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/.travis.yml">.travis.yml</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/MANIFEST.in">MANIFEST.in</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/README.rst">README.rst</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/run_test_and_report.sh">run_test_and_report.sh</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/setup.cfg">setup.cfg</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/setup.py">setup.py</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/test_and_report.sh">test_and_report.sh</a>')
 
        response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/tox.ini">tox.ini</a>')
 

	
 
    def test_index_revision(self):
 
        self.log_user()
 
@@ -79,7 +87,7 @@ class TestFilesController(TestController
 
        self.log_user()
 
        response = self.app.get(url(controller='files', action='index',
 
                                    repo_name=HG_REPO,
 
                                    revision='27cd5cce30c96924232dffcd24178a07ffeb5dfc',
 
                                    revision='8911406ad776fdd3d0b9932a2e89677e57405a48',
 
                                    f_path='vcs/nodes.py'))
 

	
 
        response.mustcontain("""<div class="commit">Partially implemented <a class="issue-tracker-link" href="https://myissueserver.com/vcs_test_hg/issue/16">#16</a>. filecontent/commit message/author/node name are safe_unicode now.
 
@@ -100,7 +108,41 @@ removed extra unicode conversion in diff
 
                                extra_environ={'HTTP_X_PARTIAL_XHR': '1'},)
 
        #test or history
 
        response.mustcontain("""<optgroup label="Changesets">
 
<option selected="selected" value="8911406ad776fdd3d0b9932a2e89677e57405a48">r167:8911406ad776 (default)</option>
 
<option value="dbec37a0d5cab8ff39af4cfc4a4cd3996e4acfc6">r648:dbec37a0d5ca (default)</option>
 
<option value="1d20ed9eda9482d46ff0a6af5812550218b3ff15">r639:1d20ed9eda94 (default)</option>
 
<option value="0173395e822797f098799ed95c1a81b6a547a9ad">r547:0173395e8227 (default)</option>
 
<option value="afbb45ade933a8182f1d8ec5d4d1bb2de2572043">r546:afbb45ade933 (default)</option>
 
<option value="6f093e30cac34e6b4b11275a9f22f80c5d7ad1f7">r502:6f093e30cac3 (default)</option>
 
<option value="c7e2212dd2ae975d1d06534a3d7e317165c06960">r476:c7e2212dd2ae (default)</option>
 
<option value="45477506df79f701bf69419aac3e1f0fed3c5bcf">r472:45477506df79 (default)</option>
 
<option value="5fc76cb25d11e07c60de040f78b8cd265ff10d53">r469:5fc76cb25d11 (default)</option>
 
<option value="b073433cf8994969ee5cd7cce84cbe587bb880b2">r468:b073433cf899 (default)</option>
 
<option value="7a74dbfcacd1dbcb58bb9c860b2f29fbb22c4c96">r467:7a74dbfcacd1 (default)</option>
 
<option value="71ee52cc4d629096bdbee036325975dac2af4501">r465:71ee52cc4d62 (default)</option>
 
<option value="a5b217d26c5f111e72bae4de672b084ee0fbf75c">r452:a5b217d26c5f (default)</option>
 
<option value="47aedd538bf616eedcb0e7d630ea476df0e159c7">r450:47aedd538bf6 (default)</option>
 
<option value="8e4915fa32d727dcbf09746f637a5f82e539511e">r432:8e4915fa32d7 (default)</option>
 
<option value="25213a5fbb048dff8ba65d21e466a835536e5b70">r356:25213a5fbb04 (default)</option>
 
<option value="23debcedddc1c23c14be33e713e7786d4a9de471">r351:23debcedddc1 (default)</option>
 
<option value="61e25b2a90a19e7fffd75dea1e4c7e20df526bbe">r342:61e25b2a90a1 (default)</option>
 
<option value="fb95b340e0d03fa51f33c56c991c08077c99303e">r318:fb95b340e0d0 (webvcs)</option>
 
<option value="bda35e0e564fbbc5cd26fe0a37fb647a254c99fe">r303:bda35e0e564f (default)</option>
 
<option value="97ff74896d7dbf3115a337a421d44b55154acc89">r302:97ff74896d7d (default)</option>
 
<option value="cec3473c3fdb9599c98067182a075b49bde570f9">r293:cec3473c3fdb (default)</option>
 
<option value="0e86c43eef866a013a587666a877c879899599bb">r289:0e86c43eef86 (default)</option>
 
<option value="91a27c312808100cf20a602f78befbbff9d89bfd">r288:91a27c312808 (default)</option>
 
<option value="400e36a1670a57d11e3edcb5b07bf82c30006d0b">r287:400e36a1670a (default)</option>
 
<option value="014fb17dfc95b0995e838c565376bf9a993e230a">r261:014fb17dfc95 (default)</option>
 
<option value="cca7aebbc4d6125798446b11e69dc8847834a982">r260:cca7aebbc4d6 (default)</option>
 
<option value="14cdb2957c011a5feba36f50d960d9832ba0f0c1">r258:14cdb2957c01 (workdir)</option>
 
<option value="34df20118ed74b5987d22a579e8a60e903da5bf8">r245:34df20118ed7 (default)</option>
 
<option value="0375d9042a64a1ac1641528f0f0668f9a339e86d">r233:0375d9042a64 (workdir)</option>
 
<option value="94aa45fc1806c04d4ba640933edf682c22478453">r222:94aa45fc1806 (workdir)</option>
 
<option value="7ed99bc738818879941e3ce20243f8856a7cfc84">r188:7ed99bc73881 (default)</option>
 
<option value="1e85975528bcebe853732a9e5fb8dbf4461f6bb2">r184:1e85975528bc (default)</option>
 
<option value="ed30beddde7bbddb26042625be19bcd11576c1dd">r183:ed30beddde7b (default)</option>
 
<option value="a6664e18181c6fc81b751a8d01474e7e1a3fe7fc">r177:a6664e18181c (default)</option>
 
<option value="8911406ad776fdd3d0b9932a2e89677e57405a48">r167:8911406ad776 (default)</option>
 
<option value="aa957ed78c35a1541f508d2ec90e501b0a9e3167">r165:aa957ed78c35 (default)</option>
 
<option value="48e11b73e94c0db33e736eaeea692f990cb0b5f1">r140:48e11b73e94c (default)</option>
 
<option value="adf3cbf483298563b968a6c673cd5bde5f7d5eea">r126:adf3cbf48329 (default)</option>
 
@@ -135,16 +177,23 @@ removed extra unicode conversion in diff
 
<option value="3803844fdbd3b711175fc3da9bdacfcd6d29a6fb">r7:3803844fdbd3 (default)</option>
 
</optgroup>
 
<optgroup label="Branches">
 
<option value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">default</option>
 
<option value="97e8b885c04894463c51898e14387d80c30ed1ee">git</option>
 
<option value="2e6a2bf9356ca56df08807f4ad86d480da72a8f4">web</option>
 
<option value="96507bd11ecc815ebc6270fdf6db110928c09c1e">default</option>
 
<option value="4f7e2131323e0749a740c0a56ab68ae9269c562a">stable</option>
 
</optgroup>
 
<optgroup label="Tags">
 
<option value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">tip</option>
 
<option value="fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200">0.1.4</option>
 
<option value="17544fbfcd33ffb439e2b728b5d526b1ef30bfcf">0.1.3</option>
 
<option value="a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720">0.1.2</option>
 
<option value="eb3a60fc964309c1a318b8dfe26aa2d1586c85ae">0.1.1</option>
 
<option value="2c96c02def9a7c997f33047761a53943e6254396">v0.2.0</option>
 
<option value="8680b1d1cee3aa3c1ab3734b76ee164bbedbc5c9">v0.1.9</option>
 
<option value="ecb25ba9c96faf1e65a0bc3fd914918420a2f116">v0.1.8</option>
 
<option value="f67633a2894edaf28513706d558205fa93df9209">v0.1.7</option>
 
<option value="02b38c0eb6f982174750c0e309ff9faddc0c7e12">v0.1.6</option>
 
<option value="a6664e18181c6fc81b751a8d01474e7e1a3fe7fc">v0.1.5</option>
 
<option value="fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200">v0.1.4</option>
 
<option value="17544fbfcd33ffb439e2b728b5d526b1ef30bfcf">v0.1.3</option>
 
<option value="a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720">v0.1.2</option>
 
<option value="fef5bfe1dc17611d5fb59a7f6f95c55c3606f933">v0.1.11</option>
 
<option value="92831aebf2f8dd4879e897024b89d09af214df1c">v0.1.10</option>
 
<option value="eb3a60fc964309c1a318b8dfe26aa2d1586c85ae">v0.1.1</option>
 
<option value="96507bd11ecc815ebc6270fdf6db110928c09c1e">tip</option>
 
</optgroup>
 
""")
 

	
 
@@ -167,8 +216,42 @@ removed extra unicode conversion in diff
 
                                    annotate=True),
 
                                extra_environ={'HTTP_X_PARTIAL_XHR': '1'})
 

	
 
        response.mustcontain("""<optgroup label="Changesets">
 
<option selected="selected" value="8911406ad776fdd3d0b9932a2e89677e57405a48">r167:8911406ad776 (default)</option>
 
        response.mustcontain("""
 
<option value="dbec37a0d5cab8ff39af4cfc4a4cd3996e4acfc6">r648:dbec37a0d5ca (default)</option>
 
<option value="1d20ed9eda9482d46ff0a6af5812550218b3ff15">r639:1d20ed9eda94 (default)</option>
 
<option value="0173395e822797f098799ed95c1a81b6a547a9ad">r547:0173395e8227 (default)</option>
 
<option value="afbb45ade933a8182f1d8ec5d4d1bb2de2572043">r546:afbb45ade933 (default)</option>
 
<option value="6f093e30cac34e6b4b11275a9f22f80c5d7ad1f7">r502:6f093e30cac3 (default)</option>
 
<option value="c7e2212dd2ae975d1d06534a3d7e317165c06960">r476:c7e2212dd2ae (default)</option>
 
<option value="45477506df79f701bf69419aac3e1f0fed3c5bcf">r472:45477506df79 (default)</option>
 
<option value="5fc76cb25d11e07c60de040f78b8cd265ff10d53">r469:5fc76cb25d11 (default)</option>
 
<option value="b073433cf8994969ee5cd7cce84cbe587bb880b2">r468:b073433cf899 (default)</option>
 
<option value="7a74dbfcacd1dbcb58bb9c860b2f29fbb22c4c96">r467:7a74dbfcacd1 (default)</option>
 
<option value="71ee52cc4d629096bdbee036325975dac2af4501">r465:71ee52cc4d62 (default)</option>
 
<option value="a5b217d26c5f111e72bae4de672b084ee0fbf75c">r452:a5b217d26c5f (default)</option>
 
<option value="47aedd538bf616eedcb0e7d630ea476df0e159c7">r450:47aedd538bf6 (default)</option>
 
<option value="8e4915fa32d727dcbf09746f637a5f82e539511e">r432:8e4915fa32d7 (default)</option>
 
<option value="25213a5fbb048dff8ba65d21e466a835536e5b70">r356:25213a5fbb04 (default)</option>
 
<option value="23debcedddc1c23c14be33e713e7786d4a9de471">r351:23debcedddc1 (default)</option>
 
<option value="61e25b2a90a19e7fffd75dea1e4c7e20df526bbe">r342:61e25b2a90a1 (default)</option>
 
<option value="fb95b340e0d03fa51f33c56c991c08077c99303e">r318:fb95b340e0d0 (webvcs)</option>
 
<option value="bda35e0e564fbbc5cd26fe0a37fb647a254c99fe">r303:bda35e0e564f (default)</option>
 
<option value="97ff74896d7dbf3115a337a421d44b55154acc89">r302:97ff74896d7d (default)</option>
 
<option value="cec3473c3fdb9599c98067182a075b49bde570f9">r293:cec3473c3fdb (default)</option>
 
<option value="0e86c43eef866a013a587666a877c879899599bb">r289:0e86c43eef86 (default)</option>
 
<option value="91a27c312808100cf20a602f78befbbff9d89bfd">r288:91a27c312808 (default)</option>
 
<option value="400e36a1670a57d11e3edcb5b07bf82c30006d0b">r287:400e36a1670a (default)</option>
 
<option value="014fb17dfc95b0995e838c565376bf9a993e230a">r261:014fb17dfc95 (default)</option>
 
<option value="cca7aebbc4d6125798446b11e69dc8847834a982">r260:cca7aebbc4d6 (default)</option>
 
<option value="14cdb2957c011a5feba36f50d960d9832ba0f0c1">r258:14cdb2957c01 (workdir)</option>
 
<option value="34df20118ed74b5987d22a579e8a60e903da5bf8">r245:34df20118ed7 (default)</option>
 
<option value="0375d9042a64a1ac1641528f0f0668f9a339e86d">r233:0375d9042a64 (workdir)</option>
 
<option value="94aa45fc1806c04d4ba640933edf682c22478453">r222:94aa45fc1806 (workdir)</option>
 
<option value="7ed99bc738818879941e3ce20243f8856a7cfc84">r188:7ed99bc73881 (default)</option>
 
<option value="1e85975528bcebe853732a9e5fb8dbf4461f6bb2">r184:1e85975528bc (default)</option>
 
<option value="ed30beddde7bbddb26042625be19bcd11576c1dd">r183:ed30beddde7b (default)</option>
 
<option value="a6664e18181c6fc81b751a8d01474e7e1a3fe7fc">r177:a6664e18181c (default)</option>
 
<option value="8911406ad776fdd3d0b9932a2e89677e57405a48">r167:8911406ad776 (default)</option>
 
<option value="aa957ed78c35a1541f508d2ec90e501b0a9e3167">r165:aa957ed78c35 (default)</option>
 
<option value="48e11b73e94c0db33e736eaeea692f990cb0b5f1">r140:48e11b73e94c (default)</option>
 
<option value="adf3cbf483298563b968a6c673cd5bde5f7d5eea">r126:adf3cbf48329 (default)</option>
 
@@ -203,16 +286,23 @@ removed extra unicode conversion in diff
 
<option value="3803844fdbd3b711175fc3da9bdacfcd6d29a6fb">r7:3803844fdbd3 (default)</option>
 
</optgroup>
 
<optgroup label="Branches">
 
<option value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">default</option>
 
<option value="97e8b885c04894463c51898e14387d80c30ed1ee">git</option>
 
<option value="2e6a2bf9356ca56df08807f4ad86d480da72a8f4">web</option>
 
<option value="96507bd11ecc815ebc6270fdf6db110928c09c1e">default</option>
 
<option value="4f7e2131323e0749a740c0a56ab68ae9269c562a">stable</option>
 
</optgroup>
 
<optgroup label="Tags">
 
<option value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">tip</option>
 
<option value="fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200">0.1.4</option>
 
<option value="17544fbfcd33ffb439e2b728b5d526b1ef30bfcf">0.1.3</option>
 
<option value="a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720">0.1.2</option>
 
<option value="eb3a60fc964309c1a318b8dfe26aa2d1586c85ae">0.1.1</option>
 
<option value="2c96c02def9a7c997f33047761a53943e6254396">v0.2.0</option>
 
<option value="8680b1d1cee3aa3c1ab3734b76ee164bbedbc5c9">v0.1.9</option>
 
<option value="ecb25ba9c96faf1e65a0bc3fd914918420a2f116">v0.1.8</option>
 
<option value="f67633a2894edaf28513706d558205fa93df9209">v0.1.7</option>
 
<option value="02b38c0eb6f982174750c0e309ff9faddc0c7e12">v0.1.6</option>
 
<option value="a6664e18181c6fc81b751a8d01474e7e1a3fe7fc">v0.1.5</option>
 
<option value="fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200">v0.1.4</option>
 
<option value="17544fbfcd33ffb439e2b728b5d526b1ef30bfcf">v0.1.3</option>
 
<option value="a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720">v0.1.2</option>
 
<option value="fef5bfe1dc17611d5fb59a7f6f95c55c3606f933">v0.1.11</option>
 
<option value="92831aebf2f8dd4879e897024b89d09af214df1c">v0.1.10</option>
 
<option value="eb3a60fc964309c1a318b8dfe26aa2d1586c85ae">v0.1.1</option>
 
<option value="96507bd11ecc815ebc6270fdf6db110928c09c1e">tip</option>
 
</optgroup>""")
 

	
 
    def test_file_annotation_git(self):
rhodecode/tests/functional/test_home.py
Show inline comments
 
@@ -29,11 +29,11 @@ class TestHomeController(TestController)
 
                        r"""alt=\"Public repository\" src=\"/images/icons/lock_"""
 
                        r"""open.png\"/>""")
 

	
 
        response.mustcontain(
 
r"""<a title=\"Marcin Kuzminski &amp;lt;marcin@python-works.com&amp;gt;:\n\n"""
 
r"""merge\" class=\"tooltip\" href=\"/vcs_test_hg/changeset/27cd5cce30c96924232"""
 
r"""dffcd24178a07ffeb5dfc\">r173:27cd5cce30c9</a>"""
 
)
 
        response.mustcontain("""fixes issue with having custom format for git-log""")
 
        response.mustcontain("""/%s/changeset/5f2c6ee195929b0be80749243c18121c9864a3b3""" % GIT_REPO)
 

	
 
        response.mustcontain("""disable security checks on hg clone for travis""")
 
        response.mustcontain("""/%s/changeset/96507bd11ecc815ebc6270fdf6db110928c09c1e""" % HG_REPO)
 

	
 
    def test_repo_summary_with_anonymous_access_disabled(self):
 
        anon = User.get_default_user()
rhodecode/tests/functional/test_journal.py
Show inline comments
 
@@ -14,10 +14,10 @@ class TestJournalController(TestControll
 

	
 
    def test_stop_following_repository(self):
 
        session = self.log_user()
 
#        usr = self.Session.query(User).filter(User.username == 'test_admin').one()
 
#        repo = self.Session.query(Repository).filter(Repository.repo_name == HG_REPO).one()
 
#        usr = Session().query(User).filter(User.username == 'test_admin').one()
 
#        repo = Session().query(Repository).filter(Repository.repo_name == HG_REPO).one()
 
#
 
#        followings = self.Session.query(UserFollowing)\
 
#        followings = Session().query(UserFollowing)\
 
#            .filter(UserFollowing.user == usr)\
 
#            .filter(UserFollowing.follows_repository == repo).all()
 
#
rhodecode/tests/functional/test_login.py
Show inline comments
 
@@ -5,15 +5,16 @@ from rhodecode.lib.utils2 import generat
 
from rhodecode.lib.auth import check_password
 
from rhodecode.lib import helpers as h
 
from rhodecode.model import validators
 
from rhodecode.model.meta import Session
 

	
 

	
 
class TestLoginController(TestController):
 

	
 
    def tearDown(self):
 
        for n in Notification.query().all():
 
            self.Session().delete(n)
 
            Session().delete(n)
 

	
 
        self.Session().commit()
 
        Session().commit()
 
        self.assertEqual(Notification.query().all(), [])
 

	
 
    def test_index(self):
 
@@ -216,7 +217,7 @@ class TestLoginController(TestController
 
        self.assertEqual(response.status, '302 Found')
 
        self.checkSessionFlash(response, 'You have successfully registered into RhodeCode')
 

	
 
        ret = self.Session().query(User).filter(User.username == 'test_regular4').one()
 
        ret = Session().query(User).filter(User.username == 'test_regular4').one()
 
        self.assertEqual(ret.username, username)
 
        self.assertEqual(check_password(password, ret.password), True)
 
        self.assertEqual(ret.email, email)
 
@@ -254,8 +255,8 @@ class TestLoginController(TestController
 
        new.name = name
 
        new.lastname = lastname
 
        new.api_key = generate_api_key(username)
 
        self.Session().add(new)
 
        self.Session().commit()
 
        Session().add(new)
 
        Session().commit()
 

	
 
        response = self.app.post(url(controller='login',
 
                                     action='password_reset'),
rhodecode/tests/functional/test_search.py
Show inline comments
 
@@ -25,14 +25,14 @@ class TestSearchController(TestControlle
 
        self.log_user()
 
        response = self.app.get(url(controller='search', action='index'),
 
                                {'q': 'def repo'})
 
        response.mustcontain('39 results')
 
        response.mustcontain('58 results')
 

	
 
    def test_repo_search(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='search', action='index'),
 
                                {'q': 'repository:%s def test' % HG_REPO})
 

	
 
        response.mustcontain('4 results')
 
        response.mustcontain('18 results')
 

	
 
    def test_search_last(self):
 
        self.log_user()
 
@@ -67,7 +67,7 @@ class TestSearchController(TestControlle
 
                                {'q': 'changed:tests/utils.py',
 
                                 'type': 'commit'})
 

	
 
        response.mustcontain('20 results')
 
        response.mustcontain('29 results')
 

	
 
    def test_search_commit_changed_files_get_commit(self):
 
        self.log_user()
 
@@ -75,7 +75,7 @@ class TestSearchController(TestControlle
 
                                {'q': 'changed:vcs/utils/lazy.py',
 
                                 'type': 'commit'})
 

	
 
        response.mustcontain('7 results')
 
        response.mustcontain('11 results')
 
        response.mustcontain('36e0fc9d2808c5022a24f49d6658330383ed8666')
 
        response.mustcontain('af182745859d779f17336241a0815d15166ae1ee')
 
        response.mustcontain('17438a11f72b93f56d0e08e7d1fa79a378578a82')
rhodecode/tests/functional/test_summary.py
Show inline comments
 
@@ -36,13 +36,16 @@ class TestSummaryController(TestControll
 
        response = self.app.get(url(controller='summary', action='index',
 
                                    repo_name=HG_REPO))
 
        response.mustcontain(
 
            """var data = [["py", {"count": 42, "desc": ["Python"]}], """
 
            """["rst", {"count": 11, "desc": ["Rst"]}], """
 
            """var data = [["py", {"count": 68, "desc": ["Python"]}], """
 
            """["rst", {"count": 16, "desc": ["Rst"]}], """
 
            """["css", {"count": 2, "desc": ["Css"]}], """
 
            """["sh", {"count": 2, "desc": ["Bash"]}], """
 
            """["makefile", {"count": 1, "desc": ["Makefile", "Makefile"]}],"""
 
            """ ["cfg", {"count": 1, "desc": ["Ini"]}], """
 
            """["css", {"count": 1, "desc": ["Css"]}], """
 
            """["bat", {"count": 1, "desc": ["Batch"]}]];"""
 
            """["yml", {"count": 1, "desc": ["Yaml"]}], """
 
            """["makefile", {"count": 1, "desc": ["Makefile", "Makefile"]}], """
 
            """["js", {"count": 1, "desc": ["Javascript"]}], """
 
            """["cfg", {"count": 1, "desc": ["Ini"]}], """
 
            """["ini", {"count": 1, "desc": ["Ini"]}], """
 
            """["html", {"count": 1, "desc": ["EvoqueHtml", "Html"]}]];"""
 
        )
 

	
 
        # clone url...
 
@@ -118,5 +121,5 @@ class TestSummaryController(TestControll
 
    def _enable_stats(self):
 
        r = Repository.get_by_repo_name(HG_REPO)
 
        r.enable_statistics = True
 
        self.Session.add(r)
 
        self.Session.commit()
 
        Session().add(r)
 
        Session().commit()
rhodecode/tests/functional/test_tags.py
Show inline comments
 
from rhodecode.tests import *
 

	
 

	
 
class TestTagsController(TestController):
 

	
 
    def test_index(self):
 
    def test_index_hg(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='tags', action='index', repo_name=HG_REPO))
 
        response.mustcontain("""<a href="/%s/files/27cd5cce30c96924232dffcd24178a07ffeb5dfc/">tip</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200/">0.1.4</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/17544fbfcd33ffb439e2b728b5d526b1ef30bfcf/">0.1.3</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720/">0.1.2</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/eb3a60fc964309c1a318b8dfe26aa2d1586c85ae/">0.1.1</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/96507bd11ecc815ebc6270fdf6db110928c09c1e/">tip</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/2c96c02def9a7c997f33047761a53943e6254396/">v0.2.0</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/fef5bfe1dc17611d5fb59a7f6f95c55c3606f933/">v0.1.11</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/92831aebf2f8dd4879e897024b89d09af214df1c/">v0.1.10</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/8680b1d1cee3aa3c1ab3734b76ee164bbedbc5c9/">v0.1.9</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/ecb25ba9c96faf1e65a0bc3fd914918420a2f116/">v0.1.8</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/f67633a2894edaf28513706d558205fa93df9209/">v0.1.7</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/02b38c0eb6f982174750c0e309ff9faddc0c7e12/">v0.1.6</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/a6664e18181c6fc81b751a8d01474e7e1a3fe7fc/">v0.1.5</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200/">v0.1.4</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/17544fbfcd33ffb439e2b728b5d526b1ef30bfcf/">v0.1.3</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720/">v0.1.2</a>""" % HG_REPO)
 
        response.mustcontain("""<a href="/%s/files/eb3a60fc964309c1a318b8dfe26aa2d1586c85ae/">v0.1.1</a>""" % HG_REPO)
 

	
 
    def test_index_git(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='tags', action='index', repo_name=GIT_REPO))
 

	
 
        response.mustcontain("""<a href="/%s/files/137fea89f304a42321d40488091ee2ed419a3686/">v0.2.2</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/5051d0fa344d4408a2659d9a0348eb2d41868ecf/">v0.2.1</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/599ba911aa24d2981225f3966eb659dfae9e9f30/">v0.2.0</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/c60f01b77c42dce653d6b1d3b04689862c261929/">v0.1.11</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/10cddef6b794696066fb346434014f0a56810218/">v0.1.10</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/341d28f0eec5ddf0b6b77871e13c2bbd6bec685c/">v0.1.9</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/74ebce002c088b8a5ecf40073db09375515ecd68/">v0.1.8</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/4d78bf73b5c22c82b68f902f138f7881b4fffa2c/">v0.1.7</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/0205cb3f44223fb3099d12a77a69c81b798772d9/">v0.1.6</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/6c0ce52b229aa978889e91b38777f800e85f330b/">v0.1.5</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/7d735150934cd7645ac3051903add952390324a5/">v0.1.4</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/5a3a8fb005554692b16e21dee62bf02667d8dc3e/">v0.1.3</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/0ba5f8a4660034ff25c0cac2a5baabf5d2791d63/">v0.1.2</a>""" % GIT_REPO)
 
        response.mustcontain("""<a href="/%s/files/e6ea6d16e2f26250124a1f4b4fe37a912f9d86a0/">v0.1.1</a>""" % GIT_REPO)
rhodecode/tests/vcs/__init__.py
Show inline comments
 
@@ -19,10 +19,10 @@ function at ``tests/__init__.py``.
 
.. _unittest: http://pypi.python.org/pypi/unittest
 

	
 
"""
 
import os
 
from rhodecode.lib import vcs
 
from rhodecode.lib.vcs.utils.compat import unittest
 
from utils import VCSTestError, SCMFetcher
 
from rhodecode.tests.vcs.conf import *
 
from rhodecode.tests.vcs.utils import VCSTestError, SCMFetcher
 

	
 
from rhodecode.tests import *
 

	
 

	
 
@@ -36,7 +36,7 @@ def setup_package():
 
            'alias': 'hg',
 
            'test_repo_path': TEST_HG_REPO,
 
            'remote_repo': HG_REMOTE_REPO,
 
            'clone_cmd': 'hg clone',
 
            'clone_cmd': 'hg clone --insecure',
 
        },
 
        'git': {
 
            'alias': 'git',
 
@@ -52,5 +52,16 @@ def setup_package():
 
    except VCSTestError, err:
 
        raise RuntimeError(str(err))
 

	
 
#start_dir = os.path.abspath(os.path.dirname(__file__))
 
#unittest.defaultTestLoader.discover(start_dir)
 

	
 
def collector():
 
    setup_package()
 
    start_dir = os.path.abspath(os.path.dirname(__file__))
 
    return unittest.defaultTestLoader.discover(start_dir)
 

	
 

	
 
def main():
 
    collector()
 
    unittest.main()
 

	
 
#if __name__ == '__main__':
 
#    main()
rhodecode/tests/vcs/base.py
Show inline comments
 
@@ -3,14 +3,13 @@ Module providing backend independent mix
 
InMemoryChangeset class is working properly at backend class.
 
"""
 
import os
 
from rhodecode.lib import vcs
 
import time
 
import shutil
 
import datetime
 
from rhodecode.lib.vcs.utils.compat import unittest
 
from rhodecode.tests.vcs.conf import SCM_TESTS, get_new_dir
 

	
 
from conf import SCM_TESTS, get_new_dir
 

	
 
from rhodecode.lib import vcs
 
from rhodecode.lib.vcs.utils.compat import unittest
 
from rhodecode.lib.vcs.nodes import FileNode
 

	
 

	
 
@@ -68,6 +67,7 @@ class BackendTestMixin(object):
 
        cls.repo_path = get_new_dir(str(time.time()))
 
        cls.repo = Backend(cls.repo_path, create=True)
 
        cls.imc = cls.repo.in_memory_changeset
 
        cls.default_branch = cls.repo.DEFAULT_BRANCH_NAME
 

	
 
        for commit in cls._get_commits():
 
            for node in commit.get('added', []):
rhodecode/tests/vcs/conf.py
Show inline comments
 
"""
 
Unit tests configuration module for vcs.
 
"""
 

	
 
import os
 
import time
 
import hashlib
 
import tempfile
 
import datetime
 
import shutil
 
from rhodecode.tests import *
 
from utils import get_normalized_path
 
from os.path import join as jn
 

	
 
TEST_TMP_PATH = TESTS_TMP_PATH
 
#__all__ = (
 
#    'TEST_HG_REPO', 'TEST_GIT_REPO', 'HG_REMOTE_REPO', 'GIT_REMOTE_REPO',
 
#    'SCM_TESTS',
 
#)
 
#
 
#SCM_TESTS = ['hg', 'git']
 
#uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple())))
 
#
 
__all__ = (
 
    'TEST_HG_REPO', 'TEST_GIT_REPO', 'HG_REMOTE_REPO', 'GIT_REMOTE_REPO',
 
    'SCM_TESTS',
 
)
 

	
 
SCM_TESTS = ['hg', 'git']
 
uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple())))
 

	
 
THIS = os.path.abspath(os.path.dirname(__file__))
 
#
 
#GIT_REMOTE_REPO = 'git://github.com/codeinn/vcs.git'
 
#
 
#TEST_TMP_PATH = os.environ.get('VCS_TEST_ROOT', '/tmp')
 
#TEST_GIT_REPO = os.environ.get('VCS_TEST_GIT_REPO',
 
#                              jn(TEST_TMP_PATH, 'vcs-git'))
 
#TEST_GIT_REPO_CLONE = os.environ.get('VCS_TEST_GIT_REPO_CLONE',
 
#                            jn(TEST_TMP_PATH, 'vcsgitclone%s' % uniq_suffix))
 
#TEST_GIT_REPO_PULL = os.environ.get('VCS_TEST_GIT_REPO_PULL',
 
#                            jn(TEST_TMP_PATH, 'vcsgitpull%s' % uniq_suffix))
 
#
 
#HG_REMOTE_REPO = 'http://bitbucket.org/marcinkuzminski/vcs'
 
#TEST_HG_REPO = os.environ.get('VCS_TEST_HG_REPO',
 
#                              jn(TEST_TMP_PATH, 'vcs-hg'))
 
#TEST_HG_REPO_CLONE = os.environ.get('VCS_TEST_HG_REPO_CLONE',
 
#                              jn(TEST_TMP_PATH, 'vcshgclone%s' % uniq_suffix))
 
#TEST_HG_REPO_PULL = os.environ.get('VCS_TEST_HG_REPO_PULL',
 
#                              jn(TEST_TMP_PATH, 'vcshgpull%s' % uniq_suffix))
 
#
 
#TEST_DIR = os.environ.get('VCS_TEST_ROOT', tempfile.gettempdir())
 
#TEST_REPO_PREFIX = 'vcs-test'
 
#
 
#
 
#def get_new_dir(title):
 
#    """
 
#    Returns always new directory path.
 
#    """
 
#    name = TEST_REPO_PREFIX
 
#    if title:
 
#        name = '-'.join((name, title))
 
#    hex = hashlib.sha1(str(time.time())).hexdigest()
 
#    name = '-'.join((name, hex))
 
#    path = os.path.join(TEST_DIR, name)
 
#    return get_normalized_path(path)
 

	
 
GIT_REMOTE_REPO = 'git://github.com/codeinn/vcs.git'
 

	
 
TEST_TMP_PATH = os.environ.get('VCS_TEST_ROOT', '/tmp')
 
TEST_GIT_REPO = os.environ.get('VCS_TEST_GIT_REPO',
 
                              jn(TEST_TMP_PATH, 'vcs-git'))
 
TEST_GIT_REPO_CLONE = os.environ.get('VCS_TEST_GIT_REPO_CLONE',
 
                            jn(TEST_TMP_PATH, 'vcsgitclone%s' % uniq_suffix))
 
TEST_GIT_REPO_PULL = os.environ.get('VCS_TEST_GIT_REPO_PULL',
 
                            jn(TEST_TMP_PATH, 'vcsgitpull%s' % uniq_suffix))
 

	
 
HG_REMOTE_REPO = 'http://bitbucket.org/marcinkuzminski/vcs'
 
TEST_HG_REPO = os.environ.get('VCS_TEST_HG_REPO',
 
                              jn(TEST_TMP_PATH, 'vcs-hg'))
 
TEST_HG_REPO_CLONE = os.environ.get('VCS_TEST_HG_REPO_CLONE',
 
                              jn(TEST_TMP_PATH, 'vcshgclone%s' % uniq_suffix))
 
TEST_HG_REPO_PULL = os.environ.get('VCS_TEST_HG_REPO_PULL',
 
                              jn(TEST_TMP_PATH, 'vcshgpull%s' % uniq_suffix))
 

	
 
TEST_DIR = os.environ.get('VCS_TEST_ROOT', tempfile.gettempdir())
 
TEST_REPO_PREFIX = 'vcs-test'
 

	
 

	
 
def get_new_dir(title):
 
    """
 
    Returns always new directory path.
 
    """
 
    name = TEST_REPO_PREFIX
 
    if title:
 
        name = '-'.join((name, title))
 
    hex = hashlib.sha1(str(time.time())).hexdigest()
 
    name = '-'.join((name, hex))
 
    path = os.path.join(TEST_DIR, name)
 
    return get_normalized_path(path)
 

	
 

	
 
PACKAGE_DIR = os.path.abspath(os.path.join(
 
    os.path.dirname(__file__), '..'))
 
_dest = jn(TESTS_TMP_PATH,'aconfig')
 
_dest = jn(TEST_TMP_PATH, 'aconfig')
 
shutil.copy(jn(THIS, 'aconfig'), _dest)
 
TEST_USER_CONFIG_FILE = _dest
 

	
 
#overide default configurations with rhodecode ones
 
from rhodecode.tests import *
rhodecode/tests/vcs/test_archives.py
Show inline comments
 
@@ -6,8 +6,8 @@ import zipfile
 
import datetime
 
import tempfile
 
import StringIO
 
from base import BackendTestMixin
 
from conf import SCM_TESTS
 
from rhodecode.tests.vcs.base import BackendTestMixin
 
from rhodecode.tests.vcs.conf import SCM_TESTS
 
from rhodecode.lib.vcs.exceptions import VCSError
 
from rhodecode.lib.vcs.nodes import FileNode
 
from rhodecode.lib.vcs.utils.compat import unittest
rhodecode/tests/vcs/test_branches.py
Show inline comments
 
from __future__ import with_statement
 

	
 
import datetime
 
from rhodecode.lib import vcs
 
import datetime
 
from rhodecode.lib.vcs.utils.compat import unittest
 
from rhodecode.lib.vcs.nodes import FileNode
 

	
 
from base import BackendTestMixin
 
from conf import SCM_TESTS
 

	
 
from rhodecode.lib.vcs.nodes import FileNode
 
from rhodecode.tests.vcs.base import BackendTestMixin
 
from rhodecode.tests.vcs.conf import SCM_TESTS
 

	
 

	
 
class BranchesTestCaseMixin(BackendTestMixin):
rhodecode/tests/vcs/test_changesets.py
Show inline comments
 
from __future__ import with_statement
 

	
 
import datetime
 
from rhodecode.lib import vcs
 
import datetime
 
from base import BackendTestMixin
 
from conf import SCM_TESTS
 
from rhodecode.tests.vcs.base import BackendTestMixin
 
from rhodecode.tests.vcs.conf import SCM_TESTS
 

	
 
from rhodecode.lib.vcs.backends.base import BaseChangeset
 
from rhodecode.lib.vcs.nodes import FileNode, AddedFileNodesGenerator,\
 
from rhodecode.lib.vcs.nodes import (
 
    FileNode, AddedFileNodesGenerator,
 
    ChangedFileNodesGenerator, RemovedFileNodesGenerator
 
from rhodecode.lib.vcs.exceptions import BranchDoesNotExistError
 
from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
 
from rhodecode.lib.vcs.exceptions import RepositoryError
 
)
 
from rhodecode.lib.vcs.exceptions import (
 
    BranchDoesNotExistError, ChangesetDoesNotExistError,
 
    RepositoryError
 
)
 
from rhodecode.lib.vcs.utils.compat import unittest
 

	
 

	
rhodecode/tests/vcs/test_filenodes_unicode_path.py
Show inline comments
 
@@ -5,8 +5,8 @@ from __future__ import with_statement
 
import datetime
 
from rhodecode.lib.vcs.nodes import FileNode
 
from rhodecode.lib.vcs.utils.compat import unittest
 
from test_inmemchangesets import BackendBaseTestCase
 
from conf import SCM_TESTS
 
from rhodecode.tests.vcs.test_inmemchangesets import BackendBaseTestCase
 
from rhodecode.tests.vcs.conf import SCM_TESTS
 

	
 

	
 
class FileNodeUnicodePathTestsMixin(object):
rhodecode/tests/vcs/test_getitem.py
Show inline comments
 
from __future__ import with_statement
 

	
 
import datetime
 
from base import BackendTestMixin
 
from conf import SCM_TESTS
 
from rhodecode.tests.vcs.base import BackendTestMixin
 
from rhodecode.tests.vcs.conf import SCM_TESTS
 
from rhodecode.lib.vcs.nodes import FileNode
 
from rhodecode.lib.vcs.utils.compat import unittest
 

	
rhodecode/tests/vcs/test_getslice.py
Show inline comments
 
from __future__ import with_statement
 

	
 
import datetime
 
from base import BackendTestMixin
 
from conf import SCM_TESTS
 
from rhodecode.tests.vcs.base import BackendTestMixin
 
from rhodecode.tests.vcs.conf import SCM_TESTS
 
from rhodecode.lib.vcs.nodes import FileNode
 
from rhodecode.lib.vcs.utils.compat import unittest
 

	
rhodecode/tests/vcs/test_git.py
Show inline comments
 
@@ -8,7 +8,7 @@ from rhodecode.lib.vcs.exceptions import
 
from rhodecode.lib.vcs.nodes import NodeKind, FileNode, DirNode, NodeState
 
from rhodecode.lib.vcs.utils.compat import unittest
 
from rhodecode.tests.vcs.base import BackendTestMixin
 
from conf import TEST_GIT_REPO, TEST_GIT_REPO_CLONE, get_new_dir
 
from rhodecode.tests.vcs.conf import TEST_GIT_REPO, TEST_GIT_REPO_CLONE, get_new_dir
 

	
 

	
 
class GitRepositoryTest(unittest.TestCase):
rhodecode/tests/vcs/test_hg.py
Show inline comments
 
@@ -4,7 +4,7 @@ import os
 
from rhodecode.lib.vcs.backends.hg import MercurialRepository, MercurialChangeset
 
from rhodecode.lib.vcs.exceptions import RepositoryError, VCSError, NodeDoesNotExistError
 
from rhodecode.lib.vcs.nodes import NodeKind, NodeState
 
from conf import PACKAGE_DIR, TEST_HG_REPO, TEST_HG_REPO_CLONE, \
 
from rhodecode.tests.vcs.conf import PACKAGE_DIR, TEST_HG_REPO, TEST_HG_REPO_CLONE, \
 
    TEST_HG_REPO_PULL
 
from rhodecode.lib.vcs.utils.compat import unittest
 

	
 
@@ -156,9 +156,10 @@ class MercurialRepositoryTest(unittest.T
 

	
 
        #active branches
 
        self.assertTrue('default' in self.repo.branches)
 
        self.assertTrue('git' in self.repo.branches)
 
        self.assertTrue('stable' in self.repo.branches)
 

	
 
        # closed
 
        self.assertTrue('git' in self.repo._get_branches(closed=True))
 
        self.assertTrue('web' in self.repo._get_branches(closed=True))
 

	
 
        for name, id in self.repo.branches.items():
rhodecode/tests/vcs/test_inmemchangesets.py
Show inline comments
 
@@ -3,10 +3,11 @@ Tests so called "in memory changesets" c
 
"""
 
from __future__ import with_statement
 

	
 
from rhodecode.lib import vcs
 
import time
 
import datetime
 
from conf import SCM_TESTS, get_new_dir
 

	
 
from rhodecode.lib import vcs
 
from rhodecode.tests.vcs.conf import SCM_TESTS, get_new_dir
 
from rhodecode.lib.vcs.exceptions import EmptyRepositoryError
 
from rhodecode.lib.vcs.exceptions import NodeAlreadyAddedError
 
from rhodecode.lib.vcs.exceptions import NodeAlreadyExistsError
rhodecode/tests/vcs/test_repository.py
Show inline comments
 
from __future__ import with_statement
 
import datetime
 
from base import BackendTestMixin
 
from conf import SCM_TESTS
 
from conf import TEST_USER_CONFIG_FILE
 
from rhodecode.tests.vcs.base import BackendTestMixin
 
from rhodecode.tests.vcs.conf import SCM_TESTS
 
from rhodecode.tests.vcs.conf import TEST_USER_CONFIG_FILE
 
from rhodecode.lib.vcs.nodes import FileNode
 
from rhodecode.lib.vcs.utils.compat import unittest
 
from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
rhodecode/tests/vcs/test_tags.py
Show inline comments
 
from __future__ import with_statement
 

	
 
from base import BackendTestMixin
 
from conf import SCM_TESTS
 
from rhodecode.tests.vcs.base import BackendTestMixin
 
from rhodecode.tests.vcs.conf import SCM_TESTS
 
from rhodecode.lib.vcs.exceptions import TagAlreadyExistError
 
from rhodecode.lib.vcs.exceptions import TagDoesNotExistError
 
from rhodecode.lib.vcs.utils.compat import unittest
rhodecode/tests/vcs/test_utils.py
Show inline comments
 
@@ -18,7 +18,7 @@ from rhodecode.lib.vcs.utils import auth
 
from rhodecode.lib.vcs.utils.paths import get_user_home
 
from rhodecode.lib.vcs.exceptions import VCSError
 

	
 
from conf import TEST_HG_REPO, TEST_GIT_REPO, TEST_TMP_PATH
 
from rhodecode.tests.vcs.conf import TEST_HG_REPO, TEST_GIT_REPO, TEST_TMP_PATH
 

	
 

	
 
class PathsTest(unittest.TestCase):
rhodecode/tests/vcs/test_vcs.py
Show inline comments
 
from __future__ import with_statement
 

	
 
import os
 
import shutil
 

	
 
from rhodecode.lib.vcs import VCSError, get_repo, get_backend
 
from rhodecode.lib.vcs.backends.hg import MercurialRepository
 
from rhodecode.lib.vcs.utils.compat import unittest
 
from conf import TEST_HG_REPO, TEST_GIT_REPO, TEST_TMP_PATH
 
import os
 
import shutil
 
from rhodecode.tests.vcs.conf import TEST_HG_REPO, TEST_GIT_REPO, TEST_TMP_PATH
 

	
 

	
 

	
 
class VCSTest(unittest.TestCase):
rhodecode/tests/vcs/test_workdirs.py
Show inline comments
 
@@ -3,8 +3,8 @@ from __future__ import with_statement
 
import datetime
 
from rhodecode.lib.vcs.nodes import FileNode
 
from rhodecode.lib.vcs.utils.compat import unittest
 
from base import BackendTestMixin
 
from conf import SCM_TESTS
 
from rhodecode.tests.vcs.base import BackendTestMixin
 
from rhodecode.tests.vcs.conf import SCM_TESTS
 

	
 

	
 
class WorkdirTestCaseMixin(BackendTestMixin):

Changeset was too big and was cut off... Show full diff anyway

0 comments (0 inline, 0 general)