]> git.proxmox.com Git - mirror_edk2.git/blame - 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
CommitLineData
4234283c
LG
1## @file\r
2# This file is for installed package information database operations\r
3#\r
4# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
5#\r
6# This program and the accompanying materials are licensed and made available \r
7# under the terms and conditions of the BSD License which accompanies this \r
8# distribution. The full text of the license may be found at \r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11#\r
12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14#\r
15\r
16'''\r
17Dependency\r
18'''\r
19\r
20##\r
21# Import Modules\r
22#\r
23from os import getenv\r
24from os import environ\r
25from os.path import dirname\r
26\r
27import Logger.Log as Logger\r
28from Logger import StringTable as ST\r
29from Library.Parsing import GetWorkspacePackage\r
30from Library.Parsing import GetWorkspaceModule\r
31from PomAdapter.InfPomAlignment import InfPomAlignment\r
32from Logger.ToolError import FatalError\r
33from Logger.ToolError import EDK1_INF_ERROR\r
34from Logger.ToolError import UNKNOWN_ERROR\r
35(DEPEX_CHECK_SUCCESS, DEPEX_CHECK_MODULE_NOT_FOUND, \\r
36DEPEX_CHECK_PACKAGE_NOT_FOUND, DEPEX_CHECK_DP_NOT_FOUND) = (0, 1, 2, 3)\r
37\r
38\r
39## IpiDb\r
40#\r
41# This class represents the installed package information database\r
42# Add/Remove/Get installed distribution package information here.\r
43# \r
44# \r
45# @param object: Inherited from object class\r
46#\r
47class DependencyRules(object):\r
48 def __init__(self, Datab):\r
49 self.IpiDb = Datab\r
50 self.WsPkgList = GetWorkspacePackage()\r
51 self.WsModuleList = GetWorkspaceModule()\r
52\r
53 ## Check whether a module exists in current workspace.\r
54 #\r
55 # @param Guid: Guid of a module\r
56 # @param Version: Version of a module\r
57 #\r
d0acc87a 58 def CheckModuleExists(self, Guid, Version, Name, Path, ReturnCode=DEPEX_CHECK_SUCCESS):\r
4234283c
LG
59 if ReturnCode:\r
60 pass\r
61 Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST)\r
d0acc87a
LG
62 ModuleList = self.IpiDb.GetModInPackage(Guid, Version, Name, Path)\r
63 ModuleList.extend(self.IpiDb.GetStandaloneModule(Guid, Version, Name, Path))\r
4234283c
LG
64 Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST_FINISH)\r
65 if len(ModuleList) > 0:\r
66 return True\r
67 else:\r
68 return False\r
69 \r
70 ## Check whether a module depex satisfied by current workspace or dist.\r
71 #\r
72 # @param ModuleObj: A module object\r
73 # @param DpObj: A depex object\r
74 #\r
75 def CheckModuleDepexSatisfied(self, ModuleObj, DpObj=None, \\r
76 ReturnCode=DEPEX_CHECK_SUCCESS):\r
77 if ReturnCode:\r
78 pass\r
79 Logger.Verbose(ST.MSG_CHECK_MODULE_DEPEX_START)\r
80 Result = True\r
81 Dep = None\r
82 if ModuleObj.GetPackageDependencyList():\r
83 Dep = ModuleObj.GetPackageDependencyList()[0]\r
84 for Dep in ModuleObj.GetPackageDependencyList():\r
85 #\r
86 # first check whether the dependency satisfied by current workspace\r
87 #\r
88 Exist = self.CheckPackageExists(Dep.GetGuid(), Dep.GetVersion())\r
89 #\r
90 # check whether satisfied by current distribution \r
91 #\r
92 if not Exist:\r
93 if DpObj == None:\r
94 Result = False\r
95 break\r
96 for GuidVerPair in DpObj.PackageSurfaceArea.keys():\r
97 if Dep.GetGuid() == GuidVerPair[0]:\r
98 if Dep.GetVersion() == None or \\r
99 len(Dep.GetVersion()) == 0:\r
100 Result = True\r
101 break\r
102 if Dep.GetVersion() == GuidVerPair[1]:\r
103 Result = True\r
104 break\r
105 else:\r
106 Result = False\r
107 break\r
108 \r
109 if not Result:\r
110 Logger.Error("CheckModuleDepex", UNKNOWN_ERROR, \\r
111 ST.ERR_DEPENDENCY_NOT_MATCH % (ModuleObj.GetName(), \\r
112 Dep.GetPackageFilePath(), \\r
113 Dep.GetGuid(), \\r
114 Dep.GetVersion()))\r
115 return Result\r
116 \r
117 ## Check whether a package exists in current workspace.\r
118 #\r
119 # @param Guid: Guid of a package\r
120 # @param Version: Version of a package\r
121 #\r
122 def CheckPackageExists(self, Guid, Version):\r
123 Logger.Verbose(ST.MSG_CHECK_PACKAGE_START)\r
124 for (PkgName, PkgGuid, PkgVer, PkgPath) in self.WsPkgList:\r
125 if PkgName or PkgPath:\r
126 pass\r
127 if (PkgGuid == Guid):\r
128 #\r
129 # if version is not empty and not equal, then not match\r
130 #\r
131 if Version and (PkgVer != Version):\r
132 return False\r
133 else:\r
134 return True\r
135 else:\r
136 return False\r
137 \r
138 Logger.Verbose(ST.MSG_CHECK_PACKAGE_FINISH)\r
139 \r
140 ## Check whether a package depex satisfied by current workspace.\r
141 #\r
142 # @param PkgObj: A package object\r
143 # @param DpObj: A package depex object\r
144 #\r
145 def CheckPackageDepexSatisfied(self, PkgObj, DpObj=None, \\r
146 ReturnCode=DEPEX_CHECK_SUCCESS):\r
147 \r
148 ModuleDict = PkgObj.GetModuleDict()\r
149 for ModKey in ModuleDict.keys():\r
150 ModObj = ModuleDict[ModKey]\r
151 if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):\r
152 continue\r
153 else:\r
154 return False\r
155 return True\r
156 \r
157 ## Check whether a DP exists in current workspace.\r
158 #\r
159 # @param Guid: Guid of a module\r
160 # @param Version: Version of a module\r
161 #\r
162 def CheckDpExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS):\r
163 if ReturnCode:\r
164 pass\r
165 Logger.Verbose(ST.MSG_CHECK_DP_START)\r
166 DpList = self.IpiDb.GetDp(Guid, Version)\r
167 if len(DpList) > 0:\r
168 return True\r
169 else:\r
170 return False\r
171 \r
172 Logger.Verbose(ST.MSG_CHECK_DP_FINISH) \r
173 \r
174 ## Check whether a DP depex satisfied by current workspace.\r
175 #\r
176 # @param DpObj: Depex object\r
177 # @param ReturnCode: ReturnCode\r
178 #\r
179 def CheckDpDepexSatisfied(self, DpObj, ReturnCode=DEPEX_CHECK_SUCCESS):\r
180 \r
181 for PkgKey in DpObj.PackageSurfaceArea.keys():\r
182 PkgObj = DpObj.PackageSurfaceArea[PkgKey]\r
183 if self.CheckPackageDepexSatisfied(PkgObj, DpObj, ReturnCode):\r
184 continue\r
185 else:\r
186 return False\r
187 \r
188 for ModKey in DpObj.ModuleSurfaceArea.keys():\r
189 ModObj = DpObj.ModuleSurfaceArea[ModKey]\r
190 if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):\r
191 continue\r
192 else:\r
193 return False\r
194 \r
195 return True\r
196 \r
197 ## Check whether a DP depex satisfied by current workspace. Return False \r
198 # if Can not remove (there is dependency), True else\r
199 #\r
200 # @param DpGuid: File's guid\r
201 # @param DpVersion: File's version\r
202 # @param ReturnCode: ReturnCode\r
203 # \r
204 def CheckDpDepexForRemove(self, DpGuid, DpVersion, \\r
205 ReturnCode=DEPEX_CHECK_SUCCESS):\r
206 if ReturnCode:\r
207 pass\r
208 Removable = True\r
209 DependModuleList = []\r
210 WsModuleList = self.WsModuleList\r
211 #\r
212 # remove modules that included in current DP\r
213 # List of item (FilePath)\r
214 DpModuleList = self.IpiDb.GetDpModuleList(DpGuid, DpVersion) \r
215 for Module in DpModuleList:\r
216 if Module in WsModuleList:\r
217 WsModuleList.remove(Module)\r
218 else:\r
219 Logger.Warn("UPT\n",\r
220 ST.ERR_MODULE_NOT_INSTALLED % Module)\r
221 #\r
222 # get packages in current Dp and find the install path\r
223 # List of item (PkgGuid, PkgVersion, InstallPath)\r
224 DpPackageList = self.IpiDb.GetPackageListFromDp(DpGuid, DpVersion) \r
225 DpPackagePathList = []\r
226 WorkSP = environ["WORKSPACE"]\r
227 for (PkgName, PkgGuid, PkgVersion, DecFile) in self.WsPkgList:\r
228 if PkgName:\r
229 pass\r
230 DecPath = dirname(DecFile)\r
231 if DecPath.find(WorkSP) > -1:\r
232 InstallPath = DecPath[DecPath.find(WorkSP) + len(WorkSP) + 1:]\r
233 DecFileRelaPath = \\r
234 DecFile[DecFile.find(WorkSP) + len(WorkSP) + 1:]\r
235 else:\r
236 InstallPath = DecPath\r
237 DecFileRelaPath = DecFile\r
238 \r
239 if (PkgGuid, PkgVersion, InstallPath) in DpPackageList:\r
240 DpPackagePathList.append(DecFileRelaPath)\r
241 DpPackageList.remove((PkgGuid, PkgVersion, InstallPath))\r
242 \r
243 #\r
244 # the left items in DpPackageList are the packages that installed but not found anymore\r
245 #\r
246 for (PkgGuid, PkgVersion, InstallPath) in DpPackageList:\r
247 Logger.Warn("UPT",\r
248 ST.WARN_INSTALLED_PACKAGE_NOT_FOUND%(PkgGuid, PkgVersion, InstallPath))\r
249 \r
250 #\r
251 # check modules to see if has dependency on package of current DP\r
252 #\r
253 for Module in WsModuleList:\r
254 if (CheckModuleDependFromInf(Module, DpPackagePathList)):\r
255 Removable = False\r
256 DependModuleList.append(Module)\r
257 return (Removable, DependModuleList)\r
258\r
259\r
260## check whether module depends on packages in DpPackagePathList, return True \r
261# if found, False else\r
262#\r
263# @param Path: a module path\r
264# @param DpPackagePathList: a list of Package Paths\r
265#\r
266def CheckModuleDependFromInf(Path, DpPackagePathList):\r
267 \r
268 # \r
269 # use InfParser to parse inf, then get the information for now,\r
270 # later on, may consider only parse to get the package dependency info \r
271 # (Need to take care how to deal wit Macros)\r
272 #\r
273 WorkSP = getenv('WORKSPACE')\r
274 \r
275 try:\r
276 PomAli = InfPomAlignment(Path, WorkSP, Skip=True)\r
277\r
278 for Item in PomAli.GetPackageDependencyList():\r
279 if Item.GetPackageFilePath() in DpPackagePathList:\r
280 Logger.Info(ST.MSG_MODULE_DEPEND_ON % (Path, Item.GetPackageFilePath()))\r
281 return True\r
282 else:\r
283 return False\r
284 except FatalError, ErrCode:\r
285 if ErrCode.message == EDK1_INF_ERROR:\r
286 Logger.Warn("UPT",\r
287 ST.WRN_EDK1_INF_FOUND%Path)\r
288 return False\r
289 else:\r
290 return False\r
291 \r
292\r
293\r