Add new-line characters in error message to make them shorter in multi-lines.
[mirror_edk2.git] / Tools / Python / MkFar.py
CommitLineData
e853a9d4 1#!/usr/bin/env python
2
10d6603f 3import os, sys, getopt, string, xml.dom.minidom, zipfile, md5
e853a9d4 4from XmlRoutines import *
5from WorkspaceRoutines import *
6
fb96878e 7class Far:
8 """This class is used to collect arbitrarty data from the template file."""
9 def __init__(far):
10 """Assign the default values for the far fields."""
11 far.FileName = "output.far"
12 far.FarName=""
13 far.Version=""
14 far.License=""
15 far.Description=""
16 far.Copyright=""
17 far.SpdFiles=""
18 far.FpdFile=""
19 far.ExtraFile=""
20
21far = Far()
22
e853a9d4 23def parseMsa(msaFile, spdDir):
24
69932b41 25 filelist = [msaFile]
e853a9d4 26
27 msaDir = os.path.dirname(msaFile)
28
10d6603f 29 msa = xml.dom.minidom.parse(inWorkspace(os.path.join(spdDir, msaFile)))
e853a9d4 30
31 xmlPaths = [
10d6603f 32 "/ModuleSurfaceArea/SourceFiles/Filename",
33 "/ModuleSurfaceArea/NonProcessedFiles/Filename" ]
34
e853a9d4 35 for xmlPath in xmlPaths:
36 for f in XmlList(msa, xmlPath):
37 filelist.append(str(os.path.join(msaDir, XmlElementData(f))))
38
39 return filelist
40
41def parseSpd(spdFile):
42
10d6603f 43 files = []
e853a9d4 44
45 spdDir = os.path.dirname(spdFile)
46
47 spd = xml.dom.minidom.parse(inWorkspace(spdFile))
48
49 xmlPaths = [
50 "/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass/IncludeHeader",
51 "/PackageSurfaceArea/IndustryStdIncludes/IndustryStdHeader/IncludeHeader",
3ff56e5e 52 "/PackageSurfaceArea/PackageHeaders/IncludePkgHeader" ]
e853a9d4 53
54 for xmlPath in xmlPaths:
55 for f in XmlList(spd, xmlPath):
10d6603f 56 files.append(str(XmlElementData(f)))
e853a9d4 57
d32aaa95 58 for f in XmlList(spd, "/PackageSurfaceArea/MsaFiles/Filename"):
10d6603f 59 msaFile = str(XmlElementData(f))
60 files += parseMsa(msaFile, spdDir)
61
62 cwd = os.getcwd()
63 os.chdir(inWorkspace(spdDir))
64 for root, dirs, entries in os.walk("Include"):
65 for r in ["CVS", ".svn"]:
66 if r in dirs:
67 dirs.remove(r)
68 for entry in entries:
69 files.append(os.path.join(os.path.normpath(root), entry))
70 os.chdir(cwd)
71
72 return files
73
74def makeFarHeader(doc):
75
76 header = doc.createElement("FarHeader")
77 name = doc.createElement("FarName")
fb96878e 78 name.appendChild(doc.createTextNode(far.FarName))
10d6603f 79 header.appendChild(name)
80 guidVal = doc.createElement("GuidValue")
81 guidVal.appendChild(doc.createTextNode(genguid()))
82 header.appendChild(guidVal)
83 ver = doc.createElement("Version")
fb96878e 84 ver.appendChild(doc.createTextNode(far.Version))
10d6603f 85 header.appendChild(ver)
86 abstract = doc.createElement("Abstract")
fb96878e 87 abstract.appendChild(doc.createTextNode(far.Abstract))
10d6603f 88 header.appendChild(abstract)
89 desc = doc.createElement("Description")
fb96878e 90 desc.appendChild(doc.createTextNode(far.Description))
10d6603f 91 header.appendChild(desc)
92 copy = doc.createElement("Copyright")
fb96878e 93 copy.appendChild(doc.createTextNode(far.Copyright))
10d6603f 94 header.appendChild(copy)
95 lic = doc.createElement("License")
fb96878e 96 lic.appendChild(doc.createTextNode(far.License))
10d6603f 97 header.appendChild(lic)
98 spec = doc.createElement("Specification")
99 spec.appendChild(doc.createTextNode("FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052"))
100 header.appendChild(spec)
101
102 return header
103
104def getSpdGuidVersion(spdFile):
e853a9d4 105
10d6603f 106 spd = xml.dom.minidom.parse(inWorkspace(spdFile))
107
108 return (XmlElement(spd, "/PackageSurfaceArea/SpdHeader/GuidValue"),
109 XmlElement(spd, "/PackageSurfaceArea/SpdHeader/Version"))
e853a9d4 110
111def makeFar(filelist, farname):
112
69932b41 113 domImpl = xml.dom.minidom.getDOMImplementation()
114 man = domImpl.createDocument(None, "FrameworkArchiveManifest", None)
115 top_element = man.documentElement
116
10d6603f 117 top_element.appendChild(makeFarHeader(man))
d32aaa95 118
69932b41 119 packList = man.createElement("FarPackageList")
120 top_element.appendChild(packList)
d32aaa95 121
69932b41 122 platList = man.createElement("FarPlatformList")
123 top_element.appendChild(platList)
d32aaa95 124
69932b41 125 contents = man.createElement("Contents")
126 top_element.appendChild(contents)
d32aaa95 127
10d6603f 128 exts = man.createElement("UserExtensions")
129 top_element.appendChild(exts)
130
e853a9d4 131 zip = zipfile.ZipFile(farname, "w")
d32aaa95 132 for infile in filelist:
133 if not os.path.exists(inWorkspace(infile)):
134 print "Skipping non-existent file '%s'." % infile
135 (_, extension) = os.path.splitext(infile)
e853a9d4 136 if extension == ".spd":
d32aaa95 137 filelist = parseSpd(infile)
10d6603f 138 spdDir = os.path.dirname(infile)
139
140 (spdGuid, spdVersion) = getSpdGuidVersion(infile)
69932b41 141
d32aaa95 142 package = man.createElement("FarPackage")
143 packList.appendChild(package)
69932b41 144
10d6603f 145 spdfilename = farFileNode(man, inWorkspace(infile))
146 zip.write(inWorkspace(infile), infile)
147 spdfilename.appendChild(man.createTextNode(infile))
d32aaa95 148 package.appendChild(spdfilename)
69932b41 149
10d6603f 150 guidValue = man.createElement("GuidValue")
151 guidValue.appendChild(man.createTextNode(spdGuid))
152 package.appendChild(guidValue)
153
154 version = man.createElement("Version")
155 version.appendChild(man.createTextNode(spdVersion))
156 package.appendChild(version)
157
158 defaultPath = man.createElement("DefaultPath")
159 defaultPath.appendChild(man.createTextNode(spdDir))
160 package.appendChild(defaultPath)
161
162 farPlatformList = man.createElement("FarPlatformList")
163 package.appendChild(farPlatformList)
164
165 packContents = man.createElement("Contents")
166 package.appendChild(packContents)
167
168 ue = man.createElement("UserExtensions")
169 package.appendChild(ue)
d32aaa95 170
171 for spdfile in filelist:
10d6603f 172 content = farFileNode(man, inWorkspace(os.path.join(spdDir, spdfile)))
173 zip.write(inWorkspace(os.path.join(spdDir, spdfile)), spdfile)
174 content.appendChild(man.createTextNode(spdfile))
175 packContents.appendChild(content)
69932b41 176
e853a9d4 177 elif extension == ".fpd":
d32aaa95 178
179 platform = man.createElement("FarPlatform")
180 platList.appendChild(platform)
181
10d6603f 182 fpdfilename = farFileNode(man, inWorkspace(infile))
183 zip.write(inWorkspace(infile), infile)
d32aaa95 184 platform.appendChild(fpdfilename)
d32aaa95 185 fpdfilename.appendChild( man.createTextNode(infile) )
186
e853a9d4 187 else:
10d6603f 188 content = farFileNode(man, inWorkspace(infile))
189 zip.write(inWorkspace(infile), infile)
190 content.appendChild(man.createTextNode(infile))
191 contents.appendChild(content)
d32aaa95 192
d0f7ef3e 193 zip.writestr("FrameworkArchiveManifest.xml", man.toprettyxml(2*" "))
e853a9d4 194 zip.close()
195 return
196
10d6603f 197def farFileNode(doc, filename):
198 content = doc.createElement("FarFilename")
199 f=open(filename, "rb")
200 content.setAttribute("Md5sum", md5.md5(f.read()).hexdigest())
201 f.close()
202 return content
203
d0f7ef3e 204# This acts like the main() function for the script, unless it is 'import'ed
205# into another script.
e853a9d4 206if __name__ == '__main__':
207
208 # Create a pretty printer for dumping data structures in a readable form.
209 # pp = pprint.PrettyPrinter(indent=2)
210
211 # Process the command line args.
fb96878e 212 optlist, args = getopt.getopt(sys.argv[1:], 'hf:t:', [ 'template=', 'far=', 'help'])
d0f7ef3e 213
214 for o, a in optlist:
215 if o in ["-h", "--help"]:
216 print """
217Pass a list of .spd and .fpd files to be placed into a far for distribution.
218You may give the name of the far with a -f or --far option. For example:
219
220 %s --far library.far MdePkg/MdePkg.spd
221
fb96878e 222The file paths of .spd and .fpd are treated as relative to the WORKSPACE
223envirnonment variable which must be set to a valid workspace root directory.
d0f7ef3e 224""" % os.path.basename(sys.argv[0])
225
226 sys.exit()
fb96878e 227 if o in ["-t", "--template"]:
228 # The template file is processed first, so that command line options can
229 # override it.
230 templateName = a
231 execfile(templateName)
d0f7ef3e 232 if o in ["-f", "--far"]:
fb96878e 233 far.FileName = a
234 if os.path.exists(far.FileName):
235 print "Error: File %s exists. Not overwriting." % far.FileName
236 sys.exit()
e853a9d4 237
fb96878e 238 makeFar(args, far.FileName)