]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/Core/PackageFile.py
This patch is going to:
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Core / PackageFile.py
1 ## @file
2 #
3 # PackageFile class represents the zip file of a distribution package.
4 #
5 # Copyright (c) 2011 - 2014, 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 PackageFile
18 '''
19
20 ##
21 # Import Modules
22 #
23 import os.path
24 import zipfile
25 import tempfile
26 import platform
27
28 from Logger.ToolError import FILE_OPEN_FAILURE
29 from Logger.ToolError import FILE_CHECKSUM_FAILURE
30 from Logger.ToolError import FILE_NOT_FOUND
31 from Logger.ToolError import FILE_DECOMPRESS_FAILURE
32 from Logger.ToolError import FILE_UNKNOWN_ERROR
33 from Logger.ToolError import FILE_WRITE_FAILURE
34 from Logger.ToolError import FILE_COMPRESS_FAILURE
35 import Logger.Log as Logger
36 from Logger import StringTable as ST
37 from Library.Misc import CreateDirectory
38 from Library.Misc import RemoveDirectory
39 from Core.FileHook import __FileHookOpen__
40
41
42 class PackageFile:
43 def __init__(self, FileName, Mode="r"):
44 self._FileName = FileName
45 if Mode not in ["r", "w", "a"]:
46 Mode = "r"
47 try:
48 self._ZipFile = zipfile.ZipFile(FileName, Mode, \
49 zipfile.ZIP_DEFLATED)
50 self._Files = {}
51 for Filename in self._ZipFile.namelist():
52 self._Files[os.path.normpath(Filename)] = Filename
53 except BaseException, Xstr:
54 Logger.Error("PackagingTool", FILE_OPEN_FAILURE,
55 ExtraData="%s (%s)" % (FileName, str(Xstr)))
56
57 BadFile = self._ZipFile.testzip()
58 if BadFile != None:
59 Logger.Error("PackagingTool", FILE_CHECKSUM_FAILURE,
60 ExtraData="[%s] in %s" % (BadFile, FileName))
61
62 def GetZipFile(self):
63 return self._ZipFile
64
65 ## Get file name
66 #
67 def __str__(self):
68 return self._FileName
69
70 ## Extract the file
71 #
72 # @param To: the destination file
73 #
74 def Unpack(self, ToDest):
75 for FileN in self._ZipFile.namelist():
76 ToFile = os.path.normpath(os.path.join(ToDest, FileN))
77 Msg = "%s -> %s" % (FileN, ToFile)
78 Logger.Info(Msg)
79 self.Extract(FileN, ToFile)
80
81 ## Extract the file
82 #
83 # @param File: the extracted file
84 # @param ToFile: the destination file
85 #
86 def UnpackFile(self, File, ToFile):
87 File = File.replace('\\', '/')
88 if File in self._ZipFile.namelist():
89 Msg = "%s -> %s" % (File, ToFile)
90 Logger.Info(Msg)
91 self.Extract(File, ToFile)
92 return ToFile
93
94 return ''
95
96 ## Extract the file
97 #
98 # @param Which: the source path
99 # @param ToDest: the destination path
100 #
101 def Extract(self, Which, ToDest):
102 Which = os.path.normpath(Which)
103 if Which not in self._Files:
104 Logger.Error("PackagingTool", FILE_NOT_FOUND,
105 ExtraData="[%s] in %s" % (Which, self._FileName))
106 try:
107 FileContent = self._ZipFile.read(self._Files[Which])
108 except BaseException, Xstr:
109 Logger.Error("PackagingTool", FILE_DECOMPRESS_FAILURE,
110 ExtraData="[%s] in %s (%s)" % (Which, \
111 self._FileName, \
112 str(Xstr)))
113 try:
114 CreateDirectory(os.path.dirname(ToDest))
115 if os.path.exists(ToDest) and not os.access(ToDest, os.W_OK):
116 Logger.Warn("PackagingTool", \
117 ST.WRN_FILE_NOT_OVERWRITTEN % ToDest)
118 return
119 else:
120 ToFile = __FileHookOpen__(ToDest, 'wb')
121 except BaseException, Xstr:
122 Logger.Error("PackagingTool", FILE_OPEN_FAILURE,
123 ExtraData="%s (%s)" % (ToDest, str(Xstr)))
124
125 try:
126 ToFile.write(FileContent)
127 ToFile.close()
128 except BaseException, Xstr:
129 Logger.Error("PackagingTool", FILE_WRITE_FAILURE,
130 ExtraData="%s (%s)" % (ToDest, str(Xstr)))
131
132 ## Remove the file
133 #
134 # @param Files: the removed files
135 #
136 def Remove(self, Files):
137 TmpDir = os.path.join(tempfile.gettempdir(), ".packaging")
138 if os.path.exists(TmpDir):
139 RemoveDirectory(TmpDir, True)
140
141 os.mkdir(TmpDir)
142 self.Unpack(TmpDir)
143 for SinF in Files:
144 SinF = os.path.normpath(SinF)
145 if SinF not in self._Files:
146 Logger.Error("PackagingTool", FILE_NOT_FOUND,
147 ExtraData="%s is not in %s!" % \
148 (SinF, self._FileName))
149 self._Files.pop(SinF)
150 self._ZipFile.close()
151
152 self._ZipFile = zipfile.ZipFile(self._FileName, "w", \
153 zipfile.ZIP_DEFLATED)
154 Cwd = os.getcwd()
155 os.chdir(TmpDir)
156 self.PackFiles(self._Files)
157 os.chdir(Cwd)
158 RemoveDirectory(TmpDir, True)
159
160 ## Pack the files under Top directory, the directory shown in the zipFile start from BaseDir,
161 # BaseDir should be the parent directory of the Top directory, for example,
162 # Pack(Workspace\Dir1, Workspace) will pack files under Dir1, and the path in the zipfile will
163 # start from Workspace
164 #
165 # @param Top: the top directory
166 # @param BaseDir: the base directory
167 #
168 def Pack(self, Top, BaseDir):
169 if not os.path.isdir(Top):
170 Logger.Error("PackagingTool", FILE_UNKNOWN_ERROR, \
171 "%s is not a directory!" %Top)
172
173 FilesToPack = []
174 Cwd = os.getcwd()
175 os.chdir(BaseDir)
176 RelaDir = Top[Top.upper().find(BaseDir.upper()).\
177 join(len(BaseDir).join(1)):]
178
179 for Root, Dirs, Files in os.walk(RelaDir):
180 if 'CVS' in Dirs:
181 Dirs.remove('CVS')
182 if '.svn' in Dirs:
183 Dirs.remove('.svn')
184
185 for Dir in Dirs:
186 if Dir.startswith('.'):
187 Dirs.remove(Dir)
188 for File1 in Files:
189 if File1.startswith('.'):
190 continue
191 ExtName = os.path.splitext(File1)[1]
192 #
193 # skip '.dec', '.inf', '.dsc', '.fdf' files
194 #
195 if ExtName.lower() in ['.dec', '.inf', '.dsc', '.fdf']:
196 continue
197 FilesToPack.append(os.path.join(Root, File1))
198 self.PackFiles(FilesToPack)
199 os.chdir(Cwd)
200
201 ## Pack the file
202 #
203 # @param Files: the files to pack
204 #
205 def PackFiles(self, Files):
206 for File1 in Files:
207 self.PackFile(File1)
208
209 ## Pack the file
210 #
211 # @param File: the files to pack
212 # @param ArcName: the Arc Name
213 #
214 def PackFile(self, File, ArcName=None):
215 try:
216 #
217 # avoid packing same file multiple times
218 #
219 if platform.system() != 'Windows':
220 File = File.replace('\\', '/')
221 ZipedFilesNameList = self._ZipFile.namelist()
222 for ZipedFile in ZipedFilesNameList:
223 if File == os.path.normpath(ZipedFile):
224 return
225 Logger.Info("packing ..." + File)
226 self._ZipFile.write(File, ArcName)
227 except BaseException, Xstr:
228 Logger.Error("PackagingTool", FILE_COMPRESS_FAILURE,
229 ExtraData="%s (%s)" % (File, str(Xstr)))
230
231 ## Write data to the packed file
232 #
233 # @param Data: data to write
234 # @param ArcName: the Arc Name
235 #
236 def PackData(self, Data, ArcName):
237 try:
238 if os.path.splitext(ArcName)[1].lower() == '.pkg':
239 Data = Data.encode('utf_8')
240 self._ZipFile.writestr(ArcName, Data)
241 except BaseException, Xstr:
242 Logger.Error("PackagingTool", FILE_COMPRESS_FAILURE,
243 ExtraData="%s (%s)" % (ArcName, str(Xstr)))
244
245 ## Close file
246 #
247 #
248 def Close(self):
249 self._ZipFile.close()
250
251
252