# -*-python-*- # # Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved. # # By using this file, you agree to the terms and conditions set forth in # the LICENSE.html file which can be found at the top level of the ViewVC # distribution or at http://viewvc.org/license-1.html. # # For more information, visit http://viewvc.org/ # # ----------------------------------------------------------------------- "Version Control lib driver for Subversion repositories" import os import os.path import re import urllib _re_url = re.compile('^(http|https|file|svn|svn\+[^:]+)://') def _canonicalize_path(path): import svn.core try: return svn.core.svn_path_canonicalize(path) except AttributeError: # svn_path_canonicalize() appeared in 1.4.0 bindings # There's so much more that we *could* do here, but if we're # here at all its because there's a really old Subversion in # place, and those older Subversion versions cared quite a bit # less about the specifics of path canonicalization. if re.search(_re_url, path): return path.rstrip('/') else: return os.path.normpath(path) def canonicalize_rootpath(rootpath): # Try to canonicalize the rootpath using Subversion semantics. rootpath = _canonicalize_path(rootpath) # ViewVC's support for local repositories is more complete and more # performant than its support for remote ones, so if we're on a # Unix-y system and we have a file:/// URL, convert it to a local # path instead. if os.name == 'posix': rootpath_lower = rootpath.lower() if rootpath_lower in ['file://localhost', 'file://localhost/', 'file://', 'file:///' ]: return '/' if rootpath_lower.startswith('file://localhost/'): rootpath = os.path.normpath(urllib.unquote(rootpath[16:])) elif rootpath_lower.startswith('file:///'): rootpath = os.path.normpath(urllib.unquote(rootpath[7:])) # Ensure that we have an absolute path (or URL), and return. if not re.search(_re_url, rootpath): assert os.path.isabs(rootpath) return rootpath def expand_root_parent(parent_path): roots = {} if re.search(_re_url, parent_path): pass else: # Any subdirectories of PARENT_PATH which themselves have a child # "format" are returned as roots. assert os.path.isabs(parent_path) subpaths = os.listdir(parent_path) for rootname in subpaths: rootpath = os.path.join(parent_path, rootname) if os.path.exists(os.path.join(rootpath, "format")): roots[rootname] = canonicalize_rootpath(rootpath) return roots def find_root_in_parent(parent_path, rootname): """Search PARENT_PATH for a root named ROOTNAME, returning the canonicalized ROOTPATH of the root if found; return None if no such root is found.""" if not re.search(_re_url, parent_path): assert os.path.isabs(parent_path) rootpath = os.path.join(parent_path, rootname) format_path = os.path.join(rootpath, "format") if os.path.exists(format_path): return canonicalize_rootpath(rootpath) return None def SubversionRepository(name, rootpath, authorizer, utilities, config_dir): rootpath = canonicalize_rootpath(rootpath) if re.search(_re_url, rootpath): import svn_ra return svn_ra.RemoteSubversionRepository(name, rootpath, authorizer, utilities, config_dir) else: import svn_repos return svn_repos.LocalSubversionRepository(name, rootpath, authorizer, utilities, config_dir)