3 """This is a python script that takes user input from the command line and
4 installs a far (Framework Archive Manifest) file into the workspace."""
6 import os
, sys
, getopt
, string
, xml
.dom
.minidom
, zipfile
, md5
7 from XmlRoutines
import *
8 from WorkspaceRoutines
import *
15 def __init__(self
, filename
="Tools/Conf/FrameworkDatabase.db"):
17 # First try to get a lock file.
18 self
.DBFile
= inWorkspace(filename
)
19 self
.lockfile
= inWorkspace("Tools/Conf/FrameworkDatabase.lock")
20 if os
.path
.exists(self
.lockfile
):
21 self
.itsMyLockFile
= False
22 print "Error: The database file is locked by ", self
.lockfile
23 raise OSError("The Database is locked.")
25 self
.lock
= open(self
.lockfile
, 'w')
26 self
.lock
.write("pid "+str(os
.getpid()))
27 self
.itsMyLockFile
= True
29 self
.dom
= XmlParseFile(inWorkspace(filename
))
31 self
.installedPackages
= {}
32 self
.installedPlatforms
= {}
33 self
.installedFars
= {}
35 for spdfile
in XmlList(self
.dom
, "/FrameworkDatabase/PackageList/Filename"):
36 filename
= str(XmlElementData(spdfile
))
37 spd
= XmlParseFileSection(inWorkspace(filename
), "SpdHeader")
38 self
.installedPackages
[XmlElement(spd
, "/SpdHeader/GuidValue"), XmlElement(spd
, "/SpdHeader/Version")] = \
39 XmlElement(spd
, "/SpdHeader/PackageName")
41 for fpdfile
in XmlList(self
.dom
, "/FrameworkDatabase/PlatformList/Filename"):
42 filename
= str(XmlElementData(fpdfile
))
43 fpd
= XmlParseFileSection(inWorkspace(filename
), "PlatformHeader")
44 self
.installedPlatforms
[XmlElement(fpd
, "/PlatformHeader/GuidValue"), XmlElement(fpd
, "/PlatformHeader/Version") ] = \
45 XmlElement(fpd
, "/PlatformHeader/PlatformName")
47 for farfile
in XmlList(self
.dom
, "/FrameworkDatabase/FarList/Filename"):
48 farGuid
= farfile
.getAttribute("FarGuid")
49 self
.installedFars
[farGuid
] = XmlElementData(farfile
)
51 self
.packageList
= XmlNode(self
.dom
, "/FrameworkDatabase/PackageList")
52 self
.platformList
= XmlNode(self
.dom
, "/FrameworkDatabase/PlatformList")
53 self
.farList
= XmlNode(self
.dom
, "/FrameworkDatabase/FarList")
56 if self
.itsMyLockFile
:
58 os
.unlink(self
.lockfile
)
60 def HasPackage(self
, spdString
):
61 """Return true iff this package is already installed."""
62 spdHeader
= XmlParseStringSection(spdString
, "SpdHeader")
63 guid
= XmlElement(spdHeader
, "/SpdHeader/GuidValue")
64 version
= XmlElement(spdHeader
, "/SpdHeader/Version")
65 return self
.installedPackages
.has_key((guid
, version
))
67 def HasPlatform(self
, fpdString
):
68 """Return true iff this platform is already installed."""
69 fpdHeader
= XmlParseStringSection(fpdString
, "PlatformHeader")
70 guid
= XmlElement(fpdHeader
, "/PlatformHeader/GuidValue")
71 version
= XmlElement(fpdHeader
, "/PlatformHeader/Version")
72 return self
.installedPlatforms
.has_key((guid
, version
))
74 def HasFar(self
, farguid
):
75 """Return true iff this far is already installed."""
76 return self
.installedFars
.has_key(farguid
)
78 def AddPackage(self
, f
):
79 filename
= self
.dom
.createElement("Filename")
80 filename
.appendChild(self
.dom
.createTextNode(f
))
81 self
.packageList
.appendChild(filename
)
83 def AddPlatform(self
, f
):
84 filename
= self
.dom
.createElement("Filename")
85 filename
.appendChild(self
.dom
.createTextNode(f
))
86 self
.platformList
.appendChild(filename
)
88 def AddFar(self
, f
, guid
=""):
89 filename
= self
.dom
.createElement("Filename")
90 filename
.setAttribute("FarGuid", guid
)
91 filename
.appendChild(self
.dom
.createTextNode(f
))
92 self
.farList
.appendChild(filename
)
96 XmlSaveFile(self
.dom
, self
.DBFile
)
98 f
=open(self
.DBFile
, 'w')
99 f
.write(self
.dom
.toprettyxml(2*" "))
102 def ExtractFile(zip, file, workspaceLocation
=""):
105 print "Extracting ", file
107 destFile
= os
.path
.join(inWorkspace(workspaceLocation
), str(file))
108 destDir
= os
.path
.dirname(destFile
)
112 f
= open(destFile
, "w")
113 f
.write(zip.read(file))
116 def InstallFar(farfile
, workspaceLocation
=""):
118 far
= zipfile
.ZipFile(farfile
, "r")
120 # Use this list to make sure we get everything from the far.
121 zipContents
= far
.namelist()
123 manifest
= xml
.dom
.minidom
.parseString(far
.read("FrameworkArchiveManifest.xml"))
124 zipContents
.remove("FrameworkArchiveManifest.xml")
127 # First we need to make sure that the far will install cleanly.
130 for farPackage
in XmlList(manifest
, "/FrameworkArchiveManifest/FarPackageList/FarPackage/FarFilename"):
131 spdfile
= str(XmlElementData(farPackage
))
132 if fdb
.HasPackage(far
.read(spdfile
)):
133 print "Error: This package is already installed: ", spdfile
136 # Check the platforms
137 for farPlatform
in XmlList(manifest
, "/FrameworkArchiveManifest/FarPlatformList/FarPlatform/FarFilename"):
138 fpdfile
= str(XmlElementData(farPlatform
))
139 if fdb
.HasPlatform(far
.read(fpdfile
)):
140 print "Error: This platform is already installed: ", fpdfile
144 thisFarGuid
= XmlElement(manifest
, "/FrameworkArchiveManifest/FarHeader/GuidValue")
145 if fdb
.HasFar(thisFarGuid
):
146 print "Error: There is a far with this guid already installed."
149 # We can not do the install
152 print "Ignoring previous errors as you requested."
156 # Install the packages
157 for farPackage
in XmlList(manifest
, "/FrameworkArchiveManifest/FarPackageList/FarPackage"):
159 filename
= XmlElement(farPackage
, "FarPackage/FarFilename")
160 fdb
.AddPackage(filename
)
161 ExtractFile(far
, filename
, workspaceLocation
)
162 zipContents
.remove(filename
)
164 for content
in XmlList(farPackage
, "FarPackage/Contents/FarFilename"):
166 filename
= XmlElementData(content
)
167 ExtractFile(far
, filename
, workspaceLocation
)
168 zipContents
.remove(filename
)
170 # Install the platforms
171 for farPlatform
in XmlList(manifest
, "/FrameworkArchiveManifest/FarPlatformList/FarPlatform"):
173 filename
= XmlElement(farPlatform
, "FarPlatform/FarFilename")
174 fdb
.AddPlatform(filename
)
175 ExtractFile(far
, filename
, workspaceLocation
)
176 zipContents
.remove(filename
)
178 # Install the Contents
179 for content
in XmlList(manifest
, "/FrameworkArchiveManifest/Contents/FarFilename"):
181 filename
= XmlElementData(content
)
182 ExtractFile(far
, filename
, workspaceLocation
)
183 zipContents
.remove(filename
)
185 # What if there are more files in the far?
186 if not zipContents
== []:
187 print "There are still files in the far:", zipContents
189 fdb
.AddFar(farfile
, thisFarGuid
)
191 # If everything has gone well, we can put the manifest file in a safe place...
192 farDir
= inWorkspace("Tools/Conf/InstalledFars/")
194 f
=open(os
.path
.join(farDir
, thisFarGuid
), 'w')
195 f
.write(far
.read("FrameworkArchiveManifest.xml"))
198 # Write out the new database
203 # This acts like the main() function for the script, unless it is 'import'ed
204 # into another script.
205 if __name__
== '__main__':
207 # Process the command line args.
208 optlist
, args
= getopt
.getopt(sys
.argv
[1:], '?hvf', ['help', 'verbose', 'force'])
210 # First pass through the options list.
212 if o
in ["-h", "--help"]:
214 Install a far (Framework Archive) into the current workspace.
215 """ % os
.path
.basename(sys
.argv
[0])
218 optlist
.remove((o
,a
))
219 if o
in ["-v", "--verbose"]:
221 if o
in ["-f", "--force"]:
227 print "Please pass a far filename on the command line."