OLD | NEW |
---|---|
1 #!/usr/bin/env python2 | 1 #!/usr/bin/env python2 |
2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
3 | 3 |
4 # Copyright 2015 Google Inc. All Rights Reserved. | 4 # Copyright 2015 Google Inc. All Rights Reserved. |
5 # | 5 # |
6 # Licensed under the Apache License, Version 2.0 (the "License"); | 6 # Licensed under the Apache License, Version 2.0 (the "License"); |
7 # you may not use this file except in compliance with the License. | 7 # you may not use this file except in compliance with the License. |
8 # You may obtain a copy of the License at | 8 # You may obtain a copy of the License at |
9 # | 9 # |
10 # http://www.apache.org/licenses/LICENSE-2.0 | 10 # http://www.apache.org/licenses/LICENSE-2.0 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
62 | 62 |
63 # Name of the service worker static script. | 63 # Name of the service worker static script. |
64 SW_STATIC_SCRIPT_NAME = 'sw_static.js' | 64 SW_STATIC_SCRIPT_NAME = 'sw_static.js' |
65 | 65 |
66 # Largest number that the cache version can be. | 66 # Largest number that the cache version can be. |
67 MAX_CACHE_VERSION = 1000000 | 67 MAX_CACHE_VERSION = 1000000 |
68 | 68 |
69 # Where this file is located (so we can find resources). | 69 # Where this file is located (so we can find resources). |
70 SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) | 70 SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) |
71 | 71 |
72 # Name of the app info script. | |
73 INFO_SCRIPT_NAME = 'app.info.js' | |
74 | |
72 # Maps dependency managers to the folder they install dependencies into. | 75 # Maps dependency managers to the folder they install dependencies into. |
73 DEPENDENCY_MANAGER_INSTALL_FOLDER = { | 76 DEPENDENCY_MANAGER_INSTALL_FOLDER = { |
74 'bower': 'bower_components', | 77 'bower': 'bower_components', |
75 'npm': 'node_modules', | 78 'npm': 'node_modules', |
76 } | 79 } |
77 | 80 |
78 SW_FORMAT_STRING = """/** | 81 SW_FORMAT_STRING = """/** |
79 * @file Service worker generated by Caterpillar. | 82 * @file Service worker generated by Caterpillar. |
80 */ | 83 */ |
81 | 84 |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
433 sw_js = generate_service_worker(output_dir, ca_manifest, required_js_paths, | 436 sw_js = generate_service_worker(output_dir, ca_manifest, required_js_paths, |
434 boilerplate_dir) | 437 boilerplate_dir) |
435 | 438 |
436 # We can now write the service worker. Note that it must be in the root. | 439 # We can now write the service worker. Note that it must be in the root. |
437 sw_path = os.path.join(output_dir, SW_SCRIPT_NAME) | 440 sw_path = os.path.join(output_dir, SW_SCRIPT_NAME) |
438 logging.debug('Writing service worker to `%s`.', sw_path) | 441 logging.debug('Writing service worker to `%s`.', sw_path) |
439 with open(sw_path, 'w') as sw_file: | 442 with open(sw_path, 'w') as sw_file: |
440 sw_file.write(surrogateescape.encode(sw_js)) | 443 sw_file.write(surrogateescape.encode(sw_js)) |
441 | 444 |
442 | 445 |
446 def add_app_info(output_dir, ca_manifest): | |
447 """Adds an app info script, containing metadata, to a web app. | |
448 | |
449 Args: | |
450 output_dir: Path to web app to add app info script to. | |
451 ca_manifest: Chrome App manifest dictionary. | |
452 """ | |
453 logging.debug('Generating app info script.') | |
454 js_manifest = json.dumps(ca_manifest, sort_keys=True, indent=2, | |
455 separators=(',', ': ')).replace('"', "'") | |
Matthew Alger
2016/01/28 23:25:32
Changed this to drop trailing spaces by explicitly
Matt Giuca
2016/01/29 02:34:27
Fair enough.
Why is " being replaced with '? Isn'
Matt Giuca
2016/01/29 03:06:53
Acknowledged.
| |
456 app_info_js = ('chrome.caterpillar.manifest = {manifest};\n').format( | |
457 manifest=js_manifest) | |
458 app_info_path = os.path.join(output_dir, INFO_SCRIPT_NAME) | |
459 logging.debug('Writing app info script to `%s`.', app_info_path) | |
460 with open(app_info_path, 'w') as app_info_file: | |
461 app_info_file.write(app_info_js.encode('utf-8')) | |
462 | |
463 | |
443 class InstallationError(Exception): | 464 class InstallationError(Exception): |
444 """Exception raised when a dependency fails to install.""" | 465 """Exception raised when a dependency fails to install.""" |
445 | 466 |
446 pass | 467 pass |
447 | 468 |
448 | 469 |
449 def install_dependency(call, output_dir): | 470 def install_dependency(call, output_dir): |
450 """Installs a dependency into a directory. | 471 """Installs a dependency into a directory. |
451 | 472 |
452 Assumes that there is no output on stdout if installation fails. | 473 Assumes that there is no output on stdout if installation fails. |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
619 for dependency in dependencies: | 640 for dependency in dependencies: |
620 # Note that dependencies are installed into the root, but we need paths | 641 # Note that dependencies are installed into the root, but we need paths |
621 # relative to Caterpillar's boilerplate directory. | 642 # relative to Caterpillar's boilerplate directory. |
622 dependency_path = os.path.join('..', | 643 dependency_path = os.path.join('..', |
623 DEPENDENCY_MANAGER_INSTALL_FOLDER[dependency['manager']], | 644 DEPENDENCY_MANAGER_INSTALL_FOLDER[dependency['manager']], |
624 dependency['name'], dependency['path']) | 645 dependency['name'], dependency['path']) |
625 required_dependency_paths.append(dependency_path) | 646 required_dependency_paths.append(dependency_path) |
626 | 647 |
627 required_polyfill_paths = polyfill_paths(polyfillable) | 648 required_polyfill_paths = polyfill_paths(polyfillable) |
628 | 649 |
650 # Additionally, we may generate some files we want to use in HTML script tags, | |
651 # but we don't want to install as a dependency or copy from a static JS file. | |
652 required_generated_paths = [] | |
653 | |
629 # Read in and check the manifest file. | 654 # Read in and check the manifest file. |
630 try: | 655 try: |
631 ca_manifest = chrome_app.manifest.get(input_dir) | 656 ca_manifest = chrome_app.manifest.get(input_dir) |
632 chrome_app.manifest.localize(ca_manifest, input_dir) | 657 chrome_app.manifest.localize(ca_manifest, input_dir) |
633 chrome_app.manifest.verify(ca_manifest) | 658 chrome_app.manifest.verify(ca_manifest) |
634 except ValueError as e: | 659 except ValueError as e: |
635 logging.error(e.message) | 660 logging.error(e.message) |
636 return | 661 return |
637 | 662 |
638 # TODO(alger): Identify background scripts and determine start_url. | 663 # TODO(alger): Identify background scripts and determine start_url. |
639 start_url = config['start_url'] | 664 start_url = config['start_url'] |
640 logging.info('Got start URL from config file: `%s`', start_url) | 665 logging.info('Got start URL from config file: `%s`', start_url) |
641 | 666 |
642 # Generate a progressive web app manifest. | 667 # Generate a progressive web app manifest. |
643 pwa_manifest = generate_web_manifest(ca_manifest, start_url) | 668 pwa_manifest = generate_web_manifest(ca_manifest, start_url) |
644 pwa_manifest_path = os.path.join(output_dir, PWA_MANIFEST_FILENAME) | 669 pwa_manifest_path = os.path.join(output_dir, PWA_MANIFEST_FILENAME) |
645 with open(pwa_manifest_path, 'w') as pwa_manifest_file: | 670 with open(pwa_manifest_path, 'w') as pwa_manifest_file: |
646 json.dump(pwa_manifest, pwa_manifest_file, indent=4, sort_keys=True) | 671 json.dump(pwa_manifest, pwa_manifest_file, indent=4, sort_keys=True) |
647 logging.debug('Wrote `%s` to `%s`.', PWA_MANIFEST_FILENAME, pwa_manifest_path) | 672 logging.debug('Wrote `%s` to `%s`.', PWA_MANIFEST_FILENAME, pwa_manifest_path) |
648 | 673 |
674 # Generate and write an app info file so we can access Chrome App metadata | |
675 # from polyfills and scripts. | |
676 add_app_info(output_dir, ca_manifest) | |
677 required_generated_paths.append(os.path.join('..', INFO_SCRIPT_NAME)) | |
678 | |
649 # Remove unnecessary files from the output web app. This must be done before | 679 # Remove unnecessary files from the output web app. This must be done before |
650 # the service worker is generated, or these files will be cached. | 680 # the service worker is generated, or these files will be cached. |
651 cleanup_output_dir(output_dir) | 681 cleanup_output_dir(output_dir) |
652 | 682 |
653 # Edit the HTML and JS code of the output web app. | 683 # Edit the HTML and JS code of the output web app. |
654 # This is adding TODOs, injecting tags, etc. - anything that involves editing | 684 # This is adding TODOs, injecting tags, etc. - anything that involves editing |
655 # user code directly. This must be done before the static code is copied | 685 # user code directly. This must be done before the static code is copied |
656 # across, or the polyfills will have TODOs added to them. | 686 # across, or the polyfills will have TODOs added to them. |
657 # Order is significant here - always, then dependencies, then polyfills. | 687 # Order is significant here - always, then dependencies, then polyfills. |
658 required_script_paths = (required_always_paths + required_dependency_paths | 688 required_script_paths = (required_always_paths + required_generated_paths + |
659 + required_polyfill_paths) | 689 required_dependency_paths + required_polyfill_paths) |
660 edit_code(output_dir, required_script_paths, ca_manifest, config) | 690 edit_code(output_dir, required_script_paths, ca_manifest, config) |
661 | 691 |
662 # We want the static SW file to be copied in too, so we add it here. | 692 # We want the static SW file to be copied in too, so we add it here. |
663 # We have to add it after edit_code or it would be included in the HTML, but | 693 # We have to add it after edit_code or it would be included in the HTML, but |
664 # this is service worker-only code, and shouldn't be included there. | 694 # this is service worker-only code, and shouldn't be included there. |
665 required_always_paths.append(SW_STATIC_SCRIPT_NAME) | 695 required_always_paths.append(SW_STATIC_SCRIPT_NAME) |
666 | 696 |
667 # Copy static code from Caterpillar into the output web app. | 697 # Copy static code from Caterpillar into the output web app. |
668 # This must be done before the service worker is generated, or these files | 698 # This must be done before the service worker is generated, or these files |
669 # will not be cached. | 699 # will not be cached. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
748 if args.mode == 'config': | 778 if args.mode == 'config': |
749 configuration.generate_and_save(args.output, args.interactive) | 779 configuration.generate_and_save(args.output, args.interactive) |
750 | 780 |
751 elif args.mode == 'convert': | 781 elif args.mode == 'convert': |
752 config = configuration.load(args.config) | 782 config = configuration.load(args.config) |
753 convert_app(args.input, args.output, config, args.force) | 783 convert_app(args.input, args.output, config, args.force) |
754 | 784 |
755 | 785 |
756 if __name__ == '__main__': | 786 if __name__ == '__main__': |
757 sys.exit(main()) | 787 sys.exit(main()) |
OLD | NEW |