]>
Commit | Line | Data |
---|---|---|
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 | |
17 | Dependency\r | |
18 | '''\r | |
19 | \r | |
20 | ##\r | |
21 | # Import Modules\r | |
22 | #\r | |
23 | from os import getenv\r | |
24 | from os import environ\r | |
25 | from os.path import dirname\r | |
26 | \r | |
27 | import Logger.Log as Logger\r | |
28 | from Logger import StringTable as ST\r | |
29 | from Library.Parsing import GetWorkspacePackage\r | |
30 | from Library.Parsing import GetWorkspaceModule\r | |
31 | from PomAdapter.InfPomAlignment import InfPomAlignment\r | |
32 | from Logger.ToolError import FatalError\r | |
33 | from Logger.ToolError import EDK1_INF_ERROR\r | |
34 | from Logger.ToolError import UNKNOWN_ERROR\r | |
35 | (DEPEX_CHECK_SUCCESS, DEPEX_CHECK_MODULE_NOT_FOUND, \\r | |
36 | DEPEX_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 | |
47 | class 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 | |
266 | def 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 |