Convert VCSs and rename to VcsRegistry
This commit is contained in:
parent
ab25807876
commit
db36eee4e3
197
src/main.py
197
src/main.py
|
@ -53,16 +53,7 @@ from urllib.parse import urlparse
|
|||
|
||||
from diffuse import utils
|
||||
from diffuse import constants
|
||||
from diffuse.vcs.folder_set import FolderSet
|
||||
from diffuse.vcs.bzr import Bzr
|
||||
from diffuse.vcs.cvs import Cvs
|
||||
from diffuse.vcs.darcs import Darcs
|
||||
from diffuse.vcs.git import Git
|
||||
from diffuse.vcs.hg import Hg
|
||||
from diffuse.vcs.mtn import Mtn
|
||||
from diffuse.vcs.rcs import Rcs
|
||||
from diffuse.vcs.svk import Svk
|
||||
from diffuse.vcs.svn import Svn
|
||||
from diffuse.vcs.vcs_registry import VcsRegistry
|
||||
|
||||
if not hasattr(__builtins__, 'WindowsError'):
|
||||
# define 'WindowsError' so 'except' statements will work on all platforms
|
||||
|
@ -1192,191 +1183,7 @@ def convert_to_format(s, format):
|
|||
s += '\r'
|
||||
return s
|
||||
|
||||
# returns the Windows drive or share from a from an absolute path
|
||||
def drive_from_path(s):
|
||||
c = s.split(os.sep)
|
||||
if len(c) > 3 and c[0] == '' and c[1] == '':
|
||||
return os.path.join(c[:4])
|
||||
return c[0]
|
||||
|
||||
# escape arguments for use with bash
|
||||
def bashEscape(s):
|
||||
return "'" + s.replace("'", "'\\''") + "'"
|
||||
|
||||
# utility method to help find folders used by version control systems
|
||||
def _find_parent_dir_with(path, dir_name):
|
||||
while True:
|
||||
name = os.path.join(path, dir_name)
|
||||
if os.path.isdir(name):
|
||||
return path
|
||||
newpath = os.path.dirname(path)
|
||||
if newpath == path:
|
||||
break
|
||||
path = newpath
|
||||
|
||||
def _get_bzr_repo(path, prefs):
|
||||
p = _find_parent_dir_with(path, '.bzr')
|
||||
if p:
|
||||
return Bzr(p)
|
||||
|
||||
def _get_cvs_repo(path, prefs):
|
||||
if os.path.isdir(os.path.join(path, 'CVS')):
|
||||
return Cvs(path)
|
||||
|
||||
def _get_darcs_repo(path, prefs):
|
||||
p = _find_parent_dir_with(path, '_darcs')
|
||||
if p:
|
||||
return Darcs(p)
|
||||
|
||||
def _get_git_repo(path, prefs):
|
||||
if 'GIT_DIR' in os.environ:
|
||||
try:
|
||||
d = path
|
||||
ss = utils.popenReadLines(d, [ prefs.getString('git_bin'), 'rev-parse', '--show-prefix' ], prefs, 'git_bash')
|
||||
if len(ss) > 0:
|
||||
# be careful to handle trailing slashes
|
||||
d = d.split(os.sep)
|
||||
if d[-1] != '':
|
||||
d.append('')
|
||||
ss = strip_eol(ss[0]).split('/')
|
||||
if ss[-1] != '':
|
||||
ss.append('')
|
||||
n = len(ss)
|
||||
if n <= len(d):
|
||||
del d[-n:]
|
||||
if len(d) == 0:
|
||||
d = os.curdir
|
||||
else:
|
||||
d = os.sep.join(d)
|
||||
return Git(d)
|
||||
except (IOError, OSError, WindowsError):
|
||||
# working tree not found
|
||||
pass
|
||||
# search for .git directory (project) or .git file (submodule)
|
||||
while True:
|
||||
name = os.path.join(path, '.git')
|
||||
if os.path.isdir(name) or os.path.isfile(name):
|
||||
return Git(path)
|
||||
newpath = os.path.dirname(path)
|
||||
if newpath == path:
|
||||
break
|
||||
path = newpath
|
||||
|
||||
def _get_hg_repo(path, prefs):
|
||||
p = _find_parent_dir_with(path, '.hg')
|
||||
if p:
|
||||
return Hg(p)
|
||||
|
||||
def _get_mtn_repo(path, prefs):
|
||||
p = _find_parent_dir_with(path, '_MTN')
|
||||
if p:
|
||||
return Mtn(p)
|
||||
|
||||
def _get_rcs_repo(path, prefs):
|
||||
if os.path.isdir(os.path.join(path, 'RCS')):
|
||||
return Rcs(path)
|
||||
|
||||
# [rfailliot] this code doesn't seem to work, but was in 0.4.8 too.
|
||||
# I'm letting it here until further tests are done, but it is possible
|
||||
# this code never actually worked.
|
||||
try:
|
||||
for s in os.listdir(path):
|
||||
if s.endswith(',v') and os.path.isfile(os.path.join(path, s)):
|
||||
return Rcs(path)
|
||||
except OSError:
|
||||
# the user specified an invalid folder name
|
||||
pass
|
||||
|
||||
def _get_svn_repo(path, prefs):
|
||||
p = _find_parent_dir_with(path, '.svn')
|
||||
if p:
|
||||
return Svn(p)
|
||||
|
||||
def _get_svk_repo(path, prefs):
|
||||
name = path
|
||||
# parse the ~/.svk/config file to discover which directories are part of
|
||||
# SVK repositories
|
||||
if utils.isWindows():
|
||||
name = name.upper()
|
||||
svkroot = os.environ.get('SVKROOT', None)
|
||||
if svkroot is None:
|
||||
svkroot = os.path.expanduser('~/.svk')
|
||||
svkconfig = os.path.join(svkroot, 'config')
|
||||
if os.path.isfile(svkconfig):
|
||||
try:
|
||||
# find working copies by parsing the config file
|
||||
f = open(svkconfig, 'r')
|
||||
ss = readlines(f)
|
||||
f.close()
|
||||
projs, sep = [], os.sep
|
||||
# find the separator character
|
||||
for s in ss:
|
||||
if s.startswith(' sep: ') and len(s) > 7:
|
||||
sep = s[7]
|
||||
# find the project directories
|
||||
i = 0
|
||||
while i < len(ss):
|
||||
s = ss[i]
|
||||
i += 1
|
||||
if s.startswith(' hash: '):
|
||||
while i < len(ss) and ss[i].startswith(' '):
|
||||
s = ss[i]
|
||||
i += 1
|
||||
if s.endswith(': ') and i < len(ss) and ss[i].startswith(' depotpath: '):
|
||||
key = s[4:-2].replace(sep, os.sep)
|
||||
# parse directory path
|
||||
j, n, tt = 0, len(key), []
|
||||
while j < n:
|
||||
if key[j] == '"':
|
||||
# quoted string
|
||||
j += 1
|
||||
while j < n:
|
||||
if key[j] == '"':
|
||||
j += 1
|
||||
break
|
||||
elif key[j] == '\\':
|
||||
# escaped character
|
||||
j += 1
|
||||
if j < n:
|
||||
tt.append(key[j])
|
||||
j += 1
|
||||
else:
|
||||
tt.append(key[j])
|
||||
j += 1
|
||||
key = ''.join(tt).replace(sep, os.sep)
|
||||
if utils.isWindows():
|
||||
key = key.upper()
|
||||
projs.append(key)
|
||||
break
|
||||
# check if the file belongs to one of the project directories
|
||||
if FolderSet(projs).contains(name):
|
||||
return Svk(path)
|
||||
except IOError:
|
||||
utils.logError(_('Error parsing %s.') % (svkconfig, ))
|
||||
|
||||
class VCSs:
|
||||
def __init__(self):
|
||||
# initialise the VCS objects
|
||||
self._get_repo = { 'bzr': _get_bzr_repo, 'cvs': _get_cvs_repo, 'darcs': _get_darcs_repo, 'git': _get_git_repo, 'hg': _get_hg_repo, 'mtn': _get_mtn_repo, 'rcs': _get_rcs_repo, 'svk': _get_svk_repo, 'svn': _get_svn_repo }
|
||||
|
||||
def setSearchOrder(self, ordering):
|
||||
self._search_order = ordering
|
||||
|
||||
# determines which VCS to use for files in the named folder
|
||||
def findByFolder(self, path, prefs):
|
||||
path = os.path.abspath(path)
|
||||
for vcs in prefs.getString('vcs_search_order').split():
|
||||
if vcs in self._get_repo:
|
||||
repo = self._get_repo[vcs](path, prefs)
|
||||
if repo:
|
||||
return repo
|
||||
|
||||
# determines which VCS to use for the named file
|
||||
def findByFilename(self, name, prefs):
|
||||
if name is not None:
|
||||
return self.findByFolder(os.path.dirname(name), prefs)
|
||||
|
||||
theVCSs = VCSs()
|
||||
theVCSs = VcsRegistry()
|
||||
|
||||
# utility method to step advance an adjustment
|
||||
def step_adjustment(adj, delta):
|
||||
|
|
11
src/utils.py
11
src/utils.py
|
@ -104,6 +104,17 @@ def safeRelativePath(abspath1, name, prefs, cygwin_pref):
|
|||
s = s.replace('/', '\\')
|
||||
return s
|
||||
|
||||
# returns the Windows drive or share from a from an absolute path
|
||||
def drive_from_path(s):
|
||||
c = s.split(os.sep)
|
||||
if len(c) > 3 and c[0] == '' and c[1] == '':
|
||||
return os.path.join(c[:4])
|
||||
return c[0]
|
||||
|
||||
# escape arguments for use with bash
|
||||
def bashEscape(s):
|
||||
return "'" + s.replace("'", "'\\''") + "'"
|
||||
|
||||
# use popen to read the output of a command
|
||||
def popenRead(dn, cmd, prefs, bash_pref, success_results=None):
|
||||
if success_results is None:
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
# Diffuse: a graphical tool for merging and comparing text files.
|
||||
#
|
||||
# Copyright (C) 2019 Derrick Moser <derrick_moser@yahoo.com>
|
||||
# Copyright (C) 2021 Romain Failliot <romain.failliot@foolstep.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
import os
|
||||
|
||||
from diffuse import utils
|
||||
from diffuse.vcs.folder_set import FolderSet
|
||||
from diffuse.vcs.bzr import Bzr
|
||||
from diffuse.vcs.cvs import Cvs
|
||||
from diffuse.vcs.darcs import Darcs
|
||||
from diffuse.vcs.git import Git
|
||||
from diffuse.vcs.hg import Hg
|
||||
from diffuse.vcs.mtn import Mtn
|
||||
from diffuse.vcs.rcs import Rcs
|
||||
from diffuse.vcs.svk import Svk
|
||||
from diffuse.vcs.svn import Svn
|
||||
|
||||
class VcsRegistry:
|
||||
def __init__(self):
|
||||
# initialise the VCS objects
|
||||
self._get_repo = {
|
||||
'bzr': _get_bzr_repo,
|
||||
'cvs': _get_cvs_repo,
|
||||
'darcs': _get_darcs_repo,
|
||||
'git': _get_git_repo,
|
||||
'hg': _get_hg_repo,
|
||||
'mtn': _get_mtn_repo,
|
||||
'rcs': _get_rcs_repo,
|
||||
'svk': _get_svk_repo,
|
||||
'svn': _get_svn_repo
|
||||
}
|
||||
|
||||
def setSearchOrder(self, ordering):
|
||||
self._search_order = ordering
|
||||
|
||||
# determines which VCS to use for files in the named folder
|
||||
def findByFolder(self, path, prefs):
|
||||
path = os.path.abspath(path)
|
||||
for vcs in prefs.getString('vcs_search_order').split():
|
||||
if vcs in self._get_repo:
|
||||
repo = self._get_repo[vcs](path, prefs)
|
||||
if repo:
|
||||
return repo
|
||||
|
||||
# determines which VCS to use for the named file
|
||||
def findByFilename(self, name, prefs):
|
||||
if name is not None:
|
||||
return self.findByFolder(os.path.dirname(name), prefs)
|
||||
|
||||
|
||||
# utility method to help find folders used by version control systems
|
||||
def _find_parent_dir_with(path, dir_name):
|
||||
while True:
|
||||
name = os.path.join(path, dir_name)
|
||||
if os.path.isdir(name):
|
||||
return path
|
||||
newpath = os.path.dirname(path)
|
||||
if newpath == path:
|
||||
break
|
||||
path = newpath
|
||||
|
||||
def _get_bzr_repo(path, prefs):
|
||||
p = _find_parent_dir_with(path, '.bzr')
|
||||
if p:
|
||||
return Bzr(p)
|
||||
|
||||
def _get_cvs_repo(path, prefs):
|
||||
if os.path.isdir(os.path.join(path, 'CVS')):
|
||||
return Cvs(path)
|
||||
|
||||
def _get_darcs_repo(path, prefs):
|
||||
p = _find_parent_dir_with(path, '_darcs')
|
||||
if p:
|
||||
return Darcs(p)
|
||||
|
||||
def _get_git_repo(path, prefs):
|
||||
if 'GIT_DIR' in os.environ:
|
||||
try:
|
||||
d = path
|
||||
ss = utils.popenReadLines(d, [ prefs.getString('git_bin'), 'rev-parse', '--show-prefix' ], prefs, 'git_bash')
|
||||
if len(ss) > 0:
|
||||
# be careful to handle trailing slashes
|
||||
d = d.split(os.sep)
|
||||
if d[-1] != '':
|
||||
d.append('')
|
||||
ss = strip_eol(ss[0]).split('/')
|
||||
if ss[-1] != '':
|
||||
ss.append('')
|
||||
n = len(ss)
|
||||
if n <= len(d):
|
||||
del d[-n:]
|
||||
if len(d) == 0:
|
||||
d = os.curdir
|
||||
else:
|
||||
d = os.sep.join(d)
|
||||
return Git(d)
|
||||
except (IOError, OSError, WindowsError):
|
||||
# working tree not found
|
||||
pass
|
||||
# search for .git directory (project) or .git file (submodule)
|
||||
while True:
|
||||
name = os.path.join(path, '.git')
|
||||
if os.path.isdir(name) or os.path.isfile(name):
|
||||
return Git(path)
|
||||
newpath = os.path.dirname(path)
|
||||
if newpath == path:
|
||||
break
|
||||
path = newpath
|
||||
|
||||
def _get_hg_repo(path, prefs):
|
||||
p = _find_parent_dir_with(path, '.hg')
|
||||
if p:
|
||||
return Hg(p)
|
||||
|
||||
def _get_mtn_repo(path, prefs):
|
||||
p = _find_parent_dir_with(path, '_MTN')
|
||||
if p:
|
||||
return Mtn(p)
|
||||
|
||||
def _get_rcs_repo(path, prefs):
|
||||
if os.path.isdir(os.path.join(path, 'RCS')):
|
||||
return Rcs(path)
|
||||
|
||||
# [rfailliot] this code doesn't seem to work, but was in 0.4.8 too.
|
||||
# I'm letting it here until further tests are done, but it is possible
|
||||
# this code never actually worked.
|
||||
try:
|
||||
for s in os.listdir(path):
|
||||
if s.endswith(',v') and os.path.isfile(os.path.join(path, s)):
|
||||
return Rcs(path)
|
||||
except OSError:
|
||||
# the user specified an invalid folder name
|
||||
pass
|
||||
|
||||
def _get_svn_repo(path, prefs):
|
||||
p = _find_parent_dir_with(path, '.svn')
|
||||
if p:
|
||||
return Svn(p)
|
||||
|
||||
def _get_svk_repo(path, prefs):
|
||||
name = path
|
||||
# parse the ~/.svk/config file to discover which directories are part of
|
||||
# SVK repositories
|
||||
if utils.isWindows():
|
||||
name = name.upper()
|
||||
svkroot = os.environ.get('SVKROOT', None)
|
||||
if svkroot is None:
|
||||
svkroot = os.path.expanduser('~/.svk')
|
||||
svkconfig = os.path.join(svkroot, 'config')
|
||||
if os.path.isfile(svkconfig):
|
||||
try:
|
||||
# find working copies by parsing the config file
|
||||
f = open(svkconfig, 'r')
|
||||
ss = readlines(f)
|
||||
f.close()
|
||||
projs, sep = [], os.sep
|
||||
# find the separator character
|
||||
for s in ss:
|
||||
if s.startswith(' sep: ') and len(s) > 7:
|
||||
sep = s[7]
|
||||
# find the project directories
|
||||
i = 0
|
||||
while i < len(ss):
|
||||
s = ss[i]
|
||||
i += 1
|
||||
if s.startswith(' hash: '):
|
||||
while i < len(ss) and ss[i].startswith(' '):
|
||||
s = ss[i]
|
||||
i += 1
|
||||
if s.endswith(': ') and i < len(ss) and ss[i].startswith(' depotpath: '):
|
||||
key = s[4:-2].replace(sep, os.sep)
|
||||
# parse directory path
|
||||
j, n, tt = 0, len(key), []
|
||||
while j < n:
|
||||
if key[j] == '"':
|
||||
# quoted string
|
||||
j += 1
|
||||
while j < n:
|
||||
if key[j] == '"':
|
||||
j += 1
|
||||
break
|
||||
elif key[j] == '\\':
|
||||
# escaped character
|
||||
j += 1
|
||||
if j < n:
|
||||
tt.append(key[j])
|
||||
j += 1
|
||||
else:
|
||||
tt.append(key[j])
|
||||
j += 1
|
||||
key = ''.join(tt).replace(sep, os.sep)
|
||||
if utils.isWindows():
|
||||
key = key.upper()
|
||||
projs.append(key)
|
||||
break
|
||||
# check if the file belongs to one of the project directories
|
||||
if FolderSet(projs).contains(name):
|
||||
return Svk(path)
|
||||
except IOError:
|
||||
utils.logError(_('Error parsing %s.') % (svkconfig, ))
|
Loading…
Reference in New Issue