Snap for 7024209 from ea6c7d7c9177be09d2386ae4adc319b62193b39c to androidx-master-release

Change-Id: I894dbdb67e16702a3d35493be0ba394b0e1ff420
diff --git a/pre-upload.py b/pre-upload.py
index eaf611e..0e032f4 100755
--- a/pre-upload.py
+++ b/pre-upload.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,8 +19,6 @@
 when developing.
 """
 
-from __future__ import print_function
-
 import argparse
 import datetime
 import os
@@ -65,6 +62,9 @@
     FAILED = COLOR.color(COLOR.RED, 'FAILED')
     WARNING = COLOR.color(COLOR.YELLOW, 'WARNING')
 
+    # How long a hook is allowed to run before we warn that it is "too slow".
+    _SLOW_HOOK_DURATION = datetime.timedelta(seconds=30)
+
     def __init__(self, project_name):
         """Create a new Output object for a specified project.
 
@@ -76,6 +76,8 @@
         self.hook_index = 0
         self.success = True
         self.start_time = datetime.datetime.now()
+        self.hook_start_time = None
+        self._curr_hook_name = None
 
     def set_num_hooks(self, num_hooks):
         """Keep track of how many hooks we'll be running.
@@ -102,28 +104,38 @@
         Args:
           hook_name: name of the hook.
         """
+        self._curr_hook_name = hook_name
+        self.hook_start_time = datetime.datetime.now()
         status_line = '[%s %d/%d] %s' % (self.RUNNING, self.hook_index,
                                          self.num_hooks, hook_name)
         self.hook_index += 1
         rh.terminal.print_status_line(status_line)
 
-    def hook_error(self, hook_name, error):
+    def hook_finish(self):
+        """Finish processing any per-hook state."""
+        duration = datetime.datetime.now() - self.hook_start_time
+        if duration >= self._SLOW_HOOK_DURATION:
+            self.hook_warning(
+                'This hook took %s to finish which is fairly slow for '
+                'developers.\nPlease consider moving the check to the '
+                'server/CI system instead.' %
+                (rh.utils.timedelta_str(duration),))
+
+    def hook_error(self, error):
         """Print an error for a single hook.
 
         Args:
-          hook_name: name of the hook.
           error: error string.
         """
-        self.error(hook_name, error)
+        self.error(self._curr_hook_name, error)
 
-    def hook_warning(self, hook_name, warning):
+    def hook_warning(self, warning):
         """Print a warning for a single hook.
 
         Args:
-          hook_name: name of the hook.
           warning: warning string.
         """
-        status_line = '[%s] %s' % (self.WARNING, hook_name)
+        status_line = '[%s] %s' % (self.WARNING, self._curr_hook_name)
         rh.terminal.print_status_line(status_line, print_newline=True)
         print(warning, file=sys.stderr)
 
@@ -306,13 +318,14 @@
             if rel_proj_dir in exclusion_scope:
                 break
             hook_results = hook(project, commit, desc, diff)
+            output.hook_finish()
             (error, warning) = _process_hook_results(hook_results)
             if error is not None or warning is not None:
                 if warning is not None:
-                    output.hook_warning(name, warning)
+                    output.hook_warning(warning)
                 if error is not None:
                     ret = False
-                    output.hook_error(name, error)
+                    output.hook_error(error)
                 for result in hook_results:
                     if result.fixup_func:
                         fixup_func_list.append((name, commit,
diff --git a/rh/__init__.py b/rh/__init__.py
index c36cb89..9050fb6 100644
--- a/rh/__init__.py
+++ b/rh/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +14,6 @@
 
 """Common repohook objects/constants."""
 
-from __future__ import print_function
-
 import collections
 
 
diff --git a/rh/config.py b/rh/config.py
index b75e03b..ed75007 100644
--- a/rh/config.py
+++ b/rh/config.py
@@ -1,4 +1,3 @@
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +14,6 @@
 
 """Manage various config files."""
 
-from __future__ import print_function
-
 import configparser
 import functools
 import itertools
diff --git a/rh/config_test.py b/rh/config_test.py
index 794e50f..80fc832 100755
--- a/rh/config_test.py
+++ b/rh/config_test.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +15,6 @@
 
 """Integration tests for the config module (via PREUPLOAD.cfg)."""
 
-from __future__ import print_function
-
 import argparse
 import os
 import re
diff --git a/rh/config_unittest.py b/rh/config_unittest.py
index 4b27c5a..3e3e470 100755
--- a/rh/config_unittest.py
+++ b/rh/config_unittest.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +15,6 @@
 
 """Unittests for the config module."""
 
-from __future__ import print_function
-
 import os
 import shutil
 import sys
diff --git a/rh/git.py b/rh/git.py
index da9d55c..ab1e35f 100644
--- a/rh/git.py
+++ b/rh/git.py
@@ -1,4 +1,3 @@
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +14,6 @@
 
 """Git helper functions."""
 
-from __future__ import print_function
-
 import os
 import re
 import sys
diff --git a/rh/hooks.py b/rh/hooks.py
index 66aa030..8cea251 100644
--- a/rh/hooks.py
+++ b/rh/hooks.py
@@ -1,4 +1,3 @@
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +14,6 @@
 
 """Functions that implement the actual checks."""
 
-from __future__ import print_function
-
 import collections
 import fnmatch
 import json
diff --git a/rh/hooks_unittest.py b/rh/hooks_unittest.py
index 87d2820..716e1da 100755
--- a/rh/hooks_unittest.py
+++ b/rh/hooks_unittest.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +15,6 @@
 
 """Unittests for the hooks module."""
 
-from __future__ import print_function
-
 import os
 import sys
 import unittest
diff --git a/rh/results.py b/rh/results.py
index bdac83c..bdf7626 100644
--- a/rh/results.py
+++ b/rh/results.py
@@ -1,4 +1,3 @@
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +14,6 @@
 
 """Common errors thrown when repo preupload checks fail."""
 
-from __future__ import print_function
-
 import os
 import sys
 
diff --git a/rh/shell.py b/rh/shell.py
index 4c6c45c..dda3be3 100644
--- a/rh/shell.py
+++ b/rh/shell.py
@@ -1,4 +1,3 @@
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +14,6 @@
 
 """Functions for working with shell code."""
 
-from __future__ import print_function
-
 import os
 import sys
 
diff --git a/rh/shell_unittest.py b/rh/shell_unittest.py
index 47182a5..21478cf 100755
--- a/rh/shell_unittest.py
+++ b/rh/shell_unittest.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +15,6 @@
 
 """Unittests for the shell module."""
 
-from __future__ import print_function
-
 import difflib
 import os
 import sys
diff --git a/rh/signals.py b/rh/signals.py
index 45d4e8a..c8a8d81 100644
--- a/rh/signals.py
+++ b/rh/signals.py
@@ -1,4 +1,3 @@
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +14,6 @@
 
 """Signal related functionality."""
 
-from __future__ import print_function
-
 import os
 import signal
 import sys
diff --git a/rh/terminal.py b/rh/terminal.py
index c549f12..39c96ac 100644
--- a/rh/terminal.py
+++ b/rh/terminal.py
@@ -1,4 +1,3 @@
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,8 +17,6 @@
 This module handles terminal interaction including ANSI color codes.
 """
 
-from __future__ import print_function
-
 import os
 import sys
 
diff --git a/rh/utils.py b/rh/utils.py
index 5c3e753..1b36c7a 100644
--- a/rh/utils.py
+++ b/rh/utils.py
@@ -1,4 +1,3 @@
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +14,6 @@
 
 """Various utility functions."""
 
-from __future__ import print_function
-
 import errno
 import functools
 import os
diff --git a/rh/utils_unittest.py b/rh/utils_unittest.py
index bddb0e7..f3098a9 100755
--- a/rh/utils_unittest.py
+++ b/rh/utils_unittest.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +15,6 @@
 
 """Unittests for the utils module."""
 
-from __future__ import print_function
-
 import datetime
 import os
 import sys
diff --git a/tools/android_test_mapping_format.py b/tools/android_test_mapping_format.py
index 47e09c5..b87b886 100755
--- a/tools/android_test_mapping_format.py
+++ b/tools/android_test_mapping_format.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2018 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,8 +22,6 @@
    import TEST_MAPPING files.
 """
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
diff --git a/tools/android_test_mapping_format_unittest.py b/tools/android_test_mapping_format_unittest.py
index 9191a25..9bef300 100755
--- a/tools/android_test_mapping_format_unittest.py
+++ b/tools/android_test_mapping_format_unittest.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2018 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tools/clang-format.py b/tools/clang-format.py
index 958f543..2533b15 100755
--- a/tools/clang-format.py
+++ b/tools/clang-format.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +15,6 @@
 
 """Wrapper to run git-clang-format and parse its output."""
 
-from __future__ import print_function
-
 import argparse
 import os
 import sys
diff --git a/tools/google-java-format.py b/tools/google-java-format.py
index 5a537c0..6659511 100755
--- a/tools/google-java-format.py
+++ b/tools/google-java-format.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +15,6 @@
 
 """Wrapper to run google-java-format to check for any malformatted changes."""
 
-from __future__ import print_function
-
 import argparse
 import os
 import sys
diff --git a/tools/pylint.py b/tools/pylint.py
index 8af1adc..60f4b67 100755
--- a/tools/pylint.py
+++ b/tools/pylint.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding:utf-8 -*-
 # Copyright 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +15,6 @@
 
 """Wrapper to run pylint with the right settings."""
 
-from __future__ import print_function
-
 import argparse
 import errno
 import os