| #!/usr/bin/env python3 |
| |
| # Zephyr launcher which is interoperable with: |
| # |
| # 1. "mono-repo" Zephyr installations that have 'make flash' |
| # etc. supplied by a copy of some west code in scripts/meta. |
| # |
| # 2. "multi-repo" Zephyr installations where west is provided in a |
| # separate Git repository elsewhere. |
| # |
| # This is basically a copy of the "wrapper" functionality in the west |
| # bootstrap script for the multi-repo case, plus a fallback onto the |
| # copy in scripts/meta/west for mono-repo installs. |
| |
| import os |
| import subprocess |
| import sys |
| |
| import colorama |
| |
| if sys.version_info < (3,): |
| sys.exit('fatal error: you are running Python 2') |
| |
| # Top-level west directory, containing west itself and the manifest. |
| WEST_DIR = 'west' |
| # Subdirectory to check out the west source repository into. |
| WEST = 'west' |
| # File inside of WEST_DIR which marks it as the top level of the |
| # Zephyr project installation. |
| # |
| # (The WEST_DIR name is not distinct enough to use when searching for |
| # the top level; other directories named "west" may exist elsewhere, |
| # e.g. zephyr/doc/west.) |
| WEST_MARKER = '.west_topdir' |
| |
| |
| class WestError(RuntimeError): |
| pass |
| |
| |
| class WestNotFound(WestError): |
| '''Neither the current directory nor any parent has a West installation.''' |
| |
| |
| def find_west_topdir(start): |
| '''Find the top-level installation directory, starting at ``start``. |
| |
| If none is found, raises WestNotFound.''' |
| cur_dir = start |
| |
| while True: |
| if os.path.isfile(os.path.join(cur_dir, WEST_DIR, WEST_MARKER)): |
| return cur_dir |
| |
| parent_dir = os.path.dirname(cur_dir) |
| if cur_dir == parent_dir: |
| # At the root |
| raise WestNotFound('Could not find a West installation ' |
| 'in this or any parent directory') |
| cur_dir = parent_dir |
| |
| |
| def append_to_pythonpath(directory): |
| pp = os.environ.get('PYTHONPATH') |
| os.environ['PYTHONPATH'] = ':'.join(([pp] if pp else []) + [directory]) |
| |
| |
| def wrap(topdir, argv): |
| # Replace the wrapper process with the "real" west |
| |
| # sys.argv[1:] strips the argv[0] of the wrapper script itself |
| west_git_repo = os.path.join(topdir, WEST_DIR, WEST) |
| argv = ([sys.executable, |
| os.path.join(west_git_repo, 'src', 'west', 'main.py')] + |
| argv) |
| |
| try: |
| append_to_pythonpath(os.path.join(west_git_repo, 'src')) |
| subprocess.check_call(argv) |
| except subprocess.CalledProcessError as e: |
| sys.exit(e.returncode) |
| |
| |
| def run_scripts_meta_west(): |
| try: |
| subprocess.check_call([sys.executable, |
| os.path.join(os.environ['ZEPHYR_BASE'], |
| 'scripts', 'meta', 'west', |
| 'main.py')] + sys.argv[1:]) |
| except subprocess.CalledProcessError as e: |
| sys.exit(e.returncode) |
| |
| |
| def main(): |
| try: |
| topdir = find_west_topdir(__file__) |
| except WestNotFound: |
| topdir = None |
| |
| try: |
| if topdir is not None: |
| wrap(topdir, sys.argv[1:]) |
| else: |
| run_scripts_meta_west() |
| finally: |
| print(colorama.Fore.LIGHTRED_EX, end='') |
| print('NOTE: you just ran a copy of west from {};'. |
| format(os.path.dirname(__file__)), |
| 'this will be removed from the Zephyr repository in the future.', |
| 'West is now developed separately.') |
| print(colorama.Style.RESET_ALL, end='', flush=True) |
| |
| |
| if __name__ == '__main__': |
| main() |