]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/Core/DependencyRules.py
Sync BaseTool trunk (version r2460) into EDKII BaseTools. The change mainly includes:
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Core / DependencyRules.py
1 ## @file
2 # This file is for installed package information database operations
3 #
4 # Copyright (c) 2011, 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 #
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 Dependency
18 '''
19
20 ##
21 # Import Modules
22 #
23 from os import getenv
24 from os import environ
25 from os.path import dirname
26
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)
37
38
39 ## IpiDb
40 #
41 # This class represents the installed package information database
42 # Add/Remove/Get installed distribution package information here.
43 #
44 #
45 # @param object: Inherited from object class
46 #
47 class DependencyRules(object):
48 def __init__(self, Datab):
49 self.IpiDb = Datab
50 self.WsPkgList = GetWorkspacePackage()
51 self.WsModuleList = GetWorkspaceModule()
52
53 ## Check whether a module exists in current workspace.
54 #
55 # @param Guid: Guid of a module
56 # @param Version: Version of a module
57 #
58 def CheckModuleExists(self, Guid, Version, Name, Path, ReturnCode=DEPEX_CHECK_SUCCESS):
59 if ReturnCode:
60 pass
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:
66 return True
67 else:
68 return False
69
70 ## Check whether a module depex satisfied by current workspace or dist.
71 #
72 # @param ModuleObj: A module object
73 # @param DpObj: A depex object
74 #
75 def CheckModuleDepexSatisfied(self, ModuleObj, DpObj=None, \
76 ReturnCode=DEPEX_CHECK_SUCCESS):
77 if ReturnCode:
78 pass
79 Logger.Verbose(ST.MSG_CHECK_MODULE_DEPEX_START)
80 Result = True
81 Dep = None
82 if ModuleObj.GetPackageDependencyList():
83 Dep = ModuleObj.GetPackageDependencyList()[0]
84 for Dep in ModuleObj.GetPackageDependencyList():
85 #
86 # first check whether the dependency satisfied by current workspace
87 #
88 Exist = self.CheckPackageExists(Dep.GetGuid(), Dep.GetVersion())
89 #
90 # check whether satisfied by current distribution
91 #
92 if not Exist:
93 if DpObj == None:
94 Result = False
95 break
96 for GuidVerPair in DpObj.PackageSurfaceArea.keys():
97 if Dep.GetGuid() == GuidVerPair[0]:
98 if Dep.GetVersion() == None or \
99 len(Dep.GetVersion()) == 0:
100 Result = True
101 break
102 if Dep.GetVersion() == GuidVerPair[1]:
103 Result = True
104 break
105 else:
106 Result = False
107 break
108
109 if not Result:
110 Logger.Error("CheckModuleDepex", UNKNOWN_ERROR, \
111 ST.ERR_DEPENDENCY_NOT_MATCH % (ModuleObj.GetName(), \
112 Dep.GetPackageFilePath(), \
113 Dep.GetGuid(), \
114 Dep.GetVersion()))
115 return Result
116
117 ## Check whether a package exists in current workspace.
118 #
119 # @param Guid: Guid of a package
120 # @param Version: Version of a package
121 #
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:
126 pass
127 if (PkgGuid == Guid):
128 #
129 # if version is not empty and not equal, then not match
130 #
131 if Version and (PkgVer != Version):
132 return False
133 else:
134 return True
135 else:
136 return False
137
138 Logger.Verbose(ST.MSG_CHECK_PACKAGE_FINISH)
139
140 ## Check whether a package depex satisfied by current workspace.
141 #
142 # @param PkgObj: A package object
143 # @param DpObj: A package depex object
144 #
145 def CheckPackageDepexSatisfied(self, PkgObj, DpObj=None, \
146 ReturnCode=DEPEX_CHECK_SUCCESS):
147
148 ModuleDict = PkgObj.GetModuleDict()
149 for ModKey in ModuleDict.keys():
150 ModObj = ModuleDict[ModKey]
151 if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
152 continue
153 else:
154 return False
155 return True
156
157 ## Check whether a DP exists in current workspace.
158 #
159 # @param Guid: Guid of a module
160 # @param Version: Version of a module
161 #
162 def CheckDpExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS):
163 if ReturnCode:
164 pass
165 Logger.Verbose(ST.MSG_CHECK_DP_START)
166 DpList = self.IpiDb.GetDp(Guid, Version)
167 if len(DpList) > 0:
168 return True
169 else:
170 return False
171
172 Logger.Verbose(ST.MSG_CHECK_DP_FINISH)
173
174 ## Check whether a DP depex satisfied by current workspace.
175 #
176 # @param DpObj: Depex object
177 # @param ReturnCode: ReturnCode
178 #
179 def CheckDpDepexSatisfied(self, DpObj, ReturnCode=DEPEX_CHECK_SUCCESS):
180
181 for PkgKey in DpObj.PackageSurfaceArea.keys():
182 PkgObj = DpObj.PackageSurfaceArea[PkgKey]
183 if self.CheckPackageDepexSatisfied(PkgObj, DpObj, ReturnCode):
184 continue
185 else:
186 return False
187
188 for ModKey in DpObj.ModuleSurfaceArea.keys():
189 ModObj = DpObj.ModuleSurfaceArea[ModKey]
190 if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
191 continue
192 else:
193 return False
194
195 return True
196
197 ## Check whether a DP depex satisfied by current workspace. Return False
198 # if Can not remove (there is dependency), True else
199 #
200 # @param DpGuid: File's guid
201 # @param DpVersion: File's version
202 # @param ReturnCode: ReturnCode
203 #
204 def CheckDpDepexForRemove(self, DpGuid, DpVersion, \
205 ReturnCode=DEPEX_CHECK_SUCCESS):
206 if ReturnCode:
207 pass
208 Removable = True
209 DependModuleList = []
210 WsModuleList = self.WsModuleList
211 #
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)
218 else:
219 Logger.Warn("UPT\n",
220 ST.ERR_MODULE_NOT_INSTALLED % Module)
221 #
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:
228 if PkgName:
229 pass
230 DecPath = dirname(DecFile)
231 if DecPath.find(WorkSP) > -1:
232 InstallPath = DecPath[DecPath.find(WorkSP) + len(WorkSP) + 1:]
233 DecFileRelaPath = \
234 DecFile[DecFile.find(WorkSP) + len(WorkSP) + 1:]
235 else:
236 InstallPath = DecPath
237 DecFileRelaPath = DecFile
238
239 if (PkgGuid, PkgVersion, InstallPath) in DpPackageList:
240 DpPackagePathList.append(DecFileRelaPath)
241 DpPackageList.remove((PkgGuid, PkgVersion, InstallPath))
242
243 #
244 # the left items in DpPackageList are the packages that installed but not found anymore
245 #
246 for (PkgGuid, PkgVersion, InstallPath) in DpPackageList:
247 Logger.Warn("UPT",
248 ST.WARN_INSTALLED_PACKAGE_NOT_FOUND%(PkgGuid, PkgVersion, InstallPath))
249
250 #
251 # check modules to see if has dependency on package of current DP
252 #
253 for Module in WsModuleList:
254 if (CheckModuleDependFromInf(Module, DpPackagePathList)):
255 Removable = False
256 DependModuleList.append(Module)
257 return (Removable, DependModuleList)
258
259
260 ## check whether module depends on packages in DpPackagePathList, return True
261 # if found, False else
262 #
263 # @param Path: a module path
264 # @param DpPackagePathList: a list of Package Paths
265 #
266 def CheckModuleDependFromInf(Path, DpPackagePathList):
267
268 #
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)
272 #
273 WorkSP = getenv('WORKSPACE')
274
275 try:
276 PomAli = InfPomAlignment(Path, WorkSP, Skip=True)
277
278 for Item in PomAli.GetPackageDependencyList():
279 if Item.GetPackageFilePath() in DpPackagePathList:
280 Logger.Info(ST.MSG_MODULE_DEPEND_ON % (Path, Item.GetPackageFilePath()))
281 return True
282 else:
283 return False
284 except FatalError, ErrCode:
285 if ErrCode.message == EDK1_INF_ERROR:
286 Logger.Warn("UPT",
287 ST.WRN_EDK1_INF_FOUND%Path)
288 return False
289 else:
290 return False
291
292
293