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