]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Scripts/UpdateBuildVersions.py
BaseTools/BinToPcd: Fix Python 2.7.x compatibility issue
[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
5b0671c1
GL
93 except IOError as err_val:\r
94 (errno, strerror) = err_val.args\r
bd63012c 95 file_list.close()\r
96 if not Opt.silent:\r
97 sys.stderr.write("I/O ERROR : %s : %s\n" % (str(errno), strerror))\r
98 sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)\r
99 if os.path.exists(filename):\r
100 sys.stderr.write(" : Partial results may be in this file: %s\n" % filename)\r
101 sys.stderr.flush()\r
102 returnValue = errno\r
103\r
5b0671c1
GL
104 except OSError as err_val:\r
105 (errno, strerror) = err_val.args\r
bd63012c 106 file_list.close()\r
107 if not Opt.silent:\r
108 sys.stderr.write("OS ERROR : %s : %s\n" % (str(errno), strerror))\r
109 sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)\r
110 if os.path.exists(filename):\r
111 sys.stderr.write(" : Partial results may be in this file: %s\n" % filename)\r
112 sys.stderr.flush()\r
113 returnValue = errno\r
114\r
115 except KeyboardInterrupt:\r
116 file_list.close()\r
117 if not Opt.silent:\r
118 sys.stderr.write("ERROR : Command terminated by user : %s\n" % CmdLine)\r
119 if os.path.exists(filename):\r
120 sys.stderr.write(" : Partial results may be in this file: %s\n" % filename)\r
121 sys.stderr.flush()\r
122 returnValue = 1\r
123\r
124 finally:\r
125 if not file_list.closed:\r
126 file_list.flush()\r
127 os.fsync(file_list.fileno())\r
128 file_list.close()\r
129\r
130 if os.path.exists(filename):\r
131 fd_ = open(filename, 'r')\r
132 Results = fd_.readlines()\r
133 fd_.close()\r
134 os.unlink(filename)\r
135\r
136 if returnValue > 0:\r
137 return returnValue\r
138\r
139 return Results\r
140\r
141\r
142def UpdateBuildVersionPython(Rev, UserModified, opts):\r
143 """ This routine will update the BuildVersion.h files in the C source tree """\r
144 for SubDir in ["Common", "UPT"]:\r
145 PyPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "Python", SubDir)\r
146 BuildVersionPy = os.path.join(PyPath, "BuildVersion.py")\r
147 fd_ = open(os.path.normpath(BuildVersionPy), 'r')\r
148 contents = fd_.readlines()\r
149 fd_.close()\r
150 if opts.HAVE_SVN is False:\r
151 BuildVersionOrig = os.path.join(PyPath, "orig_BuildVersion.py")\r
152 fd_ = open (BuildVersionOrig, 'w')\r
153 for line in contents:\r
154 fd_.write(line)\r
155 fd_.flush()\r
156 fd_.close()\r
157 new_content = []\r
158 for line in contents:\r
159 if line.strip().startswith("gBUILD_VERSION"):\r
160 new_line = "gBUILD_VERSION = \"Developer Build based on Revision: %s\"" % Rev\r
161 if UserModified:\r
162 new_line = "gBUILD_VERSION = \"Developer Build based on Revision: %s with Modified Sources\"" % Rev\r
163 new_content.append(new_line)\r
164 continue\r
165 new_content.append(line)\r
166\r
167 fd_ = open(os.path.normpath(BuildVersionPy), 'w')\r
168 for line in new_content:\r
169 fd_.write(line)\r
170 fd_.close()\r
171\r
172\r
173def UpdateBuildVersionH(Rev, UserModified, opts):\r
174 """ This routine will update the BuildVersion.h files in the C source tree """\r
175 CPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "C", "Include", "Common")\r
176 BuildVersionH = os.path.join(CPath, "BuildVersion.h")\r
177 fd_ = open(os.path.normpath(BuildVersionH), 'r')\r
178 contents = fd_.readlines()\r
179 fd_.close()\r
180 if opts.HAVE_SVN is False:\r
181 BuildVersionOrig = os.path.join(CPath, "orig_BuildVersion.h")\r
182 fd_ = open(BuildVersionOrig, 'w')\r
183 for line in contents:\r
184 fd_.write(line)\r
185 fd_.flush()\r
186 fd_.close()\r
187\r
188 new_content = []\r
189 for line in contents:\r
190 if line.strip().startswith("#define"):\r
191 new_line = "#define __BUILD_VERSION \"Developer Build based on Revision: %s\"" % Rev\r
192 if UserModified:\r
193 new_line = "#define __BUILD_VERSION \"Developer Build based on Revision: %s with Modified Sources\"" % \\r
194 Rev\r
195 new_content.append(new_line)\r
196 continue\r
197 new_content.append(line)\r
198\r
199 fd_ = open(os.path.normpath(BuildVersionH), 'w')\r
200 for line in new_content:\r
201 fd_.write(line)\r
202 fd_.close()\r
203\r
204\r
205def RevertCmd(Filename, Opt):\r
206 """ This is the shell command that does the SVN revert """\r
207 CmdLine = "svn revert %s" % Filename.replace("\\", "/").strip()\r
208 try:\r
209 subprocess.check_output(args=shlex.split(CmdLine))\r
210 except subprocess.CalledProcessError as err_val:\r
211 if not Opt.silent:\r
212 sys.stderr.write("Subprocess ERROR : %s\n" % err_val)\r
213 sys.stderr.flush()\r
214\r
5b0671c1
GL
215 except IOError as err_val:\r
216 (errno, strerror) = err_val.args\r
bd63012c 217 if not Opt.silent:\r
218 sys.stderr.write("I/O ERROR : %d : %s\n" % (str(errno), strerror))\r
219 sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)\r
220 sys.stderr.flush()\r
221\r
5b0671c1
GL
222 except OSError as err_val:\r
223 (errno, strerror) = err_val.args\r
bd63012c 224 if not Opt.silent:\r
225 sys.stderr.write("OS ERROR : %d : %s\n" % (str(errno), strerror))\r
226 sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)\r
227 sys.stderr.flush()\r
228\r
229 except KeyboardInterrupt:\r
230 if not Opt.silent:\r
231 sys.stderr.write("ERROR : Command terminated by user : %s\n" % CmdLine)\r
232 sys.stderr.flush()\r
233\r
234 if Opt.verbose:\r
235 sys.stdout.write("Reverted this file: %s\n" % Filename)\r
236 sys.stdout.flush()\r
237\r
238\r
239def GetSvnRevision(opts):\r
240 """ Get the current revision of the BaseTools/Source tree, and check if any of the files have been modified """\r
241 Revision = "Unknown"\r
242 Modified = False\r
243\r
244 if opts.HAVE_SVN is False:\r
245 sys.stderr.write("WARNING: the svn command-line tool is not available.\n")\r
246 return (Revision, Modified)\r
247\r
248 SrcPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source")\r
249 # Check if there are modified files.\r
250 Cwd = os.getcwd()\r
251 os.chdir(SrcPath)\r
252\r
253 StatusCmd = "svn st -v --depth infinity --non-interactive"\r
254 contents = ShellCommandResults(StatusCmd, opts)\r
255 os.chdir(Cwd)\r
0d1f5b2b 256 if isinstance(contents, ListType):\r
bd63012c 257 for line in contents:\r
258 if line.startswith("M "):\r
259 Modified = True\r
260 break\r
261\r
262 # Get the repository revision of BaseTools/Source\r
263 InfoCmd = "svn info %s" % SrcPath.replace("\\", "/").strip()\r
264 Revision = 0\r
265 contents = ShellCommandResults(InfoCmd, opts)\r
0d1f5b2b 266 if isinstance(contents, IntType):\r
bd63012c 267 return 0, Modified\r
268 for line in contents:\r
269 line = line.strip()\r
270 if line.startswith("Revision:"):\r
271 Revision = line.replace("Revision:", "").strip()\r
272 break\r
273\r
274 return (Revision, Modified)\r
275\r
276\r
277def CheckSvn(opts):\r
278 """\r
279 This routine will return True if an svn --version command succeeds, or False if it fails.\r
280 If it failed, SVN is not available.\r
281 """\r
282 OriginalSilent = opts.silent\r
283 opts.silent = True\r
284 VerCmd = "svn --version"\r
285 contents = ShellCommandResults(VerCmd, opts)\r
286 opts.silent = OriginalSilent\r
0d1f5b2b 287 if isinstance(contents, IntType):\r
bd63012c 288 if opts.verbose:\r
289 sys.stdout.write("SVN does not appear to be available.\n")\r
290 sys.stdout.flush()\r
291 return False\r
292\r
293 if opts.verbose:\r
294 sys.stdout.write("Found %s" % contents[0])\r
295 sys.stdout.flush()\r
296 return True\r
297\r
298\r
299def CopyOrig(Src, Dest, Opt):\r
300 """ Overwrite the Dest File with the Src File content """\r
301 try:\r
302 fd_ = open(Src, 'r')\r
303 contents = fd_.readlines()\r
304 fd_.close()\r
305 fd_ = open(Dest, 'w')\r
306 for line in contents:\r
307 fd_.write(line)\r
308 fd_.flush()\r
309 fd_.close()\r
310 except IOError:\r
311 if not Opt.silent:\r
312 sys.stderr.write("Unable to restore this file: %s\n" % Dest)\r
313 sys.stderr.flush()\r
314 return 1\r
315\r
316 os.remove(Src)\r
317 if Opt.verbose:\r
318 sys.stdout.write("Restored this file: %s\n" % Src)\r
319 sys.stdout.flush()\r
320\r
321 return 0\r
322\r
323\r
324def CheckOriginals(Opts):\r
325 """\r
326 If SVN was not available, then the tools may have made copies of the original BuildVersion.* files using\r
327 orig_BuildVersion.* for the name. If they exist, replace the existing BuildVersion.* file with the corresponding\r
328 orig_BuildVersion.* file.\r
329 Returns 0 if this succeeds, or 1 if the copy function fails. It will also return 0 if the orig_BuildVersion.* file\r
330 does not exist.\r
331 """\r
332 CPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "C", "Include", "Common")\r
333 BuildVersionH = os.path.join(CPath, "BuildVersion.h")\r
334 OrigBuildVersionH = os.path.join(CPath, "orig_BuildVersion.h")\r
335 if not os.path.exists(OrigBuildVersionH):\r
336 return 0\r
337 if CopyOrig(OrigBuildVersionH, BuildVersionH, Opts):\r
338 return 1\r
339 for SubDir in ["Common", "UPT"]:\r
340 PyPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "Python", SubDir)\r
341 BuildVersionPy = os.path.join(PyPath, "BuildVersion.h")\r
342 OrigBuildVersionPy = os.path.join(PyPath, "orig_BuildVersion.h")\r
343 if not os.path.exists(OrigBuildVersionPy):\r
344 return 0\r
345 if CopyOrig(OrigBuildVersionPy, BuildVersionPy, Opts):\r
346 return 1\r
347\r
348 return 0\r
349\r
350\r
351def RevertBuildVersionFiles(opts):\r
352 """\r
353 This routine will attempt to perform an SVN --revert on each of the BuildVersion.* files\r
354 """\r
355 if not opts.HAVE_SVN:\r
356 if CheckOriginals(opts):\r
357 return 1\r
358 return 0\r
359 # SVN is available\r
360 BuildVersionH = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "C", "Include", "Common", "BuildVersion.h")\r
361 RevertCmd(BuildVersionH, opts)\r
362 for SubDir in ["Common", "UPT"]:\r
363 BuildVersionPy = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "Python", SubDir, "BuildVersion.py")\r
364 RevertCmd(BuildVersionPy, opts)\r
365\r
366def UpdateRevisionFiles():\r
367 """ Main routine that will update the BuildVersion.py and BuildVersion.h files."""\r
368 options = ParseOptions()\r
369 # Check the working environment\r
370 if "WORKSPACE" not in os.environ.keys():\r
371 sys.stderr.write(SYS_ENV_ERR % 'WORKSPACE')\r
372 return 1\r
373 if 'BASE_TOOLS_PATH' not in os.environ.keys():\r
374 sys.stderr.write(SYS_ENV_ERR % 'BASE_TOOLS_PATH')\r
375 return 1\r
376 if not os.path.exists(os.environ['BASE_TOOLS_PATH']):\r
377 sys.stderr.write("Unable to locate the %s directory." % os.environ['BASE_TOOLS_PATH'])\r
378 return 1\r
379\r
380\r
381 options.HAVE_SVN = CheckSvn(options)\r
382 if options.TEST_SVN:\r
383 return (not options.HAVE_SVN)\r
384 # done processing the option, now use the option.HAVE_SVN as a flag. True = Have it, False = Don't have it.\r
385 if options.REVERT:\r
386 # Just revert the tools an exit\r
387 RevertBuildVersionFiles(options)\r
388 else:\r
389 # Revert any changes in the BuildVersion.* files before setting them again.\r
390 RevertBuildVersionFiles(options)\r
391 Revision, Modified = GetSvnRevision(options)\r
392 if options.verbose:\r
393 sys.stdout.write("Revision: %s is Modified: %s\n" % (Revision, Modified))\r
394 sys.stdout.flush()\r
395 UpdateBuildVersionH(Revision, Modified, options)\r
396 UpdateBuildVersionPython(Revision, Modified, options)\r
397\r
398 return 0\r
399\r
400\r
401if __name__ == "__main__":\r
402 sys.exit(UpdateRevisionFiles())\r
403\r
404\r