]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/MkPkg.py
3c2771f881bb21ad8289afd4ff0c50314e6525f1
[mirror_edk2.git] / BaseTools / Source / Python / UPT / MkPkg.py
1 ## @file
2 # Install distribution package.
3 #
4 # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
5 #
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
7 #
8
9 '''
10 MkPkg
11 '''
12
13 ##
14 # Import Modules
15 #
16 from os import remove
17 from os import getcwd
18 from os import chdir
19 import os.path
20 from sys import stdin
21 from sys import platform
22 from traceback import format_exc
23 from platform import python_version
24 from hashlib import md5
25 from time import strftime
26 from time import localtime
27 from uuid import uuid4
28
29 from Logger import StringTable as ST
30 from Logger.ToolError import OPTION_UNKNOWN_ERROR
31 from Logger.ToolError import OPTION_VALUE_INVALID
32 from Logger.ToolError import ABORT_ERROR
33 from Logger.ToolError import UPT_REPKG_ERROR
34 from Logger.ToolError import CODE_ERROR
35 from Logger.ToolError import FatalError
36 from Logger.ToolError import FILE_NOT_FOUND
37 import Logger.Log as Logger
38
39 from Xml.XmlParser import DistributionPackageXml
40 from Xml.IniToXml import IniToXml
41
42 from Library import GlobalData
43 from Library.ParserValidate import IsValidPath
44
45 from Core.DistributionPackageClass import DistributionPackageClass
46 from Core.PackageFile import PackageFile
47 from Common.MultipleWorkspace import MultipleWorkspace as mws
48
49 ## CheckForExistingDp
50 #
51 # Check if there is a same name DP file existing
52 # @param Path: The path to be checked
53 #
54 def CheckForExistingDp(Path):
55 if os.path.exists(Path):
56 Logger.Info(ST.MSG_DISTRIBUTION_PACKAGE_FILE_EXISTS % Path)
57 Input = stdin.readline()
58 Input = Input.replace('\r', '').replace('\n', '')
59 if Input.upper() != "Y":
60 Logger.Error("\nMkPkg", ABORT_ERROR, ST.ERR_USER_ABORT, RaiseError=True)
61
62 ## Tool entrance method
63 #
64 # This method mainly dispatch specific methods per the command line options.
65 # If no error found, return zero value so the caller of this tool can know
66 # if it's executed successfully or not.
67 #
68 #
69 def Main(Options = None):
70 if Options is None:
71 Logger.Error("\nMkPkg", OPTION_UNKNOWN_ERROR, ST.ERR_OPTION_NOT_FOUND)
72 try:
73 DataBase = GlobalData.gDB
74 ContentFileClosed = True
75 WorkspaceDir = GlobalData.gWORKSPACE
76
77 #
78 # Init PackFileToCreate
79 #
80 if not Options.PackFileToCreate:
81 Logger.Error("\nMkPkg", OPTION_UNKNOWN_ERROR, ST.ERR_OPTION_NOT_FOUND)
82
83 #
84 # Handle if the distribution package file already exists
85 #
86 CheckForExistingDp(Options.PackFileToCreate)
87
88 #
89 # Check package file existing and valid
90 #
91 CheckFileList('.DEC', Options.PackageFileList, ST.ERR_INVALID_PACKAGE_NAME, ST.ERR_INVALID_PACKAGE_PATH)
92 #
93 # Check module file existing and valid
94 #
95 CheckFileList('.INF', Options.ModuleFileList, ST.ERR_INVALID_MODULE_NAME, ST.ERR_INVALID_MODULE_PATH)
96
97 #
98 # Get list of files that installed with RePackage attribute available
99 #
100 RePkgDict = DataBase.GetRePkgDict()
101
102 ContentFile = PackageFile(GlobalData.gCONTENT_FILE, "w")
103 ContentFileClosed = False
104
105 #
106 # Add temp distribution header
107 #
108 if Options.PackageInformationDataFile:
109 XmlFile = IniToXml(Options.PackageInformationDataFile)
110 DistPkg = DistributionPackageXml().FromXml(XmlFile)
111 remove(XmlFile)
112
113 #
114 # add distribution level tool/misc files
115 # before pack, current dir should be workspace dir, else the full
116 # path will be in the pack file
117 #
118 Cwd = getcwd()
119 chdir(WorkspaceDir)
120 ToolObject = DistPkg.Tools
121 MiscObject = DistPkg.MiscellaneousFiles
122 FileList = []
123 if ToolObject:
124 FileList += ToolObject.GetFileList()
125 if MiscObject:
126 FileList += MiscObject.GetFileList()
127 for FileObject in FileList:
128 #
129 # If you have unicode file names, please convert them to byte
130 # strings in your desired encoding before passing them to
131 # write().
132 #
133 FromFile = os.path.normpath(FileObject.GetURI()).encode('utf_8')
134 FileFullPath = mws.join(WorkspaceDir, FromFile)
135 if FileFullPath in RePkgDict:
136 (DpGuid, DpVersion, DpName, Repackage) = RePkgDict[FileFullPath]
137 if not Repackage:
138 Logger.Error("\nMkPkg",
139 UPT_REPKG_ERROR,
140 ST.ERR_UPT_REPKG_ERROR,
141 ExtraData=ST.MSG_REPKG_CONFLICT %\
142 (FileFullPath, DpGuid, DpVersion, DpName)
143 )
144 else:
145 DistPkg.Header.RePackage = True
146 ContentFile.PackFile(FromFile)
147 chdir(Cwd)
148
149 #
150 # Add init dp information
151 #
152 else:
153 DistPkg = DistributionPackageClass()
154 DistPkg.Header.Name = 'Distribution Package'
155 DistPkg.Header.Guid = str(uuid4())
156 DistPkg.Header.Version = '1.0'
157
158 DistPkg.GetDistributionPackage(WorkspaceDir, Options.PackageFileList, \
159 Options.ModuleFileList)
160 FileList, MetaDataFileList = DistPkg.GetDistributionFileList()
161 for File in FileList + MetaDataFileList:
162 FileFullPath = os.path.normpath(os.path.join(WorkspaceDir, File))
163 #
164 # check whether file was included in a distribution that can not
165 # be repackaged
166 #
167 if FileFullPath in RePkgDict:
168 (DpGuid, DpVersion, DpName, Repackage) = RePkgDict[FileFullPath]
169 if not Repackage:
170 Logger.Error("\nMkPkg",
171 UPT_REPKG_ERROR,
172 ST.ERR_UPT_REPKG_ERROR,
173 ExtraData = \
174 ST.MSG_REPKG_CONFLICT %(FileFullPath, DpName, \
175 DpGuid, DpVersion)
176 )
177 else:
178 DistPkg.Header.RePackage = True
179
180 Cwd = getcwd()
181 chdir(WorkspaceDir)
182 ContentFile.PackFiles(FileList)
183 chdir(Cwd)
184
185 Logger.Verbose(ST.MSG_COMPRESS_DISTRIBUTION_PKG)
186
187 ContentFile.Close()
188 ContentFileClosed = True
189
190 #
191 # Add Md5Signature
192 #
193 DistPkg.Header.Signature = md5(open(str(ContentFile), 'rb').read()).hexdigest()
194 #
195 # Add current Date
196 #
197 DistPkg.Header.Date = str(strftime("%Y-%m-%dT%H:%M:%S", localtime()))
198
199 #
200 # Finish final dp file
201 #
202 DistPkgFile = PackageFile(Options.PackFileToCreate, "w")
203 DistPkgFile.PackFile(str(ContentFile))
204 DistPkgXml = DistributionPackageXml()
205 DistPkgFile.PackData(DistPkgXml.ToXml(DistPkg), GlobalData.gDESC_FILE)
206 DistPkgFile.Close()
207 Logger.Quiet(ST.MSG_FINISH)
208 ReturnCode = 0
209
210 except FatalError as XExcept:
211 ReturnCode = XExcept.args[0]
212 if Logger.GetLevel() <= Logger.DEBUG_9:
213 Logger.Quiet(ST.MSG_PYTHON_ON % \
214 (python_version(), platform) + format_exc())
215 except KeyboardInterrupt:
216 ReturnCode = ABORT_ERROR
217 if Logger.GetLevel() <= Logger.DEBUG_9:
218 Logger.Quiet(ST.MSG_PYTHON_ON % \
219 (python_version(), platform) + format_exc())
220 except OSError:
221 pass
222 except:
223 Logger.Error(
224 "\nMkPkg",
225 CODE_ERROR,
226 ST.ERR_UNKNOWN_FATAL_CREATING_ERR % \
227 Options.PackFileToCreate,
228 ExtraData=ST.MSG_SEARCH_FOR_HELP,
229 RaiseError=False
230 )
231 Logger.Quiet(ST.MSG_PYTHON_ON % \
232 (python_version(), platform) + format_exc())
233 ReturnCode = CODE_ERROR
234 finally:
235 if os.path.exists(GlobalData.gCONTENT_FILE):
236 if not ContentFileClosed:
237 ContentFile.Close()
238 os.remove(GlobalData.gCONTENT_FILE)
239
240 return ReturnCode
241
242
243 ## CheckFileList
244 #
245 # @param QualifiedExt: QualifiedExt
246 # @param FileList: FileList
247 # @param ErrorStringExt: ErrorStringExt
248 # @param ErrorStringFullPath: ErrorStringFullPath
249 #
250 def CheckFileList(QualifiedExt, FileList, ErrorStringExt, ErrorStringFullPath):
251 if not FileList:
252 return
253 WorkspaceDir = GlobalData.gWORKSPACE
254 WorkspaceDir = os.path.normpath(WorkspaceDir)
255 for Item in FileList:
256 Ext = os.path.splitext(Item)[1]
257 if Ext.upper() != QualifiedExt.upper():
258 Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \
259 ErrorStringExt % Item)
260
261 Item = os.path.normpath(Item)
262 Path = mws.join(WorkspaceDir, Item)
263 if not os.path.exists(Path):
264 Logger.Error("\nMkPkg", FILE_NOT_FOUND, ST.ERR_NOT_FOUND % Item)
265 elif Item == Path:
266 Logger.Error("\nMkPkg", OPTION_VALUE_INVALID,
267 ErrorStringFullPath % Item)
268 elif not IsValidPath(Item, WorkspaceDir):
269 Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \
270 ErrorStringExt % Item)
271
272 if not os.path.split(Item)[0]:
273 Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \
274 ST.ERR_INVALID_METAFILE_PATH % Item)