diff options
author | Mike Frysinger <vapier@google.com> | 2021-01-04 21:55:26 -0500 |
---|---|---|
committer | Mike Frysinger <vapier@google.com> | 2021-01-05 22:18:24 +0000 |
commit | 47692019b326a8c47aa579c0d9b92e0a3871800a (patch) | |
tree | 1fcc3a08becae0054554fba83fd29336d6f1184e | |
parent | 1469c28ec3e221cf08a9f83a415945443eac0be4 (diff) | |
download | git-repo-47692019b326a8c47aa579c0d9b92e0a3871800a.tar.gz |
launcher: support Python 3.5 for now
The codebase still supports Python 3.5, so allow use of that instead
of requiring Python 3.6+. Supporting this mode well is a bit tricky
as we want to first scan for newer versions before falling back to
older ones. And we have to avoid infinite loops in the process.
Bug: https://crbug.com/gerrit/13795
Change-Id: I47949a173899bfa9ab20d3fefa1a97bf002659f6
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/292442
Reviewed-by: Michael Mortensen <mmortensen@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
-rwxr-xr-x | repo | 33 |
1 files changed, 23 insertions, 10 deletions
@@ -32,6 +32,13 @@ import subprocess | |||
32 | import sys | 32 | import sys |
33 | 33 | ||
34 | 34 | ||
35 | # These should never be newer than the main.py version since this needs to be a | ||
36 | # bit more flexible with older systems. See that file for more details on the | ||
37 | # versions we select. | ||
38 | MIN_PYTHON_VERSION_SOFT = (3, 6) | ||
39 | MIN_PYTHON_VERSION_HARD = (3, 5) | ||
40 | |||
41 | |||
35 | # Keep basic logic in sync with repo_trace.py. | 42 | # Keep basic logic in sync with repo_trace.py. |
36 | class Trace(object): | 43 | class Trace(object): |
37 | """Trace helper logic.""" | 44 | """Trace helper logic.""" |
@@ -70,8 +77,6 @@ def check_python_version(): | |||
70 | def reexec(prog): | 77 | def reexec(prog): |
71 | exec_command([prog] + sys.argv) | 78 | exec_command([prog] + sys.argv) |
72 | 79 | ||
73 | MIN_PYTHON_VERSION = (3, 6) | ||
74 | |||
75 | ver = sys.version_info | 80 | ver = sys.version_info |
76 | major = ver.major | 81 | major = ver.major |
77 | minor = ver.minor | 82 | minor = ver.minor |
@@ -80,17 +85,24 @@ def check_python_version(): | |||
80 | if (major, minor) < (2, 7): | 85 | if (major, minor) < (2, 7): |
81 | print('repo: error: Your Python version is too old. ' | 86 | print('repo: error: Your Python version is too old. ' |
82 | 'Please use Python {}.{} or newer instead.'.format( | 87 | 'Please use Python {}.{} or newer instead.'.format( |
83 | *MIN_PYTHON_VERSION), file=sys.stderr) | 88 | *MIN_PYTHON_VERSION_SOFT), file=sys.stderr) |
84 | sys.exit(1) | 89 | sys.exit(1) |
85 | 90 | ||
86 | # Try to re-exec the version specific Python 3 if needed. | 91 | # Try to re-exec the version specific Python 3 if needed. |
87 | if (major, minor) < MIN_PYTHON_VERSION: | 92 | if (major, minor) < MIN_PYTHON_VERSION_SOFT: |
88 | # Python makes releases ~once a year, so try our min version +10 to help | 93 | # Python makes releases ~once a year, so try our min version +10 to help |
89 | # bridge the gap. This is the fallback anyways so perf isn't critical. | 94 | # bridge the gap. This is the fallback anyways so perf isn't critical. |
90 | min_major, min_minor = MIN_PYTHON_VERSION | 95 | min_major, min_minor = MIN_PYTHON_VERSION_SOFT |
91 | for inc in range(0, 10): | 96 | for inc in range(0, 10): |
92 | reexec('python{}.{}'.format(min_major, min_minor + inc)) | 97 | reexec('python{}.{}'.format(min_major, min_minor + inc)) |
93 | 98 | ||
99 | # Fallback to older versions if possible. | ||
100 | for inc in range(MIN_PYTHON_VERSION_SOFT[1] - MIN_PYTHON_VERSION_HARD[1], 0, -1): | ||
101 | # Don't downgrade, and don't reexec ourselves (which would infinite loop). | ||
102 | if (min_major, min_minor - inc) <= (major, minor): | ||
103 | break | ||
104 | reexec('python{}.{}'.format(min_major, min_minor - inc)) | ||
105 | |||
94 | # Try the generic Python 3 wrapper, but only if it's new enough. We don't | 106 | # Try the generic Python 3 wrapper, but only if it's new enough. We don't |
95 | # want to go from (still supported) Python 2.7 to (unsupported) Python 3.5. | 107 | # want to go from (still supported) Python 2.7 to (unsupported) Python 3.5. |
96 | try: | 108 | try: |
@@ -103,18 +115,19 @@ def check_python_version(): | |||
103 | except (OSError, subprocess.CalledProcessError): | 115 | except (OSError, subprocess.CalledProcessError): |
104 | python3_ver = None | 116 | python3_ver = None |
105 | 117 | ||
106 | # The python3 version looks like it's new enough, so give it a try. | 118 | # If the python3 version looks like it's new enough, give it a try. |
107 | if python3_ver and python3_ver >= MIN_PYTHON_VERSION: | 119 | if (python3_ver and python3_ver >= MIN_PYTHON_VERSION_HARD |
120 | and python3_ver != (major, minor)): | ||
108 | reexec('python3') | 121 | reexec('python3') |
109 | 122 | ||
110 | # We're still here, so diagnose things for the user. | 123 | # We're still here, so diagnose things for the user. |
111 | if major < 3: | 124 | if major < 3: |
112 | print('repo: warning: Python 2 is no longer supported; ' | 125 | print('repo: warning: Python 2 is no longer supported; ' |
113 | 'Please upgrade to Python {}.{}+.'.format(*MIN_PYTHON_VERSION), | 126 | 'Please upgrade to Python {}.{}+.'.format(*MIN_PYTHON_VERSION_HARD), |
114 | file=sys.stderr) | 127 | file=sys.stderr) |
115 | else: | 128 | elif (major, minor) < MIN_PYTHON_VERSION_HARD: |
116 | print('repo: error: Python 3 version is too old; ' | 129 | print('repo: error: Python 3 version is too old; ' |
117 | 'Please use Python {}.{} or newer.'.format(*MIN_PYTHON_VERSION), | 130 | 'Please use Python {}.{} or newer.'.format(*MIN_PYTHON_VERSION_HARD), |
118 | file=sys.stderr) | 131 | file=sys.stderr) |
119 | sys.exit(1) | 132 | sys.exit(1) |
120 | 133 | ||