Add better command line parameter handling.
[mirror_edk2.git] / Tools / Python / MkFar.py
CommitLineData
e853a9d4 1#!/usr/bin/env python
2
3import os, sys, re, getopt, string, glob, xml.dom.minidom, pprint, zipfile, tempfile
4from XmlRoutines import *
5from WorkspaceRoutines import *
6
7def parseMsa(msaFile, spdDir):
8
69932b41 9 filelist = [msaFile]
e853a9d4 10
11 msaDir = os.path.dirname(msaFile)
12
13 msa = xml.dom.minidom.parse(inWorkspace(msaFile))
14
15 xmlPaths = [
16 "/ModuleSurfaceArea/SourceFiles/Filename" ]
17
18 for xmlPath in xmlPaths:
19 for f in XmlList(msa, xmlPath):
20 filelist.append(str(os.path.join(msaDir, XmlElementData(f))))
21
22 return filelist
23
24def parseSpd(spdFile):
25
26 filelist = [spdFile]
27 msaFileList = []
28
29 spdDir = os.path.dirname(spdFile)
30
31 spd = xml.dom.minidom.parse(inWorkspace(spdFile))
32
33 xmlPaths = [
34 "/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass/IncludeHeader",
35 "/PackageSurfaceArea/IndustryStdIncludes/IndustryStdHeader/IncludeHeader",
36 "/PackageSurfaceArea/<PackageHeaders/IncludePkgHeader" ]
37
38 for xmlPath in xmlPaths:
39 for f in XmlList(spd, xmlPath):
40 filelist.append(str(os.path.join(spdDir, XmlElementData(f))))
41
d32aaa95 42 for f in XmlList(spd, "/PackageSurfaceArea/MsaFiles/Filename"):
43 msaFile = str(os.path.join(spdDir, XmlElementData(f)))
44 filelist += parseMsa(msaFile, spdDir)
e853a9d4 45
46 return filelist
47
48def makeFar(filelist, farname):
49
69932b41 50 domImpl = xml.dom.minidom.getDOMImplementation()
51 man = domImpl.createDocument(None, "FrameworkArchiveManifest", None)
52 top_element = man.documentElement
53
54 header = man.createElement("FarHeader")
55 top_element.appendChild(header)
d32aaa95 56
69932b41 57 packList = man.createElement("FarPackageList")
58 top_element.appendChild(packList)
d32aaa95 59
69932b41 60 platList = man.createElement("FarPlatformList")
61 top_element.appendChild(platList)
d32aaa95 62
69932b41 63 contents = man.createElement("Contents")
64 top_element.appendChild(contents)
d32aaa95 65
e853a9d4 66 zip = zipfile.ZipFile(farname, "w")
d32aaa95 67 for infile in filelist:
68 if not os.path.exists(inWorkspace(infile)):
69 print "Skipping non-existent file '%s'." % infile
70 (_, extension) = os.path.splitext(infile)
e853a9d4 71 if extension == ".spd":
d32aaa95 72 filelist = parseSpd(infile)
69932b41 73
d32aaa95 74 package = man.createElement("FarPackage")
75 packList.appendChild(package)
69932b41 76
d32aaa95 77 spdfilename = man.createElement("FarFilename")
78 package.appendChild(spdfilename)
69932b41 79
d32aaa95 80 spdfilename.appendChild( man.createTextNode(infile) )
81
82 for spdfile in filelist:
83 content = man.createElement("FarFilename")
84 content.appendChild( man.createTextNode(spdfile))
85 contents.appendChild(content)
69932b41 86
e853a9d4 87 elif extension == ".fpd":
d32aaa95 88 filelist = [infile]
89
90 platform = man.createElement("FarPlatform")
91 platList.appendChild(platform)
92
93 fpdfilename = man.createElement("FarFilename")
94 platform.appendChild(fpdfilename)
95
96 fpdfilename.appendChild( man.createTextNode(infile) )
97
e853a9d4 98 else:
99 filelist = []
d32aaa95 100
e853a9d4 101 for f in set(filelist):
102 zip.write(inWorkspace(f), f)
d0f7ef3e 103 zip.writestr("FrameworkArchiveManifest.xml", man.toprettyxml(2*" "))
e853a9d4 104 zip.close()
105 return
106
d0f7ef3e 107# This acts like the main() function for the script, unless it is 'import'ed
108# into another script.
e853a9d4 109if __name__ == '__main__':
110
111 # Create a pretty printer for dumping data structures in a readable form.
112 # pp = pprint.PrettyPrinter(indent=2)
113
d0f7ef3e 114 # Default name for far file.
115 farName = "output.far"
116
e853a9d4 117 # Process the command line args.
d0f7ef3e 118 optlist, args = getopt.getopt(sys.argv[1:], 'hf:', [ 'far=', 'help'])
119
120 for o, a in optlist:
121 if o in ["-h", "--help"]:
122 print """
123Pass a list of .spd and .fpd files to be placed into a far for distribution.
124You may give the name of the far with a -f or --far option. For example:
125
126 %s --far library.far MdePkg/MdePkg.spd
127
128The file paths of .spd and .fpd are relative to the WORKSPACE envirnonment
129which must be set to a valid workspace root directory.
130""" % os.path.basename(sys.argv[0])
131
132 sys.exit()
133 if o in ["-f", "--far"]:
134 farName = a
e853a9d4 135
d0f7ef3e 136 makeFar(args, farName)