1## @file
2# This file is used to define a class object to describe a distribution package
3#
4# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
5#
6# This program and the accompanying materials are licensed and made available
7# under the terms and conditions of the BSD License which accompanies this
8# distribution. The full text of the license may be found at
9# http://opensource.org/licenses/bsd-license.php
10#
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14'''
15DistributionPackageClass
16'''
17
18##
19# Import Modules
20#
21import os.path
22
23from Library.Misc import Sdict
24from Library.Misc import GetNonMetaDataFiles
25from PomAdapter.InfPomAlignment import InfPomAlignment
26from PomAdapter.DecPomAlignment import DecPomAlignment
27import Logger.Log as Logger
28from Logger import StringTable as ST
29from Logger.ToolError import OPTION_VALUE_INVALID
30from Logger.ToolError import FatalError
31from Logger.ToolError import EDK1_INF_ERROR
32from Object.POM.CommonObject import IdentificationObject
33from Object.POM.CommonObject import CommonHeaderObject
34from Object.POM.CommonObject import MiscFileObject
35from Common.MultipleWorkspace import MultipleWorkspace as mws
36
37## DistributionPackageHeaderClass
38#
39# @param IdentificationObject: Identification Object
40# @param CommonHeaderObject: Common Header Object
41#
42class DistributionPackageHeaderObject(IdentificationObject, \
43                                      CommonHeaderObject):
44    def __init__(self):
45        IdentificationObject.__init__(self)
46        CommonHeaderObject.__init__(self)
47        self.ReadOnly = ''
48        self.RePackage = ''
49        self.Vendor = ''
50        self.Date = ''
51        self.Signature = 'Md5Sum'
52        self.XmlSpecification = ''
53
54    def GetReadOnly(self):
55        return self.ReadOnly
56
57    def SetReadOnly(self, ReadOnly):
58        self.ReadOnly = ReadOnly
59
60    def GetRePackage(self):
61        return self.RePackage
62
63    def SetRePackage(self, RePackage):
64        self.RePackage = RePackage
65
66    def GetVendor(self):
67        return self.Vendor
68
69    def SetDate(self, Date):
70        self.Date = Date
71
72    def GetDate(self):
73        return self.Date
74
75    def SetSignature(self, Signature):
76        self.Signature = Signature
77
78    def GetSignature(self):
79        return self.Signature
80
81    def SetXmlSpecification(self, XmlSpecification):
82        self.XmlSpecification = XmlSpecification
83
84    def GetXmlSpecification(self):
85        return self.XmlSpecification
86
87## DistributionPackageClass
88#
89# @param object: DistributionPackageClass
90#
91class DistributionPackageClass(object):
92    def __init__(self):
93        self.Header = DistributionPackageHeaderObject()
94        #
95        # {(Guid, Version, Path) : PackageObj}
96        #
97        self.PackageSurfaceArea = Sdict()
98        #
99        # {(Guid, Version, Name, Path) : ModuleObj}
100        #
101        self.ModuleSurfaceArea = Sdict()
102        self.Tools = MiscFileObject()
103        self.MiscellaneousFiles = MiscFileObject()
104        self.UserExtensions = []
105        self.FileList = []
106
107    ## Get all included packages and modules for a distribution package
108    #
109    # @param WorkspaceDir:  WorkspaceDir
110    # @param PackageList:   A list of all packages
111    # @param ModuleList:    A list of all modules
112    #
113    def GetDistributionPackage(self, WorkspaceDir, PackageList, ModuleList):
114        # Backup WorkspaceDir
115        Root = WorkspaceDir
116
117        #
118        # Get Packages
119        #
120        if PackageList:
121            for PackageFile in PackageList:
122                PackageFileFullPath = mws.join(Root, PackageFile)
123                WorkspaceDir = mws.getWs(Root, PackageFile)
124                DecObj = DecPomAlignment(PackageFileFullPath, WorkspaceDir, CheckMulDec=True)
125                PackageObj = DecObj
126                #
127                # Parser inf file one bye one
128                #
129                ModuleInfFileList = PackageObj.GetModuleFileList()
130                for File in ModuleInfFileList:
131                    WsRelPath = os.path.join(PackageObj.GetPackagePath(), File)
132                    WsRelPath = os.path.normpath(WsRelPath)
133                    if ModuleList and WsRelPath in ModuleList:
134                        Logger.Error("UPT",
135                                     OPTION_VALUE_INVALID,
136                                     ST.ERR_NOT_STANDALONE_MODULE_ERROR%\
137                                     (WsRelPath, PackageFile))
138                    Filename = os.path.normpath\
139                    (os.path.join(PackageObj.GetRelaPath(), File))
140                    os.path.splitext(Filename)
141                    #
142                    # Call INF parser to generate Inf Object.
143                    # Actually, this call is not directly call, but wrapped by
144                    # Inf class in InfPomAlignment.
145                    #
146                    try:
147                        ModuleObj = InfPomAlignment(Filename, WorkspaceDir, PackageObj.GetPackagePath())
148
149                        #
150                        # Add module to package
151                        #
152                        ModuleDict = PackageObj.GetModuleDict()
153                        ModuleDict[(ModuleObj.GetGuid(), \
154                                    ModuleObj.GetVersion(), \
155                                    ModuleObj.GetName(), \
156                                    ModuleObj.GetCombinePath())] = ModuleObj
157                        PackageObj.SetModuleDict(ModuleDict)
158                    except FatalError, ErrCode:
159                        if ErrCode.message == EDK1_INF_ERROR:
160                            Logger.Warn("UPT",
161                                        ST.WRN_EDK1_INF_FOUND%Filename)
162                        else:
163                            raise
164
165                self.PackageSurfaceArea\
166                [(PackageObj.GetGuid(), PackageObj.GetVersion(), \
167                  PackageObj.GetCombinePath())] = PackageObj
168
169        #
170        # Get Modules
171        #
172        if ModuleList:
173            for ModuleFile in ModuleList:
174                ModuleFileFullPath = mws.join(Root, ModuleFile)
175                WorkspaceDir = mws.getWs(Root, ModuleFile)
176
177                try:
178                    ModuleObj = InfPomAlignment(ModuleFileFullPath, WorkspaceDir)
179                    ModuleKey = (ModuleObj.GetGuid(),
180                                 ModuleObj.GetVersion(),
181                                 ModuleObj.GetName(),
182                                 ModuleObj.GetCombinePath())
183                    self.ModuleSurfaceArea[ModuleKey] = ModuleObj
184                except FatalError, ErrCode:
185                    if ErrCode.message == EDK1_INF_ERROR:
186                        Logger.Error("UPT",
187                                     EDK1_INF_ERROR,
188                                     ST.WRN_EDK1_INF_FOUND%ModuleFileFullPath,
189                                     ExtraData=ST.ERR_NOT_SUPPORTED_SA_MODULE)
190                    else:
191                        raise
192
193        # Recover WorkspaceDir
194        WorkspaceDir = Root
195
196    ## Get all files included for a distribution package, except tool/misc of
197    # distribution level
198    #
199    # @retval DistFileList  A list of filepath for NonMetaDataFile, relative to workspace
200    # @retval MetaDataFileList  A list of filepath for MetaDataFile, relative to workspace
201    #
202    def GetDistributionFileList(self):
203        MetaDataFileList = []
204        SkipModulesUniList = []
205
206        for Guid, Version, Path in self.PackageSurfaceArea:
207            Package = self.PackageSurfaceArea[Guid, Version, Path]
208            PackagePath = Package.GetPackagePath()
209            FullPath = Package.GetFullPath()
210            MetaDataFileList.append(Path)
211            IncludePathList = Package.GetIncludePathList()
212            for IncludePath in IncludePathList:
213                SearchPath = os.path.normpath(os.path.join(os.path.dirname(FullPath), IncludePath))
214                AddPath = os.path.normpath(os.path.join(PackagePath, IncludePath))
215                self.FileList += GetNonMetaDataFiles(SearchPath, ['CVS', '.svn'], False, AddPath)
216            #
217            # Add the miscellaneous files on DEC file
218            #
219            for MiscFileObj in Package.GetMiscFileList():
220                for FileObj in MiscFileObj.GetFileList():
221                    MiscFileFullPath = os.path.normpath(os.path.join(PackagePath, FileObj.GetURI()))
222                    if MiscFileFullPath not in self.FileList:
223                        self.FileList.append(MiscFileFullPath)
224
225            Module = None
226            ModuleDict = Package.GetModuleDict()
227            for Guid, Version, Name, Path in ModuleDict:
228                Module = ModuleDict[Guid, Version, Name, Path]
229                ModulePath = Module.GetModulePath()
230                FullPath = Module.GetFullPath()
231                PkgRelPath = os.path.normpath(os.path.join(PackagePath, ModulePath))
232                MetaDataFileList.append(Path)
233                SkipList = ['CVS', '.svn']
234                NonMetaDataFileList = []
235                if Module.UniFileClassObject:
236                    for UniFile in Module.UniFileClassObject.IncFileList:
237                        OriPath = os.path.normpath(os.path.dirname(FullPath))
238                        UniFilePath = os.path.normpath(os.path.join(PkgRelPath, UniFile.Path[len(OriPath) + 1:]))
239                        if UniFilePath not in SkipModulesUniList:
240                            SkipModulesUniList.append(UniFilePath)
241                    for IncludeFile in Module.UniFileClassObject.IncludePathList:
242                        if IncludeFile not in SkipModulesUniList:
243                            SkipModulesUniList.append(IncludeFile)
244                NonMetaDataFileList = GetNonMetaDataFiles(os.path.dirname(FullPath), SkipList, False, PkgRelPath)
245                for NonMetaDataFile in NonMetaDataFileList:
246                    if NonMetaDataFile not in self.FileList:
247                        self.FileList.append(NonMetaDataFile)
248        for Guid, Version, Name, Path in self.ModuleSurfaceArea:
249            Module = self.ModuleSurfaceArea[Guid, Version, Name, Path]
250            ModulePath = Module.GetModulePath()
251            FullPath = Module.GetFullPath()
252            MetaDataFileList.append(Path)
253            SkipList = ['CVS', '.svn']
254            NonMetaDataFileList = []
255            if Module.UniFileClassObject:
256                for UniFile in Module.UniFileClassObject.IncFileList:
257                    OriPath = os.path.normpath(os.path.dirname(FullPath))
258                    UniFilePath = os.path.normpath(os.path.join(ModulePath, UniFile.Path[len(OriPath) + 1:]))
259                    if UniFilePath not in SkipModulesUniList:
260                        SkipModulesUniList.append(UniFilePath)
261            NonMetaDataFileList = GetNonMetaDataFiles(os.path.dirname(FullPath), SkipList, False, ModulePath)
262            for NonMetaDataFile in NonMetaDataFileList:
263                if NonMetaDataFile not in self.FileList:
264                    self.FileList.append(NonMetaDataFile)
265
266        for SkipModuleUni in SkipModulesUniList:
267            if SkipModuleUni in self.FileList:
268                self.FileList.remove(SkipModuleUni)
269
270        return  self.FileList, MetaDataFileList
271
272
273
274