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