]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/UPT/Core/DependencyRules.py
Sync BaseTools Branch (version r2271) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Core / DependencyRules.py
diff --git a/BaseTools/Source/Python/UPT/Core/DependencyRules.py b/BaseTools/Source/Python/UPT/Core/DependencyRules.py
new file mode 100644 (file)
index 0000000..ac656bb
--- /dev/null
@@ -0,0 +1,293 @@
+## @file\r
+# This file is for installed package information database operations\r
+#\r
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials are licensed and made available \r
+# under the terms and conditions of the BSD License which accompanies this \r
+# distribution. The full text of the license may be found at \r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+'''\r
+Dependency\r
+'''\r
+\r
+##\r
+# Import Modules\r
+#\r
+from os import getenv\r
+from os import environ\r
+from os.path import dirname\r
+\r
+import Logger.Log as Logger\r
+from Logger import StringTable as ST\r
+from Library.Parsing import GetWorkspacePackage\r
+from Library.Parsing import GetWorkspaceModule\r
+from PomAdapter.InfPomAlignment import InfPomAlignment\r
+from Logger.ToolError import FatalError\r
+from Logger.ToolError import EDK1_INF_ERROR\r
+from Logger.ToolError import UNKNOWN_ERROR\r
+(DEPEX_CHECK_SUCCESS, DEPEX_CHECK_MODULE_NOT_FOUND, \\r
+DEPEX_CHECK_PACKAGE_NOT_FOUND, DEPEX_CHECK_DP_NOT_FOUND) = (0, 1, 2, 3)\r
+\r
+\r
+## IpiDb\r
+#\r
+# This class represents the installed package information database\r
+# Add/Remove/Get installed distribution package information here.\r
+# \r
+# \r
+# @param object:      Inherited from object class\r
+#\r
+class DependencyRules(object):\r
+    def __init__(self, Datab):\r
+        self.IpiDb = Datab\r
+        self.WsPkgList = GetWorkspacePackage()\r
+        self.WsModuleList = GetWorkspaceModule()\r
+\r
+    ## Check whether a module exists in current workspace.\r
+    #\r
+    # @param Guid:  Guid of a module\r
+    # @param Version: Version of a module\r
+    #\r
+    def CheckModuleExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS):\r
+        if ReturnCode:\r
+            pass\r
+        Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST)\r
+        ModuleList = self.IpiDb.GetModInPackage(Guid, Version)\r
+        ModuleList.extend(self.IpiDb.GetStandaloneModule(Guid, Version))\r
+        Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST_FINISH)\r
+        if len(ModuleList) > 0:\r
+            return True\r
+        else:\r
+            return False\r
+        \r
+    ## Check whether a module depex satisfied by current workspace or dist.\r
+    #\r
+    # @param ModuleObj: A module object\r
+    # @param DpObj: A depex object\r
+    #\r
+    def CheckModuleDepexSatisfied(self, ModuleObj, DpObj=None, \\r
+                                  ReturnCode=DEPEX_CHECK_SUCCESS):\r
+        if ReturnCode:\r
+            pass\r
+        Logger.Verbose(ST.MSG_CHECK_MODULE_DEPEX_START)\r
+        Result = True\r
+        Dep = None\r
+        if ModuleObj.GetPackageDependencyList():\r
+            Dep = ModuleObj.GetPackageDependencyList()[0]\r
+        for Dep in ModuleObj.GetPackageDependencyList():\r
+            #\r
+            # first check whether the dependency satisfied by current workspace\r
+            #\r
+            Exist = self.CheckPackageExists(Dep.GetGuid(), Dep.GetVersion())\r
+            #\r
+            # check whether satisfied by current distribution \r
+            #\r
+            if not Exist:\r
+                if DpObj == None:\r
+                    Result = False\r
+                    break\r
+                for GuidVerPair in DpObj.PackageSurfaceArea.keys():\r
+                    if Dep.GetGuid() == GuidVerPair[0]:\r
+                        if Dep.GetVersion() == None or \\r
+                        len(Dep.GetVersion()) == 0:\r
+                            Result = True\r
+                            break\r
+                        if Dep.GetVersion() == GuidVerPair[1]:\r
+                            Result = True\r
+                            break\r
+                else:\r
+                    Result = False\r
+                    break\r
+        \r
+        if not Result:\r
+            Logger.Error("CheckModuleDepex", UNKNOWN_ERROR, \\r
+                         ST.ERR_DEPENDENCY_NOT_MATCH % (ModuleObj.GetName(), \\r
+                                                        Dep.GetPackageFilePath(), \\r
+                                                        Dep.GetGuid(), \\r
+                                                        Dep.GetVersion()))\r
+        return Result\r
+            \r
+    ## Check whether a package exists in current workspace.\r
+    #\r
+    # @param Guid: Guid of a package\r
+    # @param Version: Version of a package\r
+    #\r
+    def CheckPackageExists(self, Guid, Version):\r
+        Logger.Verbose(ST.MSG_CHECK_PACKAGE_START)\r
+        for (PkgName, PkgGuid, PkgVer, PkgPath) in self.WsPkgList:\r
+            if PkgName or PkgPath:\r
+                pass\r
+            if (PkgGuid == Guid):\r
+                #\r
+                # if version is not empty and not equal, then not match\r
+                #\r
+                if Version and (PkgVer != Version):\r
+                    return False\r
+                else:\r
+                    return True\r
+        else:\r
+            return False\r
+                        \r
+        Logger.Verbose(ST.MSG_CHECK_PACKAGE_FINISH)\r
+         \r
+    ## Check whether a package depex satisfied by current workspace.\r
+    #\r
+    # @param PkgObj: A package object\r
+    # @param DpObj: A package depex object\r
+    #\r
+    def CheckPackageDepexSatisfied(self, PkgObj, DpObj=None, \\r
+                                   ReturnCode=DEPEX_CHECK_SUCCESS):\r
+        \r
+        ModuleDict = PkgObj.GetModuleDict()\r
+        for ModKey in ModuleDict.keys():\r
+            ModObj = ModuleDict[ModKey]\r
+            if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):\r
+                continue\r
+            else:\r
+                return False\r
+        return True\r
+        \r
+    ## Check whether a DP exists in current workspace.\r
+    #\r
+    # @param Guid: Guid of a module\r
+    # @param Version: Version of a module\r
+    #\r
+    def CheckDpExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS):\r
+        if ReturnCode:\r
+            pass\r
+        Logger.Verbose(ST.MSG_CHECK_DP_START)\r
+        DpList = self.IpiDb.GetDp(Guid, Version)\r
+        if len(DpList) > 0:\r
+            return True\r
+        else:\r
+            return False\r
+            \r
+        Logger.Verbose(ST.MSG_CHECK_DP_FINISH) \r
+        \r
+    ## Check whether a DP depex satisfied by current workspace.\r
+    #\r
+    # @param DpObj:  Depex object\r
+    # @param ReturnCode: ReturnCode\r
+    #\r
+    def CheckDpDepexSatisfied(self, DpObj, ReturnCode=DEPEX_CHECK_SUCCESS):\r
+        \r
+        for PkgKey in DpObj.PackageSurfaceArea.keys():\r
+            PkgObj = DpObj.PackageSurfaceArea[PkgKey]\r
+            if self.CheckPackageDepexSatisfied(PkgObj, DpObj, ReturnCode):\r
+                continue\r
+            else:\r
+                return False\r
+            \r
+        for ModKey in DpObj.ModuleSurfaceArea.keys():\r
+            ModObj = DpObj.ModuleSurfaceArea[ModKey]\r
+            if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):\r
+                continue\r
+            else:\r
+                return False\r
+        \r
+        return True\r
+    \r
+    ## Check whether a DP depex satisfied by current workspace. Return False \r
+    # if Can not remove (there is dependency), True else\r
+    #\r
+    # @param DpGuid:  File's guid\r
+    # @param DpVersion: File's version\r
+    # @param ReturnCode: ReturnCode\r
+    # \r
+    def CheckDpDepexForRemove(self, DpGuid, DpVersion, \\r
+                              ReturnCode=DEPEX_CHECK_SUCCESS):\r
+        if ReturnCode:\r
+            pass\r
+        Removable = True\r
+        DependModuleList = []\r
+        WsModuleList = self.WsModuleList\r
+        #\r
+        # remove modules that included in current DP\r
+        # List of item (FilePath)\r
+        DpModuleList = self.IpiDb.GetDpModuleList(DpGuid, DpVersion) \r
+        for Module in DpModuleList:\r
+            if Module in WsModuleList:\r
+                WsModuleList.remove(Module)\r
+            else:\r
+                Logger.Warn("UPT\n",\r
+                            ST.ERR_MODULE_NOT_INSTALLED % Module)\r
+        #\r
+        # get packages in current Dp and find the install path\r
+        # List of item (PkgGuid, PkgVersion, InstallPath)\r
+        DpPackageList = self.IpiDb.GetPackageListFromDp(DpGuid, DpVersion) \r
+        DpPackagePathList = []\r
+        WorkSP = environ["WORKSPACE"]\r
+        for (PkgName, PkgGuid, PkgVersion, DecFile) in self.WsPkgList:\r
+            if PkgName:\r
+                pass\r
+            DecPath = dirname(DecFile)\r
+            if DecPath.find(WorkSP) > -1:\r
+                InstallPath = DecPath[DecPath.find(WorkSP) + len(WorkSP) + 1:]\r
+                DecFileRelaPath = \\r
+                DecFile[DecFile.find(WorkSP) + len(WorkSP) + 1:]\r
+            else:\r
+                InstallPath = DecPath\r
+                DecFileRelaPath = DecFile\r
+                \r
+            if (PkgGuid, PkgVersion, InstallPath) in DpPackageList:\r
+                DpPackagePathList.append(DecFileRelaPath)\r
+                DpPackageList.remove((PkgGuid, PkgVersion, InstallPath))\r
+        \r
+        #\r
+        # the left items in DpPackageList are the packages that installed but not found anymore\r
+        #\r
+        for (PkgGuid, PkgVersion, InstallPath) in DpPackageList:\r
+            Logger.Warn("UPT",\r
+                        ST.WARN_INSTALLED_PACKAGE_NOT_FOUND%(PkgGuid, PkgVersion, InstallPath))\r
+        \r
+        #\r
+        # check modules to see if has dependency on package of current DP\r
+        #\r
+        for Module in WsModuleList:\r
+            if (CheckModuleDependFromInf(Module, DpPackagePathList)):\r
+                Removable = False\r
+                DependModuleList.append(Module)\r
+        return (Removable, DependModuleList)\r
+\r
+\r
+## check whether module depends on packages in DpPackagePathList, return True \r
+# if found, False else\r
+#\r
+# @param Path: a module path\r
+# @param DpPackagePathList: a list of Package Paths\r
+#\r
+def CheckModuleDependFromInf(Path, DpPackagePathList):\r
+    \r
+    #  \r
+    # use InfParser to parse inf, then get the information for now,\r
+    # later on, may consider only parse to get the package dependency info \r
+    # (Need to take care how to deal wit Macros)\r
+    #\r
+    WorkSP = getenv('WORKSPACE')\r
+    \r
+    try:\r
+        PomAli = InfPomAlignment(Path, WorkSP, Skip=True)\r
+\r
+        for Item in PomAli.GetPackageDependencyList():\r
+            if Item.GetPackageFilePath() in DpPackagePathList:\r
+                Logger.Info(ST.MSG_MODULE_DEPEND_ON % (Path, Item.GetPackageFilePath()))\r
+                return True\r
+        else:\r
+            return False\r
+    except FatalError, ErrCode:\r
+        if ErrCode.message == EDK1_INF_ERROR:\r
+            Logger.Warn("UPT",\r
+                        ST.WRN_EDK1_INF_FOUND%Path)\r
+            return False\r
+        else:\r
+            return False\r
+        \r
+\r
+\r