1
2 """
3 Application class that implements pyFoamBuildHelper
4 """
5
6 from PyFoamApplication import PyFoamApplication
7 from PyFoam.Basics.GeneralVCSInterface import whichVCS,getVCS
8 from PyFoam.Error import FatalErrorPyFoamException
9
10 from subprocess import call
11 from optparse import OptionGroup
12 from os import environ,path
13 import os,subprocess
14
17 description="""\
18 This application helps with updating a
19 project and the projects it depends on. A phase (or a desired output)
20 has to be specified with an options.
21
22 If no arguments are given then it assumes that the current directory
23 is the root directory of the project to be compiled and that the only
24 project it depends on is the OpenFOAM-installation (as found in the
25 WM_PROJECT_DIR-environment variable). Arguments are assumed to be
26 other projects that are injected between these two
27 """
28
29 PyFoamApplication.__init__(self,
30 nr=0,
31 exactNr=False,
32 args=args,
33 usage="%prog [options] <command> [arguments]",
34 description=description,
35 interspersed=True)
36
38 projects=OptionGroup(self.parser,
39 "Projects",
40 "Which projects should be automatically considered")
41 self.parser.add_option_group(projects)
42
43 projects.add_option("--no-openfoam",
44 dest="openfoam",
45 default=True,
46 action="store_false",
47 help="Do not consider the OpenFOAM-directory")
48 projects.add_option("--no-current-directory",
49 dest="currentDir",
50 default=True,
51 action="store_false",
52 help="Do not consider the current directory")
53
54 phases=OptionGroup(self.parser,
55 "Action",
56 "What to do")
57 self.parser.add_option_group(phases)
58
59 phases.add_option("--info",
60 dest="action",
61 action="store_const",
62 const="info",
63 help="Only print the informations gathered")
64 phases.add_option("--name-of-the-build",
65 dest="action",
66 action="store_const",
67 const="name",
68 help="The name of the build")
69 phases.add_option("--update",
70 dest="action",
71 action="store_const",
72 const="update",
73 help="Update the sources in all directories from their servers")
74 phases.add_option("--build",
75 dest="action",
76 action="store_const",
77 const="build",
78 help="Build all projects in the correct order")
79
80 parameters=OptionGroup(self.parser,
81 "Parameters",
82 "Additional parameters")
83 self.parser.add_option_group(parameters)
84 parameters.add_option("--timeout",
85 dest="timeout",
86 action="store",
87 type="int",
88 default=None,
89 help="Default timeout (in seconds) for the update from the repositories. If none specified the default of the VCS in question is used. Only applicable if the VCS supports it")
90
92 if not self.opts.action:
93 self.error("No action defined")
94
95 dirs=[]
96 if self.opts.openfoam and "WM_PROJECT_DIR" in environ:
97 dirs.append(environ["WM_PROJECT_DIR"])
98 dirs+=self.parser.getArgs()
99 if self.opts.currentDir:
100 dirs.append(path.curdir)
101
102 fullDirs=[]
103 for d in dirs:
104 if path.isdir(d):
105 fullDirs.append(path.abspath(d))
106
107 info=dict(zip(fullDirs,[{} for i in range(len(fullDirs))]))
108
109 for d in fullDirs:
110 info[d]["writable"]=os.access(d,os.W_OK)
111
112 info[d]["isFoam"]=(d==fullDirs[0] and self.opts.openfoam)
113
114 info[d]["vcs"]=whichVCS(d)
115
116 if path.exists(path.join(d,"Allwmake")):
117 info[d]["make"]="Allwmake"
118 elif path.exists(path.join(d,"Makefile")):
119 info[d]["make"]="make"
120 else:
121 info[d]["make"]="wmake"
122
123 if info[d]["vcs"]=="":
124 info[d]["branch"]="unknown"
125 else:
126 vcs=getVCS(info[d]["vcs"],
127 d,
128 tolerant=True)
129 if vcs:
130 try:
131 info[d]["branch"]=vcs.branchName()
132 except FatalErrorPyFoamException:
133 info[d]["branch"]="notImplemented"
134
135 try:
136 info[d]["revision"]=vcs.getRevision()
137 except FatalErrorPyFoamException:
138 info[d]["revision"]="notImplemented"
139 else:
140 info[d]["branch"]="noVCS"
141 info[d]["revision"]="noVCS"
142
143 if self.opts.action=="info":
144 print "Project directories:\n"
145 for i,d in enumerate(fullDirs):
146 print "%2d. %s" % (i+1,d)
147 print " ",info[d]
148 print
149
150 self.setData({'order' : fullDirs,
151 'info' : info})
152 elif self.opts.action=="name":
153 name=""
154 if self.opts.openfoam:
155 name+="%s-%s_%s_%s_%s" % (environ["WM_PROJECT"],
156 environ["WM_PROJECT_VERSION"],
157 environ["WM_ARCH"],
158 environ["WM_OPTIONS"],
159 environ["WM_MPLIB"])
160 else:
161 name+="%s_%s" % (os.uname()[0],
162 os.uname()[-1])
163 name += "_branch-%s" % info[fullDirs[-1]]["branch"]
164
165 print name
166 self.setData({'name' : name,
167 'info' : info,
168 'order' : fullDirs})
169 elif self.opts.action=="update":
170 success=True
171 for d in fullDirs:
172 if info[d]["writable"]:
173 print "Attempting to update",d
174 print
175 vcs=getVCS(info[d]["vcs"],
176 d,
177 tolerant=True)
178 if vcs:
179 try:
180 if not vcs.update(timeout=self.opts.timeout):
181 success=False
182 except FatalErrorPyFoamException,e:
183 print "Problem:",e
184 success=False
185 else:
186 print "Not under version control ... skipping"
187 success=False
188 else:
189 print d,"not writable .... skipping update"
190
191 print
192 if not success:
193 self.error("Problem during updating")
194 elif self.opts.action=="build":
195 success=True
196 oldDir=os.getcwd()
197
198 for d in fullDirs:
199 if info[d]["writable"]:
200 print "Attempting to build",d
201 print
202 makeCommand={"make" :["make"],
203 "wmake" :["wmake"],
204 "Allwmake":["./Allwmake"]}[info[d]["make"]]
205
206 print "Changing to",d,"and executing"," ".join(makeCommand)
207 print
208 os.chdir(d)
209 erg=subprocess.call(makeCommand)
210 if erg:
211 print
212 print "Result of build command:",erg
213 success=False
214 else:
215 print d,"not writable .... skipping build"
216
217 print
218
219 os.chdir(oldDir)
220
221 if not success:
222 self.error("Problem during building")
223
224 else:
225 self.error("Unimplemented action",self.opts.action)
226