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