]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Scripts/UpdateBuildVersions.py
1. Update UpdateBuildVersion.py;
[mirror_edk2.git] / BaseTools / Scripts / UpdateBuildVersions.py
CommitLineData
bd63012c 1## @file\r
2# Update build revisions of the tools when performing a developer build\r
3#\r
4# This script will modife the C/Include/Common/BuildVersion.h file and the two\r
5# Python scripts, Python/Common/BuildVersion.py and Python/UPT/BuildVersion.py.\r
6# If SVN is available, the tool will obtain the current checked out version of\r
7# the source tree for including the the --version commands.\r
8\r
22a99b87 9# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
bd63012c 10#\r
11# This program and the accompanying materials\r
12# are licensed and made available under the terms and conditions of the BSD License\r
13# which accompanies this distribution. The full text of the license may be found at\r
14# http://opensource.org/licenses/bsd-license.php\r
15#\r
16# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
17# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
18##\r
19""" This program will update the BuildVersion.py and BuildVersion.h files used to set a tool's version value """\r
20from __future__ import absolute_import\r
21\r
22import os\r
23import shlex\r
24import subprocess\r
25import sys\r
26\r
27from argparse import ArgumentParser, SUPPRESS\r
28from tempfile import NamedTemporaryFile\r
29from types import IntType, ListType\r
30\r
31\r
32SYS_ENV_ERR = "ERROR : %s system environment variable must be set prior to running this tool.\n"\r
33\r
34__execname__ = "UpdateBuildVersions.py"\r
22a99b87
YL
35SVN_REVISION = "$LastChangedRevision: 3 $"\r
36SVN_REVISION = SVN_REVISION.replace("$LastChangedRevision:", "").replace("$", "").strip()\r
bd63012c 37__copyright__ = "Copyright (c) 2014, Intel Corporation. All rights reserved."\r
38VERSION_NUMBER = "0.7.0"\r
39__version__ = "Version %s.%s" % (VERSION_NUMBER, SVN_REVISION)\r
40\r
41\r
42def ParseOptions():\r
43 """\r
44 Parse the command-line options.\r
45 The options for this tool will be passed along to the MkBinPkg tool.\r
46 """\r
47 parser = ArgumentParser(\r
48 usage=("%s [options]" % __execname__),\r
49 description=__copyright__,\r
50 conflict_handler='resolve')\r
51\r
52 # Standard Tool Options\r
53 parser.add_argument("--version", action="version",\r
54 version=__execname__ + " " + __version__)\r
55 parser.add_argument("-s", "--silent", action="store_true",\r
56 dest="silent",\r
57 help="All output will be disabled, pass/fail determined by the exit code")\r
58 parser.add_argument("-v", "--verbose", action="store_true",\r
59 dest="verbose",\r
60 help="Enable verbose output")\r
61 # Tool specific options\r
62 parser.add_argument("--revert", action="store_true",\r
63 dest="REVERT", default=False,\r
64 help="Revert the BuildVersion files only")\r
65 parser.add_argument("--svn-test", action="store_true",\r
66 dest="TEST_SVN", default=False,\r
67 help="Test if the svn command is available")\r
68 parser.add_argument("--svnFlag", action="store_true",\r
69 dest="HAVE_SVN", default=False,\r
70 help=SUPPRESS)\r
71\r
72 return(parser.parse_args())\r
73\r
74\r
75def ShellCommandResults(CmdLine, Opt):\r
76 """ Execute the comand, returning the output content """\r
77 file_list = NamedTemporaryFile(delete=False)\r
78 filename = file_list.name\r
79 Results = []\r
80\r
81 returnValue = 0\r
82 try:\r
83 subprocess.check_call(args=shlex.split(CmdLine), stderr=subprocess.STDOUT, stdout=file_list)\r
84 except subprocess.CalledProcessError as err_val:\r
85 file_list.close()\r
86 if not Opt.silent:\r
87 sys.stderr.write("ERROR : %d : %s\n" % (err_val.returncode, err_val.__str__()))\r
88 if os.path.exists(filename):\r
89 sys.stderr.write(" : Partial results may be in this file: %s\n" % filename)\r
90 sys.stderr.flush()\r
91 returnValue = err_val.returncode\r
92\r
93 except IOError as (errno, strerror):\r
94 file_list.close()\r
95 if not Opt.silent:\r
96 sys.stderr.write("I/O ERROR : %s : %s\n" % (str(errno), strerror))\r
97 sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)\r
98 if os.path.exists(filename):\r
99 sys.stderr.write(" : Partial results may be in this file: %s\n" % filename)\r
100 sys.stderr.flush()\r
101 returnValue = errno\r
102\r
103 except OSError as (errno, strerror):\r
104 file_list.close()\r
105 if not Opt.silent:\r
106 sys.stderr.write("OS ERROR : %s : %s\n" % (str(errno), strerror))\r
107 sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)\r
108 if os.path.exists(filename):\r
109 sys.stderr.write(" : Partial results may be in this file: %s\n" % filename)\r
110 sys.stderr.flush()\r
111 returnValue = errno\r
112\r
113 except KeyboardInterrupt:\r
114 file_list.close()\r
115 if not Opt.silent:\r
116 sys.stderr.write("ERROR : Command terminated by user : %s\n" % CmdLine)\r
117 if os.path.exists(filename):\r
118 sys.stderr.write(" : Partial results may be in this file: %s\n" % filename)\r
119 sys.stderr.flush()\r
120 returnValue = 1\r
121\r
122 finally:\r
123 if not file_list.closed:\r
124 file_list.flush()\r
125 os.fsync(file_list.fileno())\r
126 file_list.close()\r
127\r
128 if os.path.exists(filename):\r
129 fd_ = open(filename, 'r')\r
130 Results = fd_.readlines()\r
131 fd_.close()\r
132 os.unlink(filename)\r
133\r
134 if returnValue > 0:\r
135 return returnValue\r
136\r
137 return Results\r
138\r
139\r
140def UpdateBuildVersionPython(Rev, UserModified, opts):\r
141 """ This routine will update the BuildVersion.h files in the C source tree """\r
142 for SubDir in ["Common", "UPT"]:\r
143 PyPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "Python", SubDir)\r
144 BuildVersionPy = os.path.join(PyPath, "BuildVersion.py")\r
145 fd_ = open(os.path.normpath(BuildVersionPy), 'r')\r
146 contents = fd_.readlines()\r
147 fd_.close()\r
148 if opts.HAVE_SVN is False:\r
149 BuildVersionOrig = os.path.join(PyPath, "orig_BuildVersion.py")\r
150 fd_ = open (BuildVersionOrig, 'w')\r
151 for line in contents:\r
152 fd_.write(line)\r
153 fd_.flush()\r
154 fd_.close()\r
155 new_content = []\r
156 for line in contents:\r
157 if line.strip().startswith("gBUILD_VERSION"):\r
158 new_line = "gBUILD_VERSION = \"Developer Build based on Revision: %s\"" % Rev\r
159 if UserModified:\r
160 new_line = "gBUILD_VERSION = \"Developer Build based on Revision: %s with Modified Sources\"" % Rev\r
161 new_content.append(new_line)\r
162 continue\r
163 new_content.append(line)\r
164\r
165 fd_ = open(os.path.normpath(BuildVersionPy), 'w')\r
166 for line in new_content:\r
167 fd_.write(line)\r
168 fd_.close()\r
169\r
170\r
171def UpdateBuildVersionH(Rev, UserModified, opts):\r
172 """ This routine will update the BuildVersion.h files in the C source tree """\r
173 CPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "C", "Include", "Common")\r
174 BuildVersionH = os.path.join(CPath, "BuildVersion.h")\r
175 fd_ = open(os.path.normpath(BuildVersionH), 'r')\r
176 contents = fd_.readlines()\r
177 fd_.close()\r
178 if opts.HAVE_SVN is False:\r
179 BuildVersionOrig = os.path.join(CPath, "orig_BuildVersion.h")\r
180 fd_ = open(BuildVersionOrig, 'w')\r
181 for line in contents:\r
182 fd_.write(line)\r
183 fd_.flush()\r
184 fd_.close()\r
185\r
186 new_content = []\r
187 for line in contents:\r
188 if line.strip().startswith("#define"):\r
189 new_line = "#define __BUILD_VERSION \"Developer Build based on Revision: %s\"" % Rev\r
190 if UserModified:\r
191 new_line = "#define __BUILD_VERSION \"Developer Build based on Revision: %s with Modified Sources\"" % \\r
192 Rev\r
193 new_content.append(new_line)\r
194 continue\r
195 new_content.append(line)\r
196\r
197 fd_ = open(os.path.normpath(BuildVersionH), 'w')\r
198 for line in new_content:\r
199 fd_.write(line)\r
200 fd_.close()\r
201\r
202\r
203def RevertCmd(Filename, Opt):\r
204 """ This is the shell command that does the SVN revert """\r
205 CmdLine = "svn revert %s" % Filename.replace("\\", "/").strip()\r
206 try:\r
207 subprocess.check_output(args=shlex.split(CmdLine))\r
208 except subprocess.CalledProcessError as err_val:\r
209 if not Opt.silent:\r
210 sys.stderr.write("Subprocess ERROR : %s\n" % err_val)\r
211 sys.stderr.flush()\r
212\r
213 except IOError as (errno, strerror):\r
214 if not Opt.silent:\r
215 sys.stderr.write("I/O ERROR : %d : %s\n" % (str(errno), strerror))\r
216 sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)\r
217 sys.stderr.flush()\r
218\r
219 except OSError as (errno, strerror):\r
220 if not Opt.silent:\r
221 sys.stderr.write("OS ERROR : %d : %s\n" % (str(errno), strerror))\r
222 sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)\r
223 sys.stderr.flush()\r
224\r
225 except KeyboardInterrupt:\r
226 if not Opt.silent:\r
227 sys.stderr.write("ERROR : Command terminated by user : %s\n" % CmdLine)\r
228 sys.stderr.flush()\r
229\r
230 if Opt.verbose:\r
231 sys.stdout.write("Reverted this file: %s\n" % Filename)\r
232 sys.stdout.flush()\r
233\r
234\r
235def GetSvnRevision(opts):\r
236 """ Get the current revision of the BaseTools/Source tree, and check if any of the files have been modified """\r
237 Revision = "Unknown"\r
238 Modified = False\r
239\r
240 if opts.HAVE_SVN is False:\r
241 sys.stderr.write("WARNING: the svn command-line tool is not available.\n")\r
242 return (Revision, Modified)\r
243\r
244 SrcPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source")\r
245 # Check if there are modified files.\r
246 Cwd = os.getcwd()\r
247 os.chdir(SrcPath)\r
248\r
249 StatusCmd = "svn st -v --depth infinity --non-interactive"\r
250 contents = ShellCommandResults(StatusCmd, opts)\r
251 os.chdir(Cwd)\r
252 if type(contents) is ListType:\r
253 for line in contents:\r
254 if line.startswith("M "):\r
255 Modified = True\r
256 break\r
257\r
258 # Get the repository revision of BaseTools/Source\r
259 InfoCmd = "svn info %s" % SrcPath.replace("\\", "/").strip()\r
260 Revision = 0\r
261 contents = ShellCommandResults(InfoCmd, opts)\r
262 if type(contents) is IntType:\r
263 return 0, Modified\r
264 for line in contents:\r
265 line = line.strip()\r
266 if line.startswith("Revision:"):\r
267 Revision = line.replace("Revision:", "").strip()\r
268 break\r
269\r
270 return (Revision, Modified)\r
271\r
272\r
273def CheckSvn(opts):\r
274 """\r
275 This routine will return True if an svn --version command succeeds, or False if it fails.\r
276 If it failed, SVN is not available.\r
277 """\r
278 OriginalSilent = opts.silent\r
279 opts.silent = True\r
280 VerCmd = "svn --version"\r
281 contents = ShellCommandResults(VerCmd, opts)\r
282 opts.silent = OriginalSilent\r
283 if type(contents) is IntType:\r
284 if opts.verbose:\r
285 sys.stdout.write("SVN does not appear to be available.\n")\r
286 sys.stdout.flush()\r
287 return False\r
288\r
289 if opts.verbose:\r
290 sys.stdout.write("Found %s" % contents[0])\r
291 sys.stdout.flush()\r
292 return True\r
293\r
294\r
295def CopyOrig(Src, Dest, Opt):\r
296 """ Overwrite the Dest File with the Src File content """\r
297 try:\r
298 fd_ = open(Src, 'r')\r
299 contents = fd_.readlines()\r
300 fd_.close()\r
301 fd_ = open(Dest, 'w')\r
302 for line in contents:\r
303 fd_.write(line)\r
304 fd_.flush()\r
305 fd_.close()\r
306 except IOError:\r
307 if not Opt.silent:\r
308 sys.stderr.write("Unable to restore this file: %s\n" % Dest)\r
309 sys.stderr.flush()\r
310 return 1\r
311\r
312 os.remove(Src)\r
313 if Opt.verbose:\r
314 sys.stdout.write("Restored this file: %s\n" % Src)\r
315 sys.stdout.flush()\r
316\r
317 return 0\r
318\r
319\r
320def CheckOriginals(Opts):\r
321 """\r
322 If SVN was not available, then the tools may have made copies of the original BuildVersion.* files using\r
323 orig_BuildVersion.* for the name. If they exist, replace the existing BuildVersion.* file with the corresponding\r
324 orig_BuildVersion.* file.\r
325 Returns 0 if this succeeds, or 1 if the copy function fails. It will also return 0 if the orig_BuildVersion.* file\r
326 does not exist.\r
327 """\r
328 CPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "C", "Include", "Common")\r
329 BuildVersionH = os.path.join(CPath, "BuildVersion.h")\r
330 OrigBuildVersionH = os.path.join(CPath, "orig_BuildVersion.h")\r
331 if not os.path.exists(OrigBuildVersionH):\r
332 return 0\r
333 if CopyOrig(OrigBuildVersionH, BuildVersionH, Opts):\r
334 return 1\r
335 for SubDir in ["Common", "UPT"]:\r
336 PyPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "Python", SubDir)\r
337 BuildVersionPy = os.path.join(PyPath, "BuildVersion.h")\r
338 OrigBuildVersionPy = os.path.join(PyPath, "orig_BuildVersion.h")\r
339 if not os.path.exists(OrigBuildVersionPy):\r
340 return 0\r
341 if CopyOrig(OrigBuildVersionPy, BuildVersionPy, Opts):\r
342 return 1\r
343\r
344 return 0\r
345\r
346\r
347def RevertBuildVersionFiles(opts):\r
348 """\r
349 This routine will attempt to perform an SVN --revert on each of the BuildVersion.* files\r
350 """\r
351 if not opts.HAVE_SVN:\r
352 if CheckOriginals(opts):\r
353 return 1\r
354 return 0\r
355 # SVN is available\r
356 BuildVersionH = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "C", "Include", "Common", "BuildVersion.h")\r
357 RevertCmd(BuildVersionH, opts)\r
358 for SubDir in ["Common", "UPT"]:\r
359 BuildVersionPy = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "Python", SubDir, "BuildVersion.py")\r
360 RevertCmd(BuildVersionPy, opts)\r
361\r
362def UpdateRevisionFiles():\r
363 """ Main routine that will update the BuildVersion.py and BuildVersion.h files."""\r
364 options = ParseOptions()\r
365 # Check the working environment\r
366 if "WORKSPACE" not in os.environ.keys():\r
367 sys.stderr.write(SYS_ENV_ERR % 'WORKSPACE')\r
368 return 1\r
369 if 'BASE_TOOLS_PATH' not in os.environ.keys():\r
370 sys.stderr.write(SYS_ENV_ERR % 'BASE_TOOLS_PATH')\r
371 return 1\r
372 if not os.path.exists(os.environ['BASE_TOOLS_PATH']):\r
373 sys.stderr.write("Unable to locate the %s directory." % os.environ['BASE_TOOLS_PATH'])\r
374 return 1\r
375\r
376\r
377 options.HAVE_SVN = CheckSvn(options)\r
378 if options.TEST_SVN:\r
379 return (not options.HAVE_SVN)\r
380 # done processing the option, now use the option.HAVE_SVN as a flag. True = Have it, False = Don't have it.\r
381 if options.REVERT:\r
382 # Just revert the tools an exit\r
383 RevertBuildVersionFiles(options)\r
384 else:\r
385 # Revert any changes in the BuildVersion.* files before setting them again.\r
386 RevertBuildVersionFiles(options)\r
387 Revision, Modified = GetSvnRevision(options)\r
388 if options.verbose:\r
389 sys.stdout.write("Revision: %s is Modified: %s\n" % (Revision, Modified))\r
390 sys.stdout.flush()\r
391 UpdateBuildVersionH(Revision, Modified, options)\r
392 UpdateBuildVersionPython(Revision, Modified, options)\r
393\r
394 return 0\r
395\r
396\r
397if __name__ == "__main__":\r
398 sys.exit(UpdateRevisionFiles())\r
399\r
400\r