Chromium Code Reviews| Index: build/check_gn_headers.py |
| diff --git a/build/check_gn_headers.py b/build/check_gn_headers.py |
| index fe884db6cb0b8e8253d5be3ac91d59d1c4290211..c5095e618d5fa6d0e94f615be988d00cb85babae 100755 |
| --- a/build/check_gn_headers.py |
| +++ b/build/check_gn_headers.py |
| @@ -38,13 +38,13 @@ def GetHeadersFromNinja(out_dir, q): |
| ans, err = set(), None |
| try: |
| - ans = ParseNinjaDepsOutput(NinjaSource()) |
| + ans = ParseNinjaDepsOutput(NinjaSource(), out_dir) |
| except Exception as e: |
| err = str(e) |
| q.put((ans, err)) |
| -def ParseNinjaDepsOutput(ninja_out): |
| +def ParseNinjaDepsOutput(ninja_out, out_dir): |
| """Parse ninja output and get the header files""" |
| all_headers = set() |
| @@ -62,6 +62,8 @@ def ParseNinjaDepsOutput(ninja_out): |
| # build/ only contains build-specific files like build_config.h |
| # and buildflag.h, and system header files, so they should be |
| # skipped. |
| + if f.startswith(out_dir) or f.startswith('out'): |
| + continue |
| if not f.startswith('build'): |
| all_headers.add(f) |
| else: |
| @@ -128,6 +130,12 @@ def GetDepsPrefixes(q): |
| q.put((prefixes, err)) |
| +def IsBuildClean(out_dir): |
| + cmd = ['ninja', '-C', out_dir, '-n'] |
| + out = subprocess.check_output(cmd) |
| + return 'no work to do.' in out |
| + |
| + |
| def ParseWhiteList(whitelist): |
| out = set() |
| for line in whitelist.split('\n'): |
| @@ -150,6 +158,16 @@ def GetNonExistingFiles(lst): |
| def main(): |
| + |
| + def DumpJson(data): |
| + if args.json: |
| + with open(args.json, 'w') as f: |
| + json.dump(data, f) |
| + |
| + def PrintError(msg): |
| + DumpJson([]) |
| + parser.error(msg) |
| + |
| parser = argparse.ArgumentParser(description=''' |
| NOTE: Use ninja to build all targets in OUT_DIR before running |
| this script.''') |
| @@ -158,12 +176,27 @@ def main(): |
| parser.add_argument('--json', |
| help='JSON output filename for missing headers') |
| parser.add_argument('--whitelist', help='file containing whitelist') |
| + parser.add_argument('--skip-dirty-check', action='store_true', |
| + help='skip checking whether the build is dirty') |
| args, _extras = parser.parse_known_args() |
| if not os.path.isdir(args.out_dir): |
| parser.error('OUT_DIR "%s" does not exist.' % args.out_dir) |
| + if not args.skip_dirty_check and not IsBuildClean(args.out_dir): |
| + dirty_msg = 'OUT_DIR looks dirty. You need to build all there.' |
| + if args.json: |
| + # Assume running on the bots. Silently skip this step. |
| + # This is possible because "analyze" step can be wrong due to |
| + # underspecified header files. See crbug.com/725877 |
| + print dirty_msg |
| + DumpJson([]) |
| + return 0 |
| + else: |
| + # Assume running interactively. |
| + parser.error(dirty_msg) |
| + |
| d_q = Queue() |
| d_p = Process(target=GetHeadersFromNinja, args=(args.out_dir, d_q,)) |
| d_p.start() |
| @@ -190,29 +223,29 @@ def main(): |
| deps_p.join() |
| if d_err: |
| - parser.error(d_err) |
| + PrintError(d_err) |
|
Dirk Pranke
2017/06/03 01:16:37
I'd pass the parser into PrintError; relying on th
wychen
2017/06/03 07:37:37
It requires more than just |parser|. It also needs
|
| if gn_err: |
| - parser.error(gn_err) |
| + PrintError(gn_err) |
| if deps_err: |
| - parser.error(deps_err) |
| + PrintError(deps_err) |
| if len(GetNonExistingFiles(d)) > 0: |
| - parser.error('''Found non-existing files in ninja deps. You should |
| - build all in OUT_DIR.''') |
| + print 'Non-existing files in ninja deps:', GetNonExistingFiles(d) |
| + PrintError('Found non-existing files in ninja deps. You should ' + |
| + 'build all in OUT_DIR.') |
| if len(d) == 0: |
| - parser.error('OUT_DIR looks empty. You should build all there.') |
| + PrintError('OUT_DIR looks empty. You should build all there.') |
| if any((('/gen/' in i) for i in nonexisting)): |
| - parser.error('OUT_DIR looks wrong. You should build all there.') |
| + PrintError('OUT_DIR looks wrong. You should build all there.') |
| if args.whitelist: |
| whitelist = ParseWhiteList(open(args.whitelist).read()) |
| missing -= whitelist |
| + nonexisting -= whitelist |
| missing = sorted(missing) |
| nonexisting = sorted(nonexisting) |
| - if args.json: |
| - with open(args.json, 'w') as f: |
| - json.dump(missing, f) |
| + DumpJson(sorted(missing + nonexisting)) |
| if len(missing) == 0 and len(nonexisting) == 0: |
| return 0 |