From 53a63639432e1bc29c95fd066f9f387ce07fd0d0 Mon Sep 17 00:00:00 2001 From: Chad Norvell Date: Sat, 18 Feb 2023 00:45:28 +0000 Subject: [PATCH] pw_ide: .activate can be imported outside of env This module couldn't be imported outside of Pigweed/an activated Pigweed environment without raising an exception. However, the module needs to be imported by Sphinx during the docs build since it's used to generate the `pw_ide` API docs. This wasn't a problem for our own Sphinx build, but it was a problem for other tools that do a Sphinx build outside of our own (e.g. the esbonio LSP). Anyway, now you can import this file without exceptions. Exceptions will only be raised if you try to execute specific functionality that requires the Pigweed environment. Change-Id: I06fcf39f770176710df0bbc1a739077fca159835 Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/129112 Commit-Queue: Chad Norvell Reviewed-by: Anthony DiGirolamo --- pw_ide/py/pw_ide/activate.py | 49 ++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/pw_ide/py/pw_ide/activate.py b/pw_ide/py/pw_ide/activate.py index d6e34ff9e..082543bde 100644 --- a/pw_ide/py/pw_ide/activate.py +++ b/pw_ide/py/pw_ide/activate.py @@ -64,7 +64,7 @@ import shlex import subprocess import sys -from typing import Dict, Optional +from typing import cast, Dict, Optional # This expects this file to be in the Python module. If it ever moves # (e.g. to the root of the repository), this will need to change. @@ -75,7 +75,14 @@ ) -def assumed_environment_root() -> Path: +def assumed_environment_root() -> Optional[Path]: + """Infer the path to the Pigweed environment directory. + + First we look at the environment variable that should contain the path if + we're operating in an activated Pigweed environment. If we don't find the + path there, we check a few known locations. If we don't find an environment + directory in any of those locations, we return None. + """ actual_environment_root = os.environ.get('_PW_ACTUAL_ENVIRONMENT_ROOT') if ( actual_environment_root is not None @@ -91,12 +98,22 @@ def assumed_environment_root() -> Path: if default_dot_environment.exists(): return default_dot_environment.absolute() - raise RuntimeError( - 'This must be run from a bootstrapped Pigweed directory!' - ) - - -_DEFAULT_CONFIG_FILE_PATH = assumed_environment_root() / 'actions.json' + return None + + +# We're looking for the `actions.json` file that allows us to activate the +# Pigweed environment. That file is located in the Pigweed environment +# directory, so if we found an environment directory, this variable will +# have the path to `actions.json`. If it doesn't find an environment directory +# (e.g., this isn't being executed in the context of a Pigweed project), this +# will be None. Note that this is the "default" config file path because +# callers of functions that need this path can provide their own paths to an +# `actions.json` file. +_DEFAULT_CONFIG_FILE_PATH = ( + None + if assumed_environment_root() is None + else cast(Path, assumed_environment_root()) / 'actions.json' +) def _sanitize_path( @@ -207,12 +224,17 @@ def do_effect(self, effect: str): def modify_env( self, - config_file_path: Path = _DEFAULT_CONFIG_FILE_PATH, + config_file_path: Optional[Path] = _DEFAULT_CONFIG_FILE_PATH, sanitize: bool = False, ) -> 'ShellModifier': """Modify the current shell state per the actions.json file provided.""" json_file_options = {} + if config_file_path is None: + raise RuntimeError( + 'This must be run from a bootstrapped Pigweed directory!' + ) + with config_file_path.open('r') as json_file: json_file_options = json.loads(json_file.read()) @@ -310,6 +332,13 @@ def _build_argument_parser() -> argparse.ArgumentParser: description=doc, ) + default_config_file_path = None + + if _DEFAULT_CONFIG_FILE_PATH is not None: + default_config_file_path = _DEFAULT_CONFIG_FILE_PATH.relative_to( + Path.cwd() + ) + parser.add_argument( '-c', '--config-file', @@ -318,7 +347,7 @@ def _build_argument_parser() -> argparse.ArgumentParser: help='Path to actions.json config file, which defines ' 'the modifications to the shell environment ' 'needed to activate Pigweed. ' - f'Default: {_DEFAULT_CONFIG_FILE_PATH.relative_to(Path.cwd())}', + f'Default: {default_config_file_path}', ) default_shell = Path(os.environ['SHELL']).name