Sync to latest trace-viewer

bug:20761637

Cherry-pick of 26c92f4cb78a275f1ebb94dd976f37bdd7d53ce7 from AOSP

Change-Id: I645b485ff2643b6efbec1fa25de6fc81a98c3ee5
diff --git a/trace-viewer/hooks/install.py b/trace-viewer/hooks/install.py
index e918e3f..6e22fb3 100644
--- a/trace-viewer/hooks/install.py
+++ b/trace-viewer/hooks/install.py
@@ -56,6 +56,8 @@
   links = []
   links.append(Link(os.path.join('.git', 'hooks', 'pre-commit'),
                     os.path.join('hooks/pre_commit')))
+  links.append(Link(os.path.join('.git', 'hooks', 'pre-push'),
+                    os.path.join('hooks/pre_push')))
 
   for l in links:
     l.Update()
diff --git a/trace-viewer/hooks/pre_commit b/trace-viewer/hooks/pre_commit
index d029fff..22461d0 100755
--- a/trace-viewer/hooks/pre_commit
+++ b/trace-viewer/hooks/pre_commit
@@ -7,6 +7,9 @@
 import sys
 
 if __name__ == '__main__':
+  # This pre-commit hook was replaced by a pre-submit hook (see PRESUBMIT.py).
+  sys.exit(0)
+
   f = __file__
   if os.path.islink(f):
     f = os.path.abspath(os.path.join(os.path.dirname(f), os.readlink(f)))
diff --git a/trace-viewer/hooks/pre_commit.py b/trace-viewer/hooks/pre_commit.py
index f73f306..6c92d5a 100644
--- a/trace-viewer/hooks/pre_commit.py
+++ b/trace-viewer/hooks/pre_commit.py
@@ -74,15 +74,17 @@
     return self._cached_changed_contents[:]
 
   def GenerateDiff(self):
-    return self._input_api._git(['diff', '--cached', self.filename])
+    return self._input_api._git([
+        'diff', self._input_api.diff_base, '--cached', self.filename])
 
 
 class InputAPI(object):
-  def __init__(self, tvp):
+  def __init__(self, tvp, diff_base):
     self.DEFAULT_BLACK_LIST = []
     self._tvp = tvp
     self._filename_statuses = None
     self._added_files = None
+    self.diff_base = diff_base
 
   def _git(self, args):
     assert isinstance(args, list)
@@ -131,7 +133,8 @@
       return self._filename_statuses
 
     self._filename_statuses = []
-    stdout = self._git(['diff', '--cached', '--name-status'])
+    stdout = self._git([
+        'diff', self.diff_base, '--cached', '--name-status'])
     for line in stdout.split('\n'):
       line = line.strip()
       if len(line) == 0:
@@ -146,6 +149,10 @@
       self._filename_statuses.append((filename, status_char))
     return self._filename_statuses
 
+  def IsTestDataFile(self, affected_file):
+    full_path = os.path.join(self.repository_root, affected_file.filename)
+    return full_path.startswith(self._tvp.test_data_path)
+
 
 def RunChecks(input_api):
   results = []
@@ -174,10 +181,14 @@
   return results
 
 
-def Main(args):
+def GetResults(diff_base):
   tvp = trace_viewer_project.TraceViewerProject()
-  input_api = InputAPI(tvp)
-  results = RunChecks(input_api)
+  input_api = InputAPI(tvp, diff_base)
+  return RunChecks(input_api)
+
+
+def Main(args):
+  results = GetResults('HEAD')
   print '\n\n'.join(results)
 
   if len(results):
diff --git a/trace-viewer/hooks/pre_commit_checks.py b/trace-viewer/hooks/pre_commit_checks.py
index 987e3af..d6e776f 100644
--- a/trace-viewer/hooks/pre_commit_checks.py
+++ b/trace-viewer/hooks/pre_commit_checks.py
@@ -40,6 +40,9 @@
     if all(callable_rule(extension, line) for line in f.contents_as_lines):
       continue  # No violation found in full text: can skip considering diff.
 
+    if input_api.IsTestDataFile(f):
+      continue
+
     for line_num, line in f.changed_lines:
       if not callable_rule(extension, line):
         errors.append(error_formatter(f.filename, line_num, line))
@@ -90,15 +93,17 @@
                       if os.path.splitext(f.filename)[1] != '.html']
 
   results = []
-  results += _Check(html_license_re, html_sources)
-  results += _Check(non_html_license_re, non_html_sources)
+  results += _Check(input_api, html_license_re, html_sources)
+  results += _Check(input_api, non_html_license_re, non_html_sources)
   return results
 
-def _Check(license_re, sources):
+def _Check(input_api, license_re, sources):
   bad_files = []
   for f in sources:
     contents = f.contents
     if not license_re.search(contents):
+      if input_api.IsTestDataFile(f):
+        continue
       bad_files.append(f.filename)
   if bad_files:
     return [_FormatError(
diff --git a/trace-viewer/hooks/pre_push b/trace-viewer/hooks/pre_push
new file mode 100755
index 0000000..7e7a296
--- /dev/null
+++ b/trace-viewer/hooks/pre_push
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import sys
+import subprocess
+
+"""Detect forced pushes (on the client) and prompt the user before going on."""
+
+def read_from_tty():
+  try:
+    import posix  # No way to do this on Windows, just give up there.
+    with open('/dev/tty') as tty_fd:
+      return tty_fd.readline().strip()
+  except:
+    return None
+
+
+def Main():
+  # Allow force pushes in repos forked elsewhere (e.g. googlesource).
+  remote_url = sys.argv[2] if len(sys.argv) >= 2 else ''
+  if 'github.com' not in remote_url:
+    return 0
+
+  parts = sys.stdin.readline().split()
+  if len(parts) < 4:
+    return 0
+  local_ref, local_sha, remote_ref, remote_sha = parts
+  cmd = ['git', 'rev-list', '--count', remote_sha, '--not', local_sha,
+         '--max-count=1']
+
+  is_force_push = '0'
+  try:
+    is_force_push = subprocess.check_output(cmd).strip()
+  except(subprocess.CalledProcessError):
+    return 0
+
+  if is_force_push != '0':
+    sys.stderr.write('\033[31mWARNING: Force pushing will break the ' +
+                     'github.com -> googlesource.com mirroring.\033[0m\n' +
+                     'This is almost certainly a bad idea.\n')
+
+    sys.stderr.write('Type y to continue: ')
+    if read_from_tty() != 'y':
+      return 1
+
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(Main())