You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.9 KiB
98 lines
2.9 KiB
4 months ago
|
#!/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)
|