123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- #!/usr/bin/env python3
- # Copyright 2011 The ChromiumOS Authors
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """Wrapper for chromite tools.
- The script is intend to be symlinked to any number of chromite tools, attempts
- to find the path for chromite, and hands off to the right tool via exec if
- possible.
- It is intended to used strictly outside of the chroot.
- """
- import enum
- import os
- from pathlib import Path
- import subprocess
- import sys
- from typing import List, NamedTuple, Optional, Tuple
- # Min version of Python that we *want*. We warn for older versions.
- MIN_PYTHON_VER_SOFT = (3, 11)
- # Min version of Python that we *require*. We abort for older versions.
- MIN_PYTHON_VER_HARD = (3, 8)
- DEPOT_TOOLS_DIR = Path(__file__).resolve().parent
- # Directory where cros-specific CIPD packages are installed.
- CIPD_CACHE_DIR = DEPOT_TOOLS_DIR / '.cipd_bin_cros_python2'
- class Checkout(NamedTuple):
- """Some details about this checkout."""
- root: Path
- chromite_dir: Path
- def _FindChromite(path: Path) -> Optional[Checkout]:
- """Find the chromite dir in a repo, gclient, or submodule checkout."""
- path = path.resolve()
- # Depending on the checkout type (whether repo chromeos or gclient chrome)
- # Chromite lives in a different location.
- roots = (
- # CrOS checkout using normal manifest.
- ('.repo', 'chromite/.git'),
- # CrOS checkout using CitC.
- ('../.citc', 'chromite/__init__.py'),
- # Chromium checkout using gclient+DEPS.
- ('.gclient', 'src/third_party/chromite/.git'),
- # Chromium checkout using git submodules (submodules at root).
- ('.gitmodules', 'chromite/.git'),
- # Chromium checkout using git submodules.
- ('src/.gitmodules', 'src/third_party/chromite/.git'),
- # Chromium checkout using CitC.
- ('../.citc', 'third_party/chromite/__init__.py'),
- )
- while path != Path("/"):
- for root, chromite_git_dir in roots:
- if all((path / x).exists() for x in [root, chromite_git_dir]):
- return Checkout(path, (path / chromite_git_dir).parent)
- path = path.parent
- return None
- def _MissingErrorOut(target):
- sys.stderr.write("""ERROR: Couldn't find the chromite tool %s.
- Please change to a directory inside your ChromiumOS source tree
- and retry. If you need to setup a ChromiumOS source tree, see
- https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_guide.md
- """ % target)
- return 127
- def _CheckPythonVersion():
- """Verify active Python is new enough."""
- if sys.version_info >= MIN_PYTHON_VER_SOFT:
- return
- progname = os.path.basename(sys.argv[0])
- print('%s: ChromiumOS requires Python-%s+, but "%s" is "%s"' %
- (progname, '.'.join(str(x) for x in MIN_PYTHON_VER_SOFT),
- sys.executable, sys.version.replace('\n', ' ')),
- file=sys.stderr)
- if sys.version_info < MIN_PYTHON_VER_HARD:
- print('%s: fatal: giving up since Python is too old.' % (progname, ),
- file=sys.stderr)
- sys.exit(1)
- print(
- 'warning: temporarily continuing anyways; you must upgrade soon to '
- 'maintain support.',
- file=sys.stderr)
- def _BootstrapVpython27():
- """Installs the vpython2.7 packages into the cipd cache directory."""
- subprocess.run([
- 'cipd', 'ensure', '-log-level', 'info', '-ensure-file',
- DEPOT_TOOLS_DIR / 'cipd_manifest_cros_python2.txt', '-root',
- CIPD_CACHE_DIR
- ],
- check=True)
- def main():
- _CheckPythonVersion()
- result = _FindChromite(Path.cwd())
- target = os.path.basename(sys.argv[0])
- if result is None:
- return _MissingErrorOut(target)
- root, chromite_dir = result
- is_citc = (root.parent / ".citc").is_dir()
- if is_citc:
- # citc workspaces don't like dirty files like pyc.
- os.environ["PYTHONDONTWRITEBYTECODE"] = "1"
- path = chromite_dir / "bin" / target
- # Check to see if this is a script requiring vpython2.7.
- with path.open("rb") as fp:
- shebang = next(fp).strip()
- interpreter = shebang.split()[-1]
- if interpreter in (b'python', b'python2', b'python2.7', b'vpython'):
- _BootstrapVpython27()
- vpython = CIPD_CACHE_DIR / 'vpython'
- args = [vpython]
- if interpreter != b'vpython':
- args.extend(
- ['-vpython-spec', DEPOT_TOOLS_DIR / 'cros_python2.vpython'])
- args.append(path)
- path = vpython
- else:
- args = [path]
- os.execv(path, args + sys.argv[1:])
- if __name__ == '__main__':
- sys.exit(main())
|