showmyenv 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- showmyenv-1.0.0/.claude/settings.local.json +49 -0
- showmyenv-1.0.0/.gitignore +13 -0
- showmyenv-1.0.0/CLAUDE.md +97 -0
- showmyenv-1.0.0/LICENSE +21 -0
- showmyenv-1.0.0/PKG-INFO +224 -0
- showmyenv-1.0.0/PLAN.md +331 -0
- showmyenv-1.0.0/README.md +187 -0
- showmyenv-1.0.0/pyproject.toml +81 -0
- showmyenv-1.0.0/src/showmyenv/__init__.py +3 -0
- showmyenv-1.0.0/src/showmyenv/cli.py +349 -0
- showmyenv-1.0.0/src/showmyenv/collectors/__init__.py +1 -0
- showmyenv-1.0.0/src/showmyenv/collectors/cloud.py +117 -0
- showmyenv-1.0.0/src/showmyenv/collectors/docker.py +238 -0
- showmyenv-1.0.0/src/showmyenv/collectors/env_vars.py +126 -0
- showmyenv-1.0.0/src/showmyenv/collectors/ide.py +163 -0
- showmyenv-1.0.0/src/showmyenv/collectors/path_analyzer.py +152 -0
- showmyenv-1.0.0/src/showmyenv/collectors/ports.py +73 -0
- showmyenv-1.0.0/src/showmyenv/collectors/project.py +338 -0
- showmyenv-1.0.0/src/showmyenv/collectors/resolver.py +94 -0
- showmyenv-1.0.0/src/showmyenv/collectors/runtimes/__init__.py +54 -0
- showmyenv-1.0.0/src/showmyenv/collectors/runtimes/base.py +19 -0
- showmyenv-1.0.0/src/showmyenv/collectors/runtimes/dotnet.py +86 -0
- showmyenv-1.0.0/src/showmyenv/collectors/runtimes/go.py +101 -0
- showmyenv-1.0.0/src/showmyenv/collectors/runtimes/java.py +145 -0
- showmyenv-1.0.0/src/showmyenv/collectors/runtimes/node.py +129 -0
- showmyenv-1.0.0/src/showmyenv/collectors/runtimes/php.py +98 -0
- showmyenv-1.0.0/src/showmyenv/collectors/runtimes/python.py +148 -0
- showmyenv-1.0.0/src/showmyenv/collectors/runtimes/ruby.py +108 -0
- showmyenv-1.0.0/src/showmyenv/collectors/runtimes/rust.py +132 -0
- showmyenv-1.0.0/src/showmyenv/collectors/system.py +79 -0
- showmyenv-1.0.0/src/showmyenv/context.py +100 -0
- showmyenv-1.0.0/src/showmyenv/diagnostics/__init__.py +1 -0
- showmyenv-1.0.0/src/showmyenv/diagnostics/conflicts.py +153 -0
- showmyenv-1.0.0/src/showmyenv/diagnostics/doctor.py +139 -0
- showmyenv-1.0.0/src/showmyenv/diagnostics/health.py +174 -0
- showmyenv-1.0.0/src/showmyenv/diagnostics/root_cause.py +230 -0
- showmyenv-1.0.0/src/showmyenv/models.py +301 -0
- showmyenv-1.0.0/src/showmyenv/render/__init__.py +1 -0
- showmyenv-1.0.0/src/showmyenv/render/console.py +417 -0
- showmyenv-1.0.0/src/showmyenv/render/theme.py +29 -0
- showmyenv-1.0.0/src/showmyenv/report/__init__.py +1 -0
- showmyenv-1.0.0/src/showmyenv/report/compare.py +163 -0
- showmyenv-1.0.0/src/showmyenv/report/formatters/__init__.py +1 -0
- showmyenv-1.0.0/src/showmyenv/report/formatters/html.py +255 -0
- showmyenv-1.0.0/src/showmyenv/report/formatters/json_fmt.py +13 -0
- showmyenv-1.0.0/src/showmyenv/report/formatters/markdown.py +80 -0
- showmyenv-1.0.0/src/showmyenv/report/snapshot.py +31 -0
- showmyenv-1.0.0/tests/__init__.py +0 -0
- showmyenv-1.0.0/tests/collectors/__init__.py +0 -0
- showmyenv-1.0.0/tests/collectors/test_cloud.py +50 -0
- showmyenv-1.0.0/tests/collectors/test_docker.py +50 -0
- showmyenv-1.0.0/tests/collectors/test_ide.py +64 -0
- showmyenv-1.0.0/tests/collectors/test_path_analyzer.py +74 -0
- showmyenv-1.0.0/tests/collectors/test_project.py +75 -0
- showmyenv-1.0.0/tests/collectors/test_resolver.py +41 -0
- showmyenv-1.0.0/tests/collectors/test_runtimes_v2.py +86 -0
- showmyenv-1.0.0/tests/conftest.py +39 -0
- showmyenv-1.0.0/tests/diagnostics/__init__.py +0 -0
- showmyenv-1.0.0/tests/diagnostics/test_conflicts.py +87 -0
- showmyenv-1.0.0/tests/diagnostics/test_doctor.py +135 -0
- showmyenv-1.0.0/tests/diagnostics/test_health.py +105 -0
- showmyenv-1.0.0/tests/diagnostics/test_root_cause.py +148 -0
- showmyenv-1.0.0/tests/test_compare.py +125 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(python -m venv .venv)",
|
|
5
|
+
"Bash(.venv/bin/pip install *)",
|
|
6
|
+
"Bash(/usr/bin/python3 -m venv .venv)",
|
|
7
|
+
"Read(//opt/homebrew/bin/**)",
|
|
8
|
+
"Read(//usr/local/bin/**)",
|
|
9
|
+
"Bash(/opt/homebrew/bin/python3.13 -m venv .venv)",
|
|
10
|
+
"Bash(/opt/homebrew/bin/python3.11 -m venv .venv)",
|
|
11
|
+
"Bash(/opt/homebrew/bin/python3 -m venv .venv)",
|
|
12
|
+
"Bash(python3 -c \"import ensurepip; print\\(ensurepip.__version__\\)\")",
|
|
13
|
+
"Bash(/opt/homebrew/bin/python3 -m venv .venv --without-pip)",
|
|
14
|
+
"Bash(curl -sS https://bootstrap.pypa.io/get-pip.py)",
|
|
15
|
+
"Bash(.venv/bin/python3)",
|
|
16
|
+
"Bash(/opt/homebrew/bin/python3.11 --version)",
|
|
17
|
+
"Bash(/opt/homebrew/bin/python3.11 -c \"import ensurepip\")",
|
|
18
|
+
"Bash(/opt/homebrew/bin/python3.11 -m venv .venv --without-pip)",
|
|
19
|
+
"Bash(.venv/bin/python3.11 -m ensurepip)",
|
|
20
|
+
"Bash(/opt/homebrew/bin/python3.11 *)",
|
|
21
|
+
"Bash(.venv/bin/python3.11 -c \"import sys; sys.path.insert\\(0, '/opt/homebrew/lib/python3.11/site-packages'\\); import pip; print\\(pip.__version__\\)\")",
|
|
22
|
+
"Bash(/opt/homebrew/Cellar/python@3.13/3.13.13_1/bin/python3.13 --version)",
|
|
23
|
+
"Bash(/opt/homebrew/Cellar/python@3.13/3.13.13_1/bin/python3.13 -m ensurepip)",
|
|
24
|
+
"Bash(/opt/homebrew/Cellar/python@3.13/3.13.13_1/bin/pip3.13 *)",
|
|
25
|
+
"Bash(/opt/homebrew/Cellar/python@3.13/3.13.13_1/bin/python3.13 -m venv .venv --without-pip)",
|
|
26
|
+
"Bash(.venv/bin/python3.13 -c \"import sys; print\\(sys.version\\)\")",
|
|
27
|
+
"Bash(/usr/bin/python3 --version)",
|
|
28
|
+
"Bash(/usr/bin/python3 -m pip --version)",
|
|
29
|
+
"Bash(.venv/bin/pip --version)",
|
|
30
|
+
"Bash(.venv/bin/ruff format *)",
|
|
31
|
+
"Bash(.venv/bin/pytest tests/ -x -q)",
|
|
32
|
+
"Bash(.venv/bin/ruff check *)",
|
|
33
|
+
"Bash(.venv/bin/mypy src/showmyenv)",
|
|
34
|
+
"Bash(.venv/bin/pytest tests/ -q)",
|
|
35
|
+
"Bash(.venv/bin/showmyenv --version)",
|
|
36
|
+
"Bash(.venv/bin/showmyenv which *)",
|
|
37
|
+
"Bash(.venv/bin/showmyenv scan *)",
|
|
38
|
+
"Bash(.venv/bin/showmyenv quick *)",
|
|
39
|
+
"Bash(.venv/bin/showmyenv docker *)",
|
|
40
|
+
"Bash(.venv/bin/showmyenv report *)",
|
|
41
|
+
"Read(//tmp/**)",
|
|
42
|
+
"Bash(.venv/bin/pytest *)",
|
|
43
|
+
"Bash(git -C /Users/kshitizyadav/Projects/showmyenv status)",
|
|
44
|
+
"Bash(git -C /Users/kshitizyadav/Projects/showmyenv log --oneline -5)",
|
|
45
|
+
"Bash(git *)",
|
|
46
|
+
"Bash(.venv/bin/python -m build)"
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
Guidance for AI agents and contributors working in this repository.
|
|
4
|
+
|
|
5
|
+
## What this is
|
|
6
|
+
|
|
7
|
+
ShowMyEnv is a read-only environment **diagnostic** CLI. It does not just list installed versions — it explains what is *actually being used*, what is *influencing* it, what is *conflicting*, and what to *fix*. Keep that mission in mind: a change that only adds version reporting is low value; a change that explains behavior is on-mission.
|
|
8
|
+
|
|
9
|
+
## Two rules that override everything
|
|
10
|
+
|
|
11
|
+
1. **Read-only by contract.** Never write env vars, modify PATH, install/remove packages, or start/stop containers. We inspect, we never mutate. Any PR that mutates the host environment is wrong.
|
|
12
|
+
2. **Collect once, render many.** Collectors return typed dataclasses (`models.py`); renderers turn those into console/JSON/Markdown/HTML. Collectors **must not print**, and renderers **must not collect**. If you find yourself parsing text in a renderer or formatting strings in a collector, stop.
|
|
13
|
+
|
|
14
|
+
## Architecture
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
collectors/ → return dataclasses (gather facts, never print)
|
|
18
|
+
models.py → the data contract (serializable; bump schema_version on breaking change)
|
|
19
|
+
diagnostics/ → pure functions over models (health score, doctor, root-cause rules)
|
|
20
|
+
report/ → snapshot, compare, formatters (json/markdown/html)
|
|
21
|
+
render/ → Rich console output
|
|
22
|
+
cli.py → Typer app; wires commands to collectors → diagnostics → renderer
|
|
23
|
+
context.py → ScanContext: injects PATH/env/which-resolver and caches results within one run
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The root serialized object is `Scan` in `models.py`. Everything (`scan`, `report`, `snapshot`, `--json`) flows from it.
|
|
27
|
+
|
|
28
|
+
`Severity` (INFO/LOW/MEDIUM/HIGH/CRITICAL) and `Finding` are the shared vocabulary. Every issue any module detects is a `Finding`. The health score deducts points by `Finding`, so each deduction is explainable.
|
|
29
|
+
|
|
30
|
+
## Commands
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Setup (uses a venv; never install into the user's global env)
|
|
34
|
+
python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
35
|
+
pip install -e ".[dev]"
|
|
36
|
+
|
|
37
|
+
# Run during development
|
|
38
|
+
python -m showmyenv scan
|
|
39
|
+
python -m showmyenv which
|
|
40
|
+
python -m showmyenv health
|
|
41
|
+
|
|
42
|
+
# Quality gates — run all three before considering work done
|
|
43
|
+
ruff format . # format
|
|
44
|
+
ruff check . --fix # lint
|
|
45
|
+
mypy src/showmyenv # type check (strict on models + collectors)
|
|
46
|
+
pytest # tests
|
|
47
|
+
pytest tests/collectors/test_path_analyzer.py -k shadow # focused run
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If a task touches collection or models, run `mypy` — the model layer is a contract and must stay typed.
|
|
51
|
+
|
|
52
|
+
## Dependency policy (strict)
|
|
53
|
+
|
|
54
|
+
Runtime dependencies are limited to **`typer`, `rich`, `psutil`**. Do not add others. Do not import the docker SDK, boto3, or cloud SDKs — shell out to the user's own `docker` / `aws` / `az` / `gcloud` / language binaries via `subprocess`. Shelling out is more truthful (it reflects real resolution) and keeps the tool from breaking in the broken environments it exists to diagnose. New dev-only deps are fine in the `[dev]` extra.
|
|
55
|
+
|
|
56
|
+
## Cross-platform rules
|
|
57
|
+
|
|
58
|
+
- Use `pathlib.Path`, `os.pathsep`, and `shutil.which` (it handles Windows PATHEXT). Never hardcode `C:\...` or `/usr/local/...` — platform-specific known locations live in one table per collector.
|
|
59
|
+
- "Tool not found", "daemon not running", and "permission denied" are **normal reportable states**, not exceptions. Return a model with an INFO/relevant `Finding`; never crash a scan because one collector couldn't run.
|
|
60
|
+
- Default scan is **offline and fast**. Anything needing the network (e.g. outdated-package checks) is gated behind `--check-updates`.
|
|
61
|
+
|
|
62
|
+
## Security
|
|
63
|
+
|
|
64
|
+
- Redact by default in every report format. Detect secret-shaped env vars (tokens, keys) and never echo their values.
|
|
65
|
+
- Never dump the full environment — only the curated allowlist in `collectors/env_vars.py`.
|
|
66
|
+
- Report credential *sources* (env / file / SSO), never credential *values*.
|
|
67
|
+
|
|
68
|
+
## Recipe: add a new runtime collector
|
|
69
|
+
|
|
70
|
+
This is the most common extension. Follow the existing `collectors/runtimes/python.py` as the reference.
|
|
71
|
+
|
|
72
|
+
1. Create `collectors/runtimes/<name>.py` implementing the `RuntimeCollector` protocol from `runtimes/base.py`. It receives a `ScanContext` and returns a `RuntimeInfo`.
|
|
73
|
+
2. Populate at minimum: `active_version`, `active_path` (use `ctx.which("<bin>")`), `installed_versions` (best-effort), and any `extra` fields (e.g. version-manager root). Mark discovery confidence honestly.
|
|
74
|
+
3. Emit `Finding`s for misconfigurations you can detect (e.g. resolved binary disagrees with the relevant `*_HOME` env var).
|
|
75
|
+
4. Register the collector in the runtime registry in `collectors/runtimes/__init__.py`.
|
|
76
|
+
5. Add a fixture-based test in `tests/collectors/` using a fake PATH/which resolver — do **not** depend on the host having the runtime installed.
|
|
77
|
+
6. If the runtime introduces a new conflict class, add a rule in `diagnostics/conflicts.py` (operates on models only).
|
|
78
|
+
|
|
79
|
+
Never read `os.environ` or call `shutil.which` directly inside a collector — go through `ScanContext` so the collector stays testable.
|
|
80
|
+
|
|
81
|
+
## Recipe: add a root-cause rule
|
|
82
|
+
|
|
83
|
+
Rules live in `diagnostics/root_cause.py` as `(matches(scan) -> bool, explanation, ranked_causes, fixes)`. They consume the `Scan` model and emit findings/explanations. Adding a rule must not require touching any collector. Add a test that builds a hand-crafted `Scan` and asserts the rule fires.
|
|
84
|
+
|
|
85
|
+
## Schema changes
|
|
86
|
+
|
|
87
|
+
`models.Scan.schema_version` is persisted in snapshots and reports. Any breaking change to the serialized shape must bump it and add a migration shim so `compare` can still read older snapshots. Update the golden fixtures in `tests/fixtures/` accordingly.
|
|
88
|
+
|
|
89
|
+
## Definition of done
|
|
90
|
+
|
|
91
|
+
- Collectors don't print; renderers don't collect.
|
|
92
|
+
- New runtime deps? Only if it's `typer`/`rich`/`psutil` (it isn't — so no).
|
|
93
|
+
- `ruff format`, `ruff check`, `mypy`, and `pytest` all pass.
|
|
94
|
+
- New behavior is covered by a fixture-based test that doesn't depend on the host's real environment.
|
|
95
|
+
- Nothing mutates the host environment.
|
|
96
|
+
|
|
97
|
+
See `PLAN.md` for the full module breakdown, health-scoring weights, and phased roadmap (v0.1 → v0.2 → v1.0).
|
showmyenv-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kshitiz Yadav
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
showmyenv-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: showmyenv
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Environment diagnostic CLI: see what is actually running, what is influencing it, what conflicts, and how to fix it.
|
|
5
|
+
Project-URL: Homepage, https://github.com/kshitizyadav/showmyenv
|
|
6
|
+
Project-URL: Repository, https://github.com/kshitizyadav/showmyenv
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/kshitizyadav/showmyenv/issues
|
|
8
|
+
Author-email: Kshitiz Yadav <kshitizyadav6@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: cli,developer-tools,devtools,diagnostic,environment,path,runtime
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
24
|
+
Classifier: Topic :: System :: Systems Administration
|
|
25
|
+
Classifier: Topic :: Utilities
|
|
26
|
+
Requires-Python: >=3.9
|
|
27
|
+
Requires-Dist: psutil>=5.9.0
|
|
28
|
+
Requires-Dist: rich>=13.0.0
|
|
29
|
+
Requires-Dist: typer>=0.12.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: mypy>=1.10.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: types-psutil>=5.9.0; extra == 'dev'
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
# showmyenv
|
|
39
|
+
|
|
40
|
+
> Other tools tell you what's installed. **showmyenv** tells you what's *actually running*, what's *influencing* it, what's *conflicting* with it, and what to *fix*.
|
|
41
|
+
|
|
42
|
+
A read-only environment diagnostic CLI for developers. It inspects your shell environment and explains it — no mutations, no side effects.
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install showmyenv
|
|
48
|
+
# or
|
|
49
|
+
pipx install showmyenv
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Requires Python 3.9 or later. Runtime dependencies: `typer`, `rich`, `psutil`.
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
showmyenv # full scan (same as showmyenv scan)
|
|
58
|
+
showmyenv quick # fast scan, skips Docker/Cloud/IDE discovery
|
|
59
|
+
showmyenv health # health score with grade and per-category breakdown
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Commands
|
|
63
|
+
|
|
64
|
+
| Command | Description |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `showmyenv scan` | Full environment scan |
|
|
67
|
+
| `showmyenv quick` | Fast scan (runtimes, PATH, ports only) |
|
|
68
|
+
| `showmyenv health` | Health score and all findings |
|
|
69
|
+
| `showmyenv which` | Show how each known command resolves |
|
|
70
|
+
| `showmyenv ports` | Listening ports with likely service names |
|
|
71
|
+
| `showmyenv docker` | Docker containers, images, disk usage |
|
|
72
|
+
| `showmyenv doctor` | Check project manifest requirements against active runtimes |
|
|
73
|
+
| `showmyenv snapshot` | Save a snapshot to JSON |
|
|
74
|
+
| `showmyenv compare A B` | Diff two snapshot files |
|
|
75
|
+
| `showmyenv report` | Generate a report (`--format json\|markdown\|html`) |
|
|
76
|
+
|
|
77
|
+
All commands accept `--json` for machine-readable output.
|
|
78
|
+
|
|
79
|
+
## What it checks
|
|
80
|
+
|
|
81
|
+
### Runtimes
|
|
82
|
+
|
|
83
|
+
Detects active versions and install paths for Python, Node.js, Java, Go, Rust, .NET, Ruby, and PHP. For each runtime it reports:
|
|
84
|
+
|
|
85
|
+
- The resolved executable and its version
|
|
86
|
+
- Installed versions from version managers (pyenv, nvm, rbenv, rustup, sdkman)
|
|
87
|
+
- Misconfigurations — for example, `VIRTUAL_ENV` set but the resolved Python living outside it, or `JAVA_HOME` pointing somewhere different from the `java` on PATH
|
|
88
|
+
|
|
89
|
+
### PATH analysis
|
|
90
|
+
|
|
91
|
+
- Duplicate entries
|
|
92
|
+
- Broken entries (directory does not exist)
|
|
93
|
+
- **Shadowing** — when an older version of a tool appears earlier in PATH than a newer one, this is flagged HIGH and explained
|
|
94
|
+
|
|
95
|
+
### Project Doctor (`showmyenv doctor`)
|
|
96
|
+
|
|
97
|
+
Reads manifest files in the current directory and compares their declared runtime requirements against what is actually active:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
Runtime Required Active Status Source
|
|
101
|
+
python >=3.11 3.9.6 FAIL pyproject.toml
|
|
102
|
+
node ^18 20.11 PASS package.json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Supported manifests: `pyproject.toml`, `package.json`, `go.mod`, `pom.xml`, `build.gradle`, `Dockerfile`, `.tool-versions`, `.nvmrc`, `.python-version`, `rust-toolchain.toml`, `Gemfile`, `composer.json`, `global.json`, and more.
|
|
106
|
+
|
|
107
|
+
### Conflict detection
|
|
108
|
+
|
|
109
|
+
Pure analysis over collected data — no extra system calls:
|
|
110
|
+
|
|
111
|
+
- Virtualenv present but inactive
|
|
112
|
+
- Multiple JS package manager lockfiles (`package-lock.json` + `yarn.lock` + `pnpm-lock.yaml`)
|
|
113
|
+
- Multiple Python version managers active simultaneously
|
|
114
|
+
- `packageManager` field in `package.json` disagrees with the resolved package manager
|
|
115
|
+
|
|
116
|
+
### Root cause engine
|
|
117
|
+
|
|
118
|
+
When known problem patterns are detected, showmyenv explains them with ranked causes and actionable fixes. Current rules:
|
|
119
|
+
|
|
120
|
+
- **Package installed but won't import** — fires on interpreter/venv mismatches
|
|
121
|
+
- **Older tool shadows newer** — fires on HIGH-severity PATH shadows
|
|
122
|
+
- **Wrong Java version** — fires on JAVA_HOME mismatches or failed doctor checks
|
|
123
|
+
- **Node version mismatch** — fires on failed doctor checks or lockfile conflicts
|
|
124
|
+
- **Docker reclaimable space** — fires when Docker has significant space to reclaim
|
|
125
|
+
|
|
126
|
+
### Docker
|
|
127
|
+
|
|
128
|
+
Shells out to the local `docker` binary (no SDK dependency). Reports containers, images, disk usage, and reclaimable space. Degrades gracefully when Docker is not installed or the daemon is not running.
|
|
129
|
+
|
|
130
|
+
### Cloud environment
|
|
131
|
+
|
|
132
|
+
Detects active AWS, Azure, and GCP configuration by shelling out to `aws`, `az`, and `gcloud`. Reports the active account/project/subscription and where credentials come from (environment variable, config file, or SSO). **Credential values are never echoed.**
|
|
133
|
+
|
|
134
|
+
### IDE discovery
|
|
135
|
+
|
|
136
|
+
Finds installed editors via well-known application paths and CLI shims: VS Code, Cursor, Windsurf, IntelliJ IDEA, PyCharm, WebStorm, Vim, Neovim, Emacs, Zed.
|
|
137
|
+
|
|
138
|
+
### Health score
|
|
139
|
+
|
|
140
|
+
A weighted score from 0–100 with a letter grade (A–F):
|
|
141
|
+
|
|
142
|
+
| Category | Weight |
|
|
143
|
+
|---|---|
|
|
144
|
+
| Runtime Configuration | 25% |
|
|
145
|
+
| PATH Integrity | 20% |
|
|
146
|
+
| Dependency Health | 20% |
|
|
147
|
+
| Security Checks | 15% |
|
|
148
|
+
| Environment Variables | 10% |
|
|
149
|
+
| Docker Health | 10% |
|
|
150
|
+
|
|
151
|
+
Every point deducted traces back to a specific finding, so the score is always explainable. Categories that don't apply (e.g. no Docker) are marked N/A and excluded from the weighted average.
|
|
152
|
+
|
|
153
|
+
### Snapshots and comparison
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
showmyenv snapshot -o before.json
|
|
157
|
+
# ... make changes ...
|
|
158
|
+
showmyenv snapshot -o after.json
|
|
159
|
+
showmyenv compare before.json after.json
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The diff shows runtime version changes, new/resolved findings, health score delta, and PATH entry changes.
|
|
163
|
+
|
|
164
|
+
### Reports
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
showmyenv report --format json > report.json
|
|
168
|
+
showmyenv report --format markdown > report.md
|
|
169
|
+
showmyenv report --format html -o report.html
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The HTML report is a single self-contained file with inline CSS — suitable for attaching to a ticket or sharing with a teammate.
|
|
173
|
+
|
|
174
|
+
## Security
|
|
175
|
+
|
|
176
|
+
- **Read-only by design.** showmyenv never writes environment variables, modifies PATH, installs packages, or starts/stops services.
|
|
177
|
+
- **Secret redaction.** Environment variables matching secret-shaped patterns (`API_KEY`, `SECRET`, `TOKEN`, `PASSWORD`, etc.) are detected and their values are replaced with `[redacted]` in all output formats.
|
|
178
|
+
- **No full environment dump.** Only a curated allowlist of meaningful variables is collected and shown.
|
|
179
|
+
- **Credential sources, not values.** The cloud collector reports *where* credentials come from (env var / config file / SSO), never the credential itself.
|
|
180
|
+
|
|
181
|
+
## Environment variables understood
|
|
182
|
+
|
|
183
|
+
showmyenv reads but never modifies: `JAVA_HOME`, `PYTHONPATH`, `VIRTUAL_ENV`, `CONDA_DEFAULT_ENV`, `NODE_PATH`, `NPM_CONFIG_PREFIX`, `GOROOT`, `GOPATH`, `GOBIN`, `CARGO_HOME`, `RUSTUP_HOME`, `GEM_HOME`, `RBENV_ROOT`, `PYENV_ROOT`, `NVM_DIR`, `AWS_PROFILE`, `AWS_REGION`, `GOOGLE_CLOUD_PROJECT`, `AZURE_SUBSCRIPTION_ID`, `DOCKER_HOST`, `KUBECONFIG`, `PATH`, `SHELL`, `LANG`, `HOME`, `USER`.
|
|
184
|
+
|
|
185
|
+
## Global flags
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
--json Output as JSON (any command)
|
|
189
|
+
--no-color Disable color output
|
|
190
|
+
--check-updates Check for outdated packages (requires network, scan only)
|
|
191
|
+
--version Print version and exit
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Development
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
git clone https://github.com/kshitizyadav/showmyenv
|
|
198
|
+
cd showmyenv
|
|
199
|
+
python -m venv .venv && source .venv/bin/activate
|
|
200
|
+
pip install -e ".[dev]"
|
|
201
|
+
|
|
202
|
+
# Run during development
|
|
203
|
+
showmyenv scan
|
|
204
|
+
showmyenv health
|
|
205
|
+
showmyenv doctor
|
|
206
|
+
|
|
207
|
+
# Quality gates (run before submitting a PR)
|
|
208
|
+
ruff format .
|
|
209
|
+
ruff check . --fix
|
|
210
|
+
mypy src/showmyenv
|
|
211
|
+
pytest
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Adding a new runtime collector
|
|
215
|
+
|
|
216
|
+
1. Create `src/showmyenv/collectors/runtimes/<name>.py` following the pattern in `python.py` or `go.py`. The collector receives a `ScanContext` and returns a `RuntimeInfo`.
|
|
217
|
+
2. Register it in `src/showmyenv/collectors/runtimes/__init__.py`.
|
|
218
|
+
3. Add a fixture-based test in `tests/collectors/` using a fake binary — do not depend on the host having the runtime installed.
|
|
219
|
+
|
|
220
|
+
See `CLAUDE.md` for the full contributor guide.
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT
|