]>
git.proxmox.com Git - mirror_edk2.git/blob - Tools/Python/MkFar.py
3 """This is a python script that takes user input from the command line and
4 creates a far (Framework Archive Manifest) file for distribution."""
6 import os
, sys
, getopt
, string
, xml
.dom
.minidom
, zipfile
, md5
7 from XmlRoutines
import *
8 from WorkspaceRoutines
import *
11 """This class is used to collect arbitrarty data from the template file."""
13 """Assign the default values for the far fields."""
14 far
.FileName
= "output.far"
26 """The far object is constructed from the template file the user passed in."""
28 def parseMsa(msaFile
, spdDir
):
30 """ XXX Parse an msa file and return a list of all the files that this msa
35 msaDir
= os
.path
.dirname(msaFile
)
37 msa
= xml
.dom
.minidom
.parse(inWorkspace(os
.path
.join(spdDir
, msaFile
)))
40 "/ModuleSurfaceArea/SourceFiles/Filename",
41 "/ModuleSurfaceArea/NonProcessedFiles/Filename" ]
43 for xmlPath
in xmlPaths
:
44 for f
in XmlList(msa
, xmlPath
):
45 filelist
.append(str(os
.path
.join(msaDir
, XmlElementData(f
))))
49 def parseSpd(spdFile
):
51 """Parse an spd file and return a list of all the files that this spd
56 spdDir
= os
.path
.dirname(spdFile
)
58 spd
= xml
.dom
.minidom
.parse(inWorkspace(spdFile
))
61 "/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass/IncludeHeader",
62 "/PackageSurfaceArea/IndustryStdIncludes/IndustryStdHeader/IncludeHeader",
63 "/PackageSurfaceArea/PackageHeaders/IncludePkgHeader" ]
65 for xmlPath
in xmlPaths
:
66 for f
in XmlList(spd
, xmlPath
):
67 files
.append(str(XmlElementData(f
)))
69 for f
in XmlList(spd
, "/PackageSurfaceArea/MsaFiles/Filename"):
70 msaFile
= str(XmlElementData(f
))
71 files
+= parseMsa(msaFile
, spdDir
)
74 os
.chdir(inWorkspace(spdDir
))
75 for root
, dirs
, entries
in os
.walk("Include"):
76 # Some files need to be skipped.
77 for r
in ["CVS", ".svn"]:
81 files
.append(os
.path
.join(os
.path
.normpath(root
), entry
))
86 def makeFarHeader(doc
):
88 """Create a dom tree for the Far Header. It will use information from the
89 template file passed on the command line, if present."""
91 header
= XmlAppendChildElement(doc
.documentElement
, "FarHeader")
93 XmlAppendChildElement(header
, "FarName", far
.FarName
)
94 XmlAppendChildElement(header
, "GuidValue", genguid())
95 XmlAppendChildElement(header
, "Version", far
.Version
)
96 XmlAppendChildElement(header
, "Abstract", far
.Abstract
)
97 XmlAppendChildElement(header
, "Description", far
.Description
)
98 XmlAppendChildElement(header
, "Copyright", far
.Copyright
)
99 XmlAppendChildElement(header
, "License", far
.License
)
100 XmlAppendChildElement(header
, "Specification", "FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052")
104 def getSpdGuidVersion(spdFile
):
106 """Returns a tuple (guid, version) which is read from the given spdFile."""
108 spd
= xml
.dom
.minidom
.parse(inWorkspace(spdFile
))
110 return (XmlElement(spd
, "/PackageSurfaceArea/SpdHeader/GuidValue"),
111 XmlElement(spd
, "/PackageSurfaceArea/SpdHeader/Version"))
113 def makeFar(files
, farname
):
115 """Make a far out of the given filelist and writes it to the file farname."""
117 domImpl
= xml
.dom
.minidom
.getDOMImplementation()
118 man
= domImpl
.createDocument(None, "FrameworkArchiveManifest", None)
119 top_element
= man
.documentElement
121 top_element
.appendChild(makeFarHeader(man
))
123 packList
= XmlAppendChildElement(top_element
, "FarPackageList")
124 platList
= XmlAppendChildElement(top_element
, "FarPlatformList")
125 contents
= XmlAppendChildElement(top_element
, "Contents")
126 XmlAppendChildElement(top_element
, "UserExtensions")
128 zip = zipfile
.ZipFile(farname
, "w")
129 for infile
in set(files
):
130 if not os
.path
.exists(inWorkspace(infile
)):
131 print "Error: Non-existent file '%s'." % infile
133 (_
, extension
) = os
.path
.splitext(infile
)
134 if extension
== ".spd":
135 filelist
= parseSpd(infile
)
136 spdDir
= os
.path
.dirname(infile
)
138 (spdGuid
, spdVersion
) = getSpdGuidVersion(infile
)
140 package
= XmlAppendChildElement(packList
, "FarPackage")
141 XmlAppendChildElement(package
, "FarFilename", lean(infile
), {"Md5Sum": Md5(inWorkspace(infile
))})
142 zip.write(inWorkspace(infile
), infile
)
143 XmlAppendChildElement(package
, "GuidValue", spdGuid
)
144 XmlAppendChildElement(package
, "Version", spdVersion
)
145 XmlAppendChildElement(package
, "DefaultPath", spdDir
)
146 XmlAppendChildElement(package
, "FarPlatformList")
147 packContents
= XmlAppendChildElement(package
, "Contents")
148 XmlAppendChildElement(package
, "UserExtensions")
150 for spdfile
in filelist
:
151 XmlAppendChildElement(packContents
, "FarFilename", lean(spdfile
), {"Md5Sum": Md5(inWorkspace(os
.path
.join(spdDir
, spdfile
)))})
152 zip.write(inWorkspace(os
.path
.join(spdDir
, spdfile
)), os
.path
.join(spdDir
,spdfile
))
154 elif extension
== ".fpd":
156 platform
= XmlAppendChildElement(platList
, "FarPlatform")
157 XmlAppendChildElement(platform
, "FarFilename", lean(infile
), {"Md5Sum": Md5(inWorkspace(infile
))})
158 zip.write(inWorkspace(infile
), infile
)
161 XmlAppendChildElement(contents
, "FarFilename", lean(infile
), {"Md5Sum": Md5(inWorkspace(infile
))})
162 zip.write(inWorkspace(infile
), infile
)
164 zip.writestr("FrameworkArchiveManifest.xml", man
.toxml('UTF-8'))
168 # This acts like the main() function for the script, unless it is 'import'ed
169 # into another script.
170 if __name__
== '__main__':
172 # Create a pretty printer for dumping data structures in a readable form.
173 # pp = pprint.PrettyPrinter(indent=2)
175 # Process the command line args.
176 optlist
, args
= getopt
.getopt(sys
.argv
[1:], 'ho:t:v', [ 'template=', 'output=', 'far=', 'help', 'debug', 'verbose', 'version'])
178 # First pass through the options list.
180 if o
in ["-h", "--help"]:
182 Pass a list of .spd and .fpd files to be placed into a far for distribution.
183 You may give the name of the far with a -f or --far option. For example:
185 %s --template far-template --far library.far MdePkg/MdePkg.spd
187 The file paths of .spd and .fpd are treated as relative to the WORKSPACE
188 environment variable which must be set to a valid workspace root directory.
190 A template file may be passed in with the --template option. This template file
191 is a text file that allows more contol over the contents of the far.
192 """ % os
.path
.basename(sys
.argv
[0])
195 optlist
.remove((o
,a
))
196 if o
in ["-t", "--template"]:
197 # The template file is processed first, so that command line options can
200 execfile(templateName
)
201 optlist
.remove((o
,a
))
203 # Second pass through the options list. These can override the first pass.
206 if o
in ["-o", "--far", "--output"]:
209 # Let's err on the side of caution and not let people blow away data
211 if os
.path
.exists(far
.FileName
):
212 print "Error: File %s exists. Not overwriting." % far
.FileName
215 makeFar(far
.SpdFiles
+ far
.FpdFiles
+ far
.ExtraFiles
+ args
, far
.FileName
)