blob: 88ecee6894a322157cc982ed0a606f602def6a0e [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import subprocess
import os
import argparse
import logging
ROOT_DIR = os.path.abspath(os.path.join(__file__, os.pardir, os.pardir,
os.pardir))
# Where to cache GN results (they're expensive to compute).
GN_CACHE_PATH = os.path.abspath(os.path.join(ROOT_DIR, 'in_gn.txt'))
def stripped_lines_from_command(cmd, cwd=None):
lines = subprocess.check_output(cmd, cwd=cwd).splitlines()
return map(str.strip, lines)
def gn_desc(*args):
# GN doesn't understand absolute paths yet, so use a relative BUILD_DIR
# and pass ROOT_DIR as the CWD.
# Hard-coding Debug for now:
BUILD_DIR = '//out/Debug' # // means repository root-relative.
cmd = ['gn', 'desc', BUILD_DIR] + list(args)
return stripped_lines_from_command(cmd, cwd=ROOT_DIR)
def targets_under(target):
targets = gn_desc(target, 'deps', '--all')
return filter(lambda s: s.startswith(target), targets)
def used_files(target):
logging.info(target)
sources = map(lambda s: s[2:], gn_desc(target, 'sources'))
inputs = map(lambda s: s[2:], gn_desc(target, 'inputs'))
public = map(lambda s: s[2:], gn_desc(target, 'public'))
script = map(lambda s: s[2:], gn_desc(target, 'script'))
return sources + inputs + public + script
def find_on_disk(path):
# FIXME: Use os.walk and do fancier ignoring.
find_cmd = ['find', path, '-type', 'f']
return stripped_lines_from_command(find_cmd, cwd=ROOT_DIR)
def main():
logging.basicConfig(level=logging.INFO)
if os.path.exists(GN_CACHE_PATH):
logging.info('Using cached GN list: %s' % GN_CACHE_PATH)
in_gn = set(map(str.strip, open(GN_CACHE_PATH).readlines()))
else:
logging.info('No gn cache found, rebuilding: %s' % GN_CACHE_PATH)
in_gn = set(sum(map(used_files, targets_under('//sky')), []))
open(GN_CACHE_PATH, 'w+').write('\n'.join(in_gn))
on_disk = set(find_on_disk('sky/engine'))
# Ignore web/tests and bindings/tests
on_disk = set(filter(lambda p: '/tests/' not in p, on_disk))
missing_from_gn = sorted(on_disk - in_gn)
IGNORED_EXTENSIONS = [
'.py', # Probably some to remove, probably some to teach gn about.
# Python files not being known to gn can cause flaky builds too!
'.pyc',
'.gypi',
'.gn',
'.gni',
]
for ext in IGNORED_EXTENSIONS:
missing_from_gn = filter(lambda p: not p.endswith(ext), missing_from_gn)
# All upper-case files like README, DEPS, etc. are fine.
missing_from_gn = filter(lambda p: not os.path.basename(p).isupper(),
missing_from_gn)
print '\n'.join(missing_from_gn)
if __name__ == '__main__':
main()