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