]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/UPT.py
BaseTools/UPT: Support Unicode path
[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
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
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
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
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
4234283c
LG
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
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
231 if not Opt.PackFileToInstall.endswith('.dist'):\r
232 Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToInstall)\r
421ccda3
HC
233\r
234 AbsPath = GetFullPathDist(Opt.PackFileToInstall, WorkspaceDir)\r
235 if not AbsPath:\r
4234283c
LG
236 Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Opt.PackFileToInstall)\r
237\r
421ccda3 238 Opt.PackFileToInstall = AbsPath\r
4234283c
LG
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
421ccda3
HC
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
6cf99034
HC
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
4234283c
LG
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
421ccda3 301 try:\r
af0c61ae 302 if ReturnCode != 0 and ReturnCode != UPT_ALREADY_INSTALLED_ERROR:\r
421ccda3
HC
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
4234283c 312 GlobalData.gDB.CloseDb()\r
c03f5b2c 313\r
421ccda3 314 if pf.system() == 'Windows':\r
c03f5b2c 315 os.system('subst %s /D' % GlobalData.gWORKSPACE.replace('\\',''))\r
4234283c
LG
316\r
317 return ReturnCode\r
318\r
421ccda3
HC
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
4234283c
LG
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