summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2023-10-14 01:25:50 +0545
committerLUCI <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-10-13 20:52:46 +0000
commit3b8f9535c772178d8adeb1e0e4fc5916e311490a (patch)
treeda9f8c3bcf723d6ed0019b8d3ce3461c50894555
parent8f4f98582ef5f99db96e383400c3acf85e0eeb52 (diff)
downloadgit-repo-3b8f9535c772178d8adeb1e0e4fc5916e311490a.tar.gz
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 <aravindvasudev@google.com> Tested-by: Mike Frysinger <vapier@google.com> Commit-Queue: Mike Frysinger <vapier@google.com>
-rw-r--r--hooks.py63
1 files 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 @@
12# See the License for the specific language governing permissions and 12# See the License for the specific language governing permissions and
13# limitations under the License. 13# limitations under the License.
14 14
15import errno
16import json
17import os 15import os
18import re 16import re
19import subprocess
20import sys 17import sys
21import traceback 18import traceback
22import urllib.parse 19import urllib.parse
@@ -298,43 +295,6 @@ class RepoHook(object):
298 295
299 return interp 296 return interp
300 297
301 def _ExecuteHookViaReexec(self, interp, context, **kwargs):
302 """Execute the hook script through |interp|.
303
304 Note: Support for this feature should be dropped ~Jun 2021.
305
306 Args:
307 interp: The Python program to run.
308 context: Basic Python context to execute the hook inside.
309 kwargs: Arbitrary arguments to pass to the hook script.
310
311 Raises:
312 HookError: When the hooks failed for any reason.
313 """
314 # This logic needs to be kept in sync with _ExecuteHookViaImport below.
315 script = """
316import json, os, sys
317path = '''%(path)s'''
318kwargs = json.loads('''%(kwargs)s''')
319context = json.loads('''%(context)s''')
320sys.path.insert(0, os.path.dirname(path))
321data = open(path).read()
322exec(compile(data, path, 'exec'), context)
323context['main'](**kwargs)
324""" % {
325 "path": self._script_fullpath,
326 "kwargs": json.dumps(kwargs),
327 "context": json.dumps(context),
328 }
329
330 # We pass the script via stdin to avoid OS argv limits. It also makes
331 # unhandled exception tracebacks less verbose/confusing for users.
332 cmd = [interp, "-c", "import sys; exec(sys.stdin.read())"]
333 proc = subprocess.Popen(cmd, stdin=subprocess.PIPE)
334 proc.communicate(input=script.encode("utf-8"))
335 if proc.returncode:
336 raise HookError("Failed to run %s hook." % (self._hook_type,))
337
338 def _ExecuteHookViaImport(self, data, context, **kwargs): 298 def _ExecuteHookViaImport(self, data, context, **kwargs):
339 """Execute the hook code in |data| directly. 299 """Execute the hook code in |data| directly.
340 300
@@ -412,30 +372,13 @@ context['main'](**kwargs)
412 # See what version of python the hook has been written against. 372 # See what version of python the hook has been written against.
413 data = open(self._script_fullpath).read() 373 data = open(self._script_fullpath).read()
414 interp = self._ExtractInterpFromShebang(data) 374 interp = self._ExtractInterpFromShebang(data)
415 reexec = False
416 if interp: 375 if interp:
417 prog = os.path.basename(interp) 376 prog = os.path.basename(interp)
418 if prog.startswith("python2") and sys.version_info.major != 2: 377 if prog.startswith("python2"):
419 reexec = True 378 raise HookError("Python 2 is not supported")
420 elif prog.startswith("python3") and sys.version_info.major == 2:
421 reexec = True
422
423 # Attempt to execute the hooks through the requested version of
424 # Python.
425 if reexec:
426 try:
427 self._ExecuteHookViaReexec(interp, context, **kwargs)
428 except OSError as e:
429 if e.errno == errno.ENOENT:
430 # We couldn't find the interpreter, so fallback to
431 # importing.
432 reexec = False
433 else:
434 raise
435 379
436 # Run the hook by importing directly. 380 # Run the hook by importing directly.
437 if not reexec: 381 self._ExecuteHookViaImport(data, context, **kwargs)
438 self._ExecuteHookViaImport(data, context, **kwargs)
439 finally: 382 finally:
440 # Restore sys.path and CWD. 383 # Restore sys.path and CWD.
441 sys.path = orig_syspath 384 sys.path = orig_syspath