damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 1 | # Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | """Used by a js_binary action to compile javascript files. |
| 5 | |
| 6 | This script takes in a list of sources and dependencies and compiles them all |
| 7 | together into a single compiled .js file. The dependencies are ordered in a |
| 8 | post-order, left-to-right traversal order. If multiple instances of the same |
| 9 | source file are read, only the first is kept. The script can also take in |
| 10 | optional --flags argument which will add custom flags to the compiler. Any |
| 11 | extern files can also be passed in using the --extern flag. |
| 12 | """ |
| 13 | |
Mike Bjorge | 61bf88e | 2017-05-14 07:34:06 | [diff] [blame] | 14 | import argparse |
damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 15 | import os |
Mike Bjorge | 61bf88e | 2017-05-14 07:34:06 | [diff] [blame] | 16 | import sys |
| 17 | |
damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 18 | import compile2 |
| 19 | |
| 20 | |
| 21 | def ParseDepList(dep): |
Christopher Lam | 997fd81 | 2017-11-03 03:42:40 | [diff] [blame^] | 22 | """Parses a dependency list, returns |sources, deps, externs|.""" |
| 23 | assert os.path.isfile(dep), (dep + |
damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 24 | ' is not a js_library target') |
| 25 | with open(dep, 'r') as dep_list: |
| 26 | lines = dep_list.read().splitlines() |
| 27 | assert 'deps:' in lines, dep + ' is not formated correctly, missing "deps:"' |
Christopher Lam | 997fd81 | 2017-11-03 03:42:40 | [diff] [blame^] | 28 | deps_start = lines.index('deps:') |
| 29 | assert 'externs:' in lines, dep + ' is not formated correctly, missing "externs:"' |
| 30 | externs_start = lines.index('externs:') |
| 31 | |
| 32 | return (lines[1:deps_start], |
| 33 | lines[deps_start+1:externs_start], |
| 34 | lines[externs_start+1:]) |
damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 35 | |
| 36 | |
Christopher Lam | 997fd81 | 2017-11-03 03:42:40 | [diff] [blame^] | 37 | def CrawlDepsTree(deps, sources, externs): |
damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 38 | """Parses the dependency tree creating a post-order listing of sources.""" |
| 39 | for dep in deps: |
Christopher Lam | 997fd81 | 2017-11-03 03:42:40 | [diff] [blame^] | 40 | cur_sources, cur_deps, cur_externs = ParseDepList(dep) |
damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 41 | |
Christopher Lam | 997fd81 | 2017-11-03 03:42:40 | [diff] [blame^] | 42 | child_sources, child_externs = CrawlDepsTree( |
| 43 | cur_deps, cur_sources, cur_externs) |
| 44 | |
| 45 | # Add child dependencies of this node first. |
| 46 | new_sources = child_sources |
| 47 | |
| 48 | # Add the current node's sources and dedupe. |
| 49 | new_sources += [s for s in cur_sources if s not in new_sources] |
| 50 | |
| 51 | # Add the original sources, none of which will be dependencies of this node, |
| 52 | # and dedupe. |
| 53 | new_sources += [s for s in sources if s not in new_sources] |
| 54 | sources = new_sources |
| 55 | |
| 56 | externs += [e for e in cur_externs if e not in externs] |
| 57 | return sources, externs |
damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 58 | |
| 59 | |
| 60 | def main(): |
Mike Bjorge | 61bf88e | 2017-05-14 07:34:06 | [diff] [blame] | 61 | parser = argparse.ArgumentParser() |
damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 62 | parser.add_argument('-c', '--compiler', required=True, |
| 63 | help='Path to compiler') |
| 64 | parser.add_argument('-s', '--sources', nargs='*', default=[], |
| 65 | help='List of js source files') |
| 66 | parser.add_argument('-o', '--output', required=True, |
| 67 | help='Compile to output') |
| 68 | parser.add_argument('-d', '--deps', nargs='*', default=[], |
| 69 | help='List of js_libarary dependencies') |
| 70 | parser.add_argument('-b', '--bootstrap', |
| 71 | help='A file to include before all others') |
| 72 | parser.add_argument('-cf', '--config', nargs='*', default=[], |
| 73 | help='A list of files to include after bootstrap and ' |
| 74 | 'before all others') |
| 75 | parser.add_argument('-f', '--flags', nargs='*', default=[], |
| 76 | help='A list of custom flags to pass to the compiler. ' |
| 77 | 'Do not include leading dashes') |
| 78 | parser.add_argument('-e', '--externs', nargs='*', default=[], |
| 79 | help='A list of extern files to pass to the compiler') |
| 80 | |
| 81 | args = parser.parse_args() |
Christopher Lam | 997fd81 | 2017-11-03 03:42:40 | [diff] [blame^] | 82 | sources, externs = CrawlDepsTree(args.deps, args.sources, args.externs) |
damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 83 | |
| 84 | compiler_args = ['--%s' % flag for flag in args.flags] |
| 85 | compiler_args += ['--externs=%s' % e for e in args.externs] |
| 86 | compiler_args += [ |
| 87 | '--js_output_file', |
| 88 | args.output, |
| 89 | '--js', |
| 90 | ] |
| 91 | if args.bootstrap: |
| 92 | compiler_args += [args.bootstrap] |
| 93 | compiler_args += args.config |
| 94 | compiler_args += sources |
| 95 | |
Mike Bjorge | 61bf88e | 2017-05-14 07:34:06 | [diff] [blame] | 96 | returncode, errors = compile2.Checker().run_jar(args.compiler, compiler_args) |
| 97 | if returncode != 0: |
| 98 | print errors |
| 99 | |
| 100 | return returncode |
damargulis | 5c5337d | 2017-04-21 22:36:08 | [diff] [blame] | 101 | |
| 102 | |
| 103 | if __name__ == '__main__': |
Mike Bjorge | 61bf88e | 2017-05-14 07:34:06 | [diff] [blame] | 104 | sys.exit(main()) |