mirror of https://github.com/acidanthera/audk.git
282 lines
10 KiB
Python
282 lines
10 KiB
Python
|
## @file
|
||
|
# Install distribution package.
|
||
|
#
|
||
|
# 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.
|
||
|
#
|
||
|
|
||
|
'''
|
||
|
MkPkg
|
||
|
'''
|
||
|
|
||
|
##
|
||
|
# Import Modules
|
||
|
#
|
||
|
from os import remove
|
||
|
from os import getcwd
|
||
|
from os import chdir
|
||
|
import os.path
|
||
|
from sys import stdin
|
||
|
from sys import platform
|
||
|
from traceback import format_exc
|
||
|
from platform import python_version
|
||
|
import md5
|
||
|
from time import strftime
|
||
|
from time import localtime
|
||
|
from uuid import uuid4
|
||
|
|
||
|
from Logger import StringTable as ST
|
||
|
from Logger.ToolError import OPTION_UNKNOWN_ERROR
|
||
|
from Logger.ToolError import OPTION_VALUE_INVALID
|
||
|
from Logger.ToolError import ABORT_ERROR
|
||
|
from Logger.ToolError import UPT_REPKG_ERROR
|
||
|
from Logger.ToolError import CODE_ERROR
|
||
|
from Logger.ToolError import FatalError
|
||
|
from Logger.ToolError import FILE_NOT_FOUND
|
||
|
import Logger.Log as Logger
|
||
|
|
||
|
from Xml.XmlParser import DistributionPackageXml
|
||
|
from Xml.IniToXml import IniToXml
|
||
|
|
||
|
from Library.Misc import CheckEnvVariable
|
||
|
from Library import GlobalData
|
||
|
from Library.ParserValidate import IsValidPath
|
||
|
|
||
|
from Core.DistributionPackageClass import DistributionPackageClass
|
||
|
from Core.PackageFile import PackageFile
|
||
|
|
||
|
## CheckForExistingDp
|
||
|
#
|
||
|
# Check if there is a same name DP file existing
|
||
|
# @param Path: The path to be checked
|
||
|
#
|
||
|
def CheckForExistingDp(Path):
|
||
|
if os.path.exists(Path):
|
||
|
Logger.Info(ST.MSG_DISTRIBUTION_PACKAGE_FILE_EXISTS % Path)
|
||
|
Input = stdin.readline()
|
||
|
Input = Input.replace('\r', '').replace('\n', '')
|
||
|
if Input.upper() != "Y":
|
||
|
Logger.Error("\nMkPkg", ABORT_ERROR, ST.ERR_USER_ABORT, RaiseError=True)
|
||
|
|
||
|
## 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.
|
||
|
#
|
||
|
#
|
||
|
def Main(Options = None):
|
||
|
if Options == None:
|
||
|
Logger.Error("\nMkPkg", OPTION_UNKNOWN_ERROR, ST.ERR_OPTION_NOT_FOUND)
|
||
|
try:
|
||
|
DataBase = GlobalData.gDB
|
||
|
ContentFileClosed = True
|
||
|
CheckEnvVariable()
|
||
|
WorkspaceDir = GlobalData.gWORKSPACE
|
||
|
|
||
|
#
|
||
|
# Init PackFileToCreate
|
||
|
#
|
||
|
if not Options.PackFileToCreate:
|
||
|
Logger.Error("\nMkPkg", OPTION_UNKNOWN_ERROR, ST.ERR_OPTION_NOT_FOUND)
|
||
|
|
||
|
#
|
||
|
# Handle if the distribution package file already exists
|
||
|
#
|
||
|
CheckForExistingDp(Options.PackFileToCreate)
|
||
|
|
||
|
#
|
||
|
# Check package file existing and valid
|
||
|
#
|
||
|
CheckFileList('.DEC', Options.PackageFileList, ST.ERR_INVALID_PACKAGE_NAME, ST.ERR_INVALID_PACKAGE_PATH)
|
||
|
#
|
||
|
# Check module file existing and valid
|
||
|
#
|
||
|
CheckFileList('.INF', Options.ModuleFileList, ST.ERR_INVALID_MODULE_NAME, ST.ERR_INVALID_MODULE_PATH)
|
||
|
|
||
|
#
|
||
|
# Get list of files that installed with RePackage attribute available
|
||
|
#
|
||
|
RePkgDict = DataBase.GetRePkgDict()
|
||
|
|
||
|
ContentFile = PackageFile(GlobalData.gCONTENT_FILE, "w")
|
||
|
ContentFileClosed = False
|
||
|
|
||
|
#
|
||
|
# Add temp distribution header
|
||
|
#
|
||
|
if Options.PackageInformationDataFile:
|
||
|
XmlFile = IniToXml(Options.PackageInformationDataFile)
|
||
|
DistPkg = DistributionPackageXml().FromXml(XmlFile)
|
||
|
remove(XmlFile)
|
||
|
|
||
|
#
|
||
|
# add distribution level tool/misc files
|
||
|
# before pack, current dir should be workspace dir, else the full
|
||
|
# path will be in the pack file
|
||
|
#
|
||
|
Cwd = getcwd()
|
||
|
chdir(WorkspaceDir)
|
||
|
ToolObject = DistPkg.Tools
|
||
|
MiscObject = DistPkg.MiscellaneousFiles
|
||
|
FileList = []
|
||
|
if ToolObject:
|
||
|
FileList += ToolObject.GetFileList()
|
||
|
if MiscObject:
|
||
|
FileList += MiscObject.GetFileList()
|
||
|
for FileObject in FileList:
|
||
|
#
|
||
|
# If you have unicode file names, please convert them to byte
|
||
|
# strings in your desired encoding before passing them to
|
||
|
# write().
|
||
|
#
|
||
|
FromFile = os.path.normpath(FileObject.GetURI()).encode('utf_8')
|
||
|
FileFullPath = os.path.normpath(os.path.join(WorkspaceDir, FromFile))
|
||
|
if FileFullPath in RePkgDict:
|
||
|
(DpGuid, DpVersion, DpName, Repackage) = RePkgDict[FileFullPath]
|
||
|
if not Repackage:
|
||
|
Logger.Error("\nMkPkg",
|
||
|
UPT_REPKG_ERROR,
|
||
|
ST.ERR_UPT_REPKG_ERROR,
|
||
|
ExtraData=ST.MSG_REPKG_CONFLICT %\
|
||
|
(FileFullPath, DpGuid, DpVersion, DpName)
|
||
|
)
|
||
|
else:
|
||
|
DistPkg.Header.RePackage = True
|
||
|
ContentFile.PackFile(FromFile)
|
||
|
chdir(Cwd)
|
||
|
|
||
|
#
|
||
|
# Add init dp information
|
||
|
#
|
||
|
else:
|
||
|
DistPkg = DistributionPackageClass()
|
||
|
DistPkg.Header.Name = 'Distribution Package'
|
||
|
DistPkg.Header.Guid = str(uuid4())
|
||
|
DistPkg.Header.Version = '1.0'
|
||
|
|
||
|
DistPkg.GetDistributionPackage(WorkspaceDir, Options.PackageFileList, \
|
||
|
Options.ModuleFileList)
|
||
|
FileList, MetaDataFileList = DistPkg.GetDistributionFileList()
|
||
|
for File in FileList + MetaDataFileList:
|
||
|
FileFullPath = os.path.normpath(os.path.join(WorkspaceDir, File))
|
||
|
#
|
||
|
# check whether file was included in a distribution that can not
|
||
|
# be repackaged
|
||
|
#
|
||
|
if FileFullPath in RePkgDict:
|
||
|
(DpGuid, DpVersion, DpName, Repackage) = RePkgDict[FileFullPath]
|
||
|
if not Repackage:
|
||
|
Logger.Error("\nMkPkg",
|
||
|
UPT_REPKG_ERROR,
|
||
|
ST.ERR_UPT_REPKG_ERROR,
|
||
|
ExtraData = \
|
||
|
ST.MSG_REPKG_CONFLICT %(FileFullPath, DpName, \
|
||
|
DpGuid, DpVersion)
|
||
|
)
|
||
|
else:
|
||
|
DistPkg.Header.RePackage = True
|
||
|
|
||
|
Cwd = getcwd()
|
||
|
chdir(WorkspaceDir)
|
||
|
ContentFile.PackFiles(FileList)
|
||
|
chdir(Cwd)
|
||
|
|
||
|
Logger.Verbose(ST.MSG_COMPRESS_DISTRIBUTION_PKG)
|
||
|
|
||
|
ContentFile.Close()
|
||
|
ContentFileClosed = True
|
||
|
|
||
|
#
|
||
|
# Add Md5Sigature
|
||
|
#
|
||
|
DistPkg.Header.Signature = md5.new(open(str(ContentFile), 'rb').read()).hexdigest()
|
||
|
#
|
||
|
# Add current Date
|
||
|
#
|
||
|
DistPkg.Header.Date = str(strftime("%Y-%m-%dT%H:%M:%S", localtime()))
|
||
|
|
||
|
#
|
||
|
# Finish final dp file
|
||
|
#
|
||
|
DistPkgFile = PackageFile(Options.PackFileToCreate, "w")
|
||
|
DistPkgFile.PackFile(str(ContentFile))
|
||
|
DistPkgXml = DistributionPackageXml()
|
||
|
DistPkgFile.PackData(DistPkgXml.ToXml(DistPkg), GlobalData.gDESC_FILE)
|
||
|
DistPkgFile.Close()
|
||
|
Logger.Quiet(ST.MSG_FINISH)
|
||
|
ReturnCode = 0
|
||
|
|
||
|
except FatalError, XExcept:
|
||
|
ReturnCode = XExcept.args[0]
|
||
|
if Logger.GetLevel() <= Logger.DEBUG_9:
|
||
|
Logger.Quiet(ST.MSG_PYTHON_ON % \
|
||
|
(python_version(), platform) + format_exc())
|
||
|
except KeyboardInterrupt:
|
||
|
ReturnCode = ABORT_ERROR
|
||
|
if Logger.GetLevel() <= Logger.DEBUG_9:
|
||
|
Logger.Quiet(ST.MSG_PYTHON_ON % \
|
||
|
(python_version(), platform) + format_exc())
|
||
|
except OSError:
|
||
|
pass
|
||
|
except:
|
||
|
Logger.Error(
|
||
|
"\nMkPkg",
|
||
|
CODE_ERROR,
|
||
|
ST.ERR_UNKNOWN_FATAL_CREATING_ERR % \
|
||
|
Options.PackFileToCreate,
|
||
|
ExtraData=ST.MSG_SEARCH_FOR_HELP,
|
||
|
RaiseError=False
|
||
|
)
|
||
|
Logger.Quiet(ST.MSG_PYTHON_ON % \
|
||
|
(python_version(), platform) + format_exc())
|
||
|
ReturnCode = CODE_ERROR
|
||
|
finally:
|
||
|
if os.path.exists(GlobalData.gCONTENT_FILE):
|
||
|
if not ContentFileClosed:
|
||
|
ContentFile.Close()
|
||
|
os.remove(GlobalData.gCONTENT_FILE)
|
||
|
|
||
|
return ReturnCode
|
||
|
|
||
|
|
||
|
## CheckFileList
|
||
|
#
|
||
|
# @param QualifiedExt: QualifiedExt
|
||
|
# @param FileList: FileList
|
||
|
# @param ErrorStringExt: ErrorStringExt
|
||
|
# @param ErrorStringFullPath: ErrorStringFullPath
|
||
|
#
|
||
|
def CheckFileList(QualifiedExt, FileList, ErrorStringExt, ErrorStringFullPath):
|
||
|
if not FileList:
|
||
|
return
|
||
|
WorkspaceDir = GlobalData.gWORKSPACE
|
||
|
WorkspaceDir = os.path.normpath(WorkspaceDir)
|
||
|
for Item in FileList:
|
||
|
Ext = os.path.splitext(Item)[1]
|
||
|
if Ext.upper() != QualifiedExt.upper():
|
||
|
Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \
|
||
|
ErrorStringExt % Item)
|
||
|
|
||
|
Item = os.path.normpath(Item)
|
||
|
Path = os.path.normpath(os.path.join(WorkspaceDir, Item))
|
||
|
if not os.path.exists(Path):
|
||
|
Logger.Error("\nMkPkg", FILE_NOT_FOUND, ST.ERR_NOT_FOUND % Item)
|
||
|
elif Item == Path:
|
||
|
Logger.Error("\nMkPkg", OPTION_VALUE_INVALID,
|
||
|
ErrorStringFullPath % Item)
|
||
|
elif not IsValidPath(Item, WorkspaceDir):
|
||
|
Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \
|
||
|
ErrorStringExt % Item)
|
||
|
|
||
|
if not os.path.split(Item)[0]:
|
||
|
Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \
|
||
|
ST.ERR_INVALID_METAFILE_PATH % Item)
|