git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10502 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			219 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
## @file
 | 
						|
# Install distribution package.
 | 
						|
#
 | 
						|
# Copyright (c) 2007, 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.
 | 
						|
#
 | 
						|
 | 
						|
##
 | 
						|
# 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 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())
 |