From 3b8f9535c772178d8adeb1e0e4fc5916e311490a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 14 Oct 2023 01:25:50 +0545 Subject: [PATCH] hooks: drop support for Python 2 Stop running old repohooks via python2. Abort immediately with a clear error for the user. Bug: 302871152 Change-Id: I750c6cbbf3c7950e249512bb1bd023c32587eef5 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/389454 Reviewed-by: Aravind Vasudevan Tested-by: Mike Frysinger Commit-Queue: Mike Frysinger --- hooks.py | 63 +++----------------------------------------------------- 1 file changed, 3 insertions(+), 60 deletions(-) diff --git a/hooks.py b/hooks.py index decf0699..337c2627 100644 --- a/hooks.py +++ b/hooks.py @@ -12,11 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -import errno -import json import os import re -import subprocess import sys import traceback import urllib.parse @@ -298,43 +295,6 @@ class RepoHook(object): return interp - def _ExecuteHookViaReexec(self, interp, context, **kwargs): - """Execute the hook script through |interp|. - - Note: Support for this feature should be dropped ~Jun 2021. - - Args: - interp: The Python program to run. - context: Basic Python context to execute the hook inside. - kwargs: Arbitrary arguments to pass to the hook script. - - Raises: - HookError: When the hooks failed for any reason. - """ - # This logic needs to be kept in sync with _ExecuteHookViaImport below. - script = """ -import json, os, sys -path = '''%(path)s''' -kwargs = json.loads('''%(kwargs)s''') -context = json.loads('''%(context)s''') -sys.path.insert(0, os.path.dirname(path)) -data = open(path).read() -exec(compile(data, path, 'exec'), context) -context['main'](**kwargs) -""" % { - "path": self._script_fullpath, - "kwargs": json.dumps(kwargs), - "context": json.dumps(context), - } - - # We pass the script via stdin to avoid OS argv limits. It also makes - # unhandled exception tracebacks less verbose/confusing for users. - cmd = [interp, "-c", "import sys; exec(sys.stdin.read())"] - proc = subprocess.Popen(cmd, stdin=subprocess.PIPE) - proc.communicate(input=script.encode("utf-8")) - if proc.returncode: - raise HookError("Failed to run %s hook." % (self._hook_type,)) - def _ExecuteHookViaImport(self, data, context, **kwargs): """Execute the hook code in |data| directly. @@ -412,30 +372,13 @@ context['main'](**kwargs) # See what version of python the hook has been written against. data = open(self._script_fullpath).read() interp = self._ExtractInterpFromShebang(data) - reexec = False if interp: prog = os.path.basename(interp) - if prog.startswith("python2") and sys.version_info.major != 2: - reexec = True - elif prog.startswith("python3") and sys.version_info.major == 2: - reexec = True - - # Attempt to execute the hooks through the requested version of - # Python. - if reexec: - try: - self._ExecuteHookViaReexec(interp, context, **kwargs) - except OSError as e: - if e.errno == errno.ENOENT: - # We couldn't find the interpreter, so fallback to - # importing. - reexec = False - else: - raise + if prog.startswith("python2"): + raise HookError("Python 2 is not supported") # Run the hook by importing directly. - if not reexec: - self._ExecuteHookViaImport(data, context, **kwargs) + self._ExecuteHookViaImport(data, context, **kwargs) finally: # Restore sys.path and CWD. sys.path = orig_syspath