summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/PackagingTool
diff options
context:
space:
mode:
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2009-07-17 09:10:31 +0000
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2009-07-17 09:10:31 +0000
commit30fdf1140b8d1ce93f3821d986fa165552023440 (patch)
treec45c336a8955b1d03ea56d6c915a0e68a43b4ee9 /BaseTools/Source/Python/PackagingTool
parent577e30cdb473e4af8e65fd6f75236691d0c8dfb3 (diff)
downloadedk2-platforms-30fdf1140b8d1ce93f3821d986fa165552023440.tar.xz
Check In tool source code based on Build tool project revision r1655.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8964 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'BaseTools/Source/Python/PackagingTool')
-rw-r--r--BaseTools/Source/Python/PackagingTool/DependencyRules.py185
-rw-r--r--BaseTools/Source/Python/PackagingTool/InstallPkg.py309
-rw-r--r--BaseTools/Source/Python/PackagingTool/IpiDb.py629
-rw-r--r--BaseTools/Source/Python/PackagingTool/MkPkg.py294
-rw-r--r--BaseTools/Source/Python/PackagingTool/PackageFile.py160
-rw-r--r--BaseTools/Source/Python/PackagingTool/RmPkg.py218
6 files changed, 1795 insertions, 0 deletions
diff --git a/BaseTools/Source/Python/PackagingTool/DependencyRules.py b/BaseTools/Source/Python/PackagingTool/DependencyRules.py
new file mode 100644
index 0000000000..402694054e
--- /dev/null
+++ b/BaseTools/Source/Python/PackagingTool/DependencyRules.py
@@ -0,0 +1,185 @@
+## @file
+# This file is for installed package information database operations
+#
+# Copyright (c) 2007 ~ 2008, Intel Corporation
+# All rights reserved. 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.
+#
+
+##
+# Import Modules
+#
+import sqlite3
+import os
+
+import Common.EdkLogger as EdkLogger
+import IpiDb
+
+(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 databse
+# Add/Remove/Get installed distribution package information here.
+#
+#
+# @param object: Inherited from object class
+# @param DbPath: A string for the path of the database
+#
+# @var Conn: Connection of the database
+# @var Cur: Cursor of the connection
+#
+class DependencyRules(object):
+ def __init__(self, Db):
+ self.IpiDb = Db
+
+ ## Check whether a module exists in current workspace.
+ #
+ # @param Guid:
+ # @param Version:
+ #
+ def CheckModuleExists(self, Guid, Version, ReturnCode = DEPEX_CHECK_SUCCESS):
+ EdkLogger.verbose("\nCheck module exists in workspace started ...")
+ ModuleList = []
+ ModuleList = self.IpiDb.GetModInPackage(Guid, Version)
+ ModuleList.extend(self.IpiDb.GetStandaloneModule(Guid, Version))
+ EdkLogger.verbose("Check module exists in workspace ... DONE!")
+ if len(ModuleList) > 0:
+ return True
+ else:
+ ReturnCode = DEPEX_CHECK_MODULE_NOT_FOUND
+ return False
+
+
+ ## Check whether a module depex satified by current workspace.
+ #
+ # @param ModuleObj:
+ # @param DpObj:
+ #
+ def CheckModuleDepexSatisfied(self, ModuleObj, DpObj = None, ReturnCode = DEPEX_CHECK_SUCCESS):
+ EdkLogger.verbose("\nCheck module depex met by workspace started ...")
+ for Dep in ModuleObj.PackageDependencies:
+ Exist = self.CheckPackageExists(Dep.PackageGuid, Dep.PackageVersion, ReturnCode)
+ if not Exist:
+ if DpObj == None:
+ ReturnCode = DEPEX_CHECK_PACKAGE_NOT_FOUND
+ return False
+ for GuidVerPair in DpObj.PackageSurfaceArea.keys():
+ if Dep.PackageGuid == GuidVerPair[0]:
+ if Dep.PackageVersion == None or len(Dep.PackageVersion) == 0:
+ break
+ if Dep.PackageVersion == GuidVerPair[1]:
+ break
+ else:
+ ReturnCode = DEPEX_CHECK_PACKAGE_NOT_FOUND
+ return False
+ else:
+ ReturnCode = DEPEX_CHECK_PACKAGE_NOT_FOUND
+ return False
+ return True
+
+ EdkLogger.verbose("Check module depex met by workspace ... DONE!")
+
+ ## Check whether a package exists in current workspace.
+ #
+ # @param Guid:
+ # @param Version:
+ #
+ def CheckPackageExists(self, Guid, Version, ReturnCode = DEPEX_CHECK_SUCCESS):
+ EdkLogger.verbose("\nCheck package exists in workspace started ...")
+ PkgList = []
+ PkgList = self.IpiDb.GetPackage(Guid, Version)
+ if len(PkgList) > 0:
+ return True
+ else:
+ ReturnCode = DEPEX_CHECK_PACKAGE_NOT_FOUND
+ return False
+
+ EdkLogger.verbose("Check package exists in workspace ... DONE!")
+
+ ## Check whether a package depex satified by current workspace.
+ #
+ # @param ModuleObj:
+ # @param DpObj:
+ #
+ def CheckPackageDepexSatisfied(self, PkgObj, DpObj = None, ReturnCode = DEPEX_CHECK_SUCCESS):
+
+ for ModKey in PkgObj.Modules.keys():
+ ModObj = PkgObj.Modules[ModKey]
+ if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
+ continue
+ else:
+ return False
+ return True
+
+ ## Check whether a DP exists in current workspace.
+ #
+ # @param Guid:
+ # @param Version:
+ #
+ def CheckDpExists(self, Guid, Version, ReturnCode = DEPEX_CHECK_SUCCESS):
+ EdkLogger.verbose("\nCheck DP exists in workspace started ...")
+ DpList = []
+ DpList = self.IpiDb.GetDp(Guid, Version)
+ if len(DpList) > 0:
+ return True
+ else:
+ ReturnCode = DEPEX_CHECK_DP_NOT_FOUND
+ return False
+
+ EdkLogger.verbose("Check DP exists in workspace ... DONE!")
+
+ ## Check whether a DP depex satified by current workspace.
+ #
+ # @param ModuleObj:
+ # @param DpObj:
+ #
+ 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 = PkgObj.ModuleSurfaceArea[ModKey]
+ if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
+ continue
+ else:
+ return False
+
+ return True
+
+ ## Check whether a DP depex satified by current workspace.
+ #
+ # @param ModuleObj:
+ # @param DpObj:
+ #
+ def CheckDpDepexForRemove(self, DpGuid, DpVersion, ReturnCode = DEPEX_CHECK_SUCCESS):
+
+ # Get mod list that is dependent on pkg installed from this DP.
+ ModList = self.IpiDb.GetDpDependentModuleList(DpGuid, DpVersion)
+
+ if len(ModList) > 0:
+ return False
+
+ return True
+##
+#
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+#
+if __name__ == '__main__':
+ EdkLogger.Initialize()
+ EdkLogger.SetLevel(EdkLogger.DEBUG_0)
+
+
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/PackagingTool/InstallPkg.py b/BaseTools/Source/Python/PackagingTool/InstallPkg.py
new file mode 100644
index 0000000000..963a654ea1
--- /dev/null
+++ b/BaseTools/Source/Python/PackagingTool/InstallPkg.py
@@ -0,0 +1,309 @@
+## @file
+# Install distribution package.
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. 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.
+#
+
+##
+# Import Modules
+#
+import os
+import sys
+import glob
+import shutil
+import traceback
+import platform
+from optparse import OptionParser
+
+import Common.EdkLogger as EdkLogger
+from Common.BuildToolError import *
+from Common.Misc import *
+from Common.XmlParser import *
+from Common.InfClassObjectLight import Inf
+from Common.DecClassObjectLight import Dec
+
+from PackageFile import *
+from IpiDb import *
+from DependencyRules import *
+import md5
+
+# Version and Copyright
+VersionNumber = "0.1"
+__version__ = "%prog Version " + VersionNumber
+__copyright__ = "Copyright (c) 2008, Intel Corporation All rights reserved."
+
+## Check environment variables
+#
+# Check environment variables that must be set for build. Currently they are
+#
+# WORKSPACE The directory all packages/platforms start from
+# EDK_TOOLS_PATH The directory contains all tools needed by the build
+# PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
+#
+# If any of above environment variable is not set or has error, the build
+# will be broken.
+#
+def CheckEnvVariable():
+ # check WORKSPACE
+ if "WORKSPACE" not in os.environ:
+ EdkLogger.error("InstallPkg", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
+ ExtraData="WORKSPACE")
+
+ WorkspaceDir = os.path.normpath(os.environ["WORKSPACE"])
+ if not os.path.exists(WorkspaceDir):
+ EdkLogger.error("InstallPkg", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir)
+ elif ' ' in WorkspaceDir:
+ EdkLogger.error("InstallPkg", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path",
+ ExtraData=WorkspaceDir)
+ os.environ["WORKSPACE"] = WorkspaceDir
+
+## Parse command line options
+#
+# Using standard Python module optparse to parse command line option of this tool.
+#
+# @retval Opt A optparse.Values object containing the parsed options
+# @retval Args Target of build command
+#
+def MyOptionParser():
+ UsageString = "%prog -i <distribution_package> [-t] [-f] [-q | -v] [-h]"
+
+ Parser = OptionParser(description=__copyright__,version=__version__,prog="InstallPkg",usage=UsageString)
+
+ Parser.add_option("-?", action="help", help="show this help message and exit")
+
+ Parser.add_option("-i", "--distribution-package", action="store", type="string", dest="PackageFile",
+ help="The distribution package to be installed")
+
+ Parser.add_option("-t", "--install-tools", action="store_true", type=None, dest="Tools",
+ help="Specify it to install tools or ignore the tools of the distribution package.")
+
+ Parser.add_option("-f", "--misc-files", action="store_true", type=None, dest="MiscFiles",
+ help="Specify it to install misc file or ignore the misc files of the distribution package.")
+
+ Parser.add_option("-q", "--quiet", action="store_const", dest="LogLevel", const=EdkLogger.QUIET,
+ help="Disable all messages except FATAL ERRORS.")
+
+ Parser.add_option("-v", "--verbose", action="store_const", dest="LogLevel", const=EdkLogger.VERBOSE,
+ help="Turn on verbose output")
+
+ Parser.add_option("-d", "--debug", action="store", type="int", dest="LogLevel",
+ help="Enable debug messages at specified level.")
+
+ Parser.set_defaults(LogLevel=EdkLogger.INFO)
+
+ (Opt, Args)=Parser.parse_args()
+
+ return Opt
+
+def InstallNewPackage(WorkspaceDir, Path):
+ FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))
+ if os.path.exists(FullPath):
+ print "Directory [%s] already exists, please select another location, press [Enter] with no input to quit:" %Path
+ Input = sys.stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input == '':
+ EdkLogger.error("InstallPkg", UNKNOWN_ERROR, "User interrupt")
+ Input = Input.replace('\r', '').replace('\n', '')
+ return InstallNewPackage(WorkspaceDir, Input)
+ else:
+ return Path
+
+def InstallNewFile(WorkspaceDir, File):
+ FullPath = os.path.normpath(os.path.join(WorkspaceDir, File))
+ if os.path.exists(FullPath):
+ print "File [%s] already exists, please select another path, press [Enter] with no input to quit:" %File
+ Input = sys.stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input == '':
+ EdkLogger.error("InstallPkg", UNKNOWN_ERROR, "User interrupt")
+ Input = Input.replace('\r', '').replace('\n', '')
+ return InstallNewFile(WorkspaceDir, Input)
+ else:
+ return File
+
+## Tool entrance method
+#
+# This method mainly dispatch specific methods per the command line options.
+# If no error found, return zero value so the caller of this tool can know
+# if it's executed successfully or not.
+#
+# @retval 0 Tool was successful
+# @retval 1 Tool failed
+#
+def Main():
+ EdkLogger.Initialize()
+ Options = None
+ DistFileName = 'dist.pkg'
+ ContentFileName = 'content.zip'
+ DistFile, ContentZipFile, UnpackDir = None, None, None
+
+ Options = MyOptionParser()
+ try:
+ if Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.SetLevel(Options.LogLevel + 1)
+ else:
+ EdkLogger.SetLevel(Options.LogLevel)
+
+ CheckEnvVariable()
+ WorkspaceDir = os.environ["WORKSPACE"]
+ if not Options.PackageFile:
+ EdkLogger.error("InstallPkg", OPTION_NOT_SUPPORTED, ExtraData="Must specify one distribution package")
+
+ # unzip dist.pkg file
+ EdkLogger.quiet("Unzipping and parsing distribution package XML file ... ")
+ DistFile = PackageFile(Options.PackageFile)
+ UnpackDir = os.path.normpath(os.path.join(WorkspaceDir, ".tmp"))
+ DistPkgFile = DistFile.UnpackFile(DistFileName, os.path.normpath(os.path.join(UnpackDir, DistFileName)))
+ if not DistPkgFile:
+ EdkLogger.error("InstallPkg", FILE_NOT_FOUND, "File [%s] is broken in distribution package" %DistFileName)
+
+ # Generate distpkg
+ DistPkgObj = DistributionPackageXml()
+ DistPkg = DistPkgObj.FromXml(DistPkgFile)
+
+ # prepare check dependency
+ Db = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, "Conf/DistributionPackageDatabase.db")))
+ Db.InitDatabase()
+ Dep = DependencyRules(Db)
+
+ # Check distribution package exist
+ if Dep.CheckDpExists(DistPkg.Header.Guid, DistPkg.Header.Version):
+ EdkLogger.error("InstallPkg", UNKNOWN_ERROR, "This distribution package has been installed", ExtraData=DistPkg.Header.Name)
+
+ # unzip contents.zip file
+ ContentFile = DistFile.UnpackFile(ContentFileName, os.path.normpath(os.path.join(UnpackDir, ContentFileName)))
+ ContentZipFile = PackageFile(ContentFile)
+ if not ContentFile:
+ EdkLogger.error("InstallPkg", FILE_NOT_FOUND, "File [%s] is broken in distribution package" %ContentFileName)
+
+ # verify MD5 signature
+ Md5Sigature = md5.new(open(ContentFile).read())
+ if DistPkg.Header.Signature != Md5Sigature.hexdigest():
+ EdkLogger.error("InstallPkg", FILE_CHECKSUM_FAILURE, ExtraData=ContentFile)
+
+ # Check package exist and install
+ for Guid,Version,Path in DistPkg.PackageSurfaceArea:
+ PackagePath = os.path.dirname(Path)
+ NewPackagePath = PackagePath
+ Package = DistPkg.PackageSurfaceArea[Guid,Version,Path]
+ EdkLogger.info("Installing package ... %s" % Package.PackageHeader.Name)
+ if Dep.CheckPackageExists(Guid, Version):
+ EdkLogger.quiet("Package [%s] has been installed" %Path)
+ NewPackagePath = InstallNewPackage(WorkspaceDir, PackagePath)
+ Package.FileList = []
+ for Item in Package.MiscFiles.Files:
+ FromFile = os.path.join(PackagePath, Item.Filename)
+ ToFile = os.path.normpath(os.path.join(WorkspaceDir, NewPackagePath, Item.Filename))
+ ContentZipFile.UnpackFile(FromFile, ToFile)
+ Package.FileList.append(ToFile)
+
+ # Update package
+ Package.PackageHeader.CombinePath = Package.PackageHeader.CombinePath.replace(PackagePath, NewPackagePath, 1)
+ # Update modules of package
+ Module = None
+ for ModuleGuid, ModuleVersion, ModulePath in Package.Modules:
+ Module = Package.Modules[ModuleGuid, ModuleVersion, ModulePath]
+ NewModulePath = ModulePath.replace(PackagePath, NewPackagePath, 1)
+ del Package.Modules[ModuleGuid, ModuleVersion, ModulePath]
+ Package.Modules[ModuleGuid, ModuleVersion, NewModulePath] = Module
+ del DistPkg.PackageSurfaceArea[Guid,Version,Path]
+ DistPkg.PackageSurfaceArea[Guid,Version,Package.PackageHeader.CombinePath] = Package
+
+# SaveFileOnChange(os.path.join(Options.InstallDir, ModulePath, Module.Header.Name, ".inf"), Inf.ModuleToInf(Module), False)
+# EdkLogger.info("Installing package ... %s" % Package.Header.Name)
+# shutil.copytree(os.path.join(ContentFileDir, Path), Options.InstallDir)
+# SaveFileOnChange(os.path.join(Options.InstallDir, Path, Package.Header.Name, ".dec"), Dec.PackageToDec(Package), False)
+
+ # Check module exist and install
+ Module = None
+ for Guid,Version,Path in DistPkg.ModuleSurfaceArea:
+ ModulePath = os.path.dirname(Path)
+ NewModulePath = ModulePath
+ Module = DistPkg.ModuleSurfaceArea[Guid,Version,Path]
+ EdkLogger.info("Installing module ... %s" % Module.ModuleHeader.Name)
+ if Dep.CheckModuleExists(Guid, Version):
+ EdkLogger.quiet("Module [%s] has been installed" %Path)
+ NewModulePath = InstallNewPackage(WorkspaceDir, ModulePath)
+ Module.FileList = []
+ for Item in Module.MiscFiles.Files:
+ ModulePath = ModulePath[os.path.normpath(ModulePath).rfind(os.path.normpath('/'))+1:]
+ FromFile = os.path.join(ModulePath, Item.Filename)
+ ToFile = os.path.normpath(os.path.join(WorkspaceDir, NewModulePath, Item.Filename))
+ ContentZipFile.UnpackFile(FromFile, ToFile)
+ Module.FileList.append(ToFile)
+
+# EdkLogger.info("Installing module ... %s" % Module.Header.Name)
+# shutil.copytree(os.path.join(ContentFileDir, Path), Options.InstallDir)
+# SaveFileOnChange(os.path.join(Options.InstallDir, Path, Module.Header.Name, ".inf"), Inf.ModuleToInf(Module), False)
+
+ # Update module
+ Module.ModuleHeader.CombinePath = Module.ModuleHeader.CombinePath.replace(os.path.dirname(Path), NewModulePath, 1)
+ del DistPkg.ModuleSurfaceArea[Guid,Version,Path]
+ DistPkg.ModuleSurfaceArea[Guid,Version,Module.ModuleHeader.CombinePath] = Module
+#
+#
+# for Guid,Version,Path in DistPkg.PackageSurfaceArea:
+# print Guid,Version,Path
+# for item in DistPkg.PackageSurfaceArea[Guid,Version,Path].FileList:
+# print item
+# for Guid,Version,Path in DistPkg.ModuleSurfaceArea:
+# print Guid,Version,Path
+# for item in DistPkg.ModuleSurfaceArea[Guid,Version,Path].FileList:
+# print item
+
+ if Options.Tools:
+ EdkLogger.info("Installing tools ... ")
+ for File in DistPkg.Tools.Files:
+ FromFile = File.Filename
+ ToFile = InstallNewFile(WorkspaceDir, FromFile)
+ ContentZipFile.UnpackFile(FromFile, ToFile)
+ if Options.MiscFiles:
+ EdkLogger.info("Installing misc files ... ")
+ for File in DistPkg.MiscellaneousFiles.Files:
+ FromFile = File.Filename
+ ToFile = InstallNewFile(WorkspaceDir, FromFile)
+ ContentZipFile.UnpackFile(FromFile, ToFile)
+
+ # update database
+ EdkLogger.quiet("Update Distribution Package Database ...")
+ Db.AddDPObject(DistPkg)
+
+ except FatalError, X:
+ if Options and Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ ReturnCode = X.args[0]
+ except KeyboardInterrupt:
+ ReturnCode = ABORT_ERROR
+ if Options and Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ except:
+ EdkLogger.error(
+ "\nInstallPkg",
+ CODE_ERROR,
+ "Unknown fatal error when installing [%s]" % Options.PackageFile,
+ ExtraData="\n(Please send email to dev@buildtools.tianocore.org for help, attaching following call stack trace!)\n",
+ RaiseError=False
+ )
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ ReturnCode = CODE_ERROR
+ finally:
+ EdkLogger.quiet("Removing temp files ... ")
+ if DistFile:
+ DistFile.Close()
+ if ContentZipFile:
+ ContentZipFile.Close()
+ if UnpackDir:
+ shutil.rmtree(UnpackDir)
+
+ EdkLogger.quiet("DONE")
+ Progressor.Abort()
+
+if __name__ == '__main__':
+ sys.exit(Main())
diff --git a/BaseTools/Source/Python/PackagingTool/IpiDb.py b/BaseTools/Source/Python/PackagingTool/IpiDb.py
new file mode 100644
index 0000000000..8661edbca4
--- /dev/null
+++ b/BaseTools/Source/Python/PackagingTool/IpiDb.py
@@ -0,0 +1,629 @@
+## @file
+# This file is for installed package information database operations
+#
+# Copyright (c) 2007 ~ 2008, Intel Corporation
+# All rights reserved. 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.
+#
+
+##
+# Import Modules
+#
+import sqlite3
+import os
+import time
+import Common.EdkLogger as EdkLogger
+
+from CommonDataClass import DistributionPackageClass
+
+## IpiDb
+#
+# This class represents the installed package information databse
+# Add/Remove/Get installed distribution package information here.
+#
+#
+# @param object: Inherited from object class
+# @param DbPath: A string for the path of the database
+#
+# @var Conn: Connection of the database
+# @var Cur: Cursor of the connection
+#
+class IpiDatabase(object):
+ def __init__(self, DbPath):
+ Dir = os.path.dirname(DbPath)
+ if not os.path.isdir(Dir):
+ os.mkdir(Dir)
+ self.Conn = sqlite3.connect(DbPath, isolation_level = 'DEFERRED')
+ self.Conn.execute("PRAGMA page_size=4096")
+ self.Conn.execute("PRAGMA synchronous=OFF")
+ self.Cur = self.Conn.cursor()
+ self.DpTable = 'DpInfo'
+ self.PkgTable = 'PkgInfo'
+ self.ModInPkgTable = 'ModInPkgInfo'
+ self.StandaloneModTable = 'StandaloneModInfo'
+ self.ModDepexTable = 'ModDepexInfo'
+ self.DpFileListTable = 'DpFileListInfo'
+
+ ## Initialize build database
+ #
+ #
+ def InitDatabase(self):
+ EdkLogger.verbose("\nInitialize IPI database started ...")
+
+ #
+ # Create new table
+ #
+ SqlCommand = """create table IF NOT EXISTS %s (DpGuid TEXT NOT NULL,
+ DpVersion TEXT NOT NULL,
+ InstallTime REAL NOT NULL,
+ PkgFileName TEXT,
+ PRIMARY KEY (DpGuid, DpVersion)
+ )""" % self.DpTable
+ self.Cur.execute(SqlCommand)
+
+ SqlCommand = """create table IF NOT EXISTS %s (FilePath TEXT NOT NULL,
+ DpGuid TEXT,
+ DpVersion TEXT,
+ PRIMARY KEY (FilePath)
+ )""" % self.DpFileListTable
+ self.Cur.execute(SqlCommand)
+
+ SqlCommand = """create table IF NOT EXISTS %s (PackageGuid TEXT NOT NULL,
+ PackageVersion TEXT NOT NULL,
+ InstallTime REAL NOT NULL,
+ DpGuid TEXT,
+ DpVersion TEXT,
+ InstallPath TEXT NOT NULL,
+ PRIMARY KEY (PackageGuid, PackageVersion, InstallPath)
+ )""" % self.PkgTable
+ self.Cur.execute(SqlCommand)
+
+ SqlCommand = """create table IF NOT EXISTS %s (ModuleGuid TEXT NOT NULL,
+ ModuleVersion TEXT NOT NULL,
+ InstallTime REAL NOT NULL,
+ PackageGuid TEXT,
+ PackageVersion TEXT,
+ InstallPath TEXT NOT NULL,
+ PRIMARY KEY (ModuleGuid, ModuleVersion, InstallPath)
+ )""" % self.ModInPkgTable
+ self.Cur.execute(SqlCommand)
+
+ SqlCommand = """create table IF NOT EXISTS %s (ModuleGuid TEXT NOT NULL,
+ ModuleVersion TEXT NOT NULL,
+ InstallTime REAL NOT NULL,
+ DpGuid TEXT,
+ DpVersion TEXT,
+ InstallPath TEXT NOT NULL,
+ PRIMARY KEY (ModuleGuid, ModuleVersion, InstallPath)
+ )""" % self.StandaloneModTable
+ self.Cur.execute(SqlCommand)
+
+ SqlCommand = """create table IF NOT EXISTS %s (ModuleGuid TEXT NOT NULL,
+ ModuleVersion TEXT NOT NULL,
+ InstallPath TEXT NOT NULL,
+ DepexGuid TEXT,
+ DepexVersion TEXT
+ )""" % self.ModDepexTable
+ self.Cur.execute(SqlCommand)
+
+ self.Conn.commit()
+
+ EdkLogger.verbose("Initialize IPI database ... DONE!")
+
+ ## Add a distribution install information from DpObj
+ #
+ # @param DpObj:
+ #
+ def AddDPObject(self, DpObj):
+
+ for PkgKey in DpObj.PackageSurfaceArea.keys():
+ PkgGuid = PkgKey[0]
+ PkgVersion = PkgKey[1]
+ PkgInstallPath = PkgKey[2]
+ self.AddPackage(PkgGuid, PkgVersion, DpObj.Header.Guid, DpObj.Header.Version, PkgInstallPath)
+ PkgObj = DpObj.PackageSurfaceArea[PkgKey]
+ for ModKey in PkgObj.Modules.keys():
+ ModGuid = ModKey[0]
+ ModVersion = ModKey[1]
+ ModInstallPath = ModKey[2]
+ self.AddModuleInPackage(ModGuid, ModVersion, PkgGuid, PkgVersion, ModInstallPath)
+ ModObj = PkgObj.Modules[ModKey]
+ for Dep in ModObj.PackageDependencies:
+ DepexGuid = Dep.PackageGuid
+ DepexVersion = Dep.PackageVersion
+ self.AddModuleDepex(ModGuid, ModVersion, ModInstallPath, DepexGuid, DepexVersion)
+ for FilePath in PkgObj.FileList:
+ self.AddDpFilePathList(DpObj.Header.Guid, DpObj.Header.Version, FilePath)
+
+ for ModKey in DpObj.ModuleSurfaceArea.keys():
+ ModGuid = ModKey[0]
+ ModVersion = ModKey[1]
+ ModInstallPath = ModKey[2]
+ self.AddStandaloneModule(ModGuid, ModVersion, DpObj.Header.Guid, DpObj.Header.Version, ModInstallPath)
+ ModObj = DpObj.ModuleSurfaceArea[ModKey]
+ for Dep in ModObj.PackageDependencies:
+ DepexGuid = Dep.PackageGuid
+ DepexVersion = Dep.PackageVersion
+ self.AddModuleDepex(ModGuid, ModVersion, ModInstallPath, DepexGuid, DepexVersion)
+ for FilePath in ModObj.FileList:
+ self.AddDpFilePathList(DpObj.Header.Guid, DpObj.Header.Version, FilePath)
+
+ self.AddDp(DpObj.Header.Guid, DpObj.Header.Version, DpObj.Header.FileName)
+ ## Add a distribution install information
+ #
+ # @param Guid:
+ # @param Version:
+ # @param PkgFileName:
+ #
+ def AddDp(self, Guid, Version, PkgFileName = None):
+
+ if Version == None or len(Version.strip()) == 0:
+ Version = 'N/A'
+
+ #
+ # Add newly installed DP information to DB.
+ #
+ if PkgFileName == None or len(PkgFileName.strip()) == 0:
+ PkgFileName = 'N/A'
+ (Guid, Version, PkgFileName) = (Guid, Version, PkgFileName)
+ CurrentTime = time.time()
+ SqlCommand = """insert into %s values('%s', '%s', %s, '%s')""" % (self.DpTable, Guid, Version, CurrentTime, PkgFileName)
+ self.Cur.execute(SqlCommand)
+ self.Conn.commit()
+
+ ## Add a file list from DP
+ #
+ # @param DpGuid:
+ # @param DpVersion:
+ # @param Path
+ #
+ def AddDpFilePathList(self, DpGuid, DpVersion, Path):
+
+ SqlCommand = """insert into %s values('%s', '%s', '%s')""" % (self.DpFileListTable, Path, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+ self.Conn.commit()
+
+ ## Add a package install information
+ #
+ # @param Guid:
+ # @param Version:
+ # @param DpGuid:
+ # @param DpVersion:
+ # @param Path
+ #
+ def AddPackage(self, Guid, Version, DpGuid = None, DpVersion = None, Path = ''):
+
+ if Version == None or len(Version.strip()) == 0:
+ Version = 'N/A'
+
+ if DpGuid == None or len(DpGuid.strip()) == 0:
+ DpGuid = 'N/A'
+
+ if DpVersion == None or len(DpVersion.strip()) == 0:
+ DpVersion = 'N/A'
+
+ #
+ # Add newly installed package information to DB.
+ #
+
+ CurrentTime = time.time()
+ SqlCommand = """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % (self.PkgTable, Guid, Version, CurrentTime, DpGuid, DpVersion, Path)
+ self.Cur.execute(SqlCommand)
+ self.Conn.commit()
+
+ ## Add a module that from a package install information
+ #
+ # @param Guid:
+ # @param Version:
+ # @param PkgFileName:
+ #
+ def AddModuleInPackage(self, Guid, Version, PkgGuid = None, PkgVersion = None, Path = ''):
+
+ if Version == None or len(Version.strip()) == 0:
+ Version = 'N/A'
+
+ if PkgGuid == None or len(PkgGuid.strip()) == 0:
+ PkgGuid = 'N/A'
+
+ if PkgVersion == None or len(PkgVersion.strip()) == 0:
+ PkgVersion = 'N/A'
+
+ #
+ # Add module from package information to DB.
+ #
+ CurrentTime = time.time()
+ SqlCommand = """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % (self.ModInPkgTable, Guid, Version, CurrentTime, PkgGuid, PkgVersion, Path)
+ self.Cur.execute(SqlCommand)
+ self.Conn.commit()
+
+ ## Add a module that is standalone install information
+ #
+ # @param Guid:
+ # @param Version:
+ # @param PkgFileName:
+ #
+ def AddStandaloneModule(self, Guid, Version, DpGuid = None, DpVersion = None, Path = ''):
+
+ if Version == None or len(Version.strip()) == 0:
+ Version = 'N/A'
+
+ if DpGuid == None or len(DpGuid.strip()) == 0:
+ DpGuid = 'N/A'
+
+ if DpVersion == None or len(DpVersion.strip()) == 0:
+ DpVersion = 'N/A'
+
+ #
+ # Add module standalone information to DB.
+ #
+ CurrentTime = time.time()
+ SqlCommand = """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % (self.StandaloneModTable, Guid, Version, CurrentTime, DpGuid, DpVersion, Path)
+ self.Cur.execute(SqlCommand)
+ self.Conn.commit()
+
+ ## Add a module depex
+ #
+ # @param Guid:
+ # @param Version:
+ # @param DepexGuid:
+ # @param DepexVersion:
+ #
+ def AddModuleDepex(self, Guid, Version, Path, DepexGuid = None, DepexVersion = None):
+
+ if DepexGuid == None or len(DepexGuid.strip()) == 0:
+ DepexGuid = 'N/A'
+
+ if DepexVersion == None or len(DepexVersion.strip()) == 0:
+ DepexVersion = 'N/A'
+
+ #
+ # Add module depex information to DB.
+ #
+
+ SqlCommand = """insert into %s values('%s', '%s', '%s', '%s', '%s')""" % (self.ModDepexTable, Guid, Version, Path, DepexGuid, DepexVersion)
+ self.Cur.execute(SqlCommand)
+ self.Conn.commit()
+
+ ## Remove a distribution install information, if no version specified, remove all DPs with this Guid.
+ #
+ # @param DpObj:
+ #
+ def RemoveDpObj(self, DpGuid, DpVersion):
+
+ PkgList = self.GetPackageListFromDp(DpGuid, DpVersion)
+
+ # delete from ModDepex the standalone module's dependency
+ SqlCommand = """delete from ModDepexInfo where ModDepexInfo.ModuleGuid in
+ (select ModuleGuid from StandaloneModInfo as B where B.DpGuid = '%s' and B.DpVersion = '%s')
+ and ModDepexInfo.ModuleVersion in
+ (select ModuleVersion from StandaloneModInfo as B where B.DpGuid = '%s' and B.DpVersion = '%s')
+ and ModDepexInfo.InstallPath in
+ (select InstallPath from StandaloneModInfo as B where B.DpGuid = '%s' and B.DpVersion = '%s') """ \
+ %(DpGuid, DpVersion, DpGuid, DpVersion, DpGuid, DpVersion)
+
+# SqlCommand = """delete from %s where %s.DpGuid ='%s' and %s.DpVersion = '%s' and
+# %s.ModuleGuid = %s.ModuleGuid and %s.ModuleVersion = %s.ModuleVersion and
+# %s.InstallPath = %s.InstallPath""" \
+# % (self.ModDepexTable, self.StandaloneModTable, DpGuid, self.StandaloneModTable, DpVersion, self.ModDepexTable, self.StandaloneModTable, self.ModDepexTable, self.StandaloneModTable, self.ModDepexTable, self.StandaloneModTable)
+# print SqlCommand
+ self.Cur.execute(SqlCommand)
+
+ # delete from ModDepex the from pkg module's dependency
+ for Pkg in PkgList:
+# SqlCommand = """delete from %s where %s.PackageGuid ='%s' and %s.PackageVersion = '%s' and
+# %s.ModuleGuid = %s.ModuleGuid and %s.ModuleVersion = %s.ModuleVersion and
+# %s.InstallPath = %s.InstallPath""" \
+# % (self.ModDepexTable, self.ModInPkgTable, Pkg[0], self.ModInPkgTable, Pkg[1], self.ModDepexTable, self.ModInPkgTable, self.ModDepexTable, self.ModInPkgTable, self.ModDepexTable, self.ModInPkgTable)
+ SqlCommand = """delete from ModDepexInfo where ModDepexInfo.ModuleGuid in
+ (select ModuleGuid from ModInPkgInfo where ModInPkgInfo.PackageGuid ='%s' and ModInPkgInfo.PackageVersion = '%s')
+ and ModDepexInfo.ModuleVersion in
+ (select ModuleVersion from ModInPkgInfo where ModInPkgInfo.PackageGuid ='%s' and ModInPkgInfo.PackageVersion = '%s')
+ and ModDepexInfo.InstallPath in
+ (select InstallPath from ModInPkgInfo where ModInPkgInfo.PackageGuid ='%s' and ModInPkgInfo.PackageVersion = '%s')""" \
+ % (Pkg[0], Pkg[1],Pkg[0], Pkg[1],Pkg[0], Pkg[1])
+
+ self.Cur.execute(SqlCommand)
+
+ # delete the standalone module
+ SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.StandaloneModTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ # delete the from pkg module
+ for Pkg in PkgList:
+ SqlCommand = """delete from %s where %s.PackageGuid ='%s' and %s.PackageVersion = '%s'""" \
+ % (self.ModInPkgTable, self.ModInPkgTable, Pkg[0], self.ModInPkgTable, Pkg[1])
+ self.Cur.execute(SqlCommand)
+
+ # delete packages
+ SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.PkgTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ # delete file list from DP
+ SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpFileListTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ # delete DP
+ SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ self.Conn.commit()
+
+ ## Get a list of distribution install information.
+ #
+ # @param Guid:
+ # @param Version:
+ #
+ def GetDp(self, Guid, Version):
+
+ if Version == None or len(Version.strip()) == 0:
+ Version = 'N/A'
+ EdkLogger.verbose("\nGetting list of DP install information started ...")
+ (DpGuid, DpVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where DpGuid ='%s'""" % (self.DpTable, DpGuid)
+ self.Cur.execute(SqlCommand)
+
+ else:
+ EdkLogger.verbose("\nGetting DP install information started ...")
+ (DpGuid, DpVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ DpList = []
+ for DpInfo in self.Cur:
+ DpGuid = DpInfo[0]
+ DpVersion = DpInfo[1]
+ InstallTime = DpInfo[2]
+ PkgFileName = DpInfo[3]
+ DpList.append((DpGuid, DpVersion, InstallTime, PkgFileName))
+
+ EdkLogger.verbose("Getting DP install information ... DONE!")
+ return DpList
+
+ ## Get a list of distribution install file path information.
+ #
+ # @param Guid:
+ # @param Version:
+ #
+ def GetDpFileList(self, Guid, Version):
+
+ (DpGuid, DpVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpFileListTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ PathList = []
+ for Result in self.Cur:
+ Path = Result[0]
+ PathList.append(Path)
+
+ return PathList
+
+ ## Get a list of package information.
+ #
+ # @param Guid:
+ # @param Version:
+ #
+ def GetPackage(self, Guid, Version, DpGuid = '', DpVersion = ''):
+
+ if DpVersion == '' or DpGuid == '':
+
+ (PackageGuid, PackageVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where PackageGuid ='%s' and PackageVersion = '%s'""" % (self.PkgTable, PackageGuid, PackageVersion)
+ self.Cur.execute(SqlCommand)
+
+ elif Version == None or len(Version.strip()) == 0:
+
+ SqlCommand = """select * from %s where PackageGuid ='%s'""" % (self.PkgTable, Guid)
+ self.Cur.execute(SqlCommand)
+ else:
+ (PackageGuid, PackageVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where PackageGuid ='%s' and PackageVersion = '%s'
+ and DpGuid = '%s' and DpVersion = '%s'""" % (self.PkgTable, PackageGuid, PackageVersion, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ PkgList = []
+ for PkgInfo in self.Cur:
+ PkgGuid = PkgInfo[0]
+ PkgVersion = PkgInfo[1]
+ InstallTime = PkgInfo[2]
+ InstallPath = PkgInfo[5]
+ PkgList.append((PkgGuid, PkgVersion, InstallTime, DpGuid, DpVersion, InstallPath))
+
+ return PkgList
+
+ ## Get a list of module in package information.
+ #
+ # @param Guid:
+ # @param Version:
+ #
+ def GetModInPackage(self, Guid, Version, PkgGuid = '', PkgVersion = ''):
+
+ if PkgVersion == '' or PkgGuid == '':
+
+ (ModuleGuid, ModuleVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s'""" % (self.ModInPkgTable, ModuleGuid, ModuleVersion)
+ self.Cur.execute(SqlCommand)
+
+ else:
+ (ModuleGuid, ModuleVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s' and PackageGuid ='%s' and PackageVersion = '%s'
+ """ % (self.ModInPkgTable, ModuleGuid, ModuleVersion, PkgGuid, PkgVersion)
+ self.Cur.execute(SqlCommand)
+
+ ModList = []
+ for ModInfo in self.Cur:
+ ModGuid = ModInfo[0]
+ ModVersion = ModInfo[1]
+ InstallTime = ModInfo[2]
+ InstallPath = ModInfo[5]
+ ModList.append((ModGuid, ModVersion, InstallTime, PkgGuid, PkgVersion, InstallPath))
+
+ return ModList
+
+ ## Get a list of module standalone.
+ #
+ # @param Guid:
+ # @param Version:
+ #
+ def GetStandaloneModule(self, Guid, Version, DpGuid = '', DpVersion = ''):
+
+ if DpGuid == '':
+
+ (ModuleGuid, ModuleVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s'""" % (self.StandaloneModTable, ModuleGuid, ModuleVersion)
+ self.Cur.execute(SqlCommand)
+
+ else:
+ (ModuleGuid, ModuleVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s' and DpGuid ='%s' and DpVersion = '%s'
+ """ % (self.StandaloneModTable, ModuleGuid, ModuleVersion, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ ModList = []
+ for ModInfo in self.Cur:
+ ModGuid = ModInfo[0]
+ ModVersion = ModInfo[1]
+ InstallTime = ModInfo[2]
+ InstallPath = ModInfo[5]
+ ModList.append((ModGuid, ModVersion, InstallTime, DpGuid, DpVersion, InstallPath))
+
+ return ModList
+
+ ## Get a list of module information that comes from DP.
+ #
+ # @param DpGuid:
+ # @param DpVersion:
+ #
+ def GetStandaloneModuleInstallPathListFromDp(self, DpGuid, DpVersion):
+
+ PathList = []
+ SqlCommand = """select t1.InstallPath from %s t1 where t1.DpGuid ='%s' and t1.DpVersion = '%s'
+ """ % (self.StandaloneModTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ for Result in self.Cur:
+ InstallPath = Result[0]
+ PathList.append(InstallPath)
+
+ return PathList
+
+ ## Get a list of package information.
+ #
+ # @param DpGuid:
+ # @param DpVersion:
+ #
+ def GetPackageListFromDp(self, DpGuid, DpVersion):
+
+
+ SqlCommand = """select * from %s where DpGuid ='%s' and DpVersion = '%s'
+ """ % (self.PkgTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ PkgList = []
+ for PkgInfo in self.Cur:
+ PkgGuid = PkgInfo[0]
+ PkgVersion = PkgInfo[1]
+ InstallPath = PkgInfo[5]
+ PkgList.append((PkgGuid, PkgVersion, InstallPath))
+
+ return PkgList
+
+ ## Get a list of modules that depends on package information from a DP.
+ #
+ # @param DpGuid:
+ # @param DpVersion:
+ #
+ def GetDpDependentModuleList(self, DpGuid, DpVersion):
+
+ ModList = []
+ PkgList = self.GetPackageListFromDp(DpGuid, DpVersion)
+ if len(PkgList) > 0:
+ return ModList
+
+ for Pkg in PkgList:
+ SqlCommand = """select t1.ModuleGuid, t1.ModuleVersion, t1.InstallPath
+ from %s as t1, %s as t2, where t1.ModuleGuid = t2.ModuleGuid and
+ t1.ModuleVersion = t2.ModuleVersion and t2.DepexGuid ='%s' and (t2.DepexVersion = '%s' or t2.DepexVersion = 'N/A') and
+ t1.PackageGuid != '%s' and t1.PackageVersion != '%s'
+ """ % (self.ModInPkgTable, self.ModDepexTable, Pkg[0], Pkg[1], Pkg[0], Pkg[1])
+ self.Cur.execute(SqlCommand)
+ for ModInfo in self.Cur:
+ ModGuid = ModInfo[0]
+ ModVersion = ModInfo[1]
+ InstallPath = ModInfo[2]
+ ModList.append((ModGuid, ModVersion, InstallPath))
+
+ SqlCommand = """select t1.ModuleGuid, t1.ModuleVersion, t1.InstallPath
+ from %s as t1, %s as t2, where t1.ModuleGuid = t2.ModuleGuid and
+ t1.ModuleVersion = t2.ModuleVersion and t2.DepexGuid ='%s' and (t2.DepexVersion = '%s' or t2.DepexVersion = 'N/A') and
+ t1.DpGuid != '%s' and t1.DpVersion != '%s'
+ """ % (self.StandaloneModTable, self.ModDepexTable, Pkg[0], Pkg[1], DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+ for ModInfo in self.Cur:
+ ModGuid = ModInfo[0]
+ ModVersion = ModInfo[1]
+ InstallPath = ModInfo[2]
+ ModList.append((ModGuid, ModVersion, InstallPath))
+
+
+ return ModList
+
+ ## Get a module depex
+ #
+ # @param Guid:
+ # @param Version:
+ # @param Path:
+ #
+ def GetModuleDepex(self, Guid, Version, Path):
+
+ #
+ # Get module depex information to DB.
+ #
+
+ SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s' and InstallPath ='%s'
+ """ % (self.ModDepexTable, Guid, Version, Path)
+ self.Cur.execute(SqlCommand)
+ self.Conn.commit()
+
+ DepexList = []
+ for DepInfo in self.Cur:
+ DepexGuid = DepInfo[3]
+ DepexVersion = DepInfo[4]
+ DepexList.append((DepexGuid, DepexVersion))
+
+ return DepexList
+
+ ## Close entire database
+ #
+ # Close the connection and cursor
+ #
+ def CloseDb(self):
+
+ self.Cur.close()
+ self.Conn.close()
+
+ ## Convert To Sql String
+ #
+ # 1. Replace "'" with "''" in each item of StringList
+ #
+ # @param StringList: A list for strings to be converted
+ #
+ def __ConvertToSqlString(self, StringList):
+ return map(lambda s: s.replace("'", "''") , StringList)
+##
+#
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+#
+if __name__ == '__main__':
+ EdkLogger.Initialize()
+ EdkLogger.SetLevel(EdkLogger.DEBUG_0)
+ DATABASE_PATH = "C://MyWork//Conf//.cache//XML.db"
+ Db = IpiDatabase(DATABASE_PATH)
+ Db.InitDatabase()
+
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/PackagingTool/MkPkg.py b/BaseTools/Source/Python/PackagingTool/MkPkg.py
new file mode 100644
index 0000000000..660f48f05f
--- /dev/null
+++ b/BaseTools/Source/Python/PackagingTool/MkPkg.py
@@ -0,0 +1,294 @@
+## @file
+# Install distribution package.
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. 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.
+#
+
+##
+# Import Modules
+#
+import os
+import os.path
+import sys
+import glob
+import shutil
+import traceback
+import platform
+from optparse import OptionParser
+import md5
+import time
+import uuid
+
+from PackageFile import *
+import Common.EdkLogger as EdkLogger
+from Common.BuildToolError import *
+from Common.Misc import *
+from Common.XmlParser import *
+from CommonDataClass.DistributionPackageClass import *
+from Common.DecClassObjectLight import Dec
+from Common.InfClassObjectLight import Inf
+
+from PackageFile import *
+
+# Version and Copyright
+VersionNumber = "0.1"
+__version__ = "%prog Version " + VersionNumber
+__copyright__ = "Copyright (c) 2008, Intel Corporation All rights reserved."
+
+## Check environment variables
+#
+# Check environment variables that must be set for build. Currently they are
+#
+# WORKSPACE The directory all packages/platforms start from
+# EDK_TOOLS_PATH The directory contains all tools needed by the build
+# PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
+#
+# If any of above environment variable is not set or has error, the build
+# will be broken.
+#
+def CheckEnvVariable():
+ # check WORKSPACE
+ if "WORKSPACE" not in os.environ:
+ EdkLogger.error("MkPkg", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
+ ExtraData="WORKSPACE")
+
+ WorkspaceDir = os.path.normpath(os.environ["WORKSPACE"])
+ if not os.path.exists(WorkspaceDir):
+ EdkLogger.error("MkPkg", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir)
+ elif ' ' in WorkspaceDir:
+ EdkLogger.error("MkPkg", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path",
+ ExtraData=WorkspaceDir)
+ os.environ["WORKSPACE"] = WorkspaceDir
+
+## Parse command line options
+#
+# Using standard Python module optparse to parse command line option of this tool.
+#
+# @retval Opt A optparse.Values object containing the parsed options
+# @retval Args Target of build command
+#
+def MyOptionParser():
+ UsageString = "%prog -m <module_file> -p <package_file> [-o distribution_file] " + \
+ "[-x xml-file-header] [-t tools-directory] [-f misc-files] [-q | -v] [-h]"
+
+ Parser = OptionParser(description=__copyright__,version=__version__,prog="MkPkg",usage=UsageString)
+
+ Parser.add_option("-?", action="help", help="show this help message and exit")
+
+ Parser.add_option("-o", "--output-file", action="store", type="string", dest="DistributionFile",
+ help="Specify the distribution file to be created.")
+
+ Parser.add_option("-f", "--misc-files", action="append", type="string", dest="MiscFiles",
+ help="Specify any misc files.")
+
+ Parser.add_option("-x", "--xml-file-header", action="store", type=None, dest="TemplateFile",
+ help="Specify the xml file which includes header information for creating the distribution file.")
+
+ Parser.add_option("-t", "--tools-directory", action="store", type=None, dest="ToolsDir",
+ help="Specify the directory name of tools.")
+
+ Parser.add_option("-m", "--module", action="append", type="string", dest="ModuleFileList",
+ help="The inf file of module to be distributed standalone.")
+
+ Parser.add_option("-p", "--package", action="append", type="string", dest="PackageFileList",
+ help="The dec file of package to be distributed.")
+
+ Parser.add_option("-q", "--quiet", action="store_const", dest="LogLevel", const=EdkLogger.QUIET,
+ help="Disable all messages except FATAL ERRORS.")
+
+ Parser.add_option("-v", "--verbose", action="store_const", dest="LogLevel", const=EdkLogger.VERBOSE,
+ help="Turn on verbose output")
+
+ Parser.add_option("-d", "--debug", action="store", type="int", dest="LogLevel",
+ help="Enable debug messages at specified level.")
+
+ Parser.set_defaults(LogLevel=EdkLogger.INFO)
+
+ (Opt, Args)=Parser.parse_args()
+ # error check
+ if not Opt.ModuleFileList and not Opt.PackageFileList:
+ EdkLogger.error("MkPkg", OPTION_NOT_SUPPORTED, ExtraData="At least one package file or module file must be specified")
+ if Opt.TemplateFile:
+ if not os.path.exists(Opt.TemplateFile):
+ EdkLogger.error(
+ "\nMkPkg",
+ FILE_NOT_FOUND,
+ "Template file [%s] not found" % Opt.TemplateFile
+ )
+ return Opt
+
+## Tool entrance method
+#
+# This method mainly dispatch specific methods per the command line options.
+# If no error found, return zero value so the caller of this tool can know
+# if it's executed successfully or not.
+#
+# @retval 0 Tool was successful
+# @retval 1 Tool failed
+#
+def Main():
+ EdkLogger.Initialize()
+ Options = MyOptionParser()
+ try:
+ if Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.SetLevel(Options.LogLevel + 1)
+ else:
+ EdkLogger.SetLevel(Options.LogLevel)
+
+ CheckEnvVariable()
+ WorkspaceDir = os.environ["WORKSPACE"]
+
+ # Init DistributionFile
+ if not Options.DistributionFile:
+ Options.DistributionFile = "DistributionPackage.zip"
+
+ # Check Tools Dir
+ if Options.ToolsDir:
+ if not os.path.isdir(os.path.normpath(os.path.join(WorkspaceDir, Options.ToolsDir))):
+ EdkLogger.error(
+ "\nMkPkg",
+ FILE_NOT_FOUND,
+ "Tools directory [%s] not found" % Options.ToolsDir
+ )
+
+ # Check misc files
+ if Options.MiscFiles:
+ for Item in Options.MiscFiles:
+ FullPath = os.path.normpath(os.path.join(WorkspaceDir, Item))
+ if not os.path.isfile(FullPath):
+ EdkLogger.error(
+ "\nMkPkg",
+ FILE_NOT_FOUND,
+ "Misc file [%s] not found" % Item
+ )
+
+ #Check package file existing and valid
+ if Options.PackageFileList:
+ for Item in Options.PackageFileList:
+ (Name, Ext) = os.path.splitext(Item)
+ if Ext.upper() != '.DEC':
+ EdkLogger.error(
+ "\nMkPkg",
+ OPTION_VALUE_INVALID,
+ "[%s] is not a valid package name" % Item
+ )
+ Path = os.path.normpath(os.path.join(WorkspaceDir, Item))
+ if not os.path.exists(Path):
+ EdkLogger.error(
+ "\nMkPkg",
+ FILE_NOT_FOUND,
+ "[%s] not found" % Item
+ )
+ #Check module file existing and valid
+ if Options.ModuleFileList:
+ for Item in Options.ModuleFileList:
+ (Name, Ext) = os.path.splitext(Item)
+ if Ext.upper() != '.INF':
+ EdkLogger.error(
+ "\nMkPkg",
+ OPTION_VALUE_INVALID,
+ "[%s] is not a valid module name" % Item
+ )
+ Path = os.path.normpath(os.path.join(WorkspaceDir, Item))
+ if not os.path.exists(Path):
+ EdkLogger.error(
+ "\nMkPkg",
+ FILE_NOT_FOUND,
+ "[%s] not found" % Item
+ )
+
+ ContentFile = PackageFile("content.zip", "w")
+ DistPkg = DistributionPackageClass()
+ DistPkg.GetDistributionPackage(WorkspaceDir, Options.PackageFileList, Options.ModuleFileList)
+ DistPkgXml = DistributionPackageXml()
+ for Item in DistPkg.PackageSurfaceArea:
+ ContentFile.Pack(os.path.dirname(os.path.normpath(os.path.join(WorkspaceDir,Item[2]))))
+ for Item in DistPkg.ModuleSurfaceArea:
+ ContentFile.Pack(os.path.dirname(os.path.normpath(os.path.join(WorkspaceDir,Item[2]))))
+
+ # Add tools files and information
+ if Options.ToolsDir:
+ ToolsFiles = MiscFileClass()
+ ToolsRoot = os.path.normpath(os.path.join(WorkspaceDir, Options.ToolsDir))
+ ContentFile.Pack(ToolsRoot)
+ ToolsFileList = GetFiles(ToolsRoot, ['CVS', '.svn'])
+ for Item in ToolsFileList:
+ OriPath = Item[len(WorkspaceDir)+1:]
+ FileObj = FileClass()
+ FileObj.Filename = OriPath
+ (Name, Ext) = os.path.splitext(OriPath)
+ if Ext.upper() in ['EXE', 'COM', 'EFI']:
+ FileObj.Executable = 'True'
+ ToolsFiles.Files.append(FileObj)
+ DistPkg.Tools = ToolsFiles
+
+ # Add misc files and information
+ if Options.MiscFiles:
+ MiscFiles = MiscFileClass()
+ for Item in Options.MiscFiles:
+ ContentFile.PackFile(Item)
+ FileObj = FileClass()
+ FileObj.Filename = Item
+ (Name, Ext) = os.path.splitext(Item)
+ if Ext.upper() in ['EXE', 'COM', 'EFI']:
+ FileObj.Executable = 'True'
+ MiscFiles.Files.append(FileObj)
+ DistPkg.MiscellaneousFiles = MiscFiles
+
+ print "Compressing Distribution Package File ..."
+ ContentFile.Close()
+
+ # Add temp distribution header
+ if Options.TemplateFile:
+ TempXML = DistributionPackageXml()
+ DistPkg.Header = TempXML.FromXml(Options.TemplateFile).Header
+ # Add init dp information
+ else:
+ DistPkg.Header.Name = 'Distribution Package'
+ DistPkg.Header.Guid = str(uuid.uuid4())
+ DistPkg.Header.Version = '1.0'
+
+ # Add Md5Sigature
+ Md5Sigature = md5.new(open(str(ContentFile)).read())
+ DistPkg.Header.Signature = Md5Sigature.hexdigest()
+ # Add current Date
+ DistPkg.Header.Date = str(time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime()))
+
+ # Finish final dp file
+ DistPkgFile = PackageFile(Options.DistributionFile, "w")
+ DistPkgFile.PackFile(str(ContentFile))
+ DistPkgFile.PackData(DistPkgXml.ToXml(DistPkg), "dist.pkg")
+ DistPkgFile.Close()
+ print "DONE"
+
+ except FatalError, X:
+ if Options and Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ ReturnCode = X.args[0]
+ except KeyboardInterrupt:
+ ReturnCode = ABORT_ERROR
+ if Options and Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ except:
+ EdkLogger.error(
+ "\nMkPkg",
+ CODE_ERROR,
+ "Unknown fatal error when creating [%s]" % Options.DistributionFile,
+ ExtraData="\n(Please send email to dev@buildtools.tianocore.org for help, attaching following call stack trace!)\n",
+ RaiseError=False
+ )
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ ReturnCode = CODE_ERROR
+ finally:
+ Progressor.Abort()
+
+if __name__ == '__main__':
+ sys.exit(Main())
+
diff --git a/BaseTools/Source/Python/PackagingTool/PackageFile.py b/BaseTools/Source/Python/PackagingTool/PackageFile.py
new file mode 100644
index 0000000000..12544927c9
--- /dev/null
+++ b/BaseTools/Source/Python/PackagingTool/PackageFile.py
@@ -0,0 +1,160 @@
+## @file
+#
+# PackageFile class represents the zip file of a distribution package.
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. 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.
+#
+
+##
+# Import Modules
+#
+import os
+import sys
+import zipfile
+import tempfile
+
+from Common import EdkLogger
+from Common.Misc import *
+from Common.BuildToolError import *
+
+class PackageFile:
+ def __init__(self, FileName, Mode="r"):
+ self._FileName = FileName
+ if Mode not in ["r", "w", "a"]:
+ Mode = "r"
+ try:
+ self._ZipFile = zipfile.ZipFile(FileName, Mode, zipfile.ZIP_DEFLATED)
+ self._Files = {}
+ for F in self._ZipFile.namelist():
+ self._Files[os.path.normpath(F)] = F
+ except BaseException, X:
+ EdkLogger.error("PackagingTool", FILE_OPEN_FAILURE,
+ ExtraData="%s (%s)" % (FileName, str(X)))
+
+ BadFile = self._ZipFile.testzip()
+ if BadFile != None:
+ EdkLogger.error("PackagingTool", FILE_CHECKSUM_FAILURE,
+ ExtraData="[%s] in %s" % (BadFile, FileName))
+
+ def __str__(self):
+ return self._FileName
+
+ def Unpack(self, To):
+ for F in self._ZipFile.namelist():
+ ToFile = os.path.normpath(os.path.join(To, F))
+ print F, "->", ToFile
+ self.Extract(F, ToFile)
+
+ def UnpackFile(self, File, ToFile):
+ File = File.replace('\\', '/')
+ if File in self._ZipFile.namelist():
+ print File, "->", ToFile
+ self.Extract(File, ToFile)
+
+ return ToFile
+
+ return ''
+
+ def Extract(self, Which, To):
+ Which = os.path.normpath(Which)
+ if Which not in self._Files:
+ EdkLogger.error("PackagingTool", FILE_NOT_FOUND,
+ ExtraData="[%s] in %s" % (Which, self._FileName))
+ try:
+ FileContent = self._ZipFile.read(self._Files[Which])
+ except BaseException, X:
+ EdkLogger.error("PackagingTool", FILE_DECOMPRESS_FAILURE,
+ ExtraData="[%s] in %s (%s)" % (Which, self._FileName, str(X)))
+ try:
+ CreateDirectory(os.path.dirname(To))
+ ToFile = open(To, "wb")
+ except BaseException, X:
+ EdkLogger.error("PackagingTool", FILE_OPEN_FAILURE,
+ ExtraData="%s (%s)" % (To, str(X)))
+
+ try:
+ ToFile.write(FileContent)
+ ToFile.close()
+ except BaseException, X:
+ EdkLogger.error("PackagingTool", FILE_WRITE_FAILURE,
+ ExtraData="%s (%s)" % (To, str(X)))
+
+ def Remove(self, Files):
+ TmpDir = os.path.join(tempfile.gettempdir(), ".packaging")
+ if os.path.exists(TmpDir):
+ RemoveDirectory(TmpDir, True)
+
+ os.mkdir(TmpDir)
+ self.Unpack(TmpDir)
+ for F in Files:
+ F = os.path.normpath(F)
+ if F not in self._Files:
+ EdkLogger.error("PackagingTool", FILE_NOT_FOUND,
+ ExtraData="%s is not in %s!" % (F, self._FileName))
+ #os.remove(os.path.join(TmpDir, F)) # no need to really remove file
+ self._Files.pop(F)
+ self._ZipFile.close()
+
+ self._ZipFile = zipfile.ZipFile(self._FileName, "w", zipfile.ZIP_DEFLATED)
+ Cwd = os.getcwd()
+ os.chdir(TmpDir)
+ self.PackFiles(self._Files)
+ os.chdir(Cwd)
+ RemoveDirectory(TmpDir, True)
+
+ def Pack(self, Top):
+ if not os.path.isdir(Top):
+ EdkLogger.error("PackagingTool", FILE_UNKNOWN_ERROR, "%s is not a directory!" %Top)
+
+ FilesToPack = []
+ ParentDir = os.path.dirname(Top)
+ BaseDir = os.path.basename(Top)
+ Cwd = os.getcwd()
+ os.chdir(ParentDir)
+ for Root, Dirs, Files in os.walk(BaseDir):
+ if 'CVS' in Dirs:
+ Dirs.remove('CVS')
+ if '.svn' in Dirs:
+ Dirs.remove('.svn')
+ for F in Files:
+ FilesToPack.append(os.path.join(Root, F))
+ self.PackFiles(FilesToPack)
+ os.chdir(Cwd)
+
+ def PackFiles(self, Files):
+ for F in Files:
+ try:
+ print "packing ...", F
+ self._ZipFile.write(F)
+ except BaseException, X:
+ EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE,
+ ExtraData="%s (%s)" % (F, str(X)))
+
+ def PackFile(self, File, ArcName=None):
+ try:
+ print "packing ...", File
+ self._ZipFile.write(File, ArcName)
+ except BaseException, X:
+ EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE,
+ ExtraData="%s (%s)" % (File, str(X)))
+
+ def PackData(self, Data, ArcName):
+ try:
+ self._ZipFile.writestr(ArcName, Data)
+ except BaseException, X:
+ EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE,
+ ExtraData="%s (%s)" % (ArcName, str(X)))
+
+ def Close(self):
+ self._ZipFile.close()
+
+if __name__ == '__main__':
+ pass
+
diff --git a/BaseTools/Source/Python/PackagingTool/RmPkg.py b/BaseTools/Source/Python/PackagingTool/RmPkg.py
new file mode 100644
index 0000000000..e7eedd0776
--- /dev/null
+++ b/BaseTools/Source/Python/PackagingTool/RmPkg.py
@@ -0,0 +1,218 @@
+## @file
+# Install distribution package.
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. 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.
+#
+
+##
+# Import Modules
+#
+import os
+import sys
+import traceback
+import platform
+from optparse import OptionParser
+
+import Common.EdkLogger as EdkLogger
+from Common.BuildToolError import *
+from Common.Misc import *
+from Common.XmlParser import *
+
+from IpiDb import *
+from DependencyRules import *
+
+# Version and Copyright
+VersionNumber = "0.1"
+__version__ = "%prog Version " + VersionNumber
+__copyright__ = "Copyright (c) 2008, Intel Corporation All rights reserved."
+
+## Check environment variables
+#
+# Check environment variables that must be set for build. Currently they are
+#
+# WORKSPACE The directory all packages/platforms start from
+# EDK_TOOLS_PATH The directory contains all tools needed by the build
+# PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
+#
+# If any of above environment variable is not set or has error, the build
+# will be broken.
+#
+def CheckEnvVariable():
+ # check WORKSPACE
+ if "WORKSPACE" not in os.environ:
+ EdkLogger.error("RmPkg", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
+ ExtraData="WORKSPACE")
+
+ WorkspaceDir = os.path.normpath(os.environ["WORKSPACE"])
+ if not os.path.exists(WorkspaceDir):
+ EdkLogger.error("RmPkg", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir)
+ elif ' ' in WorkspaceDir:
+ EdkLogger.error("RmPkg", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path",
+ ExtraData=WorkspaceDir)
+ os.environ["WORKSPACE"] = WorkspaceDir
+
+## Parse command line options
+#
+# Using standard Python module optparse to parse command line option of this tool.
+#
+# @retval Opt A optparse.Values object containing the parsed options
+# @retval Args Target of build command
+#
+def MyOptionParser():
+ UsageString = "%prog -g <guid> -n <version> [-y] [-q | -v] [-h]"
+
+ Parser = OptionParser(description=__copyright__,version=__version__,prog="RmPkg",usage=UsageString)
+
+ Parser.add_option("-?", action="help", help="show this help message and exit")
+
+# Parser.add_option("-f", "--force", action="store_true", type=None, dest="ForceRemove",
+# help="Force creation - overwrite existing one.")
+
+ Parser.add_option("-y", "--yes", action="store_true", dest="Yes",
+ help="Not asking for confirmation when deleting files.")
+
+ Parser.add_option("-n", "--package-version", action="store", type="string", dest="PackageVersion",
+ help="The version of distribution package to be removed.")
+
+ Parser.add_option("-g", "--package-guid", action="store", type="string", dest="PackageGuid",
+ help="The GUID of distribution package to be removed.")
+
+ Parser.add_option("-q", "--quiet", action="store_const", dest="LogLevel", const=EdkLogger.QUIET,
+ help="Disable all messages except FATAL ERRORS.")
+
+ Parser.add_option("-v", "--verbose", action="store_const", dest="LogLevel", const=EdkLogger.VERBOSE,
+ help="Turn on verbose output")
+
+ Parser.add_option("-d", "--debug", action="store", type="int", dest="LogLevel",
+ help="Enable debug messages at specified level.")
+
+ Parser.set_defaults(LogLevel=EdkLogger.INFO)
+
+ (Opt, Args)=Parser.parse_args()
+
+ return Opt
+
+## Remove all empty dirs under the path
+def RemoveEmptyDirs(Path):
+ # Remove all sub dirs
+ for Root, Dirs, Files in os.walk(Path):
+ for Dir in Dirs:
+ FullPath = os.path.normpath(os.path.join(Root, Dir))
+ if os.path.isdir(FullPath):
+ if os.listdir(FullPath) == []:
+ os.rmdir(FullPath)
+ else:
+ RemoveEmptyDirs(FullPath)
+ # Remove itself
+ if os.path.isdir(Path) and os.listdir(Path) == []:
+ os.rmdir(Path)
+
+
+## Tool entrance method
+#
+# This method mainly dispatch specific methods per the command line options.
+# If no error found, return zero value so the caller of this tool can know
+# if it's executed successfully or not.
+#
+# @retval 0 Tool was successful
+# @retval 1 Tool failed
+#
+def Main():
+ EdkLogger.Initialize()
+ Options = MyOptionParser()
+ try:
+ if not Options.PackageGuid and not Options.PackageVersion:
+ EdkLogger.error("RmPkg", OPTION_MISSING, ExtraData="The GUID and Version of distribution package must be specified")
+
+ if Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.SetLevel(Options.LogLevel + 1)
+ else:
+ EdkLogger.SetLevel(Options.LogLevel)
+
+ CheckEnvVariable()
+ WorkspaceDir = os.environ["WORKSPACE"]
+
+ # Prepare check dependency
+ Db = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, "Conf/DistributionPackageDatabase.db")))
+ Db.InitDatabase()
+ Dep = DependencyRules(Db)
+
+ Guid = Options.PackageGuid
+ Version = Options.PackageVersion
+
+ # Check Dp existing
+ if not Dep.CheckDpExists(Guid, Version):
+ EdkLogger.error("RmPkg", UNKNOWN_ERROR, "This distribution package are not installed!")
+
+ # Check Dp depex
+ if not Dep.CheckDpDepexForRemove(Guid, Version):
+ print "Some packages/modules are depending on this distribution package, do you really want to remove it?"
+ print "Press Y to delete all files or press other keys to quit:"
+ Input = Input = sys.stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input.upper() != 'Y':
+ EdkLogger.error("RmPkg", UNKNOWN_ERROR, "User interrupt")
+
+ # Remove all files
+ if not Options.Yes:
+ print "All files of the distribution package will be removed, do you want to continue?"
+ print "Press Y to remove all files or press other keys to quit:"
+ Input = Input = sys.stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input.upper() != 'Y':
+ EdkLogger.error("RmPkg", UNKNOWN_ERROR, "User interrupt")
+
+ # Remove all files
+ MissingFileList = []
+ for Item in Db.GetDpFileList(Guid, Version):
+ if os.path.isfile(Item):
+ print "Removing file [%s] ..." % Item
+ os.remove(Item)
+ else:
+ MissingFileList.append(Item)
+
+ # Remove all empty dirs of package
+ for Item in Db.GetPackageListFromDp(Guid, Version):
+ Dir = os.path.dirname(Item[2])
+ RemoveEmptyDirs(Dir)
+
+ # Remove all empty dirs of module
+ for Item in Db.GetStandaloneModuleInstallPathListFromDp(Guid, Version):
+ Dir = os.path.dirname(Item)
+ RemoveEmptyDirs(Dir)
+
+ # update database
+ EdkLogger.quiet("Update Distribution Package Database ...")
+ Db.RemoveDpObj(Guid, Version)
+ EdkLogger.quiet("DONE")
+
+ except FatalError, X:
+ if Options and Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ ReturnCode = X.args[0]
+ except KeyboardInterrupt:
+ ReturnCode = ABORT_ERROR
+ if Options and Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ except:
+ EdkLogger.error(
+ "\nRmPkg",
+ CODE_ERROR,
+ "Unknown fatal error when removing package",
+ ExtraData="\n(Please send email to dev@buildtools.tianocore.org for help, attaching following call stack trace!)\n",
+ RaiseError=False
+ )
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ ReturnCode = CODE_ERROR
+ finally:
+ Progressor.Abort()
+
+if __name__ == '__main__':
+ sys.exit(Main())