1
# -*- coding: utf-8 -*-
3
# Copyright © 2011 Pierre Raybaut
4
# Licensed under the terms of the MIT License
5
# (see spyderlib/__init__.py for details)
7
"""Utilities for version control systems"""
13
from spyderlib.baseconfig import _
14
from spyderlib.utils import programs
15
from spyderlib.utils.misc import abspardir
19
'.hg': dict(name="Mercurial",
20
commit=( ('thg', ['commit']),
21
('hgtk', ['commit']) ),
22
browse=( ('thg', ['log']),
25
'.git': dict(name="git",
26
commit=( ('git', ['gui']), ),
27
browse=( ('gitk', []), )
32
def get_vcs_infos(path):
33
"""Return VCS infos if path is a supported VCS repository"""
34
for dirname, infos in VCS_INFOS.iteritems():
35
vcs_path = osp.join(path, dirname)
36
if osp.isdir(vcs_path):
40
def get_vcs_root(path):
41
"""Return VCS root directory path
42
Return None if path is not within a supported VCS repository"""
44
while get_vcs_infos(path) is None:
45
path = abspardir(path)
46
if path == previous_path:
50
return osp.abspath(path)
53
def is_vcs_repository(path):
54
"""Return True if path is a supported VCS repository"""
55
return get_vcs_root(path) is not None
58
def run_vcs_tool(path, tool):
59
"""If path is a valid VCS repository, run the corresponding VCS tool
60
Supported VCS tools: 'commit', 'browse'
61
Return False if the VCS tool is not installed"""
62
infos = get_vcs_infos(get_vcs_root(path))
63
for name, args in infos[tool]:
64
if programs.find_program(name):
65
programs.run_program(name, args, cwd=path)
68
raise RuntimeError(_("For %s support, please install one of the<br/> "
69
"following tools:<br/><br/> %s")
71
', '.join([name for name,cmd in infos['commit']])
75
def is_hg_installed():
76
"""Return True if Mercurial is installed"""
77
return programs.find_program('hg') is not None
80
def get_hg_revision(repopath):
81
"""Return Mercurial revision for the repository located at repopath
82
Result is a tuple (global, local, branch), with None values on error
84
>>> get_hg_revision(".")
85
('eba7273c69df+', '2015+', 'default')
88
hg = programs.find_program('hg')
89
assert hg is not None and osp.isdir(osp.join(repopath, '.hg'))
90
output = subprocess.check_output([hg, 'id', '-nib', repopath])
91
# output is now: ('eba7273c69df+ 2015+ default\n', None)
92
return tuple(output.strip().split())
93
except (subprocess.CalledProcessError, AssertionError, AttributeError):
94
# print("Error: Failed to get revision number from Mercurial - %s" % exc)
95
return (None, None, None)
98
if __name__ == '__main__':
99
print get_vcs_root(osp.dirname(__file__))
100
print get_vcs_root(r'D:\Python\ipython\IPython\frontend')
101
#run_vcs_tool(r'D:\Python\userconfig\userconfig', 'commit')
102
print get_hg_revision(osp.dirname(__file__)+"/../..")
103
print get_hg_revision('/')
1
# -*- coding: utf-8 -*-
3
# Copyright © 2011 Pierre Raybaut
4
# Licensed under the terms of the MIT License
5
# (see spyderlib/__init__.py for details)
7
"""Utilities for version control systems"""
9
from __future__ import print_function
15
from spyderlib.utils import programs
16
from spyderlib.utils.misc import abspardir
24
commit=( ('thg', ['commit']),
25
('hgtk', ['commit']) ),
26
browse=( ('thg', ['log']),
32
commit=( ('git', ['gui']), ),
33
browse=( ('gitk', []), ))
37
class ActionToolNotFound(RuntimeError):
38
"""Exception to transmit information about supported tools for
39
failed attempt to execute given action"""
41
def __init__(self, vcsname, action, tools):
42
RuntimeError.__init__(self)
43
self.vcsname = vcsname
48
def get_vcs_info(path):
49
"""Return support status dict if path is under VCS root"""
50
for info in SUPPORTED:
51
vcs_path = osp.join(path, info['rootdir'])
52
if osp.isdir(vcs_path):
56
def get_vcs_root(path):
57
"""Return VCS root directory path
58
Return None if path is not within a supported VCS repository"""
60
while get_vcs_info(path) is None:
61
path = abspardir(path)
62
if path == previous_path:
66
return osp.abspath(path)
69
def is_vcs_repository(path):
70
"""Return True if path is a supported VCS repository"""
71
return get_vcs_root(path) is not None
74
def run_vcs_tool(path, action):
75
"""If path is a valid VCS repository, run the corresponding VCS tool
76
Supported VCS actions: 'commit', 'browse'
77
Return False if the VCS tool is not installed"""
78
info = get_vcs_info(get_vcs_root(path))
79
tools = info['actions'][action]
80
for tool, args in tools:
81
if programs.find_program(tool):
82
programs.run_program(tool, args, cwd=path)
85
cmdnames = [name for name, args in tools]
86
raise ActionToolNotFound(info['name'], action, cmdnames)
88
def is_hg_installed():
89
"""Return True if Mercurial is installed"""
90
return programs.find_program('hg') is not None
93
def get_hg_revision(repopath):
94
"""Return Mercurial revision for the repository located at repopath
95
Result is a tuple (global, local, branch), with None values on error
97
>>> get_hg_revision(".")
98
('eba7273c69df+', '2015+', 'default')
101
hg = programs.find_program('hg')
102
assert hg is not None and osp.isdir(osp.join(repopath, '.hg'))
103
output, _err = subprocess.Popen([hg, 'id', '-nib', repopath],
104
stdout=subprocess.PIPE).communicate()
105
# output is now: ('eba7273c69df+ 2015+ default\n', None)
106
# Split 2 times max to allow spaces in branch names.
107
return tuple(output.decode().strip().split(None, 2))
108
except (subprocess.CalledProcessError, AssertionError, AttributeError):
109
# print("Error: Failed to get revision number from Mercurial - %s" % exc)
110
return (None, None, None)
113
if __name__ == '__main__':
114
print(get_vcs_root(osp.dirname(__file__)))
115
print(get_vcs_root(r'D:\Python\ipython\IPython\kernel'))
116
#run_vcs_tool(r'D:\Python\userconfig\userconfig', 'commit')
117
print(get_hg_revision(osp.dirname(__file__)+"/../.."))
118
print(get_hg_revision('/'))