tools_webrtc dir converted to py3 + top level PRESUBMIT script

Bug: webrtc:13607
Change-Id: Ib018e43ea977cc24dd71048e68e3343741f7f31b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/249083
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Jeremy Leconte <jleconte@google.com>
Commit-Queue: Christoffer Jansson <jansson@google.com>
Cr-Commit-Position: refs/heads/main@{#35953}
diff --git a/tools_webrtc/vim/webrtc.ycm_extra_conf.py b/tools_webrtc/vim/webrtc.ycm_extra_conf.py
index 12a09ed..d11f79a 100644
--- a/tools_webrtc/vim/webrtc.ycm_extra_conf.py
+++ b/tools_webrtc/vim/webrtc.ycm_extra_conf.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env vpython3
+
 # Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
 #
 # Use of this source code is governed by a BSD-style license
@@ -75,12 +77,8 @@
 }
 
 
-def PathExists(*args):
-    return os.path.exists(os.path.join(*args))
-
-
 def FindWebrtcSrcFromFilename(filename):
-    """Searches for the root of the WebRTC checkout.
+  """Searches for the root of the WebRTC checkout.
 
   Simply checks parent directories until it finds .gclient and src/.
 
@@ -90,20 +88,20 @@
   Returns:
     (String) Path of 'src/', or None if unable to find.
   """
-    curdir = os.path.normpath(os.path.dirname(filename))
-    while not (os.path.basename(curdir) == 'src'
-               and PathExists(curdir, 'DEPS') and
-               (PathExists(curdir, '..', '.gclient')
-                or PathExists(curdir, '.git'))):
-        nextdir = os.path.normpath(os.path.join(curdir, '..'))
-        if nextdir == curdir:
-            return None
-        curdir = nextdir
-    return curdir
+  curdir = os.path.normpath(os.path.dirname(filename))
+  while not (os.path.basename(curdir) == 'src'
+             and os.path.exists(os.path.join(curdir, 'DEPS')) and
+             (os.path.exists(os.path.join(curdir, '..', '.gclient'))
+              or os.path.exists(os.path.join(curdir, '.git')))):
+    nextdir = os.path.normpath(os.path.join(curdir, '..'))
+    if nextdir == curdir:
+      return None
+    curdir = nextdir
+  return curdir
 
 
 def GetDefaultSourceFile(webrtc_root, filename):
-    """Returns the default source file to use as an alternative to `filename`.
+  """Returns the default source file to use as an alternative to `filename`.
 
   Compile flags used to build the default source file is assumed to be a
   close-enough approximation for building `filename`.
@@ -115,13 +113,13 @@
   Returns:
     (String) Absolute path to substitute source file.
   """
-    if 'test.' in filename:
-        return os.path.join(webrtc_root, 'base', 'logging_unittest.cc')
-    return os.path.join(webrtc_root, 'base', 'logging.cc')
+  if 'test.' in filename:
+    return os.path.join(webrtc_root, 'base', 'logging_unittest.cc')
+  return os.path.join(webrtc_root, 'base', 'logging.cc')
 
 
 def GetNinjaBuildOutputsForSourceFile(out_dir, filename):
-    """Returns a list of build outputs for filename.
+  """Returns a list of build outputs for filename.
 
   The list is generated by invoking 'ninja -t query' tool to retrieve a list of
   inputs and outputs of `filename`. This list is then filtered to only include
@@ -135,35 +133,35 @@
     (List of Strings) List of target names. Will return [] if `filename` doesn't
         yield any .o or .obj outputs.
   """
-    # Ninja needs the path to the source file relative to the output build
-    # directory.
-    rel_filename = os.path.relpath(filename, out_dir)
+  # Ninja needs the path to the source file relative to the output build
+  # directory.
+  rel_filename = os.path.relpath(filename, out_dir)
 
-    p = subprocess.Popen(['ninja', '-C', out_dir, '-t', 'query', rel_filename],
-                         stdout=subprocess.PIPE,
-                         stderr=subprocess.STDOUT,
-                         universal_newlines=True)
-    stdout, _ = p.communicate()
-    if p.returncode != 0:
-        return []
+  p = subprocess.Popen(['ninja', '-C', out_dir, '-t', 'query', rel_filename],
+                       stdout=subprocess.PIPE,
+                       stderr=subprocess.STDOUT,
+                       universal_newlines=True)
+  stdout, _ = p.communicate()
+  if p.returncode != 0:
+    return []
 
-    # The output looks like:
-    #   ../../relative/path/to/source.cc:
-    #     outputs:
-    #       obj/reative/path/to/target.source.o
-    #       obj/some/other/target2.source.o
-    #       another/target.txt
-    #
-    outputs_text = stdout.partition('\n  outputs:\n')[2]
-    output_lines = [line.strip() for line in outputs_text.split('\n')]
-    return [
-        target for target in output_lines
-        if target and (target.endswith('.o') or target.endswith('.obj'))
-    ]
+  # The output looks like:
+  #   ../../relative/path/to/source.cc:
+  #     outputs:
+  #       obj/reative/path/to/target.source.o
+  #       obj/some/other/target2.source.o
+  #       another/target.txt
+  #
+  outputs_text = stdout.partition('\n  outputs:\n')[2]
+  output_lines = [line.strip() for line in outputs_text.split('\n')]
+  return [
+      target for target in output_lines
+      if target and (target.endswith('.o') or target.endswith('.obj'))
+  ]
 
 
 def GetClangCommandLineForNinjaOutput(out_dir, build_target):
-    """Returns the Clang command line for building `build_target`
+  """Returns the Clang command line for building `build_target`
 
   Asks ninja for the list of commands used to build `filename` and returns the
   final Clang invocation.
@@ -176,25 +174,25 @@
     (String or None) Clang command line or None if a Clang command line couldn't
         be determined.
   """
-    p = subprocess.Popen(
-        ['ninja', '-v', '-C', out_dir, '-t', 'commands', build_target],
-        stdout=subprocess.PIPE,
-        universal_newlines=True)
-    stdout, _ = p.communicate()
-    if p.returncode != 0:
-        return None
-
-    # Ninja will return multiple build steps for all dependencies up to
-    # `build_target`. The build step we want is the last Clang invocation, which
-    # is expected to be the one that outputs `build_target`.
-    for line in reversed(stdout.split('\n')):
-        if 'clang' in line:
-            return line
+  p = subprocess.Popen(
+      ['ninja', '-v', '-C', out_dir, '-t', 'commands', build_target],
+      stdout=subprocess.PIPE,
+      universal_newlines=True)
+  stdout, _ = p.communicate()
+  if p.returncode != 0:
     return None
 
+  # Ninja will return multiple build steps for all dependencies up to
+  # `build_target`. The build step we want is the last Clang invocation, which
+  # is expected to be the one that outputs `build_target`.
+  for line in reversed(stdout.split('\n')):
+    if 'clang' in line:
+      return line
+  return None
+
 
 def GetClangCommandLineFromNinjaForSource(out_dir, filename):
-    """Returns a Clang command line used to build `filename`.
+  """Returns a Clang command line used to build `filename`.
 
   The same source file could be built multiple times using different tool
   chains. In such cases, this command returns the first Clang invocation. We
@@ -210,17 +208,17 @@
     (String or None): Command line for Clang invocation using `filename` as a
         source. Returns None if no such command line could be found.
   """
-    build_targets = GetNinjaBuildOutputsForSourceFile(out_dir, filename)
-    for build_target in build_targets:
-        command_line = GetClangCommandLineForNinjaOutput(out_dir, build_target)
-        if command_line:
-            return command_line
-    return None
+  build_targets = GetNinjaBuildOutputsForSourceFile(out_dir, filename)
+  for build_target in build_targets:
+    command_line = GetClangCommandLineForNinjaOutput(out_dir, build_target)
+    if command_line:
+      return command_line
+  return None
 
 
 def GetClangOptionsFromCommandLine(clang_commandline, out_dir,
                                    additional_flags):
-    """Extracts relevant command line options from `clang_commandline`
+  """Extracts relevant command line options from `clang_commandline`
 
   Args:
     clang_commandline: (String) Full Clang invocation.
@@ -232,48 +230,46 @@
     (List of Strings) The list of command line flags for this source file. Can
     be empty.
   """
-    clang_flags = [] + additional_flags
+  clang_flags = [] + additional_flags
 
-    # Parse flags that are important for YCM's purposes.
-    clang_tokens = shlex.split(clang_commandline)
-    for flag_index, flag in enumerate(clang_tokens):
-        if flag.startswith('-I'):
-            # Relative paths need to be resolved, because they're relative to
-            # the output dir, not the source.
-            if flag[2] == '/':
-                clang_flags.append(flag)
-            else:
-                abs_path = os.path.normpath(os.path.join(out_dir, flag[2:]))
-                clang_flags.append('-I' + abs_path)
-        elif flag.startswith('-std'):
-            clang_flags.append(flag)
-        elif flag.startswith('-') and flag[1] in 'DWFfmO':
-            if (flag == '-Wno-deprecated-register' or
-                flag == '-Wno-header-guard'):
-                # These flags causes libclang (3.3) to crash. Remove it until
-                # things are fixed.
-                continue
-            clang_flags.append(flag)
-        elif flag == '-isysroot':
-            # On Mac -isysroot <path> is used to find the system headers.
-            # Copy over both flags.
-            if flag_index + 1 < len(clang_tokens):
-                clang_flags.append(flag)
-                clang_flags.append(clang_tokens[flag_index + 1])
-        elif flag.startswith('--sysroot='):
-            # On Linux we use a sysroot image.
-            sysroot_path = flag.lstrip('--sysroot=')
-            if sysroot_path.startswith('/'):
-                clang_flags.append(flag)
-            else:
-                abs_path = os.path.normpath(os.path.join(
-                    out_dir, sysroot_path))
-                clang_flags.append('--sysroot=' + abs_path)
-    return clang_flags
+  # Parse flags that are important for YCM's purposes.
+  clang_tokens = shlex.split(clang_commandline)
+  for flag_index, flag in enumerate(clang_tokens):
+    if flag.startswith('-I'):
+      # Relative paths need to be resolved, because they're relative to
+      # the output dir, not the source.
+      if flag[2] == '/':
+        clang_flags.append(flag)
+      else:
+        abs_path = os.path.normpath(os.path.join(out_dir, flag[2:]))
+        clang_flags.append('-I' + abs_path)
+    elif flag.startswith('-std'):
+      clang_flags.append(flag)
+    elif flag.startswith('-') and flag[1] in 'DWFfmO':
+      if flag in ['-Wno-deprecated-register', '-Wno-header-guard']:
+        # These flags causes libclang (3.3) to crash. Remove it until
+        # things are fixed.
+        continue
+      clang_flags.append(flag)
+    elif flag == '-isysroot':
+      # On Mac -isysroot <path> is used to find the system headers.
+      # Copy over both flags.
+      if flag_index + 1 < len(clang_tokens):
+        clang_flags.append(flag)
+        clang_flags.append(clang_tokens[flag_index + 1])
+    elif flag.startswith('--sysroot='):
+      # On Linux we use a sysroot image.
+      sysroot_path = flag.lstrip('--sysroot=')
+      if sysroot_path.startswith('/'):
+        clang_flags.append(flag)
+      else:
+        abs_path = os.path.normpath(os.path.join(out_dir, sysroot_path))
+        clang_flags.append('--sysroot=' + abs_path)
+  return clang_flags
 
 
 def GetClangOptionsFromNinjaForFilename(webrtc_root, filename):
-    """Returns the Clang command line options needed for building `filename`.
+  """Returns the Clang command line options needed for building `filename`.
 
   Command line options are based on the command used by ninja for building
   `filename`. If `filename` is a .h file, uses its companion .cc or .cpp file.
@@ -289,55 +285,54 @@
     (List of Strings) The list of command line flags for this source file. Can
     be empty.
   """
-    if not webrtc_root:
-        return []
+  if not webrtc_root:
+    return []
 
-    # Generally, everyone benefits from including WebRTC's src/, because all of
-    # WebRTC's includes are relative to that.
-    additional_flags = ['-I' + os.path.join(webrtc_root)]
+  # Generally, everyone benefits from including WebRTC's src/, because all of
+  # WebRTC's includes are relative to that.
+  additional_flags = ['-I' + os.path.join(webrtc_root)]
 
-    # Version of Clang used to compile WebRTC can be newer then version of
-    # libclang that YCM uses for completion. So it's possible that YCM's
-    # libclang doesn't know about some used warning options, which causes
-    # compilation warnings (and errors, because of '-Werror');
-    additional_flags.append('-Wno-unknown-warning-option')
+  # Version of Clang used to compile WebRTC can be newer then version of
+  # libclang that YCM uses for completion. So it's possible that YCM's
+  # libclang doesn't know about some used warning options, which causes
+  # compilation warnings (and errors, because of '-Werror');
+  additional_flags.append('-Wno-unknown-warning-option')
 
-    sys.path.append(os.path.join(webrtc_root, 'tools', 'vim'))
-    from ninja_output import GetNinjaOutputDirectory
-    out_dir = GetNinjaOutputDirectory(webrtc_root)
+  sys.path.append(os.path.join(webrtc_root, 'tools', 'vim'))
+  from ninja_output import GetNinjaOutputDirectory
+  out_dir = GetNinjaOutputDirectory(webrtc_root)
 
-    basename, extension = os.path.splitext(filename)
-    if extension == '.h':
-        candidates = [basename + ext for ext in _HEADER_ALTERNATES]
-    else:
-        candidates = [filename]
+  basename, extension = os.path.splitext(filename)
+  if extension == '.h':
+    candidates = [basename + ext for ext in _HEADER_ALTERNATES]
+  else:
+    candidates = [filename]
 
-    clang_line = None
-    buildable_extension = extension
-    for candidate in candidates:
-        clang_line = GetClangCommandLineFromNinjaForSource(out_dir, candidate)
-        if clang_line:
-            buildable_extension = os.path.splitext(candidate)[1]
-            break
+  clang_line = None
+  buildable_extension = extension
+  for candidate in candidates:
+    clang_line = GetClangCommandLineFromNinjaForSource(out_dir, candidate)
+    if clang_line:
+      buildable_extension = os.path.splitext(candidate)[1]
+      break
 
-    additional_flags += _EXTENSION_FLAGS.get(buildable_extension, [])
+  additional_flags += _EXTENSION_FLAGS.get(buildable_extension, [])
 
-    if not clang_line:
-        # If ninja didn't know about filename or it's companion files, then try
-        # a default build target. It is possible that the file is new, or
-        # build.ninja is stale.
-        clang_line = GetClangCommandLineFromNinjaForSource(
-            out_dir, GetDefaultSourceFile(webrtc_root, filename))
+  if not clang_line:
+    # If ninja didn't know about filename or it's companion files, then try
+    # a default build target. It is possible that the file is new, or
+    # build.ninja is stale.
+    clang_line = GetClangCommandLineFromNinjaForSource(
+        out_dir, GetDefaultSourceFile(webrtc_root, filename))
 
-    if not clang_line:
-        return additional_flags
+  if not clang_line:
+    return additional_flags
 
-    return GetClangOptionsFromCommandLine(clang_line, out_dir,
-                                          additional_flags)
+  return GetClangOptionsFromCommandLine(clang_line, out_dir, additional_flags)
 
 
 def FlagsForFile(filename):
-    """This is the main entry point for YCM. Its interface is fixed.
+  """This is the main entry point for YCM. Its interface is fixed.
 
   Args:
     filename: (String) Path to source file being edited.
@@ -347,16 +342,15 @@
       'flags': (List of Strings) Command line flags.
       'do_cache': (Boolean) True if the result should be cached.
   """
-    abs_filename = os.path.abspath(filename)
-    webrtc_root = FindWebrtcSrcFromFilename(abs_filename)
-    clang_flags = GetClangOptionsFromNinjaForFilename(webrtc_root,
-                                                      abs_filename)
+  abs_filename = os.path.abspath(filename)
+  webrtc_root = FindWebrtcSrcFromFilename(abs_filename)
+  clang_flags = GetClangOptionsFromNinjaForFilename(webrtc_root, abs_filename)
 
-    # If clang_flags could not be determined, then assume that was due to a
-    # transient failure. Preventing YCM from caching the flags allows us to
-    # try to determine the flags again.
-    should_cache_flags_for_file = bool(clang_flags)
+  # If clang_flags could not be determined, then assume that was due to a
+  # transient failure. Preventing YCM from caching the flags allows us to
+  # try to determine the flags again.
+  should_cache_flags_for_file = bool(clang_flags)
 
-    final_flags = _DEFAULT_FLAGS + clang_flags
+  final_flags = _DEFAULT_FLAGS + clang_flags
 
-    return {'flags': final_flags, 'do_cache': should_cache_flags_for_file}
+  return {'flags': final_flags, 'do_cache': should_cache_flags_for_file}