summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/UPT/Core/DependencyRules.py
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/Python/UPT/Core/DependencyRules.py')
-rw-r--r--BaseTools/Source/Python/UPT/Core/DependencyRules.py267
1 files changed, 191 insertions, 76 deletions
diff --git a/BaseTools/Source/Python/UPT/Core/DependencyRules.py b/BaseTools/Source/Python/UPT/Core/DependencyRules.py
index 752d8e8f41..4608ed6030 100644
--- a/BaseTools/Source/Python/UPT/Core/DependencyRules.py
+++ b/BaseTools/Source/Python/UPT/Core/DependencyRules.py
@@ -1,7 +1,7 @@
## @file
# This file is for installed package information database operations
#
-# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available
# under the terms and conditions of the BSD License which accompanies this
@@ -20,14 +20,14 @@ Dependency
##
# Import Modules
#
-from os import getenv
-from os import environ
from os.path import dirname
import Logger.Log as Logger
from Logger import StringTable as ST
from Library.Parsing import GetWorkspacePackage
from Library.Parsing import GetWorkspaceModule
+from Library.Misc import GetRelativePath
+from Library import GlobalData
from PomAdapter.InfPomAlignment import InfPomAlignment
from Logger.ToolError import FatalError
from Logger.ToolError import EDK1_INF_ERROR
@@ -36,11 +36,9 @@ from Logger.ToolError import UNKNOWN_ERROR
DEPEX_CHECK_PACKAGE_NOT_FOUND, DEPEX_CHECK_DP_NOT_FOUND) = (0, 1, 2, 3)
-## IpiDb
+## DependencyRules
#
-# This class represents the installed package information database
-# Add/Remove/Get installed distribution package information here.
-#
+# This class represents the dependency rule check mechanism
#
# @param object: Inherited from object class
#
@@ -49,15 +47,17 @@ class DependencyRules(object):
self.IpiDb = Datab
self.WsPkgList = GetWorkspacePackage()
self.WsModuleList = GetWorkspaceModule()
-
- ## Check whether a module exists in current workspace.
+ self.PkgsToBeDepend = []
+
+ ## Check whether a module exists by checking the Guid+Version+Name+Path combination
#
# @param Guid: Guid of a module
# @param Version: Version of a module
+ # @param Name: Name of a module
+ # @param Path: Path of a module
+ # @return: True if module existed, else False
#
- def CheckModuleExists(self, Guid, Version, Name, Path, ReturnCode=DEPEX_CHECK_SUCCESS):
- if ReturnCode:
- pass
+ def CheckModuleExists(self, Guid, Version, Name, Path):
Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST)
ModuleList = self.IpiDb.GetModInPackage(Guid, Version, Name, Path)
ModuleList.extend(self.IpiDb.GetStandaloneModule(Guid, Version, Name, Path))
@@ -67,15 +67,14 @@ class DependencyRules(object):
else:
return False
- ## Check whether a module depex satisfied by current workspace or dist.
+ ## Check whether a module depex satisfied.
#
# @param ModuleObj: A module object
- # @param DpObj: A depex object
+ # @param DpObj: A distribution object
+ # @return: True if module depex satisfied
+ # False else
#
- def CheckModuleDepexSatisfied(self, ModuleObj, DpObj=None, \
- ReturnCode=DEPEX_CHECK_SUCCESS):
- if ReturnCode:
- pass
+ def CheckModuleDepexSatisfied(self, ModuleObj, DpObj=None):
Logger.Verbose(ST.MSG_CHECK_MODULE_DEPEX_START)
Result = True
Dep = None
@@ -114,97 +113,122 @@ class DependencyRules(object):
Dep.GetVersion()))
return Result
- ## Check whether a package exists in current workspace.
+ ## Check whether a package exists in a package list specified by PkgsToBeDepend.
#
# @param Guid: Guid of a package
# @param Version: Version of a package
+ # @return: True if package exist
+ # False else
#
def CheckPackageExists(self, Guid, Version):
Logger.Verbose(ST.MSG_CHECK_PACKAGE_START)
- for (PkgName, PkgGuid, PkgVer, PkgPath) in self.WsPkgList:
- if PkgName or PkgPath:
- pass
+ Found = False
+ for (PkgGuid, PkgVer) in self.PkgsToBeDepend:
if (PkgGuid == Guid):
#
# if version is not empty and not equal, then not match
#
if Version and (PkgVer != Version):
- return False
+ Found = False
+ break
else:
- return True
+ Found = True
+ break
else:
- return False
-
+ Found = False
+
Logger.Verbose(ST.MSG_CHECK_PACKAGE_FINISH)
+ return Found
- ## Check whether a package depex satisfied by current workspace.
+ ## Check whether a package depex satisfied.
#
# @param PkgObj: A package object
- # @param DpObj: A package depex object
+ # @param DpObj: A distribution object
+ # @return: True if package depex satisified
+ # False else
#
- def CheckPackageDepexSatisfied(self, PkgObj, DpObj=None, \
- ReturnCode=DEPEX_CHECK_SUCCESS):
-
+ def CheckPackageDepexSatisfied(self, PkgObj, DpObj=None):
ModuleDict = PkgObj.GetModuleDict()
for ModKey in ModuleDict.keys():
ModObj = ModuleDict[ModKey]
- if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
+ if self.CheckModuleDepexSatisfied(ModObj, DpObj):
continue
else:
return False
return True
- ## Check whether a DP exists in current workspace.
+ ## Check whether a DP exists.
#
- # @param Guid: Guid of a module
- # @param Version: Version of a module
- #
- def CheckDpExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS):
- if ReturnCode:
- pass
+ # @param Guid: Guid of a Distribution
+ # @param Version: Version of a Distribution
+ # @return: True if Distribution exist
+ # False else
+ def CheckDpExists(self, Guid, Version):
Logger.Verbose(ST.MSG_CHECK_DP_START)
DpList = self.IpiDb.GetDp(Guid, Version)
if len(DpList) > 0:
- return True
+ Found = True
else:
- return False
-
- Logger.Verbose(ST.MSG_CHECK_DP_FINISH)
-
+ Found = False
+
+ Logger.Verbose(ST.MSG_CHECK_DP_FINISH)
+ return Found
+
+ ## Check whether a DP depex satisfied by current workspace for Install
+ #
+ # @param DpObj: A distribution object
+ # @return: True if distribution depex satisfied
+ # False else
+ #
+ def CheckInstallDpDepexSatisfied(self, DpObj):
+ self.PkgsToBeDepend = [(PkgInfo[1], PkgInfo[2]) for PkgInfo in self.WsPkgList]
+ return self.CheckDpDepexSatisfied(DpObj)
+
+ ## Check whether a DP depex satisfied by current workspace
+ # (excluding the original distribution's packages to be replaced) for Replace
+ #
+ # @param DpObj: A distribution object
+ # @param OrigDpGuid: The original distribution's Guid
+ # @param OrigDpVersion: The original distribution's Version
+ #
+ def ReplaceCheckNewDpDepex(self, DpObj, OrigDpGuid, OrigDpVersion):
+ self.PkgsToBeDepend = [(PkgInfo[1], PkgInfo[2]) for PkgInfo in self.WsPkgList]
+ OrigDpPackageList = self.IpiDb.GetPackageListFromDp(OrigDpGuid, OrigDpVersion)
+ for OrigPkgInfo in OrigDpPackageList:
+ Guid, Version = OrigPkgInfo[0], OrigPkgInfo[1]
+ if (Guid, Version) in self.PkgsToBeDepend:
+ self.PkgsToBeDepend.remove((Guid, Version))
+ return self.CheckDpDepexSatisfied(DpObj)
+
## Check whether a DP depex satisfied by current workspace.
#
- # @param DpObj: Depex object
- # @param ReturnCode: ReturnCode
+ # @param DpObj: A distribution object
#
- def CheckDpDepexSatisfied(self, DpObj, ReturnCode=DEPEX_CHECK_SUCCESS):
-
+ def CheckDpDepexSatisfied(self, DpObj):
for PkgKey in DpObj.PackageSurfaceArea.keys():
PkgObj = DpObj.PackageSurfaceArea[PkgKey]
- if self.CheckPackageDepexSatisfied(PkgObj, DpObj, ReturnCode):
+ if self.CheckPackageDepexSatisfied(PkgObj, DpObj):
continue
else:
return False
for ModKey in DpObj.ModuleSurfaceArea.keys():
ModObj = DpObj.ModuleSurfaceArea[ModKey]
- if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
+ if self.CheckModuleDepexSatisfied(ModObj, DpObj):
continue
else:
return False
return True
- ## Check whether a DP depex satisfied by current workspace. Return False
- # if Can not remove (there is dependency), True else
+ ## Check whether a DP could be removed from current workspace.
#
# @param DpGuid: File's guid
# @param DpVersion: File's version
- # @param ReturnCode: ReturnCode
- #
- def CheckDpDepexForRemove(self, DpGuid, DpVersion, \
- ReturnCode=DEPEX_CHECK_SUCCESS):
- if ReturnCode:
- pass
+ # @retval Removable: True if distribution could be removed, False Else
+ # @retval DependModuleList: the list of modules that make distribution can not be removed
+ #
+ def CheckDpDepexForRemove(self, DpGuid, DpVersion):
Removable = True
DependModuleList = []
WsModuleList = self.WsModuleList
@@ -223,15 +247,14 @@ class DependencyRules(object):
# List of item (PkgGuid, PkgVersion, InstallPath)
DpPackageList = self.IpiDb.GetPackageListFromDp(DpGuid, DpVersion)
DpPackagePathList = []
- WorkSP = environ["WORKSPACE"]
+ WorkSP = GlobalData.gWORKSPACE
for (PkgName, PkgGuid, PkgVersion, DecFile) in self.WsPkgList:
if PkgName:
pass
DecPath = dirname(DecFile)
if DecPath.find(WorkSP) > -1:
- InstallPath = DecPath[DecPath.find(WorkSP) + len(WorkSP) + 1:]
- DecFileRelaPath = \
- DecFile[DecFile.find(WorkSP) + len(WorkSP) + 1:]
+ InstallPath = GetRelativePath(DecPath,WorkSP)
+ DecFileRelaPath = GetRelativePath(DecFile,WorkSP)
else:
InstallPath = DecPath
DecFileRelaPath = DecFile
@@ -251,26 +274,87 @@ class DependencyRules(object):
# check modules to see if has dependency on package of current DP
#
for Module in WsModuleList:
- if (CheckModuleDependFromInf(Module, DpPackagePathList)):
+ if (not VerifyRemoveModuleDep(Module, DpPackagePathList)):
Removable = False
DependModuleList.append(Module)
return (Removable, DependModuleList)
+ ## Check whether a DP could be replaced by a distribution containing NewDpPkgList
+ # from current workspace.
+ #
+ # @param OrigDpGuid: original Dp's Guid
+ # @param OrigDpVersion: original Dp's version
+ # @param NewDpPkgList: a list of package information (Guid, Version) in new Dp
+ # @retval Replaceable: True if distribution could be replaced, False Else
+ # @retval DependModuleList: the list of modules that make distribution can not be replaced
+ #
+ def CheckDpDepexForReplace(self, OrigDpGuid, OrigDpVersion, NewDpPkgList):
+ Replaceable = True
+ DependModuleList = []
+ WsModuleList = self.WsModuleList
+ #
+ # remove modules that included in current DP
+ # List of item (FilePath)
+ DpModuleList = self.IpiDb.GetDpModuleList(OrigDpGuid, OrigDpVersion)
+ for Module in DpModuleList:
+ if Module in WsModuleList:
+ WsModuleList.remove(Module)
+ else:
+ Logger.Warn("UPT\n",
+ ST.ERR_MODULE_NOT_INSTALLED % Module)
+
+ OtherPkgList = NewDpPkgList
+ #
+ # get packages in current Dp and find the install path
+ # List of item (PkgGuid, PkgVersion, InstallPath)
+ DpPackageList = self.IpiDb.GetPackageListFromDp(OrigDpGuid, OrigDpVersion)
+ DpPackagePathList = []
+ WorkSP = GlobalData.gWORKSPACE
+ for (PkgName, PkgGuid, PkgVersion, DecFile) in self.WsPkgList:
+ if PkgName:
+ pass
+ DecPath = dirname(DecFile)
+ if DecPath.find(WorkSP) > -1:
+ InstallPath = GetRelativePath(DecPath,WorkSP)
+ DecFileRelaPath = GetRelativePath(DecFile,WorkSP)
+ else:
+ InstallPath = DecPath
+ DecFileRelaPath = DecFile
+
+ if (PkgGuid, PkgVersion, InstallPath) in DpPackageList:
+ DpPackagePathList.append(DecFileRelaPath)
+ DpPackageList.remove((PkgGuid, PkgVersion, InstallPath))
+ else:
+ OtherPkgList.append((PkgGuid, PkgVersion))
+
+ #
+ # the left items in DpPackageList are the packages that installed but not found anymore
+ #
+ for (PkgGuid, PkgVersion, InstallPath) in DpPackageList:
+ Logger.Warn("UPT",
+ ST.WARN_INSTALLED_PACKAGE_NOT_FOUND%(PkgGuid, PkgVersion, InstallPath))
+
+ #
+ # check modules to see if it can be satisfied by package not belong to removed DP
+ #
+ for Module in WsModuleList:
+ if (not VerifyReplaceModuleDep(Module, DpPackagePathList, OtherPkgList)):
+ Replaceable = False
+ DependModuleList.append(Module)
+ return (Replaceable, DependModuleList)
+
+
## check whether module depends on packages in DpPackagePathList, return True
# if found, False else
#
# @param Path: a module path
# @param DpPackagePathList: a list of Package Paths
+# @retval: False: module depends on package in DpPackagePathList
+# True: module doesn't depend on package in DpPackagePathList
#
-def CheckModuleDependFromInf(Path, DpPackagePathList):
-
- #
- # use InfParser to parse inf, then get the information for now,
- # later on, may consider only parse to get the package dependency info
- # (Need to take care how to deal wit Macros)
- #
- WorkSP = getenv('WORKSPACE')
+def VerifyRemoveModuleDep(Path, DpPackagePathList):
+ WorkSP = GlobalData.gWORKSPACE
try:
PomAli = InfPomAlignment(Path, WorkSP, Skip=True)
@@ -278,16 +362,47 @@ def CheckModuleDependFromInf(Path, DpPackagePathList):
for Item in PomAli.GetPackageDependencyList():
if Item.GetPackageFilePath() in DpPackagePathList:
Logger.Info(ST.MSG_MODULE_DEPEND_ON % (Path, Item.GetPackageFilePath()))
- return True
+ return False
else:
- return False
+ return True
except FatalError, ErrCode:
if ErrCode.message == EDK1_INF_ERROR:
Logger.Warn("UPT",
ST.WRN_EDK1_INF_FOUND%Path)
- return False
+ return True
else:
- return False
-
+ return True
+
+## check whether module depends on packages in DpPackagePathList and can not be satisfied by OtherPkgList
+#
+# @param Path: a module path
+# @param DpPackagePathList: a list of Package Paths
+# @param OtherPkgList: a list of Package Information (Guid, Version)
+# @retval: False: module depends on package in DpPackagePathList and can not be satisfied by OtherPkgList
+# True: either module doesn't depend on DpPackagePathList or module depends on DpPackagePathList
+# but can be satisfied by OtherPkgList
+#
+def VerifyReplaceModuleDep(Path, DpPackagePathList, OtherPkgList):
+ WorkSP = GlobalData.gWORKSPACE
+
+ try:
+ PomAli = InfPomAlignment(Path, WorkSP, Skip=True)
+
+ for Item in PomAli.GetPackageDependencyList():
+ if Item.GetPackageFilePath() in DpPackagePathList:
+ Guid, Version = Item.GetGuid(), Item.GetVersion()
+ if (Guid, Version) not in OtherPkgList:
+ Logger.Info(ST.MSG_MODULE_DEPEND_ON % (Path, Item.GetPackageFilePath()))
+ return False
+ else:
+ return True
+ except FatalError, ErrCode:
+ if ErrCode.message == EDK1_INF_ERROR:
+ Logger.Warn("UPT",
+ ST.WRN_EDK1_INF_FOUND%Path)
+ return True
+ else:
+ return True
+