You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			145 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			145 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
#!/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, 8)
 | 
						|
# 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())
 |