Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Unified Diff: tools_webrtc/presubmit_checks_lib/check_orphan_headers.py

Issue 2872493002: Adding PRESUBMIT check on orphan headers files. (Closed)
Patch Set: adding shebang line Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « PRESUBMIT.py ('k') | tools_webrtc/presubmit_checks_lib/check_orphan_headers_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools_webrtc/presubmit_checks_lib/check_orphan_headers.py
diff --git a/tools_webrtc/presubmit_checks_lib/check_orphan_headers.py b/tools_webrtc/presubmit_checks_lib/check_orphan_headers.py
new file mode 100644
index 0000000000000000000000000000000000000000..707c49fcc5347a3bc83257b0ff7d31cb9b90a34c
--- /dev/null
+++ b/tools_webrtc/presubmit_checks_lib/check_orphan_headers.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+# Copyright (c) 2017 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
+
+
+# TARGET_RE matches a GN target, and extracts the target name and the contents.
+TARGET_RE = re.compile(r'(?P<indent>\s*)\w+\("(?P<target_name>\w+)"\) {'
+ r'(?P<target_contents>.*?)'
+ r'(?P=indent)}',
+ re.MULTILINE | re.DOTALL)
+
+# SOURCES_RE matches a block of sources inside a GN target.
+SOURCES_RE = re.compile(r'sources \+?= \[(?P<sources>.*?)\]',
+ re.MULTILINE | re.DOTALL)
+
+SOURCE_FILE_RE = re.compile(r'.*\"(?P<source_file>.*)\"')
+
+
+class NoBuildGnFoundError(Exception):
+ pass
+
+
+class WrongFileTypeError(Exception):
+ pass
+
+
+def _ReadFile(file_path):
+ """Returns the content of file_path in a string.
+
+ Args:
+ file_path: the path of the file to read.
+ Returns:
+ A string with the content of the file.
+ """
+ with open(file_path) as f:
+ return f.read()
+
+
+def GetBuildGnPathFromFilePath(file_path, file_exists_check, root_dir_path):
+ """Returns the BUILD.gn file responsible for file_path.
+
+ Args:
+ file_path: the absolute path to the .h file to check.
+ file_exists_check: a function that defines how to check if a file exists
+ on the file system.
+ root_dir_path: the absolute path of the root of project.
+
+ Returns:
+ A string with the absolute path to the BUILD.gn file responsible to include
+ file_path in a target.
+ """
+ if not file_path.endswith('.h'):
+ raise WrongFileTypeError(
+ 'File {} is not an header file (.h)'.format(file_path))
+ candidate_dir = os.path.dirname(file_path)
+ while candidate_dir.startswith(root_dir_path):
+ candidate_build_gn_path = os.path.join(candidate_dir, 'BUILD.gn')
+ if file_exists_check(candidate_build_gn_path):
+ return candidate_build_gn_path
+ else:
+ candidate_dir = os.path.abspath(os.path.join(candidate_dir,
+ os.pardir))
+ raise NoBuildGnFoundError(
+ 'No BUILD.gn file found for file: `{}`'.format(file_path))
+
+
+def IsHeaderInBuildGn(header_path, build_gn_path):
+ """Returns True if the header is listed in the BUILD.gn file.
+
+ Args:
+ header_path: the absolute path to the header to check.
+ build_gn_path: the absolute path to the header to check.
+
+ Returns:
+ bool: True if the header_path is an header that is listed in
+ at least one GN target in the BUILD.gn file specified by
+ the argument build_gn_path.
+ """
+ target_abs_path = os.path.dirname(build_gn_path)
+ build_gn_content = _ReadFile(build_gn_path)
+ headers_in_build_gn = GetHeadersInBuildGnFileSources(build_gn_content,
+ target_abs_path)
+ return header_path in headers_in_build_gn
+
+
+def GetHeadersInBuildGnFileSources(file_content, target_abs_path):
+ """Returns a set with all the .h files in the file_content.
+
+ Args:
+ file_content: a string with the content of the BUILD.gn file.
+ target_abs_path: the absolute path to the directory where the
+ BUILD.gn file lives.
+
+ Returns:
+ A set with all the headers (.h file) in the file_content.
+ The set contains absolute paths.
+ """
+ headers_in_sources = set([])
+ for target_match in TARGET_RE.finditer(file_content):
+ target_contents = target_match.group('target_contents')
+ for sources_match in SOURCES_RE.finditer(target_contents):
+ sources = sources_match.group('sources')
+ for source_file_match in SOURCE_FILE_RE.finditer(sources):
+ source_file = source_file_match.group('source_file')
+ if source_file.endswith('.h'):
+ headers_in_sources.add(os.path.join(target_abs_path, source_file))
+ return headers_in_sources
« no previous file with comments | « PRESUBMIT.py ('k') | tools_webrtc/presubmit_checks_lib/check_orphan_headers_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698