X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=Tools%2FPython%2FMkFar.py;h=2848b1de6596093c432236a13fe9eb897f3ee653;hb=84e73ac219356983b29e3866017189a36c82b323;hp=1dba1fc4aae0ad3a7f9148fafa822e28e43c0eb1;hpb=e853a9d4831ae95363ce5fdcce71cbb23aff2269;p=mirror_edk2.git diff --git a/Tools/Python/MkFar.py b/Tools/Python/MkFar.py index 1dba1fc4aa..2848b1de65 100755 --- a/Tools/Python/MkFar.py +++ b/Tools/Python/MkFar.py @@ -1,19 +1,51 @@ #!/usr/bin/env python -import os, sys, re, getopt, string, glob, xml.dom.minidom, pprint, zipfile, tempfile +"""This is a python script that takes user input from the command line and +creates a far (Framework Archive Manifest) file for distribution.""" + +import os, sys, getopt, string, xml.dom.minidom, zipfile, md5 from XmlRoutines import * from WorkspaceRoutines import * +class Far: + """This class is used to collect arbitrarty data from the template file.""" + def __init__(far): + """Assign the default values for the far fields.""" + far.FileName = "output.far" + far.FarName="" + far.Version="" + far.License="" + far.Abstract="" + far.Description="" + far.Copyright="" + far.SpdFiles=[] + far.FpdFiles=[] + far.ExtraFiles=[] + +far = Far() +"""The far object is constructed from the template file the user passed in.""" + +def AddToZip(zip, infile): + + """Add a file to a zip file, provided it is not already there.""" + + if not infile in zip.namelist(): + zip.write(inWorkspace(infile), infile) + def parseMsa(msaFile, spdDir): - filelist = [] + """Parse an msa file and return a list of all the files that this msa + includes.""" + + filelist = [msaFile] msaDir = os.path.dirname(msaFile) - msa = xml.dom.minidom.parse(inWorkspace(msaFile)) + msa = xml.dom.minidom.parse(inWorkspace(os.path.join(spdDir, msaFile))) xmlPaths = [ - "/ModuleSurfaceArea/SourceFiles/Filename" ] + "/ModuleSurfaceArea/SourceFiles/Filename", + "/ModuleSurfaceArea/NonProcessedFiles/Filename" ] for xmlPath in xmlPaths: for f in XmlList(msa, xmlPath): @@ -23,63 +55,176 @@ def parseMsa(msaFile, spdDir): def parseSpd(spdFile): - filelist = [spdFile] - msaFileList = [] + """Parse an spd file and return a list of all the files that this spd + includes.""" + + files = [] spdDir = os.path.dirname(spdFile) spd = xml.dom.minidom.parse(inWorkspace(spdFile)) + # We are currently ignoring these hints. + readonly = XmlElement(spd, "/PackageSurfaceArea/PackageDefinitions/ReadOnly") != "false" + repackage = XmlElement(spd, "/PackageSurfaceArea/PackageDefinitions/RePackage") != "false" + xmlPaths = [ "/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass/IncludeHeader", - "/PackageSurfaceArea/IndustryStdIncludes/IndustryStdHeader/IncludeHeader", - "/PackageSurfaceArea/ - - -""" - zip = zipfile.ZipFile(farname, "w") - for file in args: - if not os.path.exists(inWorkspace(file)): - print "Skipping non-existent file '%s'." % file - (_, extension) = os.path.splitext(file) + """Returns a tuple (guid, version) which is read from the given spdFile.""" + + spd = xml.dom.minidom.parse(inWorkspace(spdFile)) + + return (XmlElement(spd, "/PackageSurfaceArea/SpdHeader/GuidValue"), + XmlElement(spd, "/PackageSurfaceArea/SpdHeader/Version")) + +def makeFar(files, farname): + + """Make a far out of the given filelist and writes it to the file farname.""" + + domImpl = xml.dom.minidom.getDOMImplementation() + man = domImpl.createDocument(None, "FrameworkArchiveManifest", None) + top_element = man.documentElement + + top_element.appendChild(makeFarHeader(man)) + + packList = XmlAppendChildElement(top_element, "FarPackageList") + platList = XmlAppendChildElement(top_element, "FarPlatformList") + contents = XmlAppendChildElement(top_element, "Contents") + XmlAppendChildElement(top_element, "UserExtensions") + + try: + zip = zipfile.ZipFile(farname, "w", zipfile.ZIP_DEFLATED) + except: + zip = zipfile.ZipFile(farname, "w", zipfile.ZIP_STORED) + for infile in set(files): + if not os.path.exists(inWorkspace(infile)): + print "Error: Non-existent file '%s'." % infile + sys.exit() + (_, extension) = os.path.splitext(infile) if extension == ".spd": - filelist = parseSpd(file) + filelist = parseSpd(infile) + spdDir = os.path.dirname(infile) + + (spdGuid, spdVersion) = getSpdGuidVersion(infile) + + package = XmlAppendChildElement(packList, "FarPackage") + XmlAppendChildElement(package, "FarFilename", lean(infile), {"Md5Sum": Md5(inWorkspace(infile))}) + AddToZip(zip, infile) + XmlAppendChildElement(package, "GuidValue", spdGuid) + XmlAppendChildElement(package, "Version", spdVersion) + XmlAppendChildElement(package, "DefaultPath", spdDir) + XmlAppendChildElement(package, "FarPlatformList") + packContents = XmlAppendChildElement(package, "Contents") + XmlAppendChildElement(package, "UserExtensions") + + for spdfile in filelist: + XmlAppendChildElement(packContents, "FarFilename", lean(spdfile), {"Md5Sum": Md5(inWorkspace(os.path.join(spdDir, spdfile)))}) + AddToZip(zip, os.path.join(spdDir,spdfile)) + elif extension == ".fpd": - filelist = [file] + + platform = XmlAppendChildElement(platList, "FarPlatform") + XmlAppendChildElement(platform, "FarFilename", lean(infile), {"Md5Sum": Md5(inWorkspace(infile))}) + AddToZip(zip, infile) + else: - filelist = [] - for f in set(filelist): - zip.write(inWorkspace(f), f) - zip.writestr("FrameworkArchiveManifest.xml", man) + XmlAppendChildElement(contents, "FarFilename", lean(infile), {"Md5Sum": Md5(inWorkspace(infile))}) + AddToZip(zip, infile) + + zip.writestr("FrameworkArchiveManifest.xml", man.toxml('UTF-8')) zip.close() return -# This acts like the main() function for the script, unless it is 'import'ed into another -# script. +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. if __name__ == '__main__': # Create a pretty printer for dumping data structures in a readable form. # pp = pprint.PrettyPrinter(indent=2) # Process the command line args. - optlist, args = getopt.getopt(sys.argv[1:], 'h', [ 'example-long-arg=', 'testing']) - - makeFar(args, "test.far") + optlist, args = getopt.getopt(sys.argv[1:], 'ho:t:v', [ 'template=', 'output=', 'far=', 'help', 'debug', 'verbose', 'version']) + + # First pass through the options list. + for o, a in optlist: + if o in ["-h", "--help"]: + print """ +Pass a list of .spd and .fpd files to be placed into a far for distribution. +You may give the name of the far with a -f or --far option. For example: + + %s --template far-template --far library.far MdePkg/MdePkg.spd + +The file paths of .spd and .fpd are treated as relative to the WORKSPACE +environment variable which must be set to a valid workspace root directory. + +A template file may be passed in with the --template option. This template file +is a text file that allows more contol over the contents of the far. +""" % os.path.basename(sys.argv[0]) + + sys.exit() + optlist.remove((o,a)) + if o in ["-t", "--template"]: + # The template file is processed first, so that command line options can + # override it. + templateName = a + execfile(templateName) + optlist.remove((o,a)) + + # Second pass through the options list. These can override the first pass. + for o, a in optlist: + if o in ["-o", "--far", "--output"]: + far.FileName = a + + # Let's err on the side of caution and not let people blow away data + # accidentally. + if os.path.exists(far.FileName): + print "Error: File %s exists. Not overwriting." % far.FileName + sys.exit() + + makeFar(far.SpdFiles + far.FpdFiles + far.ExtraFiles + args, far.FileName)