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