]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/UPT/UPT.py
BaseTools/UPT: Support Unicode path
[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 - 2017, 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
24encoding = locale.getdefaultlocale()[1]\r
25if encoding:\r
26 reload(sys)\r
27 sys.setdefaultencoding(encoding)\r
28from Core import FileHook\r
29import os.path\r
30from sys import platform\r
31import platform as pf\r
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
46from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR\r
47from Common.MultipleWorkspace import MultipleWorkspace as mws\r
48\r
49import MkPkg\r
50import InstallPkg\r
51import RmPkg\r
52import InventoryWs\r
53import ReplacePkg\r
54import TestInstall\r
55from Library.Misc import GetWorkspace\r
56from Library import GlobalData\r
57from Core.IpiDb import IpiDatabase\r
58from BuildVersion import gBUILD_VERSION\r
59\r
60## CheckConflictOption\r
61#\r
62# CheckConflictOption\r
63#\r
64def CheckConflictOption(Opt):\r
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
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
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
81\r
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
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
93 elif Opt.debug_level != None:\r
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
111 Parser = OptionParser(version=(MSG_VERSION + ' Build ' + gBUILD_VERSION), description=MSG_DESCRIPTION,\r
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
123 Parser.add_option("-i", "--install", action="store", type="string", dest="Install_Distribution_Package_File",\r
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
141 Parser.add_option("-l", "--list", action="store_true", dest="List_Dist_Installed",\r
142 help=ST.HLP_LIST_DIST_INSTALLED)\r
143\r
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
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
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
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
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
174 ("TestDistFiles", Opt.Test_Install_Distribution_Package_Files)\r
175 ]\r
176\r
177 for Var in Var2Var:\r
178 setattr(Opt, Var[0], Var[1])\r
179\r
180 try:\r
181 GlobalData.gWORKSPACE, GlobalData.gPACKAGE_PATH = GetWorkspace()\r
182 except FatalError, XExcept:\r
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
187 # Support WORKSPACE is a long path\r
188 # Only works for windows system\r
189 if pf.system() == 'Windows':\r
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
197\r
198 WorkspaceDir = GlobalData.gWORKSPACE\r
199\r
200 SetLogLevel(Opt)\r
201\r
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
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
231 if not Opt.PackFileToInstall.endswith('.dist'):\r
232 Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToInstall)\r
233\r
234 AbsPath = GetFullPathDist(Opt.PackFileToInstall, WorkspaceDir)\r
235 if not AbsPath:\r
236 Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Opt.PackFileToInstall)\r
237\r
238 Opt.PackFileToInstall = AbsPath\r
239 setattr(Opt, 'PackageFile', Opt.PackFileToInstall)\r
240 RunModule = InstallPkg.Main\r
241\r
242 elif Opt.PackFileToRemove:\r
243 if not Opt.PackFileToRemove.endswith('.dist'):\r
244 Logger.Error("RemovePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToRemove)\r
245 head, tail = os.path.split(Opt.PackFileToRemove)\r
246 if head or not tail:\r
247 Logger.Error("RemovePkg",\r
248 FILE_TYPE_MISMATCH,\r
249 ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REMOVE % Opt.PackFileToRemove)\r
250\r
251 setattr(Opt, 'DistributionFile', Opt.PackFileToRemove)\r
252 RunModule = RmPkg.Main\r
253 elif Opt.InventoryWs:\r
254 RunModule = InventoryWs.Main\r
255\r
256 elif Opt.PackFileToBeReplaced and not Opt.PackFileToReplace:\r
257 Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_U_OPTION)\r
258\r
259 elif Opt.PackFileToReplace:\r
260 if not Opt.PackFileToReplace.endswith('.dist'):\r
261 Logger.Error("ReplacePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToReplace)\r
262 if not Opt.PackFileToBeReplaced:\r
263 Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_O_OPTION)\r
264 if not Opt.PackFileToBeReplaced.endswith('.dist'):\r
265 Logger.Error("ReplacePkg",\r
266 FILE_TYPE_MISMATCH,\r
267 ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToBeReplaced)\r
268\r
269 head, tail = os.path.split(Opt.PackFileToBeReplaced)\r
270 if head or not tail:\r
271 Logger.Error("ReplacePkg",\r
272 FILE_TYPE_MISMATCH,\r
273 ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG % Opt.PackFileToBeReplaced)\r
274\r
275 AbsPath = GetFullPathDist(Opt.PackFileToReplace, WorkspaceDir)\r
276 if not AbsPath:\r
277 Logger.Error("ReplacePkg", FILE_NOT_FOUND, ST.ERR_REPLACE_DIST_NOT_FOUND % Opt.PackFileToReplace)\r
278\r
279 Opt.PackFileToReplace = AbsPath\r
280 RunModule = ReplacePkg.Main\r
281\r
282 elif Opt.Test_Install_Distribution_Package_Files:\r
283 for Dist in Opt.Test_Install_Distribution_Package_Files:\r
284 if not Dist.endswith('.dist'):\r
285 Logger.Error("TestInstall", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Dist)\r
286\r
287 setattr(Opt, 'DistFiles', Opt.Test_Install_Distribution_Package_Files)\r
288 RunModule = TestInstall.Main\r
289\r
290 else:\r
291 Parser.print_usage()\r
292 return OPTION_MISSING\r
293\r
294 ReturnCode = RunModule(Opt)\r
295 except FatalError, XExcept:\r
296 ReturnCode = XExcept.args[0]\r
297 if Logger.GetLevel() <= Logger.DEBUG_9:\r
298 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \\r
299 format_exc())\r
300 finally:\r
301 try:\r
302 if ReturnCode != 0 and ReturnCode != UPT_ALREADY_INSTALLED_ERROR:\r
303 Logger.Quiet(ST.MSG_RECOVER_START)\r
304 GlobalData.gDB.RollBack()\r
305 Mgr.rollback()\r
306 Logger.Quiet(ST.MSG_RECOVER_DONE)\r
307 else:\r
308 GlobalData.gDB.Commit()\r
309 Mgr.commit()\r
310 except StandardError:\r
311 Logger.Quiet(ST.MSG_RECOVER_FAIL)\r
312 GlobalData.gDB.CloseDb()\r
313\r
314 if pf.system() == 'Windows':\r
315 os.system('subst %s /D' % GlobalData.gWORKSPACE.replace('\\',''))\r
316\r
317 return ReturnCode\r
318\r
319## GetFullPathDist\r
320#\r
321# This function will check DistFile existence, if not absolute path, then try current working directory,\r
322# then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None\r
323#\r
324# @param DistFile: The distribution file in either relative path or absolute path\r
325# @param WorkspaceDir: Workspace Directory\r
326# @return AbsPath: The Absolute path of the distribution file if existed, None else\r
327#\r
328def GetFullPathDist(DistFile, WorkspaceDir):\r
329 if os.path.isabs(DistFile):\r
330 if not (os.path.exists(DistFile) and os.path.isfile(DistFile)):\r
331 return None\r
332 else:\r
333 return DistFile\r
334 else:\r
335 AbsPath = os.path.normpath(os.path.join(os.getcwd(), DistFile))\r
336 if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)):\r
337 AbsPath = os.path.normpath(os.path.join(WorkspaceDir, DistFile))\r
338 if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)):\r
339 return None\r
340\r
341 return AbsPath\r
342\r
343if __name__ == '__main__':\r
344 RETVAL = Main()\r
345 #\r
346 # 0-127 is a safe return range, and 1 is a standard default error\r
347 #\r
348 if RETVAL < 0 or RETVAL > 127:\r
349 RETVAL = 1\r
350 sys.exit(RETVAL)\r