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