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] <command> [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="action",
66 action="store_const",
67 const="info",
68 help="Only print the informations gathered")
69 phases.add_option("--name-of-the-build",
70 dest="action",
71 action="store_const",
72 const="name",
73 help="The name of the build")
74 phases.add_option("--update",
75 dest="action",
76 action="store_const",
77 const="update",
78 help="Update the sources in all directories from their servers")
79 phases.add_option("--build",
80 dest="action",
81 action="store_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.action:
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 if self.opts.action=="info":
149 print_("Project directories:\n")
150 for i,d in enumerate(fullDirs):
151 print_("%2d. %s" % (i+1,d))
152 print_(" ",info[d])
153 print_()
154
155 self.setData({'order' : fullDirs,
156 'info' : info})
157 elif self.opts.action=="name":
158 name=""
159 if self.opts.openfoam:
160 name+="%s-%s_%s_%s_%s" % (environ["WM_PROJECT"],
161 environ["WM_PROJECT_VERSION"],
162 environ["WM_ARCH"],
163 environ["WM_OPTIONS"],
164 environ["WM_MPLIB"])
165 else:
166 name+="%s_%s" % (uname()[0],
167 uname()[-1])
168 name += "_branch-%s" % info[fullDirs[-1]]["branch"]
169
170 print_(name)
171 self.setData({'name' : name,
172 'info' : info,
173 'order' : fullDirs})
174 elif self.opts.action=="update":
175 success=True
176 for d in fullDirs:
177 if info[d]["writable"]:
178 print_("Attempting to update",d)
179 print_()
180 vcs=getVCS(info[d]["vcs"],
181 d,
182 tolerant=True)
183 if vcs:
184 try:
185 if not vcs.update(timeout=self.opts.timeout):
186 success=False
187 except FatalErrorPyFoamException:
188 e = sys.exc_info()[1]
189 print_("Problem:",e)
190 success=False
191 else:
192 print_("Not under version control ... skipping")
193 success=False
194 else:
195 print_(d,"not writable .... skipping update")
196
197 print_()
198 if not success:
199 self.error("Problem during updating")
200 elif self.opts.action=="build":
201 success=True
202 oldDir=os.getcwd()
203
204 for d in fullDirs:
205 if info[d]["writable"]:
206 print_("Attempting to build",d)
207 print_()
208 makeCommand={"make" :["make"],
209 "wmake" :["wmake"],
210 "Allwmake":["./Allwmake"]}[info[d]["make"]]
211
212 print_("Changing to",d,"and executing"," ".join(makeCommand))
213 print_()
214 os.chdir(d)
215 erg=subprocess.call(makeCommand)
216 if erg:
217 print_()
218 print_("Result of build command:",erg)
219 success=False
220 else:
221 print_(d,"not writable .... skipping build")
222
223 print_()
224
225 os.chdir(oldDir)
226
227 if not success:
228 self.error("Problem during building")
229
230 else:
231 self.error("Unimplemented action",self.opts.action)
232
233
234