1
2 """General interface to VCS implementations"""
3
4 from PyFoam.Error import notImplemented,error
5 from os import path,getcwd,chdir
6 import subprocess,os
7
8 from PyFoam.ThirdParty.six import exec_
9
11 """This is an abstract class that implements an interface to general VCS operations"""
12
13 - def __init__(self,
14 path,
15 init=False):
16 """@param path: path which is supposed to be under version control
17 @param init: initialize the version control system here"""
18
19 if init:
20 self.path=path
21 else:
22 self.path=self.getRoot(path)
23
25 """\
26 Returns the actual repository root for a path. Default implmentation
27 passes through the path
28 """
29 return path
30
32 """Executes a command and returns the output"""
33 p = subprocess.Popen(cmd,
34 shell=True,
35 stdout=subprocess.PIPE,
36 stderr=subprocess.STDOUT)
37 result=p.communicate()[0]
38 return result.strip()
39
40 - def doInPath(self,
41 func,
42 *args,**kwargs):
43 """\
44 Execute a function in the root directory of the repository. Afterwards
45 change back ot the original directory. Result of the function is returned
46
47 @param func: the function to be executed"""
48 oldDir=os.getcwd()
49 os.chdir(self.path)
50 result=func(*args,**kwargs)
51 os.chdir(oldDir)
52 return result
53
55 """Get the current revision number"""
56
57 notImplemented(self,"commit")
58
61 """Commit the current state
62 @param msg: Commit message"""
63
64 notImplemented(self,"commit")
65
66 - def update(self,
67 timeout=None):
68 """Update the working copy from the parent repository
69 @param timeout: Wait a maximum time (if the VCS supports this)"""
70
71 notImplemented(self,"update")
72
74 """Return the branch-name (or another identifying string)"""
75
76
77 notImplemented(self,"commit")
78
79 - def addPath(self,
80 path,
81 rules=[]):
82 """Add the path to the repository (no commit)
83 @param path: the path (directory or file) to commit
84 @param rules: a list of tuples: first is whether to include or exclude
85 the regular expression that is the second member of the tuple"""
86
87 notImplemented(self,"addPath")
88
89 - def clone(self,
90 dest):
91 """Clone the repository
92 @param dest: the path that should be clones to"""
93
94 notImplemented(self,"clone")
95
98 """Add to the ignore-facility of the current VCS
99 @param expr: a regular expression"""
100
101 notImplemented(self,"addRegexpToIgnore")
102
105 """Add to the ignore-facility of the current VCS
106 @param expr: a glob expression"""
107
108 notImplemented(self,"addGlobToIgnore")
109
120
121 -def getVCS(vcs,
122 path,
123 init=False,
124 tolerant=False):
125 """Factory to create a proper VCS-interface
126 @param vcs: name of the VCS-implementation
127 @param path: path which is under version control
128 @param init: whether the Version-control should be initialized here
129 @param tolerant: If there is no interface for the VCS in question return None"""
130
131 table = { "hg" : "HgInterface" ,
132 "git" : "GitInterface",
133 "svn" : "SvnInterface",
134 "svk" : "SvkInterface" }
135
136 if vcs not in table:
137 if tolerant:
138 return None
139 else:
140 error("Unknown VCS",vcs,". Known are",list(table.keys()))
141
142 modName=table[vcs]
143
144 exec_("from "+modName+" import "+modName)
145
146 return eval(modName+"(path,init)")
147
149 """Diagnose which VCS a specific directory is under
150
151 Returns a string that is consistent with the creation table in getVCS
152 """
153 if path.exists(path.join(dpath,".svn")):
154 return "svn"
155
156 def runTest(test):
157 p = subprocess.Popen(test,
158 shell=True,
159 stdout=subprocess.PIPE,
160 stderr=subprocess.STDOUT)
161 pid, sts = os.waitpid(p.pid, 0)
162 return sts
163
164 if not runTest("hg stat -q --cwd %s" % dpath):
165 return "hg"
166
167 if not runTest("svk info %s" % dpath):
168 return "svk"
169
170 oldDir=getcwd()
171 chdir(dpath)
172 status=runTest("git rev-parse")
173 chdir(oldDir)
174 if not status:
175 return "git"
176
177 return ""
178