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