5353import os , sys , glob , fnmatch , shutil , string , copy , getopt
5454from os .path import basename , dirname , join , islink , isdir , isfile
5555
56+ Error = "buildpkg.Error"
5657
5758PKG_INFO_FIELDS = """\
5859 Title
@@ -159,6 +160,7 @@ def __init__(self, title, version, desc):
159160 # variables set later
160161 self .packageRootFolder = None
161162 self .packageResourceFolder = None
163+ self .sourceFolder = None
162164 self .resourceFolder = None
163165
164166
@@ -171,16 +173,25 @@ def build(self, root, resources=None, **options):
171173 """
172174
173175 # set folder attributes
174- self .packageRootFolder = root
176+ self .sourceFolder = root
175177 if resources == None :
176- self .packageResourceFolder = root
178+ self .resourceFolder = root
179+ else :
180+ self .resourceFolder = resources
177181
178182 # replace default option settings with user ones if provided
179183 fields = self . packageInfoDefaults .keys ()
180184 for k , v in options .items ():
181185 if k in fields :
182186 self .packageInfo [k ] = v
183-
187+ elif not k in ["OutputDir" ]:
188+ raise Error , "Unknown package option: %s" % k
189+
190+ # Check where we should leave the output. Default is current directory
191+ outputdir = options .get ("OutputDir" , os .getcwd ())
192+ packageName = self .packageInfo ["Title" ]
193+ self .PackageRootFolder = os .path .join (outputdir , packageName + ".pkg" )
194+
184195 # do what needs to be done
185196 self ._makeFolders ()
186197 self ._addInfo ()
@@ -197,16 +208,11 @@ def _makeFolders(self):
197208 # packageName = "%s-%s" % (self.packageInfo["Title"],
198209 # self.packageInfo["Version"]) # ??
199210
200- packageName = self .packageInfo ["Title" ]
201- rootFolder = packageName + ".pkg"
202- contFolder = join (rootFolder , "Contents" )
203- resourceFolder = join (contFolder , "Resources" )
204- os .mkdir (rootFolder )
211+ contFolder = join (self .PackageRootFolder , "Contents" )
212+ self .packageResourceFolder = join (contFolder , "Resources" )
213+ os .mkdir (self .PackageRootFolder )
205214 os .mkdir (contFolder )
206- os .mkdir (resourceFolder )
207-
208- self .resourceFolder = resourceFolder
209-
215+ os .mkdir (self .packageResourceFolder )
210216
211217 def _addInfo (self ):
212218 "Write .info file containing installing options."
@@ -217,8 +223,8 @@ def _addInfo(self):
217223 for f in string .split (PKG_INFO_FIELDS , "\n " ):
218224 info = info + "%s %%(%s)s\n " % (f , f )
219225 info = info % self .packageInfo
220- base = basename ( self .packageRootFolder ) + ".info"
221- path = join (self .resourceFolder , base )
226+ base = self .packageInfo [ "Title" ] + ".info"
227+ path = join (self .packageResourceFolder , base )
222228 f = open (path , "w" )
223229 f .write (info )
224230
@@ -229,9 +235,9 @@ def _addBom(self):
229235 # Currently ignores if the 'mkbom' tool is not available.
230236
231237 try :
232- base = basename ( self .packageRootFolder ) + ".bom"
233- bomPath = join (self .resourceFolder , base )
234- cmd = "mkbom %s %s" % (self .packageRootFolder , bomPath )
238+ base = self .packageInfo [ "Title" ] + ".bom"
239+ bomPath = join (self .packageResourceFolder , base )
240+ cmd = "mkbom %s %s" % (self .sourceFolder , bomPath )
235241 res = os .system (cmd )
236242 except :
237243 pass
@@ -244,23 +250,16 @@ def _addArchive(self):
244250
245251 cwd = os .getcwd ()
246252
247- packageRootFolder = self .packageRootFolder
248-
249- try :
250- # create archive
251- d = dirname (packageRootFolder )
252- os .chdir (packageRootFolder )
253- base = basename (packageRootFolder ) + ".pax"
254- archPath = join (d , self .resourceFolder , base )
255- cmd = "pax -w -f %s %s" % (archPath , "." )
256- res = os .system (cmd )
257-
258- # compress archive
259- cmd = "gzip %s" % archPath
260- res = os .system (cmd )
261- except :
262- pass
263-
253+ # create archive
254+ os .chdir (self .sourceFolder )
255+ base = basename (self .packageInfo ["Title" ]) + ".pax"
256+ self .archPath = join (self .packageResourceFolder , base )
257+ cmd = "pax -w -f %s %s" % (self .archPath , "." )
258+ res = os .system (cmd )
259+
260+ # compress archive
261+ cmd = "gzip %s" % self .archPath
262+ res = os .system (cmd )
264263 os .chdir (cwd )
265264
266265
@@ -271,43 +270,47 @@ def _addResources(self):
271270 # filenames. So, it's left to Installer.app to deal with the
272271 # same file available in multiple formats...
273272
274- if not self .packageResourceFolder :
273+ if not self .resourceFolder :
275274 return
276275
277276 # find candidate resource files (txt html rtf rtfd/ or lproj/)
278277 allFiles = []
279278 for pat in string .split ("*.txt *.html *.rtf *.rtfd *.lproj" , " " ):
280- pattern = join (self .packageResourceFolder , pat )
279+ pattern = join (self .resourceFolder , pat )
281280 allFiles = allFiles + glob .glob (pattern )
282281
283282 # find pre-process and post-process scripts
284283 # naming convention: packageName.{pre,post}-{upgrade,install}
284+ # Alternatively the filenames can be {pre,post}-{upgrade,install}
285+ # in which case we prepend the package name
285286 packageName = self .packageInfo ["Title" ]
286287 for pat in ("*upgrade" , "*install" ):
287- pattern = join (self .packageResourceFolder , packageName + pat )
288+ pattern = join (self .resourceFolder , packageName + pat )
288289 allFiles = allFiles + glob .glob (pattern )
289290
290291 # check name patterns
291292 files = []
292293 for f in allFiles :
293294 for s in ("Welcome" , "License" , "ReadMe" ):
294295 if string .find (basename (f ), s ) == 0 :
295- files .append (f )
296+ files .append (( f , f ) )
296297 if f [- 6 :] == ".lproj" :
297- files .append (f )
298+ files .append ((f , f ))
299+ elif f in ["pre-upgrade" , "pre-install" , "post-upgrade" , "post-install" ]:
300+ files .append ((f , self .packageInfo ["Title" ]+ "." + f ))
298301 elif f [- 8 :] == "-upgrade" :
299- files .append (f )
302+ files .append (( f , f ) )
300303 elif f [- 8 :] == "-install" :
301- files .append (f )
304+ files .append (( f , f ) )
302305
303306 # copy files
304- for g in files :
305- f = join (self .packageResourceFolder , g )
307+ for src , dst in files :
308+ f = join (self .resourceFolder , src )
306309 if isfile (f ):
307- shutil .copy (f , self .resourceFolder )
310+ shutil .copy (f , os . path . join ( self .packageResourceFolder , dst ) )
308311 elif isdir (f ):
309312 # special case for .rtfd and .lproj folders...
310- d = join (self .resourceFolder , basename ( f ) )
313+ d = join (self .packageResourceFolder , dst )
311314 os .mkdir (d )
312315 files = GlobDirectoryWalker (f )
313316 for file in files :
@@ -326,23 +329,18 @@ def _addSizes(self):
326329 installedSize = 0
327330 zippedSize = 0
328331
329- packageRootFolder = self .packageRootFolder
330-
331- files = GlobDirectoryWalker (packageRootFolder )
332+ files = GlobDirectoryWalker (self .sourceFolder )
332333 for f in files :
333334 numFiles = numFiles + 1
334- installedSize = installedSize + os .stat (f )[6 ]
335+ installedSize = installedSize + os .lstat (f )[6 ]
335336
336- d = dirname (packageRootFolder )
337- base = basename (packageRootFolder ) + ".pax.gz"
338- archPath = join (d , self .resourceFolder , base )
339337 try :
340- zippedSize = os .stat (archPath )[6 ]
338+ zippedSize = os .stat (self . archPath + ".gz" )[6 ]
341339 except OSError : # ignore error
342340 pass
343- base = basename ( packageRootFolder ) + ".sizes"
344- f = open (join (self .resourceFolder , base ), "w" )
345- format = "NumFiles %d\n InstalledSize %d\n CompressedSize %d"
341+ base = self . packageInfo [ "Title" ] + ".sizes"
342+ f = open (join (self .packageResourceFolder , base ), "w" )
343+ format = "NumFiles %d\n InstalledSize %d\n CompressedSize %d\n "
346344 f .write (format % (numFiles , installedSize , zippedSize ))
347345
348346
0 commit comments