]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/UPT.py
BaseTools: Enhance BaseTools supports FixedAtBuild usage in VFR file
[mirror_edk2.git] / BaseTools / Source / Python / UPT / UPT.py
1 ## @file
2 #
3 # This file is the main entry for UPT
4 #
5 # Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
6 #
7 # This program and the accompanying materials are licensed and made available
8 # under the terms and conditions of the BSD License which accompanies this
9 # distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
11 #
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #
15
16 '''
17 UPT
18 '''
19
20 ## import modules
21 #
22 from Core import FileHook
23 import sys
24 import os.path
25 from sys import platform
26 import platform as pf
27 from optparse import OptionParser
28 from traceback import format_exc
29 from platform import python_version
30
31 from Logger import StringTable as ST
32 import Logger.Log as Logger
33 from Logger.StringTable import MSG_VERSION
34 from Logger.StringTable import MSG_DESCRIPTION
35 from Logger.StringTable import MSG_USAGE
36 from Logger.ToolError import FILE_NOT_FOUND
37 from Logger.ToolError import OPTION_MISSING
38 from Logger.ToolError import FILE_TYPE_MISMATCH
39 from Logger.ToolError import OPTION_CONFLICT
40 from Logger.ToolError import FatalError
41 from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR
42 from Common.MultipleWorkspace import MultipleWorkspace as mws
43
44 import MkPkg
45 import InstallPkg
46 import RmPkg
47 import InventoryWs
48 import ReplacePkg
49 import TestInstall
50 from Library.Misc import GetWorkspace
51 from Library import GlobalData
52 from Core.IpiDb import IpiDatabase
53 from BuildVersion import gBUILD_VERSION
54
55 ## CheckConflictOption
56 #
57 # CheckConflictOption
58 #
59 def CheckConflictOption(Opt):
60 if (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove or Opt.PackFileToReplace) \
61 and Opt.InventoryWs:
62 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_L_OA_EXCLUSIVE)
63 elif Opt.PackFileToReplace and (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove):
64 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_U_ICR_EXCLUSIVE)
65 elif (Opt.PackFileToCreate and Opt.PackFileToInstall and Opt.PackFileToRemove):
66 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_REQUIRE_I_C_R_OPTION)
67 elif Opt.PackFileToCreate and Opt.PackFileToInstall:
68 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_C_EXCLUSIVE)
69 elif Opt.PackFileToInstall and Opt.PackFileToRemove:
70 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_R_EXCLUSIVE)
71 elif Opt.PackFileToCreate and Opt.PackFileToRemove:
72 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE)
73 elif Opt.TestDistFiles and (Opt.PackFileToCreate or Opt.PackFileToInstall \
74 or Opt.PackFileToRemove or Opt.PackFileToReplace):
75 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE)
76
77 if Opt.CustomPath and Opt.UseGuidedPkgPath:
78 Logger.Warn("UPT", ST.WARN_CUSTOMPATH_OVERRIDE_USEGUIDEDPATH)
79 Opt.UseGuidedPkgPath = False
80
81 ## SetLogLevel
82 #
83 def SetLogLevel(Opt):
84 if Opt.opt_verbose:
85 Logger.SetLevel(Logger.VERBOSE)
86 elif Opt.opt_quiet:
87 Logger.SetLevel(Logger.QUIET + 1)
88 elif Opt.debug_level != None:
89 if Opt.debug_level < 0 or Opt.debug_level > 9:
90 Logger.Warn("UPT", ST.ERR_DEBUG_LEVEL)
91 Logger.SetLevel(Logger.INFO)
92 else:
93 Logger.SetLevel(Opt.debug_level + 1)
94 elif Opt.opt_slient:
95 Logger.SetLevel(Logger.SILENT)
96 else:
97 Logger.SetLevel(Logger.INFO)
98
99 ## Main
100 #
101 # Main
102 #
103 def Main():
104 Logger.Initialize()
105
106 Parser = OptionParser(version=(MSG_VERSION + ' Build ' + gBUILD_VERSION), description=MSG_DESCRIPTION,
107 prog="UPT.exe", usage=MSG_USAGE)
108
109 Parser.add_option("-d", "--debug", action="store", type="int", dest="debug_level", help=ST.HLP_PRINT_DEBUG_INFO)
110
111 Parser.add_option("-v", "--verbose", action="store_true", dest="opt_verbose",
112 help=ST.HLP_PRINT_INFORMATIONAL_STATEMENT)
113
114 Parser.add_option("-s", "--silent", action="store_true", dest="opt_slient", help=ST.HLP_RETURN_NO_DISPLAY)
115
116 Parser.add_option("-q", "--quiet", action="store_true", dest="opt_quiet", help=ST.HLP_RETURN_AND_DISPLAY)
117
118 Parser.add_option("-i", "--install", action="store", type="string", dest="Install_Distribution_Package_File",
119 help=ST.HLP_SPECIFY_PACKAGE_NAME_INSTALL)
120
121 Parser.add_option("-c", "--create", action="store", type="string", dest="Create_Distribution_Package_File",
122 help=ST.HLP_SPECIFY_PACKAGE_NAME_CREATE)
123
124 Parser.add_option("-r", "--remove", action="store", type="string", dest="Remove_Distribution_Package_File",
125 help=ST.HLP_SPECIFY_PACKAGE_NAME_REMOVE)
126
127 Parser.add_option("-t", "--template", action="store", type="string", dest="Package_Information_Data_File",
128 help=ST.HLP_SPECIFY_TEMPLATE_NAME_CREATE)
129
130 Parser.add_option("-p", "--dec-filename", action="append", type="string", dest="EDK2_DEC_Filename",
131 help=ST.HLP_SPECIFY_DEC_NAME_CREATE)
132
133 Parser.add_option("-m", "--inf-filename", action="append", type="string", dest="EDK2_INF_Filename",
134 help=ST.HLP_SPECIFY_INF_NAME_CREATE)
135
136 Parser.add_option("-l", "--list", action="store_true", dest="List_Dist_Installed",
137 help=ST.HLP_LIST_DIST_INSTALLED)
138
139 Parser.add_option("-f", "--force", action="store_true", dest="Yes", help=ST.HLP_DISABLE_PROMPT)
140
141 Parser.add_option("-n", "--custom-path", action="store_true", dest="CustomPath", help=ST.HLP_CUSTOM_PATH_PROMPT)
142
143 Parser.add_option("-x", "--free-lock", action="store_true", dest="SkipLock", help=ST.HLP_SKIP_LOCK_CHECK)
144
145 Parser.add_option("-u", "--replace", action="store", type="string", dest="Replace_Distribution_Package_File",
146 help=ST.HLP_SPECIFY_PACKAGE_NAME_REPLACE)
147
148 Parser.add_option("-o", "--original", action="store", type="string", dest="Original_Distribution_Package_File",
149 help=ST.HLP_SPECIFY_PACKAGE_NAME_TO_BE_REPLACED)
150
151 Parser.add_option("--use-guided-paths", action="store_true", dest="Use_Guided_Paths", help=ST.HLP_USE_GUIDED_PATHS)
152
153 Parser.add_option("-j", "--test-install", action="append", type="string",
154 dest="Test_Install_Distribution_Package_Files", help=ST.HLP_TEST_INSTALL)
155
156 Opt = Parser.parse_args()[0]
157
158 Var2Var = [
159 ("PackageInformationDataFile", Opt.Package_Information_Data_File),
160 ("PackFileToInstall", Opt.Install_Distribution_Package_File),
161 ("PackFileToCreate", Opt.Create_Distribution_Package_File),
162 ("PackFileToRemove", Opt.Remove_Distribution_Package_File),
163 ("PackageFileList", Opt.EDK2_DEC_Filename),
164 ("ModuleFileList", Opt.EDK2_INF_Filename),
165 ("InventoryWs", Opt.List_Dist_Installed),
166 ("PackFileToReplace", Opt.Replace_Distribution_Package_File),
167 ("PackFileToBeReplaced", Opt.Original_Distribution_Package_File),
168 ("UseGuidedPkgPath", Opt.Use_Guided_Paths),
169 ("TestDistFiles", Opt.Test_Install_Distribution_Package_Files)
170 ]
171
172 for Var in Var2Var:
173 setattr(Opt, Var[0], Var[1])
174
175 try:
176 GlobalData.gWORKSPACE, GlobalData.gPACKAGE_PATH = GetWorkspace()
177 except FatalError, XExcept:
178 if Logger.GetLevel() <= Logger.DEBUG_9:
179 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc())
180 return XExcept.args[0]
181
182 # Start *********************************************
183 # Support WORKSPACE is a long path
184 # Only work well on windows
185 # Linux Solution TBD
186 if pf.system() == 'Windows':
187 os.system('@echo off\nsubst b: /D')
188 os.system('subst b: "%s"' % GlobalData.gWORKSPACE)
189 GlobalData.gWORKSPACE = 'B:\\'
190 # End ***********************************************
191
192 WorkspaceDir = GlobalData.gWORKSPACE
193
194 SetLogLevel(Opt)
195
196 Mgr = FileHook.RecoverMgr(WorkspaceDir)
197 FileHook.SetRecoverMgr(Mgr)
198
199 GlobalData.gDB = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, \
200 "Conf/DistributionPackageDatabase.db")), WorkspaceDir)
201 GlobalData.gDB.InitDatabase(Opt.SkipLock)
202
203 #
204 # Make sure the Db will get closed correctly
205 #
206 try:
207 ReturnCode = 0
208 CheckConflictOption(Opt)
209
210 RunModule = None
211 if Opt.PackFileToCreate:
212 if Opt.PackageInformationDataFile:
213 if not os.path.exists(Opt.PackageInformationDataFile):
214 if not os.path.exists(os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)):
215 Logger.Error("\nUPT", FILE_NOT_FOUND, ST.ERR_NO_TEMPLATE_FILE % Opt.PackageInformationDataFile)
216 else:
217 Opt.PackageInformationDataFile = os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)
218 else:
219 Logger.Error("UPT", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_T_OPTION)
220 if not Opt.PackFileToCreate.endswith('.dist'):
221 Logger.Error("CreatePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToCreate)
222 RunModule = MkPkg.Main
223
224 elif Opt.PackFileToInstall:
225 if not Opt.PackFileToInstall.endswith('.dist'):
226 Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToInstall)
227
228 AbsPath = GetFullPathDist(Opt.PackFileToInstall, WorkspaceDir)
229 if not AbsPath:
230 Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Opt.PackFileToInstall)
231
232 Opt.PackFileToInstall = AbsPath
233 setattr(Opt, 'PackageFile', Opt.PackFileToInstall)
234 RunModule = InstallPkg.Main
235
236 elif Opt.PackFileToRemove:
237 if not Opt.PackFileToRemove.endswith('.dist'):
238 Logger.Error("RemovePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToRemove)
239 head, tail = os.path.split(Opt.PackFileToRemove)
240 if head or not tail:
241 Logger.Error("RemovePkg",
242 FILE_TYPE_MISMATCH,
243 ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REMOVE % Opt.PackFileToRemove)
244
245 setattr(Opt, 'DistributionFile', Opt.PackFileToRemove)
246 RunModule = RmPkg.Main
247 elif Opt.InventoryWs:
248 RunModule = InventoryWs.Main
249
250 elif Opt.PackFileToBeReplaced and not Opt.PackFileToReplace:
251 Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_U_OPTION)
252
253 elif Opt.PackFileToReplace:
254 if not Opt.PackFileToReplace.endswith('.dist'):
255 Logger.Error("ReplacePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToReplace)
256 if not Opt.PackFileToBeReplaced:
257 Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_O_OPTION)
258 if not Opt.PackFileToBeReplaced.endswith('.dist'):
259 Logger.Error("ReplacePkg",
260 FILE_TYPE_MISMATCH,
261 ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToBeReplaced)
262
263 head, tail = os.path.split(Opt.PackFileToBeReplaced)
264 if head or not tail:
265 Logger.Error("ReplacePkg",
266 FILE_TYPE_MISMATCH,
267 ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG % Opt.PackFileToBeReplaced)
268
269 AbsPath = GetFullPathDist(Opt.PackFileToReplace, WorkspaceDir)
270 if not AbsPath:
271 Logger.Error("ReplacePkg", FILE_NOT_FOUND, ST.ERR_REPLACE_DIST_NOT_FOUND % Opt.PackFileToReplace)
272
273 Opt.PackFileToReplace = AbsPath
274 RunModule = ReplacePkg.Main
275
276 elif Opt.Test_Install_Distribution_Package_Files:
277 for Dist in Opt.Test_Install_Distribution_Package_Files:
278 if not Dist.endswith('.dist'):
279 Logger.Error("TestInstall", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Dist)
280
281 setattr(Opt, 'DistFiles', Opt.Test_Install_Distribution_Package_Files)
282 RunModule = TestInstall.Main
283
284 else:
285 Parser.print_usage()
286 return OPTION_MISSING
287
288 ReturnCode = RunModule(Opt)
289 except FatalError, XExcept:
290 ReturnCode = XExcept.args[0]
291 if Logger.GetLevel() <= Logger.DEBUG_9:
292 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \
293 format_exc())
294 finally:
295 try:
296 if ReturnCode != 0 and ReturnCode != UPT_ALREADY_INSTALLED_ERROR:
297 Logger.Quiet(ST.MSG_RECOVER_START)
298 GlobalData.gDB.RollBack()
299 Mgr.rollback()
300 Logger.Quiet(ST.MSG_RECOVER_DONE)
301 else:
302 GlobalData.gDB.Commit()
303 Mgr.commit()
304 except StandardError:
305 Logger.Quiet(ST.MSG_RECOVER_FAIL)
306 GlobalData.gDB.CloseDb()
307 if pf.system() == 'Windows':
308 os.system('subst b: /D')
309
310 return ReturnCode
311
312 ## GetFullPathDist
313 #
314 # This function will check DistFile existence, if not absolute path, then try current working directory,
315 # then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None
316 #
317 # @param DistFile: The distribution file in either relative path or absolute path
318 # @param WorkspaceDir: Workspace Directory
319 # @return AbsPath: The Absolute path of the distribution file if existed, None else
320 #
321 def GetFullPathDist(DistFile, WorkspaceDir):
322 if os.path.isabs(DistFile):
323 if not (os.path.exists(DistFile) and os.path.isfile(DistFile)):
324 return None
325 else:
326 return DistFile
327 else:
328 AbsPath = os.path.normpath(os.path.join(os.getcwd(), DistFile))
329 if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)):
330 AbsPath = os.path.normpath(os.path.join(WorkspaceDir, DistFile))
331 if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)):
332 return None
333
334 return AbsPath
335
336 if __name__ == '__main__':
337 RETVAL = Main()
338 #
339 # 0-127 is a safe return range, and 1 is a standard default error
340 #
341 if RETVAL < 0 or RETVAL > 127:
342 RETVAL = 1
343 sys.exit(RETVAL)