]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/Core/PackageFile.py
Sync BaseTools Branch (version r2271) to EDKII main trunk.
[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, 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
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 To: 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 ToFile = open(ToDest, "wb")
120 except BaseException, Xstr:
121 Logger.Error("PackagingTool", FILE_OPEN_FAILURE,
122 ExtraData="%s (%s)" % (ToDest, str(Xstr)))
123
124 try:
125 ToFile.write(FileContent)
126 ToFile.close()
127 except BaseException, Xstr:
128 Logger.Error("PackagingTool", FILE_WRITE_FAILURE,
129 ExtraData="%s (%s)" % (ToDest, str(Xstr)))
130
131 ## Remove the file
132 #
133 # @param Files: the removed files
134 #
135 def Remove(self, Files):
136 TmpDir = os.path.join(tempfile.gettempdir(), ".packaging")
137 if os.path.exists(TmpDir):
138 RemoveDirectory(TmpDir, True)
139
140 os.mkdir(TmpDir)
141 self.Unpack(TmpDir)
142 for SinF in Files:
143 SinF = os.path.normpath(SinF)
144 if SinF not in self._Files:
145 Logger.Error("PackagingTool", FILE_NOT_FOUND,
146 ExtraData="%s is not in %s!" % \
147 (SinF, self._FileName))
148 self._Files.pop(SinF)
149 self._ZipFile.close()
150
151 self._ZipFile = zipfile.ZipFile(self._FileName, "w", \
152 zipfile.ZIP_DEFLATED)
153 Cwd = os.getcwd()
154 os.chdir(TmpDir)
155 self.PackFiles(self._Files)
156 os.chdir(Cwd)
157 RemoveDirectory(TmpDir, True)
158
159 ## Pack the files under Top directory, the directory shown in the zipFile start from BaseDir,
160 # BaseDir should be the parent directory of the Top directory, for example,
161 # Pack(Workspace\Dir1, Workspace) will pack files under Dir1, and the path in the zipfile will
162 # start from Workspace
163 #
164 # @param Top: the top directory
165 # @param BaseDir: the base directory
166 #
167 def Pack(self, Top, BaseDir):
168 if not os.path.isdir(Top):
169 Logger.Error("PackagingTool", FILE_UNKNOWN_ERROR, \
170 "%s is not a directory!" %Top)
171
172 FilesToPack = []
173 Cwd = os.getcwd()
174 os.chdir(BaseDir)
175 RelaDir = Top[Top.upper().find(BaseDir.upper()).\
176 join(len(BaseDir).join(1)):]
177
178 for Root, Dirs, Files in os.walk(RelaDir):
179 if 'CVS' in Dirs:
180 Dirs.remove('CVS')
181 if '.svn' in Dirs:
182 Dirs.remove('.svn')
183
184 for Dir in Dirs:
185 if Dir.startswith('.'):
186 Dirs.remove(Dir)
187 for File1 in Files:
188 if File1.startswith('.'):
189 continue
190 ExtName = os.path.splitext(File1)[1]
191 #
192 # skip '.dec', '.inf', '.dsc', '.fdf' files
193 #
194 if ExtName.lower() in ['.dec', '.inf', '.dsc', '.fdf']:
195 continue
196 FilesToPack.append(os.path.join(Root, File1))
197 self.PackFiles(FilesToPack)
198 os.chdir(Cwd)
199
200 ## Pack the file
201 #
202 # @param Files: the files to pack
203 #
204 def PackFiles(self, Files):
205 for File1 in Files:
206 self.PackFile(File1)
207
208 ## Pack the file
209 #
210 # @param File: the files to pack
211 # @param ArcName: the Arc Name
212 #
213 def PackFile(self, File, ArcName=None):
214 try:
215 #
216 # avoid packing same file multiple times
217 #
218 if platform.system() != 'Windows':
219 File = File.replace('\\', '/')
220 ZipedFilesNameList = self._ZipFile.namelist()
221 for ZipedFile in ZipedFilesNameList:
222 if File == os.path.normpath(ZipedFile):
223 return
224 Logger.Info("packing ..." + File)
225 self._ZipFile.write(File, ArcName)
226 except BaseException, Xstr:
227 Logger.Error("PackagingTool", FILE_COMPRESS_FAILURE,
228 ExtraData="%s (%s)" % (File, str(Xstr)))
229
230 ## Write data to the packed file
231 #
232 # @param Data: data to write
233 # @param ArcName: the Arc Name
234 #
235 def PackData(self, Data, ArcName):
236 try:
237 self._ZipFile.writestr(ArcName, Data)
238 except BaseException, Xstr:
239 Logger.Error("PackagingTool", FILE_COMPRESS_FAILURE,
240 ExtraData="%s (%s)" % (ArcName, str(Xstr)))
241
242 ## Close file
243 #
244 #
245 def Close(self):
246 self._ZipFile.close()
247
248
249