Skip to content

Commit d1fb988

Browse files
committed
Checkpoint from VS Code for coding agent session
1 parent c585b90 commit d1fb988

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

docs/pyenv-manager.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
## Overview (high-level)
2+
3+
The pyenv manager provides discovery, enumeration, selection, and metadata for Python environments installed and managed by the `pyenv` tool. It plugs into the extension's environment manager abstraction so other parts of the extension (pickers, environment API consumers, telemetry) see a consistent view of pyenv-managed interpreters.
4+
5+
Primary files:
6+
7+
- `src/managers/pyenv/main.ts` — manager registration and lifecycle hook (registration with the manager registry).
8+
- `src/managers/pyenv/pyenvManager.ts` — the manager implementation (class `PyEnvManager`). Key methods to inspect:
9+
- `initialize()` — discovers environments at startup.
10+
- `getEnvironments(scope)` — returns cached environments; supports `all`, `global`, and per-URI lookup.
11+
- `refresh(context)` — re-runs discovery and emits environment change events.
12+
- `get(scope)` / `set(scope, environment)` — workspace/global selection helpers.
13+
- `resolve(context)` — attempt to resolve a pyenv path to a `PythonEnvironment` and add it to the collection.
14+
- `clearCache()` — clears persisted pyenv selections.
15+
- `loadEnvMap()` — internal mapping between project folders and resolved environments.
16+
- `src/managers/pyenv/pyenvUtils.ts` — low-level helpers and command wrappers. Important exported functions and constants you should be aware of:
17+
- `refreshPyenv(...)` — performs the subprocess calls to `pyenv` and parses results.
18+
- `resolvePyenvPath(...)` — resolve a path supplied by user/workspace to a canonical interpreter `PythonEnvironment`.
19+
- `getPyenvForGlobal()`, `getPyenvForWorkspace()` / `setPyenvForWorkspace()` / `setPyenvForGlobal()` — persist and load user selections.
20+
- `clearPyenvCache()` — remove persisted selections.
21+
- `PYENV_VERSIONS` — group identifier used on environment entries.
22+
23+
Other integration points:
24+
- `src/common/pickers/environments.ts` — where environment entries from managers are presented in the UI.
25+
- `src/api.ts` and `src/extension.ts` — top-level APIs and registration that tie managers into the extension.
26+
27+
## Design goals
28+
29+
- Accurately discover pyenv versions and virtualenvs.
30+
- Provide stable, human-friendly metadata for each environment (id, displayName, version, type, interpreter path).
31+
- Cache results to avoid repeated heavy shell calls; run subprocesses asynchronously.
32+
- Handle shell initialization nuances that affect `pyenv` (shims and shell init scripts).
33+
- Work across macOS/Linux and Windows (including WSL) where possible.
34+
35+
## How discovery works (conceptual flow)
36+
37+
1. Manager availability check: verify `pyenv` is present (may require sourcing the user's shell configuration).
38+
2. Invoke low-level utils (e.g., `refreshPyenv`) which run `pyenv` commands to enumerate versions/virtualenvs.
39+
3. Parse `pyenv` output into `PythonEnvironment` objects that include interpreter path, group, and metadata.
40+
4. Add to the manager collection and build maps from project folders to environments.
41+
5. Expose results via the manager interface and emit change events when collection changes.
42+
43+
### Typical metadata produced for each environment
44+
- envId.id — stable identifier (e.g., `pyenv:3.8.10` or `pyenv:3.8.10:myenv`).
45+
- environmentPath — a `Uri` referencing the python executable.
46+
- version — parsed version string (when available).
47+
- displayName — friendly label shown in UI.
48+
- group — `PYENV_VERSIONS` (used for grouping in pickers).
49+
50+
## Platform and Windows/WSL considerations
51+
52+
- macOS/Linux: `pyenv` is commonly installed and initialized through shell startup files. The utils layer includes logic to run commands in a shell that sources the user's init files so pyenv shims resolve correctly.
53+
54+
- Windows: `pyenv` is not natively supported on Windows. Many Windows users run `pyenv` inside WSL. For these users:
55+
- If the extension is running in a Windows host but the project is inside WSL or a remote environment, discovery should be performed in that environment (follow the same pattern used for other managers under remote/WSL scenarios).
56+
- If `pyenv` is installed inside WSL, ensure subprocess invocations happen in WSL context (the utilities may need to be extended to shell out via `wsl.exe` or use the remote extension plumbing).
57+
- When running on Windows without WSL, mark pyenv as unavailable. The manager should gracefully no-op and not cause failures.
58+
59+
Be explicit in code when a path or command is intended for a remote/WSL environment; do not assume a single PATH behavior across platforms.
60+
61+
## Sequence diagram (high-level)
62+
63+
Here's a simple sequence diagram showing a typical discovery flow. This can be helpful when adding instrumentation or debugging:
64+
65+
```mermaid
66+
sequenceDiagram
67+
participant Manager as PyEnvManager
68+
participant Utils as pyenvUtils
69+
participant Shell as Shell/Subprocess
70+
participant API as PythonEnvironmentApi
71+
72+
Manager->>Utils: refreshPyenv(nativeFinder, api, self)
73+
Utils->>Shell: run `pyenv versions --bare` (sourced shell)
74+
Shell-->>Utils: stdout lines (versions)
75+
Utils->>Utils: parse lines -> PythonEnvironment[]
76+
Utils-->>Manager: return environments
77+
Manager->>API: loadEnvMap() (get/set workspace/global prefs)
78+
Manager->>Picker: emit onDidChangeEnvironments
79+
Picker-->>User: show updated environment list
80+
```
81+
82+
## Integration & consumers
83+
84+
Who uses the manager and where to update when changing interfaces:
85+
86+
- UI pickers: `src/common/pickers/environments.ts` — verify how environment objects are consumed and displayed.
87+
- Project-level selection: `src/managers/pyenv/pyenvManager.ts#set` and `loadEnvMap()` manage workspace/global mapping persisted via `pyenvUtils`.
88+
- Environment resolution used when a folder/URI is provided: `pyenvManager.resolve()` delegates to `resolvePyenvPath()`.
89+
90+
When adding features that alter environment object shapes, update both the manager and the pickers/consumers that rely on those fields.
91+
92+
## Debugging & tracing
93+
94+
- Enable trace logs and capture subprocess invocation details (command, env, cwd) and raw stdout/stderr when troubleshooting discovery/parsing issues.
95+
- Reproduce failing `pyenv` invocations in a terminal that matches the shell the extension uses (same login/non-login, same PATH and shell init files).
96+
- When `pyenv` returns unexpected output, capture the exact stdout and stderr and compare against what `pyenvUtils` expects to parse.
97+
98+
## Important implementation notes & gotchas (concise)
99+
100+
- Shell initialization: `pyenv` often requires shell init scripts to be sourced. The utils layer accounts for this; don't remove that logic without verifying discovery still works for typical user setups.
101+
- Shims vs real binaries: prefer resolving the real interpreter path rather than exposing the shim path to callers where feasible.
102+
- Virtualenv names and aliases: keep the raw pyenv value in metadata; normalize only for display.
103+
- Concurrency: avoid firing many simultaneous `pyenv` subprocesses — throttle or serialize as needed.
104+
105+
## File & symbol references (quick jump list)
106+
107+
- Manager class and methods: `src/managers/pyenv/pyenvManager.ts` (class `PyEnvManager`, methods listed earlier).
108+
- Low-level utils and exported helpers: `src/managers/pyenv/pyenvUtils.ts` (look for `refreshPyenv`, `resolvePyenvPath`, `getPyenvForGlobal`, `getPyenvForWorkspace`, `clearPyenvCache`).
109+
- Manager registration: `src/managers/pyenv/main.ts`.
110+
- UI pickers: `src/common/pickers/environments.ts`, `src/common/pickers/managers.ts`.
111+
- API surfaces: `src/api.ts`, `src/extension.ts`, and `src/common/*` interfaces used by managers.

0 commit comments

Comments
 (0)