2 # This file is for installed package information database operations
4 # Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
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
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.
24 from os
import environ
25 from os
.path
import dirname
27 import Logger
.Log
as Logger
28 from Logger
import StringTable
as ST
29 from Library
.Parsing
import GetWorkspacePackage
30 from Library
.Parsing
import GetWorkspaceModule
31 from PomAdapter
.InfPomAlignment
import InfPomAlignment
32 from Logger
.ToolError
import FatalError
33 from Logger
.ToolError
import EDK1_INF_ERROR
34 from Logger
.ToolError
import UNKNOWN_ERROR
35 (DEPEX_CHECK_SUCCESS
, DEPEX_CHECK_MODULE_NOT_FOUND
, \
36 DEPEX_CHECK_PACKAGE_NOT_FOUND
, DEPEX_CHECK_DP_NOT_FOUND
) = (0, 1, 2, 3)
41 # This class represents the installed package information database
42 # Add/Remove/Get installed distribution package information here.
45 # @param object: Inherited from object class
47 class DependencyRules(object):
48 def __init__(self
, Datab
):
50 self
.WsPkgList
= GetWorkspacePackage()
51 self
.WsModuleList
= GetWorkspaceModule()
53 ## Check whether a module exists in current workspace.
55 # @param Guid: Guid of a module
56 # @param Version: Version of a module
58 def CheckModuleExists(self
, Guid
, Version
, Name
, Path
, ReturnCode
=DEPEX_CHECK_SUCCESS
):
61 Logger
.Verbose(ST
.MSG_CHECK_MODULE_EXIST
)
62 ModuleList
= self
.IpiDb
.GetModInPackage(Guid
, Version
, Name
, Path
)
63 ModuleList
.extend(self
.IpiDb
.GetStandaloneModule(Guid
, Version
, Name
, Path
))
64 Logger
.Verbose(ST
.MSG_CHECK_MODULE_EXIST_FINISH
)
65 if len(ModuleList
) > 0:
70 ## Check whether a module depex satisfied by current workspace or dist.
72 # @param ModuleObj: A module object
73 # @param DpObj: A depex object
75 def CheckModuleDepexSatisfied(self
, ModuleObj
, DpObj
=None, \
76 ReturnCode
=DEPEX_CHECK_SUCCESS
):
79 Logger
.Verbose(ST
.MSG_CHECK_MODULE_DEPEX_START
)
82 if ModuleObj
.GetPackageDependencyList():
83 Dep
= ModuleObj
.GetPackageDependencyList()[0]
84 for Dep
in ModuleObj
.GetPackageDependencyList():
86 # first check whether the dependency satisfied by current workspace
88 Exist
= self
.CheckPackageExists(Dep
.GetGuid(), Dep
.GetVersion())
90 # check whether satisfied by current distribution
96 for GuidVerPair
in DpObj
.PackageSurfaceArea
.keys():
97 if Dep
.GetGuid() == GuidVerPair
[0]:
98 if Dep
.GetVersion() == None or \
99 len(Dep
.GetVersion()) == 0:
102 if Dep
.GetVersion() == GuidVerPair
[1]:
110 Logger
.Error("CheckModuleDepex", UNKNOWN_ERROR
, \
111 ST
.ERR_DEPENDENCY_NOT_MATCH
% (ModuleObj
.GetName(), \
112 Dep
.GetPackageFilePath(), \
117 ## Check whether a package exists in current workspace.
119 # @param Guid: Guid of a package
120 # @param Version: Version of a package
122 def CheckPackageExists(self
, Guid
, Version
):
123 Logger
.Verbose(ST
.MSG_CHECK_PACKAGE_START
)
124 for (PkgName
, PkgGuid
, PkgVer
, PkgPath
) in self
.WsPkgList
:
125 if PkgName
or PkgPath
:
127 if (PkgGuid
== Guid
):
129 # if version is not empty and not equal, then not match
131 if Version
and (PkgVer
!= Version
):
138 Logger
.Verbose(ST
.MSG_CHECK_PACKAGE_FINISH
)
140 ## Check whether a package depex satisfied by current workspace.
142 # @param PkgObj: A package object
143 # @param DpObj: A package depex object
145 def CheckPackageDepexSatisfied(self
, PkgObj
, DpObj
=None, \
146 ReturnCode
=DEPEX_CHECK_SUCCESS
):
148 ModuleDict
= PkgObj
.GetModuleDict()
149 for ModKey
in ModuleDict
.keys():
150 ModObj
= ModuleDict
[ModKey
]
151 if self
.CheckModuleDepexSatisfied(ModObj
, DpObj
, ReturnCode
):
157 ## Check whether a DP exists in current workspace.
159 # @param Guid: Guid of a module
160 # @param Version: Version of a module
162 def CheckDpExists(self
, Guid
, Version
, ReturnCode
=DEPEX_CHECK_SUCCESS
):
165 Logger
.Verbose(ST
.MSG_CHECK_DP_START
)
166 DpList
= self
.IpiDb
.GetDp(Guid
, Version
)
172 Logger
.Verbose(ST
.MSG_CHECK_DP_FINISH
)
174 ## Check whether a DP depex satisfied by current workspace.
176 # @param DpObj: Depex object
177 # @param ReturnCode: ReturnCode
179 def CheckDpDepexSatisfied(self
, DpObj
, ReturnCode
=DEPEX_CHECK_SUCCESS
):
181 for PkgKey
in DpObj
.PackageSurfaceArea
.keys():
182 PkgObj
= DpObj
.PackageSurfaceArea
[PkgKey
]
183 if self
.CheckPackageDepexSatisfied(PkgObj
, DpObj
, ReturnCode
):
188 for ModKey
in DpObj
.ModuleSurfaceArea
.keys():
189 ModObj
= DpObj
.ModuleSurfaceArea
[ModKey
]
190 if self
.CheckModuleDepexSatisfied(ModObj
, DpObj
, ReturnCode
):
197 ## Check whether a DP depex satisfied by current workspace. Return False
198 # if Can not remove (there is dependency), True else
200 # @param DpGuid: File's guid
201 # @param DpVersion: File's version
202 # @param ReturnCode: ReturnCode
204 def CheckDpDepexForRemove(self
, DpGuid
, DpVersion
, \
205 ReturnCode
=DEPEX_CHECK_SUCCESS
):
209 DependModuleList
= []
210 WsModuleList
= self
.WsModuleList
212 # remove modules that included in current DP
213 # List of item (FilePath)
214 DpModuleList
= self
.IpiDb
.GetDpModuleList(DpGuid
, DpVersion
)
215 for Module
in DpModuleList
:
216 if Module
in WsModuleList
:
217 WsModuleList
.remove(Module
)
220 ST
.ERR_MODULE_NOT_INSTALLED
% Module
)
222 # get packages in current Dp and find the install path
223 # List of item (PkgGuid, PkgVersion, InstallPath)
224 DpPackageList
= self
.IpiDb
.GetPackageListFromDp(DpGuid
, DpVersion
)
225 DpPackagePathList
= []
226 WorkSP
= environ
["WORKSPACE"]
227 for (PkgName
, PkgGuid
, PkgVersion
, DecFile
) in self
.WsPkgList
:
230 DecPath
= dirname(DecFile
)
231 if DecPath
.find(WorkSP
) > -1:
232 InstallPath
= DecPath
[DecPath
.find(WorkSP
) + len(WorkSP
) + 1:]
234 DecFile
[DecFile
.find(WorkSP
) + len(WorkSP
) + 1:]
236 InstallPath
= DecPath
237 DecFileRelaPath
= DecFile
239 if (PkgGuid
, PkgVersion
, InstallPath
) in DpPackageList
:
240 DpPackagePathList
.append(DecFileRelaPath
)
241 DpPackageList
.remove((PkgGuid
, PkgVersion
, InstallPath
))
244 # the left items in DpPackageList are the packages that installed but not found anymore
246 for (PkgGuid
, PkgVersion
, InstallPath
) in DpPackageList
:
248 ST
.WARN_INSTALLED_PACKAGE_NOT_FOUND
%(PkgGuid
, PkgVersion
, InstallPath
))
251 # check modules to see if has dependency on package of current DP
253 for Module
in WsModuleList
:
254 if (CheckModuleDependFromInf(Module
, DpPackagePathList
)):
256 DependModuleList
.append(Module
)
257 return (Removable
, DependModuleList
)
260 ## check whether module depends on packages in DpPackagePathList, return True
261 # if found, False else
263 # @param Path: a module path
264 # @param DpPackagePathList: a list of Package Paths
266 def CheckModuleDependFromInf(Path
, DpPackagePathList
):
269 # use InfParser to parse inf, then get the information for now,
270 # later on, may consider only parse to get the package dependency info
271 # (Need to take care how to deal wit Macros)
273 WorkSP
= getenv('WORKSPACE')
276 PomAli
= InfPomAlignment(Path
, WorkSP
, Skip
=True)
278 for Item
in PomAli
.GetPackageDependencyList():
279 if Item
.GetPackageFilePath() in DpPackagePathList
:
280 Logger
.Info(ST
.MSG_MODULE_DEPEND_ON
% (Path
, Item
.GetPackageFilePath()))
284 except FatalError
, ErrCode
:
285 if ErrCode
.message
== EDK1_INF_ERROR
:
287 ST
.WRN_EDK1_INF_FOUND
%Path
)