#!/usr/bin/env python
#
#===- git-clang-format - ClangFormat Git Integration ---------*- python -*--===#
#
#                     The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#

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
"""

import argparse
import collections
import contextlib
import errno
import os
import re
import subprocess
import sys

usage = 'git clang-format [OPTIONS] [<commit>] [--] [<file>...]'

desc = '''
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.

The following git-config settings set the default of the corresponding option:
  clangFormat.binary
  clangFormat.commit
  clangFormat.extension
  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', 'hpp',  # C++
      # Other languages that clang-format supports
      'proto', 'protodevel',  # Protocol Buffers
      'js',  # JavaScript
      'ts',  # TypeScript
      ])

  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('--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('--exclude', help='Exclude files matching this regex.')
  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('--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

  commit, files = interpret_args(opts.args, dash_dash, opts.commit)
  changed_lines = compute_diff_and_extract_lines(commit, files)
  if opts.verbose >= 1:
    ignored_files = set(changed_lines)
  filter_by_extension(changed_lines, opts.extensions.lower().split(','))
  if opts.exclude:
    for filename in changed_lines.keys():
      if re.match(opts.exclude, filename):
        del changed_lines[filename]
  if opts.verbose >= 1:
    ignored_files.difference_update(changed_lines)
    if ignored_files:
      print 'Ignoring changes in the following files:'
      for filename in ignored_files:
        print '   ', filename
    if changed_lines:
      print 'Running clang-format on the following files:'
      for filename in changed_lines:
        print '   ', filename
  if not changed_lines:
    print 'no modified files to format'
    return
  # The computed diff outputs absolute paths, so we must cd before accessing
  # those files.
  cd_to_toplevel()
  old_tree = create_tree_from_workdir(changed_lines)
  new_tree = run_clang_format_and_save_to_tree(changed_lines,
                                               binary=opts.binary,
                                               style=opts.style)
  if opts.verbose >= 1:
    print 'old tree:', old_tree
    print 'new tree:', new_tree
  if old_tree == new_tree:
    if opts.verbose >= 0:
      print 'clang-format did not modify any files'
  elif opts.diff:
    print_diff(old_tree, new_tree)
  else:
    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 '   ', filename


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:
      name, value = entry.split('\n', 1)
      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 "[commit] [--] [files...]" and return (commit, 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 argument to its
  left (if present) is taken as commit.  Otherwise, the first argument is
  checked if it is a commit or a file.  If commit is not given,
  `default_commit` is used."""
  if dash_dash:
    if len(args) == 0:
      commit = default_commit
    elif len(args) > 1:
      die('at most one commit allowed; %d given' % len(args))
    else:
      commit = args[0]
    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:
    if disambiguate_revision(args[0]):
      commit = args[0]
      files = args[1:]
    else:
      commit = default_commit
      files = args
  else:
    commit = default_commit
    files = []
  return commit, 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 stdout.strip()


def compute_diff_and_extract_lines(commit, files):
  """Calls compute_diff() followed by extract_lines()."""
  diff_process = compute_diff(commit, files)
  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(commit, files):
  """Return a subprocess object producing the diff from `commit`.

  The return value's `stdin` file object will produce a patch with the
  differences between the working directory and `commit`, filtered on `files`
  (if non-empty).  Zero context lines are used in the patch."""
  cmd = ['git', 'diff-index', '-p', '-U0', commit, '--']
  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:
    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:
        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 dictionary.keys():
    base_ext = filename.rsplit('.', 1)
    if len(base_ext) == 1 or base_ext[1].lower() not in allowed_extensions:
      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 run_clang_format_and_save_to_tree(changed_lines, 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."""
  def index_info_generator():
    for filename, line_ranges in changed_lines.iteritems():
      mode = oct(os.stat(filename).st_mode)
      blob_id = clang_format_to_blob(filename, line_ranges, binary=binary,
                                     style=style)
      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('%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, binary='clang-format',
                         style=None):
  """Run clang-format on the given file and save the result to a git blob.

  Returns the object ID (SHA-1) of the created blob."""
  clang_format_cmd = [binary, filename]
  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])
  try:
    clang_format = subprocess.Popen(clang_format_cmd, stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE)
  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))
  return 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.
  subprocess.check_call(['git', 'diff', old_tree, new_tree, '--'])


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', '-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 >>sys.stderr, ('The following files would be modified but '
                           'have unstaged changes:')
      print >>sys.stderr, unstaged_files
      print >>sys.stderr, 'Please commit, stage, or stash them first.'
      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.check_call(['git', 'checkout', '--patch', new_tree])
    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)
  if p.returncode == 0:
    if stderr:
      if verbose:
        print >>sys.stderr, '`%s` printed to stderr:' % ' '.join(args)
      print >>sys.stderr, stderr.rstrip()
    if strip:
      stdout = stdout.rstrip('\r\n')
    return stdout
  if verbose:
    print >>sys.stderr, '`%s` returned %s' % (' '.join(args), p.returncode)
  if stderr:
    print >>sys.stderr, stderr.rstrip()
  sys.exit(2)


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


if __name__ == '__main__':
  main()
