#!/usr/bin/env python3
#
#===- git-clang-format - ClangFormat Git Integration ---------*- python -*--===#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
#===------------------------------------------------------------------------===#

r"""
clang-format git integration
============================

This file provides a clang-format integration for git. Put it somewhere in your
path and ensure that it is executable. Then, "git clang-format" will invoke
clang-format on the changes in current files or a specific commit.

For further details, run:
git clang-format -h

Requires Python 2.7 or Python 3
"""

from __future__ import absolute_import, division, print_function
import argparse
import collections
import contextlib
import errno
import os
import re
import subprocess
import sys

usage = ('git clang-format [OPTIONS] [<commit>] [<commit>|--staged] '
         '[--] [<file>...]')

desc = '''
If zero or one commits are given, run clang-format on all lines that differ
between the working directory and <commit>, which defaults to HEAD.  Changes are
only applied to the working directory, or in the stage/index.

Examples:
  To format staged changes, i.e everything that's been `git add`ed:
    git clang-format

  To also format everything touched in the most recent commit:
    git clang-format HEAD~1

  If you're on a branch off main, to format everything touched on your branch:
    git clang-format main

If two commits are given (requires --diff), run clang-format on all lines in the
second <commit> that differ from the first <commit>.

The following git-config settings set the default of the corresponding option:
  clangFormat.binary
  clangFormat.commit
  clangFormat.extensions
  clangFormat.style
'''

# Name of the temporary index file in which save the output of clang-format.
# This file is created within the .git directory.
temp_index_basename = 'clang-format-index'


Range = collections.namedtuple('Range', 'start, count')


def main():
  config = load_git_config()

  # In order to keep '--' yet allow options after positionals, we need to
  # check for '--' ourselves.  (Setting nargs='*' throws away the '--', while
  # nargs=argparse.REMAINDER disallows options after positionals.)
  argv = sys.argv[1:]
  try:
    idx = argv.index('--')
  except ValueError:
    dash_dash = []
  else:
    dash_dash = argv[idx:]
    argv = argv[:idx]

  default_extensions = ','.join([
      # From clang/lib/Frontend/FrontendOptions.cpp, all lower case
      'c', 'h',  # C
      'm',  # ObjC
      'mm',  # ObjC++
      'cc', 'cp', 'cpp', 'c++', 'cxx', 'hh', 'hpp', 'hxx',  # C++
      'ccm', 'cppm', 'cxxm', 'c++m',  # C++ Modules
      'cu', 'cuh',  # CUDA
      # Other languages that clang-format supports
      'proto', 'protodevel',  # Protocol Buffers
      'java',  # Java
      'js',  # JavaScript
      'ts',  # TypeScript
      'cs',  # C Sharp
      'json',  # Json
      ])

  p = argparse.ArgumentParser(
    usage=usage, formatter_class=argparse.RawDescriptionHelpFormatter,
    description=desc)
  p.add_argument('--binary',
                 default=config.get('clangformat.binary', 'clang-format'),
                 help='path to clang-format'),
  p.add_argument('--commit',
                 default=config.get('clangformat.commit', 'HEAD'),
                 help='default commit to use if none is specified'),
  p.add_argument('--diff', action='store_true',
                 help='print a diff instead of applying the changes')
  p.add_argument('--diffstat', action='store_true',
                 help='print a diffstat instead of applying the changes')
  p.add_argument('--extensions',
                 default=config.get('clangformat.extensions',
                                    default_extensions),
                 help=('comma-separated list of file extensions to format, '
                       'excluding the period and case-insensitive')),
  p.add_argument('-f', '--force', action='store_true',
                 help='allow changes to unstaged files')
  p.add_argument('-p', '--patch', action='store_true',
                 help='select hunks interactively')
  p.add_argument('-q', '--quiet', action='count', default=0,
                 help='print less information')
  p.add_argument('--staged', '--cached', action='store_true',
                 help='format lines in the stage instead of the working dir')
  p.add_argument('--style',
                 default=config.get('clangformat.style', None),
                 help='passed to clang-format'),
  p.add_argument('-v', '--verbose', action='count', default=0,
                 help='print extra information')
  # We gather all the remaining positional arguments into 'args' since we need
  # to use some heuristics to determine whether or not <commit> was present.
  # However, to print pretty messages, we make use of metavar and help.
  p.add_argument('args', nargs='*', metavar='<commit>',
                 help='revision from which to compute the diff')
  p.add_argument('ignored', nargs='*', metavar='<file>...',
                 help='if specified, only consider differences in these files')
  opts = p.parse_args(argv)

  opts.verbose -= opts.quiet
  del opts.quiet

  commits, files = interpret_args(opts.args, dash_dash, opts.commit)
  if len(commits) > 1:
    if opts.staged:
      die('--staged is not allowed when two commits are given')
    if not opts.diff:
      die('--diff is required when two commits are given')
  else:
    if len(commits) > 2:
      die('at most two commits allowed; %d given' % len(commits))
  changed_lines = compute_diff_and_extract_lines(commits, files, opts.staged)
  if opts.verbose >= 1:
    ignored_files = set(changed_lines)
  filter_by_extension(changed_lines, opts.extensions.lower().split(','))
  # The computed diff outputs absolute paths, so we must cd before accessing
  # those files.
  cd_to_toplevel()
  filter_symlinks(changed_lines)
  if opts.verbose >= 1:
    ignored_files.difference_update(changed_lines)
    if ignored_files:
      print(
        'Ignoring changes in the following files (wrong extension or symlink):')
      for filename in ignored_files:
        print('    %s' % filename)
    if changed_lines:
      print('Running clang-format on the following files:')
      for filename in changed_lines:
        print('    %s' % filename)

  if not changed_lines:
    if opts.verbose >= 0:
      print('no modified files to format')
    return 0

  if len(commits) > 1:
    old_tree = commits[1]
    revision = old_tree
  elif opts.staged:
    old_tree = create_tree_from_index(changed_lines)
    revision = ''
  else:
    old_tree = create_tree_from_workdir(changed_lines)
    revision = None
  new_tree = run_clang_format_and_save_to_tree(changed_lines,
                                               revision,
                                               binary=opts.binary,
                                               style=opts.style)
  if opts.verbose >= 1:
    print('old tree: %s' % old_tree)
    print('new tree: %s' % new_tree)

  if old_tree == new_tree:
    if opts.verbose >= 0:
      print('clang-format did not modify any files')
    return 0

  if opts.diff:
    return print_diff(old_tree, new_tree)
  if opts.diffstat:
    return print_diffstat(old_tree, new_tree)

  changed_files = apply_changes(old_tree, new_tree, force=opts.force,
                                patch_mode=opts.patch)
  if (opts.verbose >= 0 and not opts.patch) or opts.verbose >= 1:
    print('changed files:')
    for filename in changed_files:
      print('    %s' % filename)

  return 1


def load_git_config(non_string_options=None):
  """Return the git configuration as a dictionary.

  All options are assumed to be strings unless in `non_string_options`, in which
  is a dictionary mapping option name (in lower case) to either "--bool" or
  "--int"."""
  if non_string_options is None:
    non_string_options = {}
  out = {}
  for entry in run('git', 'config', '--list', '--null').split('\0'):
    if entry:
      if '\n' in entry:
        name, value = entry.split('\n', 1)
      else:
        # A setting with no '=' ('\n' with --null) is implicitly 'true'
        name = entry
        value = 'true'
      if name in non_string_options:
        value = run('git', 'config', non_string_options[name], name)
      out[name] = value
  return out


def interpret_args(args, dash_dash, default_commit):
  """Interpret `args` as "[commits] [--] [files]" and return (commits, files).

  It is assumed that "--" and everything that follows has been removed from
  args and placed in `dash_dash`.

  If "--" is present (i.e., `dash_dash` is non-empty), the arguments to its
  left (if present) are taken as commits.  Otherwise, the arguments are checked
  from left to right if they are commits or files.  If commits are not given,
  a list with `default_commit` is used."""
  if dash_dash:
    if len(args) == 0:
      commits = [default_commit]
    else:
      commits = args
    for commit in commits:
      object_type = get_object_type(commit)
      if object_type not in ('commit', 'tag'):
        if object_type is None:
          die("'%s' is not a commit" % commit)
        else:
          die("'%s' is a %s, but a commit was expected" % (commit, object_type))
    files = dash_dash[1:]
  elif args:
    commits = []
    while args:
      if not disambiguate_revision(args[0]):
        break
      commits.append(args.pop(0))
    if not commits:
      commits = [default_commit]
    files = args
  else:
    commits = [default_commit]
    files = []
  return commits, files


def disambiguate_revision(value):
  """Returns True if `value` is a revision, False if it is a file, or dies."""
  # If `value` is ambiguous (neither a commit nor a file), the following
  # command will die with an appropriate error message.
  run('git', 'rev-parse', value, verbose=False)
  object_type = get_object_type(value)
  if object_type is None:
    return False
  if object_type in ('commit', 'tag'):
    return True
  die('`%s` is a %s, but a commit or filename was expected' %
      (value, object_type))


def get_object_type(value):
  """Returns a string description of an object's type, or None if it is not
  a valid git object."""
  cmd = ['git', 'cat-file', '-t', value]
  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  stdout, stderr = p.communicate()
  if p.returncode != 0:
    return None
  return convert_string(stdout.strip())


def compute_diff_and_extract_lines(commits, files, staged):
  """Calls compute_diff() followed by extract_lines()."""
  diff_process = compute_diff(commits, files, staged)
  changed_lines = extract_lines(diff_process.stdout)
  diff_process.stdout.close()
  diff_process.wait()
  if diff_process.returncode != 0:
    # Assume error was already printed to stderr.
    sys.exit(2)
  return changed_lines


def compute_diff(commits, files, staged):
  """Return a subprocess object producing the diff from `commits`.

  The return value's `stdin` file object will produce a patch with the
  differences between the working directory (or stage if --staged is used) and
  the first commit if a single one was specified, or the difference between
  both specified commits, filtered on `files` (if non-empty).
  Zero context lines are used in the patch."""
  git_tool = 'diff-index'
  extra_args = []
  if len(commits) > 1:
    git_tool = 'diff-tree'
  elif staged:
    extra_args += ['--cached']
  cmd = ['git', git_tool, '-p', '-U0'] + extra_args + commits + ['--']
  cmd.extend(files)
  p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
  p.stdin.close()
  return p


def extract_lines(patch_file):
  """Extract the changed lines in `patch_file`.

  The return value is a dictionary mapping filename to a list of (start_line,
  line_count) pairs.

  The input must have been produced with ``-U0``, meaning unidiff format with
  zero lines of context.  The return value is a dict mapping filename to a
  list of line `Range`s."""
  matches = {}
  for line in patch_file:
    line = convert_string(line)
    match = re.search(r'^\+\+\+\ [^/]+/(.*)', line)
    if match:
      filename = match.group(1).rstrip('\r\n')
    match = re.search(r'^@@ -[0-9,]+ \+(\d+)(,(\d+))?', line)
    if match:
      start_line = int(match.group(1))
      line_count = 1
      if match.group(3):
        line_count = int(match.group(3))
      if line_count == 0:
        line_count = 1
      if start_line == 0:
        continue
      matches.setdefault(filename, []).append(Range(start_line, line_count))
  return matches


def filter_by_extension(dictionary, allowed_extensions):
  """Delete every key in `dictionary` that doesn't have an allowed extension.

  `allowed_extensions` must be a collection of lowercase file extensions,
  excluding the period."""
  allowed_extensions = frozenset(allowed_extensions)
  for filename in list(dictionary.keys()):
    base_ext = filename.rsplit('.', 1)
    if len(base_ext) == 1 and '' in allowed_extensions:
        continue
    if len(base_ext) == 1 or base_ext[1].lower() not in allowed_extensions:
      del dictionary[filename]


def filter_symlinks(dictionary):
  """Delete every key in `dictionary` that is a symlink."""
  for filename in list(dictionary.keys()):
    if os.path.islink(filename):
      del dictionary[filename]


def cd_to_toplevel():
  """Change to the top level of the git repository."""
  toplevel = run('git', 'rev-parse', '--show-toplevel')
  os.chdir(toplevel)


def create_tree_from_workdir(filenames):
  """Create a new git tree with the given files from the working directory.

  Returns the object ID (SHA-1) of the created tree."""
  return create_tree(filenames, '--stdin')


def create_tree_from_index(filenames):
  # Copy the environment, because the files have to be read from the original
  # index.
  env = os.environ.copy()
  def index_contents_generator():
    for filename in filenames:
      git_ls_files_cmd = ['git', 'ls-files', '--stage', '-z', '--', filename]
      git_ls_files = subprocess.Popen(git_ls_files_cmd, env=env,
                                      stdin=subprocess.PIPE,
                                      stdout=subprocess.PIPE)
      stdout = git_ls_files.communicate()[0]
      yield convert_string(stdout.split(b'\0')[0])
  return create_tree(index_contents_generator(), '--index-info')


def run_clang_format_and_save_to_tree(changed_lines, revision=None,
                                      binary='clang-format', style=None):
  """Run clang-format on each file and save the result to a git tree.

  Returns the object ID (SHA-1) of the created tree."""
  # Copy the environment when formatting the files in the index, because the
  # files have to be read from the original index.
  env = os.environ.copy() if revision == '' else None
  def iteritems(container):
      try:
          return container.iteritems() # Python 2
      except AttributeError:
          return container.items() # Python 3
  def index_info_generator():
    for filename, line_ranges in iteritems(changed_lines):
      if revision is not None:
        if len(revision) > 0:
          git_metadata_cmd = ['git', 'ls-tree',
                              '%s:%s' % (revision, os.path.dirname(filename)),
                              os.path.basename(filename)]
        else:
          git_metadata_cmd = ['git', 'ls-files', '--stage', '--', filename]
        git_metadata = subprocess.Popen(git_metadata_cmd, env=env,
                                        stdin=subprocess.PIPE,
                                        stdout=subprocess.PIPE)
        stdout = git_metadata.communicate()[0]
        mode = oct(int(stdout.split()[0], 8))
      else:
        mode = oct(os.stat(filename).st_mode)
      # Adjust python3 octal format so that it matches what git expects
      if mode.startswith('0o'):
          mode = '0' + mode[2:]
      blob_id = clang_format_to_blob(filename, line_ranges,
                                     revision=revision,
                                     binary=binary,
                                     style=style,
                                     env=env)
      yield '%s %s\t%s' % (mode, blob_id, filename)
  return create_tree(index_info_generator(), '--index-info')


def create_tree(input_lines, mode):
  """Create a tree object from the given input.

  If mode is '--stdin', it must be a list of filenames.  If mode is
  '--index-info' is must be a list of values suitable for "git update-index
  --index-info", such as "<mode> <SP> <sha1> <TAB> <filename>".  Any other mode
  is invalid."""
  assert mode in ('--stdin', '--index-info')
  cmd = ['git', 'update-index', '--add', '-z', mode]
  with temporary_index_file():
    p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
    for line in input_lines:
      p.stdin.write(to_bytes('%s\0' % line))
    p.stdin.close()
    if p.wait() != 0:
      die('`%s` failed' % ' '.join(cmd))
    tree_id = run('git', 'write-tree')
    return tree_id


def clang_format_to_blob(filename, line_ranges, revision=None,
                         binary='clang-format', style=None, env=None):
  """Run clang-format on the given file and save the result to a git blob.

  Runs on the file in `revision` if not None, or on the file in the working
  directory if `revision` is None. Revision can be set to an empty string to run
  clang-format on the file in the index.

  Returns the object ID (SHA-1) of the created blob."""
  clang_format_cmd = [binary]
  if style:
    clang_format_cmd.extend(['-style='+style])
  clang_format_cmd.extend([
      '-lines=%s:%s' % (start_line, start_line+line_count-1)
      for start_line, line_count in line_ranges])
  if revision is not None:
    clang_format_cmd.extend(['-assume-filename='+filename])
    git_show_cmd = ['git', 'cat-file', 'blob', '%s:%s' % (revision, filename)]
    git_show = subprocess.Popen(git_show_cmd, env=env, stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE)
    git_show.stdin.close()
    clang_format_stdin = git_show.stdout
  else:
    clang_format_cmd.extend([filename])
    git_show = None
    clang_format_stdin = subprocess.PIPE
  try:
    clang_format = subprocess.Popen(clang_format_cmd, stdin=clang_format_stdin,
                                    stdout=subprocess.PIPE)
    if clang_format_stdin == subprocess.PIPE:
      clang_format_stdin = clang_format.stdin
  except OSError as e:
    if e.errno == errno.ENOENT:
      die('cannot find executable "%s"' % binary)
    else:
      raise
  clang_format_stdin.close()
  hash_object_cmd = ['git', 'hash-object', '-w', '--path='+filename, '--stdin']
  hash_object = subprocess.Popen(hash_object_cmd, stdin=clang_format.stdout,
                                 stdout=subprocess.PIPE)
  clang_format.stdout.close()
  stdout = hash_object.communicate()[0]
  if hash_object.returncode != 0:
    die('`%s` failed' % ' '.join(hash_object_cmd))
  if clang_format.wait() != 0:
    die('`%s` failed' % ' '.join(clang_format_cmd))
  if git_show and git_show.wait() != 0:
    die('`%s` failed' % ' '.join(git_show_cmd))
  return convert_string(stdout).rstrip('\r\n')


@contextlib.contextmanager
def temporary_index_file(tree=None):
  """Context manager for setting GIT_INDEX_FILE to a temporary file and deleting
  the file afterward."""
  index_path = create_temporary_index(tree)
  old_index_path = os.environ.get('GIT_INDEX_FILE')
  os.environ['GIT_INDEX_FILE'] = index_path
  try:
    yield
  finally:
    if old_index_path is None:
      del os.environ['GIT_INDEX_FILE']
    else:
      os.environ['GIT_INDEX_FILE'] = old_index_path
    os.remove(index_path)


def create_temporary_index(tree=None):
  """Create a temporary index file and return the created file's path.

  If `tree` is not None, use that as the tree to read in.  Otherwise, an
  empty index is created."""
  gitdir = run('git', 'rev-parse', '--git-dir')
  path = os.path.join(gitdir, temp_index_basename)
  if tree is None:
    tree = '--empty'
  run('git', 'read-tree', '--index-output='+path, tree)
  return path


def print_diff(old_tree, new_tree):
  """Print the diff between the two trees to stdout."""
  # We use the porcelain 'diff' and not plumbing 'diff-tree' because the output
  # is expected to be viewed by the user, and only the former does nice things
  # like color and pagination.
  #
  # We also only print modified files since `new_tree` only contains the files
  # that were modified, so unmodified files would show as deleted without the
  # filter.
  return subprocess.run(['git', 'diff', '--diff-filter=M',
                         '--exit-code', old_tree, new_tree]).returncode

def print_diffstat(old_tree, new_tree):
  """Print the diffstat between the two trees to stdout."""
  # We use the porcelain 'diff' and not plumbing 'diff-tree' because the output
  # is expected to be viewed by the user, and only the former does nice things
  # like color and pagination.
  #
  # We also only print modified files since `new_tree` only contains the files
  # that were modified, so unmodified files would show as deleted without the
  # filter.
  return subprocess.run(['git', 'diff', '--diff-filter=M', '--exit-code',
                         '--stat', old_tree, new_tree]).returncode

def apply_changes(old_tree, new_tree, force=False, patch_mode=False):
  """Apply the changes in `new_tree` to the working directory.

  Bails if there are local changes in those files and not `force`.  If
  `patch_mode`, runs `git checkout --patch` to select hunks interactively."""
  changed_files = run('git', 'diff-tree', '--diff-filter=M', '-r', '-z',
                      '--name-only', old_tree,
                      new_tree).rstrip('\0').split('\0')
  if not force:
    unstaged_files = run('git', 'diff-files', '--name-status', *changed_files)
    if unstaged_files:
      print('The following files would be modified but '
                'have unstaged changes:', file=sys.stderr)
      print(unstaged_files, file=sys.stderr)
      print('Please commit, stage, or stash them first.', file=sys.stderr)
      sys.exit(2)
  if patch_mode:
    # In patch mode, we could just as well create an index from the new tree
    # and checkout from that, but then the user will be presented with a
    # message saying "Discard ... from worktree".  Instead, we use the old
    # tree as the index and checkout from new_tree, which gives the slightly
    # better message, "Apply ... to index and worktree".  This is not quite
    # right, since it won't be applied to the user's index, but oh well.
    with temporary_index_file(old_tree):
      subprocess.run(['git', 'checkout', '--patch', new_tree], check=True)
    index_tree = old_tree
  else:
    with temporary_index_file(new_tree):
      run('git', 'checkout-index', '-a', '-f')
  return changed_files


def run(*args, **kwargs):
  stdin = kwargs.pop('stdin', '')
  verbose = kwargs.pop('verbose', True)
  strip = kwargs.pop('strip', True)
  for name in kwargs:
    raise TypeError("run() got an unexpected keyword argument '%s'" % name)
  p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                       stdin=subprocess.PIPE)
  stdout, stderr = p.communicate(input=stdin)

  stdout = convert_string(stdout)
  stderr = convert_string(stderr)

  if p.returncode == 0:
    if stderr:
      if verbose:
        print('`%s` printed to stderr:' % ' '.join(args), file=sys.stderr)
      print(stderr.rstrip(), file=sys.stderr)
    if strip:
      stdout = stdout.rstrip('\r\n')
    return stdout
  if verbose:
    print('`%s` returned %s' % (' '.join(args), p.returncode), file=sys.stderr)
  if stderr:
    print(stderr.rstrip(), file=sys.stderr)
  sys.exit(2)


def die(message):
  print('error:', message, file=sys.stderr)
  sys.exit(2)


def to_bytes(str_input):
    # Encode to UTF-8 to get binary data.
    if isinstance(str_input, bytes):
        return str_input
    return str_input.encode('utf-8')


def to_string(bytes_input):
    if isinstance(bytes_input, str):
        return bytes_input
    return bytes_input.encode('utf-8')


def convert_string(bytes_input):
    try:
        return to_string(bytes_input.decode('utf-8'))
    except AttributeError: # 'str' object has no attribute 'decode'.
        return str(bytes_input)
    except UnicodeError:
        return str(bytes_input)

if __name__ == '__main__':
  sys.exit(main())
