diff --git Changelog Changelog
index 07dfe16..47bbfef 100644
|
|
|
1 | 1 | Changes in version 0.7.4: |
2 | 2 | |
| 3 | - Release gtk-mac-bundler 0.7.4 (John Ralls) |
| 4 | - Make sure to check for .symbolic icon extension (Jesse van den Kieboom) |
| 5 | - Fix pixbuf loader cache path (Jesse van den Kieboom) |
| 6 | - Make sure that libraries are writeable before using otool. (Julien Woillez) |
| 7 | - Update doap to reflect correct bug tracker. (John Ralls) |
| 8 | - Bug 698196: Fix typo (John Ralls) |
| 9 | - Bug #698916: Update versions, fix pixbuf (John Ralls) |
| 10 | - Update all launchers to reflect new pango environment variables (John Ralls) |
| 11 | - launcher: Update for pango changes (Dave Vasilevsky) |
| 12 | - Correct gdk-pixbuf path in the pygtk example (John Ralls) |
| 13 | - Bring example bundle files and launchers up to date (John Ralls) |
| 14 | - The *correct* fix for pango modules. (John Ralls) |
| 15 | - Fix another typo in pango module path (John Ralls) |
| 16 | |
| 17 | Changes in version 0.7.4: |
| 18 | |
3 | 19 | - Make sure to check for .symbolic icon extension (Jesse van den Kieboom) |
4 | 20 | - Fix pixbuf loader cache path (Jesse van den Kieboom) |
5 | 21 | - Make sure that libraries are writeable before using otool. (Julien Woillez) |
diff --git bundler/bundler.py bundler/bundler.py
index 8061ac1..65b8cc0 100644
|
|
|
1 | 1 | import sys |
2 | 2 | import os, errno, glob |
3 | | import dircache, shutil |
| 3 | import shutil |
4 | 4 | import re |
5 | 5 | from plistlib import Plist |
6 | 6 | from distutils import dir_util, file_util |
7 | 7 | |
8 | | from project import * |
9 | | import utils |
| 8 | from .project import * |
| 9 | from . import utils |
10 | 10 | |
11 | 11 | class Bundler: |
12 | 12 | def __init__(self, project): |
… |
… |
class Bundler: |
32 | 32 | def recursive_rm(self, dirname): |
33 | 33 | # Extra safety ;) |
34 | 34 | if dirname in [ "/", os.getenv("HOME"), os.path.join(os.getenv("HOME"), "Desktop"), self.meta.dest ]: |
35 | | print "Eek, trying to remove a bit much, eh? (%s)" % (dirname) |
| 35 | print("Eek, trying to remove a bit much, eh? (%s)" % (dirname)) |
36 | 36 | sys.exit(1) |
37 | 37 | |
38 | 38 | if not os.path.exists(dirname): |
39 | 39 | return |
40 | 40 | |
41 | | files = dircache.listdir(dirname) |
| 41 | files = os.listdir(dirname) |
42 | 42 | for file in files: |
43 | 43 | path = os.path.join (dirname, file) |
44 | 44 | if os.path.isdir(path): |
… |
… |
class Bundler: |
68 | 68 | self.copy_path(path) |
69 | 69 | |
70 | 70 | def create_pango_setup(self): |
| 71 | if utils.has_pkgconfig_module("pango") and \ |
| 72 | not utils.has_pkgconfig_variable("pango", "pango_module_version"): |
| 73 | # Newer pango (>= 1.38) no longer has modules, skip this |
| 74 | # step in that case. |
| 75 | return |
| 76 | |
71 | 77 | # Create a temporary pangorc file just for creating the |
72 | 78 | # modules file with the right modules. |
73 | 79 | module_version = utils.evaluate_pkgconfig_variables("${pkg:pango:pango_module_version}") |
… |
… |
class Bundler: |
227 | 233 | # Clean out any libtool (*.la) files and static libraries |
228 | 234 | if os.path.isdir(dest): |
229 | 235 | for root, dirs, files in os.walk(dest): |
230 | | for name in filter(lambda l: l.endswith(".la") or l.endswith(".a"), files): |
| 236 | for name in [l for l in files if l.endswith(".la") or l.endswith(".a")]: |
231 | 237 | os.remove(os.path.join(root, name)) |
232 | 238 | |
233 | 239 | # Copies from Path.source to Path.dest, evaluating any variables |
… |
… |
class Bundler: |
247 | 253 | relative_dest = self.project.evaluate_path(Path.source[m.end():]) |
248 | 254 | dest = self.project.get_bundle_path("Contents/Resources", relative_dest) |
249 | 255 | else: |
250 | | print "Invalid bundle file, missing or invalid 'dest' property: " + Path.dest |
| 256 | print("Invalid bundle file, missing or invalid 'dest' property: " + Path.dest) |
251 | 257 | sys.exit(1) |
252 | 258 | |
253 | 259 | (dest_parent, dest_tail) = os.path.split(dest) |
… |
… |
class Bundler: |
257 | 263 | p = re.compile("[\*\?]") |
258 | 264 | (source_parent, source_tail) = os.path.split(source) |
259 | 265 | if p.search(source_parent): |
260 | | print "Can't have wildcards except in the last path component: " + source |
| 266 | print("Can't have wildcards except in the last path component: " + source) |
261 | 267 | sys.exit(1) |
262 | 268 | |
263 | 269 | if p.search(source_tail): |
… |
… |
class Bundler: |
267 | 273 | else: |
268 | 274 | source_check = source |
269 | 275 | if not os.path.exists(source_check): |
270 | | print "Cannot find source to copy: " + source |
| 276 | print("Cannot find source to copy: " + source) |
271 | 277 | sys.exit(1) |
272 | 278 | |
273 | 279 | # If the destination has a wildcard as last component (copied |
… |
… |
class Bundler: |
285 | 291 | try: |
286 | 292 | # print "Copying %s to %s" % (globbed_source, destdir) |
287 | 293 | shutil.copy(globbed_source, destdir) |
288 | | except EnvironmentError, e: |
| 294 | except EnvironmentError as e: |
289 | 295 | if e.errno == errno.ENOENT: |
290 | | print "Warning, source file missing: " + globbed_source |
| 296 | print("Warning, source file missing: " + globbed_source) |
291 | 297 | elif e.errno == errno.EEXIST: |
292 | | print "Warning, path already exits: " + dest |
| 298 | print("Warning, path already exits: " + dest) |
293 | 299 | else: |
294 | | print "Error %s when copying file: %s" % ( str(e), globbed_source ) |
| 300 | print("Error %s when copying file: %s" % ( str(e), globbed_source )) |
295 | 301 | sys.exit(1) |
296 | 302 | |
297 | 303 | else: |
… |
… |
class Bundler: |
315 | 321 | link=None, |
316 | 322 | verbose=1, |
317 | 323 | dry_run=0) |
318 | | except EnvironmentError, e: |
| 324 | except EnvironmentError as e: |
319 | 325 | if e.errno == errno.ENOENT: |
320 | | print "Warning, source file missing: " + globbed_source |
| 326 | print("Warning, source file missing: " + globbed_source) |
321 | 327 | elif e.errno == errno.EEXIST: |
322 | | print "Warning, path already exits: " + dest |
| 328 | print("Warning, path already exits: " + dest) |
323 | 329 | else: |
324 | | print "Error %s when copying file: %s" %( str(e), globbed_source ) |
| 330 | print("Error %s when copying file: %s" %( str(e), globbed_source )) |
325 | 331 | sys.exit(1) |
326 | 332 | return dest |
327 | 333 | |
… |
… |
class Bundler: |
338 | 344 | for path in self.binary_paths: |
339 | 345 | if os.path.isdir(path): |
340 | 346 | for root, dirs, files in os.walk(path): |
341 | | paths.extend(map(lambda l: os.path.join(root, l), files)) |
| 347 | paths.extend([os.path.join(root, l) for l in files]) |
342 | 348 | else: |
343 | 349 | paths.append(path) |
344 | 350 | |
345 | | paths = filter(filter_path, paths) |
| 351 | paths = list(filter(filter_path, paths)) |
346 | 352 | return list(set(paths)) |
347 | 353 | |
348 | 354 | def resolve_library_dependencies(self): |
… |
… |
class Bundler: |
366 | 372 | |
367 | 373 | def relative_path_map(line): |
368 | 374 | if not os.path.isabs(line): |
369 | | for prefix in prefixes.values(): |
| 375 | for prefix in list(prefixes.values()): |
370 | 376 | path = os.path.join(prefix, "lib", line) |
371 | 377 | if os.path.exists(path): |
372 | 378 | return path |
373 | | print "Cannot find a matching prefix for %s" % (line) |
| 379 | print("Cannot find a matching prefix for %s" % (line)) |
374 | 380 | return line |
375 | 381 | |
376 | 382 | def prefix_filter(line): |
… |
… |
class Bundler: |
378 | 384 | return False |
379 | 385 | |
380 | 386 | if line.startswith("/usr/X11"): |
381 | | print "Warning, found X11 library dependency, you most likely don't want that:", line.strip().split()[0] |
| 387 | print("Warning, found X11 library dependency, you most likely don't want that:", line.strip().split()[0]) |
382 | 388 | |
383 | 389 | if os.path.isabs(line): |
384 | | for prefix in prefixes.values(): |
| 390 | for prefix in list(prefixes.values()): |
385 | 391 | if prefix in line: |
386 | 392 | return True |
387 | 393 | |
388 | 394 | if not line.startswith("/usr/lib") and not line.startswith("/System/Library"): |
389 | | print "Warning, library not available in any prefix:", line.strip().split()[0] |
| 395 | print("Warning, library not available in any prefix:", line.strip().split()[0]) |
390 | 396 | |
391 | 397 | return False |
392 | 398 | |
393 | 399 | return True |
394 | 400 | |
395 | | lines = filter(prefix_filter, [line.strip() for line in f]) |
| 401 | lines = list(filter(prefix_filter, [line.strip() for line in f])) |
396 | 402 | p = re.compile("(.*\.dylib\.?.*)\s\(compatibility.*$") |
397 | 403 | lines = utils.filterlines(p, lines) |
398 | | lines = map(relative_path_map, lines) |
| 404 | lines = list(map(relative_path_map, lines)) |
399 | 405 | #When you need to track down errors, uncomment this blocK |
400 | 406 | # for path in paths: |
401 | 407 | # cmd = "otool -L %s" % path |
… |
… |
class Bundler: |
407 | 413 | for library in set(lines): |
408 | 414 | # Replace the real path with the right prefix so we can |
409 | 415 | # create a Path object. |
410 | | for (key, value) in prefixes.items(): |
| 416 | for (key, value) in list(prefixes.items()): |
411 | 417 | if library.startswith(value): |
412 | 418 | path = Path("${prefix:" + key + "}" + library[len(value):]) |
413 | 419 | new_libraries.append(path) |
… |
… |
class Bundler: |
415 | 421 | n_paths = len(paths) |
416 | 422 | n_iterations += 1 |
417 | 423 | if n_iterations > 10: |
418 | | print "Too many tries to resolve library dependencies" |
| 424 | print("Too many tries to resolve library dependencies") |
419 | 425 | sys.exit(1) |
420 | 426 | |
421 | 427 | self.copy_binaries(new_libraries) |
422 | 428 | paths = self.list_copied_binaries() |
423 | 429 | |
424 | 430 | def run_install_name_tool(self): |
425 | | print "Running install name tool" |
| 431 | print("Running install name tool") |
426 | 432 | |
427 | 433 | paths = self.list_copied_binaries() |
428 | 434 | prefixes = self.meta.prefixes |
… |
… |
class Bundler: |
430 | 436 | # First change all references in libraries. |
431 | 437 | for prefix in prefixes: |
432 | 438 | prefix_path = self.project.get_prefix(prefix) |
433 | | print "Going through prefix: " + prefix_path |
| 439 | print("Going through prefix: " + prefix_path) |
434 | 440 | for path in paths: |
435 | 441 | cmd = os.path.join(os.path.dirname(__file__), "run-install-name-tool-change.sh") + " " + path + " " + prefix_path + " Resources" + " change" |
436 | 442 | f = os.popen(cmd) |
437 | 443 | for line in f: |
438 | | print line |
| 444 | print(line) |
439 | 445 | |
440 | 446 | # Then change the id of all libraries. Skipping this part for now |
441 | 447 | #for path in paths: |
… |
… |
class Bundler: |
448 | 454 | for framework in self.frameworks: |
449 | 455 | fw_name, ext = os.path.splitext(os.path.basename(framework)) |
450 | 456 | fwl = os.path.join(framework, fw_name) |
451 | | print "Importing Framework: " + fwl |
| 457 | print("Importing Framework: " + fwl) |
452 | 458 | # Fix the framework IDs |
453 | 459 | cmd = os.path.join(os.path.dirname(__file__), "run-install-name-tool-change.sh") + " " + fwl + " " + fw_name + " Frameworks" + " id" |
454 | 460 | f = os.popen(cmd) |
455 | 461 | for line in f: |
456 | | print line |
| 462 | print(line) |
457 | 463 | # Fix the dependencies in other libraries |
458 | 464 | for path in paths: |
459 | 465 | cmd = os.path.join(os.path.dirname(__file__), "run-install-name-tool-change.sh") + " " + path + " " + fw_name + " Frameworks/" + fw_name + " change" |
460 | 466 | f = os.popen(cmd) |
461 | 467 | for line in f: |
462 | | print line |
| 468 | print(line) |
463 | 469 | #fix the dependencies in frameworks |
464 | 470 | for ufw in self.frameworks: |
465 | 471 | ufw_name, ext = os.path.splitext(os.path.basename(ufw)) |
… |
… |
class Bundler: |
469 | 475 | cmd = os.path.join(os.path.dirname(__file__), "run-install-name-tool-change.sh") + " " + ufwl + " " + fw_name + " Frameworks/" + fw_name + " change" |
470 | 476 | f = os.popen(cmd) |
471 | 477 | for line in f: |
472 | | print line |
| 478 | print(line) |
473 | 479 | |
474 | 480 | |
475 | 481 | def strip_debugging(self): |
476 | 482 | paths = self.list_copied_binaries() |
477 | 483 | for path in paths: |
478 | 484 | if path.endswith(".dylib") or path.endswith(".so"): |
479 | | os.chmod(path, 0644) |
| 485 | os.chmod(path, 0o644) |
480 | 486 | os.system("strip -x " + path + " 2>/dev/null") |
481 | | os.chmod(path, 0444) |
| 487 | os.chmod(path, 0o444) |
482 | 488 | else: |
483 | | os.chmod(path, 0755) |
| 489 | os.chmod(path, 0o755) |
484 | 490 | os.system("strip -ur " + path + " 2>/dev/null") |
485 | | os.chmod(path, 0555) |
| 491 | os.chmod(path, 0o555) |
486 | 492 | |
487 | 493 | # |
488 | 494 | # If you want to sign your application, set $APPLICATION_CERT with the |
… |
… |
class Bundler: |
491 | 497 | # bundle's id string. |
492 | 498 | # |
493 | 499 | def sign_binaries(self): |
494 | | if not os.environ.has_key("APPLICATION_CERT"): |
| 500 | if "APPLICATION_CERT" not in os.environ: |
495 | 501 | return |
496 | 502 | cert = os.getenv("APPLICATION_CERT") |
497 | 503 | paths = self.list_copied_binaries() |
… |
… |
class Bundler: |
501 | 507 | result = os.spawnvp(os.P_WAIT, 'codesign', cmdargs) |
502 | 508 | |
503 | 509 | if result: |
504 | | raise OSError, '"' + " ".join(cmdargs) + '" failed %d' % result |
| 510 | raise OSError('"' + " ".join(cmdargs) + '" failed %d' % result) |
505 | 511 | |
506 | 512 | def copy_icon_themes(self): |
507 | 513 | all_icons = set() |
… |
… |
class Bundler: |
604 | 610 | final_path = self.project.evaluate_path(final_path) |
605 | 611 | |
606 | 612 | if not self.meta.overwrite and os.path.exists(final_path): |
607 | | print "Bundle already exists: " + final_path |
| 613 | print("Bundle already exists: " + final_path) |
608 | 614 | sys.exit(1) |
609 | 615 | |
610 | 616 | self.create_skeleton() |
… |
… |
class Bundler: |
618 | 624 | path = self.project.get_main_binary() |
619 | 625 | source = self.project.evaluate_path(path.source) |
620 | 626 | if not os.path.exists(source): |
621 | | print "Cannot find main binary: " + source |
| 627 | print("Cannot find main binary: " + source) |
622 | 628 | sys.exit(1) |
623 | 629 | |
624 | 630 | dest = self.copy_path(path) |
… |
… |
class Bundler: |
658 | 664 | launcher_script = self.project.get_launcher_script() |
659 | 665 | if launcher_script: |
660 | 666 | path = self.copy_path(launcher_script) |
661 | | if os.environ.has_key("APPLICATION_CERT"): |
| 667 | if "APPLICATION_CERT" in os.environ: |
662 | 668 | cert = os.environ["APPLICATION_CERT"] |
663 | 669 | ident = self.project.get_bundle_id() |
664 | 670 | cmdargs = ['codesign', '-s', cert, '-i', ident, "-f", path] |
665 | 671 | result = os.spawnvp(os.P_WAIT, 'codesign', cmdargs) |
666 | 672 | if result: |
667 | | raise OSError, '"'+ " ".join(cmdargs) + '" failed %d' % result |
| 673 | raise OSError('"'+ " ".join(cmdargs) + '" failed %d' % result) |
668 | 674 | if self.meta.overwrite: |
669 | 675 | self.recursive_rm(final_path) |
670 | 676 | shutil.move(self.project.get_bundle_path(), final_path) |
671 | 677 | |
672 | 678 | if __name__ == '__main__': |
673 | 679 | if len(sys.argv) != 2: |
674 | | print "Usage: %s <bundle descriptopn file>" % (sys.argv[0]) |
| 680 | print("Usage: %s <bundle descriptopn file>" % (sys.argv[0])) |
675 | 681 | sys.exit(2) |
676 | 682 | |
677 | 683 | if not os.path.exists(sys.argv[1]): |
678 | | print "File %s does not exist" % (sys.argv[1]) |
| 684 | print("File %s does not exist" % (sys.argv[1])) |
679 | 685 | sys.exit(2) |
680 | 686 | |
681 | 687 | project = Project(sys.argv[1]) |
diff --git bundler/main.py bundler/main.py
index bcd7dda..b9b2fc5 100644
|
|
|
1 | 1 | import sys, os |
2 | 2 | |
3 | | from project import * |
4 | | from bundler import * |
| 3 | from .project import * |
| 4 | from .bundler import * |
5 | 5 | |
6 | 6 | def main(argv): |
7 | 7 | if len(argv) != 1: |
8 | | print "Usage: %s <bundle descriptopn file>" % (sys.argv[0]) |
| 8 | print("Usage: %s <bundle descriptopn file>" % (sys.argv[0])) |
9 | 9 | sys.exit(2) |
10 | 10 | |
11 | 11 | if not os.path.exists(argv[0]): |
12 | | print "File %s does not exist" % (argv[0]) |
| 12 | print("File %s does not exist" % (argv[0])) |
13 | 13 | sys.exit(2) |
14 | 14 | |
15 | 15 | project = Project(argv[0]) |
16 | 16 | bundler = Bundler(project) |
17 | | |
18 | | bundler.run() |
| 17 | try: |
| 18 | bundler.run() |
| 19 | except Exception as err: |
| 20 | print("Bundler encountered an error %s" % str(err)) |
diff --git bundler/project.py bundler/project.py
index c98b65a..60f0541 100644
|
|
import os |
5 | 5 | import xml.dom.minidom |
6 | 6 | from xml.dom.minidom import Node |
7 | 7 | from plistlib import Plist |
8 | | import utils |
| 8 | from . import utils |
9 | 9 | |
10 | 10 | # Base class for anything that can be copied into a bundle with a |
11 | 11 | # source and dest. |
… |
… |
class Data(Path): |
184 | 184 | pass |
185 | 185 | |
186 | 186 | class IconTheme: |
187 | | ICONS_NONE, ICONS_ALL, ICONS_AUTO = range(3) |
| 187 | ICONS_NONE, ICONS_ALL, ICONS_AUTO = list(range(3)) |
188 | 188 | |
189 | 189 | def __init__(self, name, icons=ICONS_AUTO): |
190 | 190 | self.name = name |
… |
… |
class Project: |
221 | 221 | # Get the first app-bundle tag and ignore any others. |
222 | 222 | self.root = utils.node_get_element_by_tag_name(doc, "app-bundle") |
223 | 223 | except: |
224 | | print "Could not load project %s:" % (project_path) |
| 224 | print("Could not load project %s:" % (project_path)) |
225 | 225 | raise |
226 | 226 | |
227 | 227 | # The directory the project file is in (as opposed to |
… |
… |
class Project: |
232 | 232 | plist_path = self.get_plist_path() |
233 | 233 | try: |
234 | 234 | plist = Plist.fromFile(plist_path) |
235 | | except EnvironmentError, e: |
| 235 | except EnvironmentError as e: |
236 | 236 | if e.errno == errno.ENOENT: |
237 | | print "Info.plist file not found: " + plist_path |
| 237 | print("Info.plist file not found: " + plist_path) |
238 | 238 | sys.exit(1) |
239 | 239 | else: |
240 | 240 | raise |
241 | 241 | self.name = plist.CFBundleExecutable |
242 | | if plist.has_key("CFBundleName"): |
| 242 | if "CFBundleName" in plist: |
243 | 243 | self.bundle_name = plist.CFBundleName |
244 | 244 | else: |
245 | 245 | self.bundle_name = plist.CFBundleExecutable |
… |
… |
class Project: |
340 | 340 | themes.append(IconTheme.from_node(node)) |
341 | 341 | |
342 | 342 | # The hicolor theme is mandatory. |
343 | | if not filter(lambda l: l.name == "hicolor", themes): |
| 343 | if not [l for l in themes if l.name == "hicolor"]: |
344 | 344 | themes.append(IconTheme("hicolor")) |
345 | 345 | |
346 | 346 | return themes |
… |
… |
class Project: |
412 | 412 | if __name__ == '__main__': |
413 | 413 | project = Project(os.path.join(os.getcwd(), 'giggle.bundle')) |
414 | 414 | |
415 | | print "General:" |
416 | | print " Project path: %s" % (project.get_project_path()) |
417 | | print " Plist path: %s" % (project.get_plist_path()) |
418 | | print " App name: %s" % (project.name) |
419 | | print " Destination: %s" % (project.get_meta().dest) |
420 | | print " Overwrite: %s" % (str(project.get_meta().overwrite)) |
| 415 | print("General:") |
| 416 | print(" Project path: %s" % (project.get_project_path())) |
| 417 | print(" Plist path: %s" % (project.get_plist_path())) |
| 418 | print(" App name: %s" % (project.name)) |
| 419 | print(" Destination: %s" % (project.get_meta().dest)) |
| 420 | print(" Overwrite: %s" % (str(project.get_meta().overwrite))) |
421 | 421 | |
422 | 422 | environment = project.get_environment() |
423 | | print "Environment:" |
| 423 | print("Environment:") |
424 | 424 | for variable in environment.runtime_variables: |
425 | | print " %s=%s" % (variable.name, variable.value) |
| 425 | print(" %s=%s" % (variable.name, variable.value)) |
426 | 426 | for script in environment.scripts: |
427 | | print " %s => %s" % (script.source, script.dest) |
| 427 | print(" %s => %s" % (script.source, script.dest)) |
428 | 428 | |
429 | | print "Frameworks:" |
| 429 | print("Frameworks:") |
430 | 430 | for framework in project.get_frameworks(): |
431 | | print " ", framework |
| 431 | print(" ", framework) |
432 | 432 | |
433 | | print "Main binary:" |
| 433 | print("Main binary:") |
434 | 434 | binary = project.get_main_binary() |
435 | | print " %s => %s" % (binary.source, binary.dest) |
| 435 | print(" %s => %s" % (binary.source, binary.dest)) |
436 | 436 | |
437 | | print "Launcher:" |
| 437 | print("Launcher:") |
438 | 438 | launcher_script = project.get_launcher_script() |
439 | | print " %s => %s" % (launcher_script.source, launcher_script.dest) |
| 439 | print(" %s => %s" % (launcher_script.source, launcher_script.dest)) |
440 | 440 | |
441 | | print "Binaries:" |
| 441 | print("Binaries:") |
442 | 442 | for binary in project.get_binaries(): |
443 | | print " %s => %s" % (binary.source, binary.dest) |
| 443 | print(" %s => %s" % (binary.source, binary.dest)) |
444 | 444 | |
diff --git bundler/project_test.py bundler/project_test.py
index 4c3d583..0ff9179 100644
|
|
import unittest |
5 | 5 | import xml.dom.minidom |
6 | 6 | from xml.dom.minidom import Node |
7 | 7 | from plistlib import Plist |
8 | | from project import Project |
9 | | import utils |
| 8 | from .project import Project |
| 9 | from . import utils |
10 | 10 | |
11 | 11 | class Mock_Project(Project): |
12 | 12 | |
… |
… |
class Mock_Project(Project): |
20 | 20 | try: |
21 | 21 | plist_path = os.path.join(self.project_dir, "test.plist") |
22 | 22 | plist = Plist.fromFile(plist_path) |
23 | | except EnvironmentError, e: |
| 23 | except EnvironmentError as e: |
24 | 24 | if e.errno == errno.ENOENT: |
25 | | print "Info.plist file not found: " + plist_path |
| 25 | print("Info.plist file not found: " + plist_path) |
26 | 26 | sys.exit(1) |
27 | 27 | else: |
28 | 28 | raise |
diff --git bundler/runtest.py bundler/runtest.py
index 309643a..2450f2d 100755
|
|
|
1 | 1 | #!/usr/bin/python |
2 | 2 | import unittest |
3 | 3 | import os |
4 | | from project_test import Project_Test |
| 4 | from .project_test import Project_Test |
5 | 5 | |
6 | 6 | def setProjects( goodpath, badpath): |
7 | 7 | if not os.path.isabs(goodpath): |
diff --git bundler/utils.py bundler/utils.py
index 78d4c47..76c83d1 100644
|
|
def evaluate_environment_variables(string): |
15 | 15 | |
16 | 16 | return string |
17 | 17 | |
| 18 | def has_pkgconfig_module(module): |
| 19 | """Returns True if the pkg-config module exists""" |
| 20 | f = os.popen("pkg-config --exists " + module) |
| 21 | f.read().strip() |
| 22 | return f.close() is None |
| 23 | |
| 24 | def has_pkgconfig_variable(module, key): |
| 25 | """Returns True if the pkg-config variable exists for the given |
| 26 | module |
| 27 | """ |
| 28 | f = os.popen("pkg-config --variable=" + key + " " + module) |
| 29 | status = bool(f.read().strip()) |
| 30 | f.close() |
| 31 | return status |
| 32 | |
18 | 33 | def evaluate_pkgconfig_variables(string): |
19 | 34 | p = re.compile("\${pkg:(.*?):(.*?)}") |
20 | 35 | m = p.search(string) |
… |
… |
def evaluate_pkgconfig_variables(string): |
24 | 39 | f = os.popen("pkg-config --variable=" + key + " " + module) |
25 | 40 | value = f.read().strip() |
26 | 41 | if not value: |
| 42 | # pango 1.38 removed modules, try to give a helpful |
| 43 | # message in case something tries to reference the no |
| 44 | # longer existing variable (most likely from old bundle |
| 45 | # xml files) when using a newer pango build. |
| 46 | if module == "pango" and key == "pango_module_version": |
| 47 | if has_pkgconfig_module("pango"): |
| 48 | raise Exception( |
| 49 | "'%s' got removed in '%s' " |
| 50 | "1.38. Remove any reference to pango " |
| 51 | "modules in your bundle xml." % ( |
| 52 | key, module)) |
27 | 53 | raise Exception("pkg-config variable '%s %s' is undefined" % (key, module)) |
28 | 54 | string = p.sub(value, string, 1) |
29 | 55 | m = p.search(string) |
… |
… |
def evaluate_pkgconfig_variables(string): |
33 | 59 | def makedirs(path): |
34 | 60 | try: |
35 | 61 | os.makedirs(path) |
36 | | except EnvironmentError, e: |
| 62 | except EnvironmentError as e: |
37 | 63 | if e.errno != errno.EEXIST: |
38 | 64 | raise |
39 | 65 | |
diff --git examples/gtk-demo.bundle examples/gtk-demo.bundle
index 4b32d6b..422126e 100644
|
|
|
79 | 79 | ${prefix}/lib/gdk-pixbuf-2.0/${pkg:${gtk}:gtk_binary_version}/loaders/*.so |
80 | 80 | </binary> |
81 | 81 | |
| 82 | <!-- No longer needed for pango >= 1.38 |
82 | 83 | <binary> |
83 | 84 | ${prefix}/lib/pango/${pkg:pango:pango_module_version}/modules/ |
84 | 85 | </binary> |
| 86 | --> |
85 | 87 | |
86 | 88 | <data> |
87 | 89 | ${prefix}/etc/pango/ |
diff --git examples/gtk3-demo.bundle examples/gtk3-demo.bundle
index ba15cd3..ec0eb4c 100644
|
|
|
69 | 69 | ${prefix}/lib/gdk-pixbuf-2.0/${pkg:gdk-pixbuf-2.0:gdk_pixbuf_binary_version}/loaders/*.so |
70 | 70 | </binary> |
71 | 71 | |
| 72 | <!-- No longer needed for pango >= 1.38 |
72 | 73 | <binary> |
73 | 74 | ${prefix}/lib/pango/${pkg:pango:pango_module_version}/modules/ |
74 | 75 | </binary> |
75 | | |
76 | | <data> |
77 | | ${prefix}/etc/pango/ |
78 | | </data> |
| 76 | --> |
79 | 77 | |
80 | 78 | <!-- Translation filenames, one for each program or library that you |
81 | 79 | want to copy in to the bundle. The "dest" attribute is |
… |
… |
|
102 | 100 | ${prefix}/share/themes |
103 | 101 | </data> |
104 | 102 | |
| 103 | <data> |
| 104 | ${prefix}/share/icons |
| 105 | </data> |
| 106 | |
105 | 107 | <!-- Copy icons. Note that the .icns file is an Apple format which |
106 | 108 | contains up to 4 sizes of icon. You can use |
107 | 109 | /Developer/Applications/Utilities/Icon Composer.app to import |
… |
… |
|
110 | 112 | ${project}/Giggle.icns |
111 | 113 | </data --> |
112 | 114 | |
113 | | <!-- This is where theme commands go. You can copy them in from your |
114 | | theme of choice if they provide and example, or you can just |
115 | | change the source path. --> |
116 | | |
117 | | <data dest="${bundle}/Contents/Resources/etc/${gtk}/gtkrc"> |
118 | | ${project}/gtkrc |
119 | | </data> |
120 | | |
121 | | <!-- Icon themes to copy. The "icons" property can be either of |
122 | | "auto", "all", or "none". All or none should be |
123 | | self-explanatory, while auto means that the script will try to |
124 | | figure out which icons are needed. This is done by getting all |
125 | | the strings from all copied binaries, and matching them against |
126 | | icon names. To be safe, you should use "all". "none" is useful |
127 | | if you want just the index.theme file but no icons, mostly |
128 | | needed for the "hicolor" base theme. |
129 | | > |
130 | | <icon-theme icons="auto"> |
131 | | Tango |
132 | | </icon-theme --> |
133 | | |
134 | | </app-bundle> |
| 115 | </app-bundle> |
diff --git examples/gtk3-launcher.sh examples/gtk3-launcher.sh
index 4aed833..9137ccb 100755
|
|
export GTK_DATA_PREFIX="$bundle_res" |
29 | 29 | export GTK_EXE_PREFIX="$bundle_res" |
30 | 30 | export GTK_PATH="$bundle_res" |
31 | 31 | |
32 | | export GTK2_RC_FILES="$bundle_etc/gtk-3.0/gtkrc" |
33 | | export GTK_IM_MODULE_FILE="$bundle_etc/gtk-3.0/gtk.immodules" |
34 | | export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-3.0/gdk-pixbuf.loaders" |
35 | | export PANGO_LIBDIR="$bundle_lib" |
| 32 | # PANGO_* is no longer needed for pango >= 1.38 |
| 33 | export PANGO_RC_FILE="$bundle_etc/pango/pangorc" |
36 | 34 | export PANGO_SYSCONFDIR="$bundle_etc" |
| 35 | export PANGO_LIBDIR="$bundle_lib" |
| 36 | |
| 37 | export GDK_PIXBUF_MODULE_FILE="$bundle_lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" |
| 38 | if [ `uname -r | cut -d . -f 1` -ge 10 ]; then |
| 39 | export GTK_IM_MODULE_FILE="$bundle_etc/gtk-3.0/gtk.immodules" |
| 40 | fi |
37 | 41 | |
38 | 42 | |
39 | 43 | APP=name |
diff --git examples/launcher.sh examples/launcher.sh
index a1dfd1b..11cd019 100755
|
|
export GTK_PATH="$bundle_res" |
31 | 31 | |
32 | 32 | export GTK2_RC_FILES="$bundle_etc/gtk-2.0/gtkrc" |
33 | 33 | export GTK_IM_MODULE_FILE="$bundle_etc/gtk-2.0/gtk.immodules" |
34 | | export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-2.0/gdk-pixbuf.loaders" |
| 34 | #N.B. When gdk-pixbuf was separated from Gtk+ the location of the |
| 35 | #loaders cache changed as well. Depending on the version of Gtk+ that |
| 36 | #you built with you may still need to use the old location: |
| 37 | #export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-2.0/gdk-pixbuf.loaders" |
| 38 | export GDK_PIXBUF_MODULE_FILE="$bundle_lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" |
35 | 39 | export PANGO_LIBDIR="$bundle_lib" |
36 | 40 | export PANGO_SYSCONFDIR="$bundle_etc" |
37 | 41 | |