EnvError
def EnvError(
*args, **kwargs
):Unspecified run-time error.
This module answers two questions every release step runs into: where a project’s tokens and settings are kept, and what environment a child command should run with.
An environment value is any named setting a build or a deploy needs, such as GITHUB_TOKEN or PORT. Some of them are secrets that should not sit in plain text. EnvStore keeps them through dockeasy, which puts secrets in the system keychain and every value in an env file (~/.config/fastops/.env unless you name another). dockeasy is imported the first time a value is read or written, not when this module loads.
When pullup runs inside a frozen desktop app, one built with py2app or a similar tool, the app’s launcher sets variables such as PYTHONHOME that point Python at the copy bundled inside the app. A child process that inherits them starts the wrong interpreter. BUNDLE_ONLY lists those variables. EnvError is raised when a value cannot be stored, or when dockeasy, which does the storing, is not installed.
A copy of this process’s environment with the frozen-app interpreter variables removed.
Remove the frozen-app interpreter variables from env when running frozen, and return it.
strip_bundle removes the BUNDLE_ONLY variables from an environment mapping and sets PYTHONUTF8=1. It changes the mapping you pass and returns that same mapping. By default it only does this when the current process is frozen; pass frozen=True or frozen=False to decide yourself, as the example does. clean_env covers the common case: a copy of this process’s environment with the bundle variables always removed.
{'PATH': '/usr/bin', 'HOME': '/Users/me', 'PYTHONUTF8': '1'}
A copy of env that runs commands in the virtual environment of python, or unchanged when python is None.
venv_env returns an environment that runs commands inside a particular virtual environment, much as source .venv/bin/activate would. Pass the path of that environment’s Python. It copies the mapping, sets VIRTUAL_ENV, puts the interpreter’s directory first on PATH, and drops PYTHONHOME and UV_PROJECT_ENVIRONMENT, either of which would send commands to a different interpreter. With no python the mapping comes back as a copy, passed only through strip_bundle.
('/repo/.venv', '/repo/.venv/bin:/usr/bin', False)
An error message for what that ends with the command that installs the missing library.
Set the package name that missing-library errors tell the reader to install.
Some of pullup’s features need another library, and the error raised when it is missing ends with the command that installs it. use_extra changes the package named in that command. A host application that bundles pullup calls it so that the message names the host’s own package. needs_extra builds the message and extra returns the name in use.
_dockeasy imports the four dockeasy functions the store uses, or raises EnvError with the install hint. Some dockeasy versions return coroutines from these functions, so _call runs whatever comes back to completion. It works whether or not an event loop is already running, which is the case inside Jupyter, and it re-raises any exception the call raised.
Read and write one project’s tokens and settings through dockeasy’s keychain and env file.
EnvStore reads and writes the values for one project.
get asks dockeasy for the key. For a secret dockeasy checks the keychain, then this process’s environment, then the env file; for an ordinary value it skips the keychain. A key found nowhere returns ''.set with secret=True, the default, writes the value to the keychain under service and to the env file. With secret=False it writes to the env file only. Either way dockeasy also puts it in os.environ.unset removes a key from the keychain, the env file and os.environ, and reports which of the first two held it.values reads several keys at once and leaves out the ones with no value. This is what a pipeline hands to a child process.'ghcr.io/example'
The examples use secret=False, so nothing touches the keychain.
{'PULLUP_DEMO_REGISTRY': 'ghcr.io/example'}
One value from an environment store, or default when it is unset or the store raises.
env_value is the forgiving read. It returns default when the key is unset and also when the store raises, for example because the keychain is locked. Unlike EnvStore.get, it reads ordinary values unless you pass secret=True. Use it wherever a missing value has a sensible fallback.