Sync BaseTools Branch (version r2271) to EDKII main trunk.
BaseTool Branch: https://edk2-buildtools.svn.sourceforge.net/svnroot/edk2-buildtools/branches/Releases/BaseTools_r2100 Signed-off-by: lgao4 Reviewed-by: hchen30 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12214 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
293
BaseTools/Source/Python/UPT/Core/DependencyRules.py
Normal file
293
BaseTools/Source/Python/UPT/Core/DependencyRules.py
Normal file
@ -0,0 +1,293 @@
|
||||
## @file
|
||||
# This file is for installed package information database operations
|
||||
#
|
||||
# Copyright (c) 2011, 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
|
||||
# distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
'''
|
||||
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 PomAdapter.InfPomAlignment import InfPomAlignment
|
||||
from Logger.ToolError import FatalError
|
||||
from Logger.ToolError import EDK1_INF_ERROR
|
||||
from Logger.ToolError import UNKNOWN_ERROR
|
||||
(DEPEX_CHECK_SUCCESS, DEPEX_CHECK_MODULE_NOT_FOUND, \
|
||||
DEPEX_CHECK_PACKAGE_NOT_FOUND, DEPEX_CHECK_DP_NOT_FOUND) = (0, 1, 2, 3)
|
||||
|
||||
|
||||
## IpiDb
|
||||
#
|
||||
# This class represents the installed package information database
|
||||
# Add/Remove/Get installed distribution package information here.
|
||||
#
|
||||
#
|
||||
# @param object: Inherited from object class
|
||||
#
|
||||
class DependencyRules(object):
|
||||
def __init__(self, Datab):
|
||||
self.IpiDb = Datab
|
||||
self.WsPkgList = GetWorkspacePackage()
|
||||
self.WsModuleList = GetWorkspaceModule()
|
||||
|
||||
## Check whether a module exists in current workspace.
|
||||
#
|
||||
# @param Guid: Guid of a module
|
||||
# @param Version: Version of a module
|
||||
#
|
||||
def CheckModuleExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS):
|
||||
if ReturnCode:
|
||||
pass
|
||||
Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST)
|
||||
ModuleList = self.IpiDb.GetModInPackage(Guid, Version)
|
||||
ModuleList.extend(self.IpiDb.GetStandaloneModule(Guid, Version))
|
||||
Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST_FINISH)
|
||||
if len(ModuleList) > 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
## Check whether a module depex satisfied by current workspace or dist.
|
||||
#
|
||||
# @param ModuleObj: A module object
|
||||
# @param DpObj: A depex object
|
||||
#
|
||||
def CheckModuleDepexSatisfied(self, ModuleObj, DpObj=None, \
|
||||
ReturnCode=DEPEX_CHECK_SUCCESS):
|
||||
if ReturnCode:
|
||||
pass
|
||||
Logger.Verbose(ST.MSG_CHECK_MODULE_DEPEX_START)
|
||||
Result = True
|
||||
Dep = None
|
||||
if ModuleObj.GetPackageDependencyList():
|
||||
Dep = ModuleObj.GetPackageDependencyList()[0]
|
||||
for Dep in ModuleObj.GetPackageDependencyList():
|
||||
#
|
||||
# first check whether the dependency satisfied by current workspace
|
||||
#
|
||||
Exist = self.CheckPackageExists(Dep.GetGuid(), Dep.GetVersion())
|
||||
#
|
||||
# check whether satisfied by current distribution
|
||||
#
|
||||
if not Exist:
|
||||
if DpObj == None:
|
||||
Result = False
|
||||
break
|
||||
for GuidVerPair in DpObj.PackageSurfaceArea.keys():
|
||||
if Dep.GetGuid() == GuidVerPair[0]:
|
||||
if Dep.GetVersion() == None or \
|
||||
len(Dep.GetVersion()) == 0:
|
||||
Result = True
|
||||
break
|
||||
if Dep.GetVersion() == GuidVerPair[1]:
|
||||
Result = True
|
||||
break
|
||||
else:
|
||||
Result = False
|
||||
break
|
||||
|
||||
if not Result:
|
||||
Logger.Error("CheckModuleDepex", UNKNOWN_ERROR, \
|
||||
ST.ERR_DEPENDENCY_NOT_MATCH % (ModuleObj.GetName(), \
|
||||
Dep.GetPackageFilePath(), \
|
||||
Dep.GetGuid(), \
|
||||
Dep.GetVersion()))
|
||||
return Result
|
||||
|
||||
## Check whether a package exists in current workspace.
|
||||
#
|
||||
# @param Guid: Guid of a package
|
||||
# @param Version: Version of a package
|
||||
#
|
||||
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
|
||||
if (PkgGuid == Guid):
|
||||
#
|
||||
# if version is not empty and not equal, then not match
|
||||
#
|
||||
if Version and (PkgVer != Version):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
Logger.Verbose(ST.MSG_CHECK_PACKAGE_FINISH)
|
||||
|
||||
## Check whether a package depex satisfied by current workspace.
|
||||
#
|
||||
# @param PkgObj: A package object
|
||||
# @param DpObj: A package depex object
|
||||
#
|
||||
def CheckPackageDepexSatisfied(self, PkgObj, DpObj=None, \
|
||||
ReturnCode=DEPEX_CHECK_SUCCESS):
|
||||
|
||||
ModuleDict = PkgObj.GetModuleDict()
|
||||
for ModKey in ModuleDict.keys():
|
||||
ModObj = ModuleDict[ModKey]
|
||||
if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
|
||||
continue
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
## Check whether a DP exists in current workspace.
|
||||
#
|
||||
# @param Guid: Guid of a module
|
||||
# @param Version: Version of a module
|
||||
#
|
||||
def CheckDpExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS):
|
||||
if ReturnCode:
|
||||
pass
|
||||
Logger.Verbose(ST.MSG_CHECK_DP_START)
|
||||
DpList = self.IpiDb.GetDp(Guid, Version)
|
||||
if len(DpList) > 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
Logger.Verbose(ST.MSG_CHECK_DP_FINISH)
|
||||
|
||||
## Check whether a DP depex satisfied by current workspace.
|
||||
#
|
||||
# @param DpObj: Depex object
|
||||
# @param ReturnCode: ReturnCode
|
||||
#
|
||||
def CheckDpDepexSatisfied(self, DpObj, ReturnCode=DEPEX_CHECK_SUCCESS):
|
||||
|
||||
for PkgKey in DpObj.PackageSurfaceArea.keys():
|
||||
PkgObj = DpObj.PackageSurfaceArea[PkgKey]
|
||||
if self.CheckPackageDepexSatisfied(PkgObj, DpObj, ReturnCode):
|
||||
continue
|
||||
else:
|
||||
return False
|
||||
|
||||
for ModKey in DpObj.ModuleSurfaceArea.keys():
|
||||
ModObj = DpObj.ModuleSurfaceArea[ModKey]
|
||||
if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
|
||||
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
|
||||
#
|
||||
# @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
|
||||
Removable = True
|
||||
DependModuleList = []
|
||||
WsModuleList = self.WsModuleList
|
||||
#
|
||||
# remove modules that included in current DP
|
||||
# List of item (FilePath)
|
||||
DpModuleList = self.IpiDb.GetDpModuleList(DpGuid, DpVersion)
|
||||
for Module in DpModuleList:
|
||||
if Module in WsModuleList:
|
||||
WsModuleList.remove(Module)
|
||||
else:
|
||||
Logger.Warn("UPT\n",
|
||||
ST.ERR_MODULE_NOT_INSTALLED % Module)
|
||||
#
|
||||
# get packages in current Dp and find the install path
|
||||
# List of item (PkgGuid, PkgVersion, InstallPath)
|
||||
DpPackageList = self.IpiDb.GetPackageListFromDp(DpGuid, DpVersion)
|
||||
DpPackagePathList = []
|
||||
WorkSP = environ["WORKSPACE"]
|
||||
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:]
|
||||
else:
|
||||
InstallPath = DecPath
|
||||
DecFileRelaPath = DecFile
|
||||
|
||||
if (PkgGuid, PkgVersion, InstallPath) in DpPackageList:
|
||||
DpPackagePathList.append(DecFileRelaPath)
|
||||
DpPackageList.remove((PkgGuid, PkgVersion, InstallPath))
|
||||
|
||||
#
|
||||
# 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 has dependency on package of current DP
|
||||
#
|
||||
for Module in WsModuleList:
|
||||
if (CheckModuleDependFromInf(Module, DpPackagePathList)):
|
||||
Removable = False
|
||||
DependModuleList.append(Module)
|
||||
return (Removable, 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
|
||||
#
|
||||
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')
|
||||
|
||||
try:
|
||||
PomAli = InfPomAlignment(Path, WorkSP, Skip=True)
|
||||
|
||||
for Item in PomAli.GetPackageDependencyList():
|
||||
if Item.GetPackageFilePath() in DpPackagePathList:
|
||||
Logger.Info(ST.MSG_MODULE_DEPEND_ON % (Path, Item.GetPackageFilePath()))
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except FatalError, ErrCode:
|
||||
if ErrCode.message == EDK1_INF_ERROR:
|
||||
Logger.Warn("UPT",
|
||||
ST.WRN_EDK1_INF_FOUND%Path)
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user