Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: src/caterpillar.py

Issue 1644913002: Caterpillar now generates app.info.js, a metadata script. Resolves #12. (Closed) Base URL: git@github.com:chromium/caterpillar.git@dependency-script-injection
Patch Set: Response to CR + whitespace fix Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/caterpillar_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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())
OLDNEW
« no previous file with comments | « no previous file | src/caterpillar_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698