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