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
116
117 -def getVCS(vcs,
118 path,
119 init=False,
120 tolerant=False):
121 """Factory to create a proper VCS-interface
122 @param vcs: name of the VCS-implementation
123 @param path: path which is under version control
124 @param init: whether the Version-control should be initialized here
125 @param tolerant: If there is no interface for the VCS in question return None"""
126
127 table = { "hg" : "HgInterface" ,
128 "git" : "GitInterface",
129 "svn" : "SvnInterface",
130 "svk" : "SvkInterface" }
131
132 if vcs not in table:
133 if tolerant:
134 return None
135 else:
136 error("Unknown VCS",vcs,". Known are",list(table.keys()))
137
138 modName=table[vcs]
139
140 exec_("from "+modName+" import "+modName)
141
142 return eval(modName+"(path,init)")
143
145 """Diagnose which VCS a specific directory is under
146
147 Returns a string that is consistent with the creation table in getVCS
148 """
149 if path.exists(path.join(dpath,".svn")):
150 return "svn"
151
152 def runTest(test):
153 p = subprocess.Popen(test,
154 shell=True,
155 stdout=subprocess.PIPE,
156 stderr=subprocess.STDOUT)
157 pid, sts = os.waitpid(p.pid, 0)
158 return sts
159
160 if not runTest("hg stat -q --cwd %s" % dpath):
161 return "hg"
162
163 if not runTest("svk info %s" % dpath):
164 return "svk"
165
166 oldDir=getcwd()
167 chdir(dpath)
168 status=runTest("git rev-parse")
169 chdir(oldDir)
170 if not status:
171 return "git"
172
173 return ""
174