## @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/ 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 -n [-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 edk2-buildtools-devel@lists.sourceforge.net 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())