12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- #!/usr/bin/env python
- #
- # Copyright 2015 Google Inc.
- #
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- # This script does a very rough simulation of BUILD file expansion,
- # mostly to see the effects of glob().
- # We start by adding some symbols to our namespace that BUILD.public calls.
- import glob
- import os
- import pprint
- import re
- def noop(*args, **kwargs):
- pass
- def select_simulator(d):
- result = []
- for k in d:
- result.append("*** BEGIN %s ***" % k)
- result.extend(d[k])
- result.append("*** END %s ***" % k)
- return result
- DOUBLE_STAR_RE = re.compile(r'/\*\*/')
- STAR_RE = re.compile(r'\*')
- DOUBLE_STAR_PLACEHOLDER = "xxxdoublestarxxx"
- STAR_PLACEHOLDER = "xxxstarxxx"
- # Returns a set of files that match pattern.
- def BUILD_glob_single(pattern):
- if pattern.find('**') < 0:
- # If pattern doesn't include **, glob.glob more-or-less does the right
- # thing.
- return glob.glob(pattern)
- # First transform pattern into a regexp.
- # Temporarily remove ** and *.
- pattern2 = DOUBLE_STAR_RE.sub(DOUBLE_STAR_PLACEHOLDER, pattern)
- pattern3 = STAR_RE.sub(STAR_PLACEHOLDER, pattern2)
- # Replace any regexp special characters.
- pattern4 = re.escape(pattern3)
- # Replace * with [^/]* and ** with .*.
- pattern5 = pattern4.replace(STAR_PLACEHOLDER, '[^/]*')
- pattern6 = pattern5.replace(DOUBLE_STAR_PLACEHOLDER, '.*/')
- # Anchor the match at the beginning and end.
- pattern7 = "^" + pattern6 + "$"
- pattern_re = re.compile(pattern7)
- matches = set()
- for root, _, files in os.walk('.'):
- for fname in files:
- # Remove initial "./".
- path = os.path.join(root, fname)[2:]
- if pattern_re.match(path):
- matches.add(path)
- return matches
- # Simulates BUILD file glob().
- def BUILD_glob(include, exclude=()):
- files = set()
- for pattern in include:
- files.update(BUILD_glob_single(pattern))
- for pattern in exclude:
- files.difference_update(BUILD_glob_single(pattern))
- return list(sorted(files))
- # With these namespaces, we can treat BUILD.public as if it were
- # Python code. This pulls its variable definitions (SRCS, HDRS,
- # DEFINES, etc.) into local_names.
- global_names = {
- 'cc_library': noop,
- 'cc_test': noop,
- 'exports_files': noop,
- 'glob': BUILD_glob,
- 'select': select_simulator,
- 'BASE_DIR': '',
- 'BASE_EXTERNAL_DEPS_ANDROID': [],
- 'BASE_EXTERNAL_DEPS_IOS': [],
- 'BASE_EXTERNAL_DEPS_UNIX': [],
- 'CONDITION_ANDROID': 'CONDITION_ANDROID',
- 'CONDITION_IOS': 'CONDITION_IOS',
- 'DM_EXTERNAL_DEPS': [],
- 'EXTERNAL_DEPS_ALL': [],
- 'EXTERNAL_INCLUDES': [],
- }
- local_names = {}
- execfile('BUILD.public', global_names, local_names)
- with open('tools/BUILD.public.expected', 'w') as out:
- print >>out, "This file is auto-generated by tools/BUILD_simulator.py."
- print >>out, "It expands BUILD.public to make it easy to see changes."
- for name, value in sorted(local_names.items()):
- print >>out, name, '= ',
- pprint.pprint(value, out)
|