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