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