webrtc/tools-webrtc/gn_check_autofix.py
Henrik Kjellander b5ffc149a9 Create top-level dir tools-webrtc and start moving things into it.
In order to get rid of the Chromium checkout for WebRTC, the plan is to
instead of cloning all of Chromium, only clone the build, third_party and
tools sub-directories. In order to do so, we must first move all things
checked into the WebRTC tools/ directory somewhere else.
Due to many hardcoded assumptions of tools/ existing in Chrome, this
is only manageble solution to the problem.

This first step only moves stuff not used by the build system or bots,
and deletes a few unused directories.

BUG=webrtc:5006
R=henrika@webrtc.org

Review-Url: https://codereview.webrtc.org/2584433002 .
Cr-Commit-Position: refs/heads/master@{#15622}
2016-12-15 08:49:06 +00:00

142 lines
4.2 KiB
Python

#!/usr/bin/env python
# Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
import os
import re
import shutil
import subprocess
import sys
import tempfile
from collections import defaultdict
TARGET_RE = re.compile(
r'(?P<indentation_level>\s*)\w*\("(?P<target_name>\w*)"\) {$')
class TemporaryDirectory(object):
def __init__(self):
self._closed = False
self._name = None
self._name = tempfile.mkdtemp()
def __enter__(self):
return self._name
def __exit__(self, exc, value, tb):
if self._name and not self._closed:
shutil.rmtree(self._name)
self._closed = True
def Run(cmd):
print 'Running:', ' '.join(cmd)
sub = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return sub.communicate()
def FixErrors(filename, missing_deps, deleted_sources):
with open(filename) as f:
lines = f.readlines()
fixed_file = ''
indentation_level = None
for line in lines:
match = TARGET_RE.match(line)
if match:
target = match.group('target_name')
if target in missing_deps:
indentation_level = match.group('indentation_level')
elif indentation_level is not None:
match = re.match(indentation_level + '}$', line)
if match:
line = ('deps = [\n' +
''.join(' "' + dep + '",\n' for dep in missing_deps[target]) +
']\n') + line
indentation_level = None
elif line.strip().startswith('deps'):
is_empty_deps = line.strip() == 'deps = []'
line = 'deps = [\n' if is_empty_deps else line
line += ''.join(' "' + dep + '",\n' for dep in missing_deps[target])
line += ']\n' if is_empty_deps else ''
indentation_level = None
if line.strip() not in deleted_sources:
fixed_file += line
with open(filename, 'w') as f:
f.write(fixed_file)
Run(['gn', 'format', filename])
def Rebase(base_path, dependency_path, dependency):
base_path = base_path.split(os.path.sep)
dependency_path = dependency_path.split(os.path.sep)
first_difference = None
shortest_length = min(len(dependency_path), len(base_path))
for i in range(shortest_length):
if dependency_path[i] != base_path[i]:
first_difference = i
break
first_difference = first_difference or shortest_length
base_path = base_path[first_difference:]
dependency_path = dependency_path[first_difference:]
return (os.path.sep.join((['..'] * len(base_path)) + dependency_path) +
':' + dependency)
def main():
deleted_sources = set()
errors_by_file = defaultdict(lambda: defaultdict(set))
with TemporaryDirectory() as tmp_dir:
mb_gen_command = ([
'tools/mb/mb.py', 'gen',
tmp_dir,
'--config-file', 'webrtc/build/mb_config.pyl',
] + sys.argv[1:])
mb_output = Run(mb_gen_command)
errors = mb_output[0].split('ERROR')[1:]
if mb_output[1]:
print mb_output[1]
return 1
for error in errors:
error = error.splitlines()
target_msg = 'The target:'
if target_msg not in error:
target_msg = 'It is not in any dependency of'
if target_msg not in error:
print '\n'.join(error)
continue
index = error.index(target_msg) + 1
path, target = error[index].strip().split(':')
if error[index+1] in ('is including a file from the target:',
'The include file is in the target(s):'):
dep = error[index+2].strip()
dep_path, dep = dep.split(':')
dep = Rebase(path, dep_path, dep)
path = os.path.join(path[2:], 'BUILD.gn')
errors_by_file[path][target].add(dep)
elif error[index+1] == 'has a source file:':
deleted_file = '"' + os.path.basename(error[index+2].strip()) + '",'
deleted_sources.add(deleted_file)
else:
print '\n'.join(error)
continue
for path, missing_deps in errors_by_file.items():
FixErrors(path, missing_deps, deleted_sources)
return 0
if __name__ == '__main__':
sys.exit(main())