Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 388fbf3

Browse files
committed
- Better commandline interface to BuildApplet, complete with options,
verbose output to the console, etc. - Allow Cocoa applets to be built with BuildApplet. No full testing has been done yet to ensure OS9 operation hasn't suffered.
1 parent 2befa48 commit 388fbf3

3 files changed

Lines changed: 159 additions & 49 deletions

File tree

Mac/Lib/buildtools.py

Lines changed: 96 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@
1717

1818
BuildError = "BuildError"
1919

20-
DEBUG=1
21-
22-
2320
# .pyc file (and 'PYC ' resource magic number)
2421
MAGIC = imp.get_magic()
2522

@@ -70,13 +67,13 @@ def findtemplate_macho():
7067
return '/'.join(execpath[:i])
7168

7269

73-
def process(template, filename, output, copy_codefragment):
70+
def process(template, filename, destname, copy_codefragment,
71+
rsrcname=None, others=[], raw=0, progress="default"):
7472

75-
if DEBUG:
73+
if progress == "default":
7674
progress = EasyDialogs.ProgressBar("Processing %s..."%os.path.split(filename)[1], 120)
7775
progress.label("Compiling...")
78-
else:
79-
progress = None
76+
progress.inc(0)
8077

8178
# Read the source and compile it
8279
# (there's no point overwriting the destination if it has a syntax error)
@@ -89,34 +86,38 @@ def process(template, filename, output, copy_codefragment):
8986
except (SyntaxError, EOFError):
9087
raise BuildError, "Syntax error in script %s" % `filename`
9188

92-
# Set the destination file name
89+
# Set the destination file name. Note that basename
90+
# does contain the whole filepath, only a .py is stripped.
9391

9492
if string.lower(filename[-3:]) == ".py":
95-
destname = filename[:-3]
96-
rsrcname = destname + '.rsrc'
93+
basename = filename[:-3]
94+
if MacOS.runtimemodel != 'macho' and not destname:
95+
destname = basename
9796
else:
97+
basename = filename
98+
99+
if not destname:
98100
if MacOS.runtimemodel == 'macho':
99-
destname = filename + '.app'
101+
destname = basename + '.app'
100102
else:
101-
destname = filename + ".applet"
102-
rsrcname = filename + '.rsrc'
103-
104-
if output:
105-
destname = output
106-
103+
destname = basename + '.applet'
104+
if not rsrcname:
105+
rsrcname = basename + '.rsrc'
106+
107107
# Try removing the output file. This fails in MachO, but it should
108108
# do any harm.
109109
try:
110110
os.remove(destname)
111111
except os.error:
112112
pass
113-
process_common(template, progress, code, rsrcname, destname, 0, copy_codefragment)
113+
process_common(template, progress, code, rsrcname, destname, 0,
114+
copy_codefragment, raw, others)
114115

115116

116117
def update(template, filename, output):
117118
if MacOS.runtimemodel == 'macho':
118119
raise BuildError, "No updating yet for MachO applets"
119-
if DEBUG:
120+
if progress:
120121
progress = EasyDialogs.ProgressBar("Updating %s..."%os.path.split(filename)[1], 120)
121122
else:
122123
progress = None
@@ -131,16 +132,20 @@ def update(template, filename, output):
131132
process_common(template, progress, None, filename, output, 1, 1)
132133

133134

134-
def process_common(template, progress, code, rsrcname, destname, is_update, copy_codefragment):
135+
def process_common(template, progress, code, rsrcname, destname, is_update,
136+
copy_codefragment, raw=0, others=[]):
135137
if MacOS.runtimemodel == 'macho':
136-
return process_common_macho(template, progress, code, rsrcname, destname, is_update)
138+
return process_common_macho(template, progress, code, rsrcname, destname,
139+
is_update, raw, others)
140+
if others:
141+
raise BuildError, "Extra files only allowed for MachoPython applets"
137142
# Create FSSpecs for the various files
138143
template_fss = macfs.FSSpec(template)
139144
template_fss, d1, d2 = macfs.ResolveAliasFile(template_fss)
140145
dest_fss = macfs.FSSpec(destname)
141146

142147
# Copy data (not resources, yet) from the template
143-
if DEBUG:
148+
if progress:
144149
progress.label("Copy data fork...")
145150
progress.set(10)
146151

@@ -157,7 +162,7 @@ def process_common(template, progress, code, rsrcname, destname, is_update, copy
157162

158163
# Open the output resource fork
159164

160-
if DEBUG:
165+
if progress:
161166
progress.label("Copy resources...")
162167
progress.set(20)
163168
try:
@@ -172,7 +177,7 @@ def process_common(template, progress, code, rsrcname, destname, is_update, copy
172177
input = Res.FSpOpenResFile(rsrcname, READ)
173178
except (MacOS.Error, ValueError):
174179
pass
175-
if DEBUG:
180+
if progress:
176181
progress.inc(50)
177182
else:
178183
if is_update:
@@ -222,7 +227,7 @@ def process_common(template, progress, code, rsrcname, destname, is_update, copy
222227
pass
223228

224229
# Create the raw data for the resource from the code object
225-
if DEBUG:
230+
if progress:
226231
progress.label("Write PYC resource...")
227232
progress.set(120)
228233

@@ -256,10 +261,11 @@ def process_common(template, progress, code, rsrcname, destname, is_update, copy
256261
dest_fss.SetFInfo(dest_finfo)
257262

258263
macostools.touched(dest_fss)
259-
if DEBUG:
264+
if progress:
260265
progress.label("Done.")
266+
progress.inc(0)
261267

262-
def process_common_macho(template, progress, code, rsrcname, destname, is_update):
268+
def process_common_macho(template, progress, code, rsrcname, destname, is_update, raw=0, others=[]):
263269
# First make sure the name ends in ".app"
264270
if destname[-4:] != '.app':
265271
destname = destname + '.app'
@@ -286,14 +292,17 @@ def process_common_macho(template, progress, code, rsrcname, destname, is_update
286292
"Contents/Resources/English.lproj/InfoPlist.strings",
287293
"Contents/Resources/python.rsrc",
288294
]
289-
copyapptree(template, destname, exceptlist)
295+
copyapptree(template, destname, exceptlist, progress)
290296
# Now either use the .plist file or the default
297+
if progress:
298+
progress.label('Create info.plist')
299+
progress.inc(0)
291300
if plistname:
292-
shutil.copy2(plistname, os.path.join(destname, 'Contents/Info.plist'))
301+
shutil.copy2(plistname, os.path.join(destname, 'Contents', 'Info.plist'))
293302
if icnsname:
294303
icnsdest = os.path.split(icnsname)[1]
295304
icnsdest = os.path.join(destname,
296-
os.path.join('Contents/Resources', icnsdest))
305+
os.path.join('Contents', 'Resources', icnsdest))
297306
shutil.copy2(icnsname, icnsdest)
298307
# XXXX Wrong. This should be parsed from plist file. Also a big hack:-)
299308
if shortname == 'PythonIDE':
@@ -302,31 +311,44 @@ def process_common_macho(template, progress, code, rsrcname, destname, is_update
302311
ownertype = 'PytA'
303312
# XXXX Should copy .icns file
304313
else:
305-
plistname = os.path.join(template, 'Contents/Resources/Applet-Info.plist')
314+
cocoainfo = ''
315+
for o in others:
316+
if o[-4:] == '.nib':
317+
nibname = os.path.split(o)[1][:-4]
318+
cocoainfo = """
319+
<key>NSMainNibFile</key>
320+
<string>%s</string>
321+
<key>NSPrincipalClass</key>
322+
<string>NSApplication</string>""" % nibname
323+
324+
325+
plistname = os.path.join(template, 'Contents', 'Resources', 'Applet-Info.plist')
306326
plistdata = open(plistname).read()
307-
plistdata = plistdata % {'appletname':shortname}
308-
ofp = open(os.path.join(destname, 'Contents/Info.plist'), 'w')
327+
plistdata = plistdata % {'appletname':shortname, 'cocoainfo':cocoainfo}
328+
ofp = open(os.path.join(destname, 'Contents', 'Info.plist'), 'w')
309329
ofp.write(plistdata)
310330
ofp.close()
311331
ownertype = 'PytA'
312332
# Create the PkgInfo file
313-
ofp = open(os.path.join(destname, 'Contents/PkgInfo'), 'wb')
333+
if progress:
334+
progress.label('Create PkgInfo')
335+
progress.inc(0)
336+
ofp = open(os.path.join(destname, 'Contents', 'PkgInfo'), 'wb')
314337
ofp.write('APPL' + ownertype)
315338
ofp.close()
316339

317340

318-
if DEBUG:
341+
if progress:
319342
progress.label("Copy resources...")
320343
progress.set(20)
321344
resfilename = '%s.rsrc' % shortname
322-
respartialpathname = 'Contents/Resources/%s' % resfilename
323345
try:
324346
output = Res.FSOpenResourceFile(
325-
os.path.join(destname, respartialpathname),
347+
os.path.join(destname, 'Contents', 'Resources', resfilename),
326348
u'', WRITE)
327349
except MacOS.Error:
328350
fsr, dummy = Res.FSCreateResourceFile(
329-
os.path.join(destname, 'Contents/Resources'),
351+
os.path.join(destname, 'Contents', 'Resources'),
330352
unicode(resfilename), '')
331353
output = Res.FSOpenResourceFile(fsr, u'', WRITE)
332354

@@ -336,7 +358,7 @@ def process_common_macho(template, progress, code, rsrcname, destname, is_update
336358
input = macresource.open_pathname(rsrcname)
337359
except (MacOS.Error, ValueError):
338360
pass
339-
if DEBUG:
361+
if progress:
340362
progress.inc(50)
341363
else:
342364
typesfound, ownertype = copyres(input, output, [], 0, progress)
@@ -355,8 +377,12 @@ def process_common_macho(template, progress, code, rsrcname, destname, is_update
355377
# Copy the resources from the template
356378

357379
input = Res.FSOpenResourceFile(
358-
os.path.join(template, 'Contents/Resources/python.rsrc'), u'', READ)
359-
dummy, tmplowner = copyres(input, output, skiptypes, 1, progress)
380+
os.path.join(template, 'Contents', 'Resources', 'python.rsrc'), u'', READ)
381+
if progress:
382+
progress.label("Copy standard resources...")
383+
progress.inc(0)
384+
## dummy, tmplowner = copyres(input, output, skiptypes, 1, progress)
385+
dummy, tmplowner = copyres(input, output, skiptypes, 1, None)
360386

361387
Res.CloseResFile(input)
362388
## if ownertype == None:
@@ -366,8 +392,29 @@ def process_common_macho(template, progress, code, rsrcname, destname, is_update
366392
Res.CloseResFile(output)
367393

368394
if code:
369-
outputfilename = os.path.join(destname, 'Contents/Resources/__main__.pyc')
395+
if raw:
396+
pycname = '__rawmain__.pyc'
397+
else:
398+
pycname = '__main__.pyc'
399+
outputfilename = os.path.join(destname, 'Contents', 'Resources', pycname)
400+
if progress:
401+
progress.label('Creating '+pycname)
402+
progress.inc(0)
370403
writepycfile(code, outputfilename)
404+
# Copy other files the user asked for
405+
for osrc in others:
406+
oname = os.path.split(osrc)[1]
407+
odst = os.path.join(destname, 'Contents', 'Resources', oname)
408+
if progress:
409+
progress.label('Copy ' + oname)
410+
progress.inc(0)
411+
if os.path.isdir(osrc):
412+
copyapptree(osrc, odst)
413+
else:
414+
shutil.copy2(osrc, odst)
415+
if progress:
416+
progress.label('Done.')
417+
progress.inc(0)
371418

372419
## macostools.touched(dest_fss)
373420

@@ -400,7 +447,7 @@ def copyres(input, output, skiptypes, skipowner, progress=None):
400447
ctor = type
401448
size = res.size
402449
attrs = res.GetResAttrs()
403-
if DEBUG and progress:
450+
if progress:
404451
progress.label("Copy %s %d %s"%(type, id, name))
405452
progress.inc(progress_cur_inc)
406453
res.LoadResource()
@@ -411,8 +458,9 @@ def copyres(input, output, skiptypes, skipowner, progress=None):
411458
except MacOS.Error:
412459
res2 = None
413460
if res2:
414-
if DEBUG and progress:
461+
if progress:
415462
progress.label("Overwrite %s %d %s"%(type, id, name))
463+
progress.inc(0)
416464
res2.RemoveResource()
417465
res.AddResource(type, id, name)
418466
res.WriteResource()
@@ -421,7 +469,7 @@ def copyres(input, output, skiptypes, skipowner, progress=None):
421469
Res.UseResFile(input)
422470
return alltypes, ctor
423471

424-
def copyapptree(srctree, dsttree, exceptlist=[]):
472+
def copyapptree(srctree, dsttree, exceptlist=[], progress=None):
425473
names = []
426474
if os.path.exists(dsttree):
427475
shutil.rmtree(dsttree)
@@ -443,6 +491,9 @@ def copyapptree(srctree, dsttree, exceptlist=[]):
443491
if os.path.isdir(srcpath):
444492
os.mkdir(dstpath)
445493
else:
494+
if progress:
495+
progress.label('Copy '+this)
496+
progress.inc(0)
446497
shutil.copy2(srcpath, dstpath)
447498

448499
def writepycfile(codeobject, cfile):

Mac/OSXResources/app/Resources/Applet-Info.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
<key>CFBundleGetInfoString</key>
2424
<string>%(appletname)s, a Python applet</string>
25+
26+
%(cocoainfo)s
2527

2628
<key>CFBundleIconFile</key>
2729
<string>PythonApplet.icns</string>

0 commit comments

Comments
 (0)