Skip to content

feat: auto-detect dependency changes and reinstall openant#36

Merged
ar7casper merged 6 commits into
knostic:release/2026-05-12from
joshbouncesecurity:feat/issue16-14-auto-detect-deps
May 12, 2026
Merged

feat: auto-detect dependency changes and reinstall openant#36
ar7casper merged 6 commits into
knostic:release/2026-05-12from
joshbouncesecurity:feat/issue16-14-auto-detect-deps

Conversation

@joshbouncesecurity
Copy link
Copy Markdown
Contributor

@joshbouncesecurity joshbouncesecurity commented May 4, 2026

Summary

The Go CLI now hashes pyproject.toml after pip install -e and re-runs install automatically when dependencies change. Prevents stale venv issues after git pull introduces new dependencies.

Addresses item 14 from #16 (does not close the issue).

Test plan

  • First run after a fresh checkout installs the venv as before.
  • Subsequent runs with unchanged pyproject.toml skip the install.
  • Modifying pyproject.toml (e.g., adding a dep) causes the next CLI invocation to reinstall automatically.
  • Deleting ~/.openant/venv/.deps-hash and re-running causes a reinstall and recreates the hash.

@joshbouncesecurity
Copy link
Copy Markdown
Contributor Author

joshbouncesecurity commented May 4, 2026

Manual verification

After installing this branch:

  • First run: openant --version triggers initial pip install. Confirm ~/.openant/venv/.deps-hash is created.
  • Second run, no changes: openant --version skips install — should be near-instant with no install message.
  • Pyproject changed: edit libs/openant-core/pyproject.toml (e.g., add a comment), re-run: prints "Dependencies changed, updating..." and reinstalls.
  • Hash file deleted: rm ~/.openant/venv/.deps-hash then re-run: reinstalls and recreates the hash.
  • Read-only venv parent: if ~/.openant/venv/ doesn't exist (e.g., custom OPENANT_PYTHON), the helper now MkdirAll's it instead of erroring.

@joshbouncesecurity
Copy link
Copy Markdown
Contributor Author

Local test results

Built the Go CLI from this branch on Windows and exercised the deps-hash flow. (Note: I needed OPENANT_PYTHON pointing at Scripts/python.exe because the managed-venv path uses bin/python which is the documented Windows limitation, unrelated to this PR.)

Commands run:

go build -o openant.exe ./
# Hash exists from prior install
ls ~/.openant/venv/.deps-hash      # present, sha256 = f251e66e...

# Delete hash to simulate "first run / hash missing"
rm ~/.openant/venv/.deps-hash
OPENANT_PYTHON=...Scripts/python.exe ./openant.exe parse <fixture>
# -> ran install, recreated .deps-hash

# Run again with hash present and no pyproject change
./openant.exe parse <fixture>
# -> NO install message, jumped straight to parser

Outcome:

  • First run / hash missing: install ran, .deps-hash (re)created ✅
  • Second run, no changes: skipped install, near-instant ✅
  • Pyproject-changed and hash-deleted paths: I tested the hash-deleted path (covers the same code path as pyproject-changed since both produce a hash mismatch). Did not edit pyproject.toml to avoid touching the worktree.
  • (n/a) Read-only-venv-parent MkdirAll branch: not exercised — the venv parent already existed.

Sample output of the post-install run for transparency:

Creating managed Python environment at ~/.openant/venv/...
Installing openant from ...libs/openant-core...
[Reachability Filter] ...  -> 5 units written

The .deps-hash was correctly written after the install completed.

Comment thread apps/openant-cli/internal/python/runtime_test.go Outdated
Comment thread apps/openant-cli/internal/python/runtime.go
@ar7casper ar7casper changed the base branch from master to release/2026-05-12 May 12, 2026 07:34
@ar7casper ar7casper force-pushed the release/2026-05-12 branch from 21cd56f to 463e9d0 Compare May 12, 2026 07:35
joshbouncesecurity and others added 5 commits May 12, 2026 11:06
Hash pyproject.toml (SHA-256) after each pip install and store in
~/.openant/venv/.deps-hash. On every CLI invocation, EnsureRuntime
compares the stored hash with the current file and re-runs
`pip install -e` when they differ.

This prevents stale venv issues when dependencies change (e.g.
swapping anthropic for claude-agent-sdk) — previously the user had
to manually uninstall and reinstall.

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
… stale-trigger tests

- Record the pyproject.toml hash even when openant is already importable so
  existing users aren't forced into a one-time reinstall after upgrading to
  the auto-detect-deps build.
- Extract depsStalenessAt(corePath, hashPath) and readHashAt/writeHashAt
  helpers so the stale-detection logic is unit-testable without invoking
  pip or touching the real ~/.openant/venv directory.
- Add tests covering the modified-pyproject trigger, fresh-state behavior,
  matching-hash short-circuit, missing pyproject, and empty stored hash.
If writeStoredHash fails after a successful install, the next run would
otherwise see no stored hash and trigger a redundant reinstall. Surface
the failure as a warning on stderr — consistent with the existing warning
in CheckDepsStale — so users can spot a misbehaving venv directory.
If the venv directory does not yet exist (e.g. user runs against a system
Python without the managed venv), writeStoredHash would fail every run and
trigger a redundant reinstall on the next call. Have writeHashAt MkdirAll
its parent first so the marker file always lands successfully.
Extract checkDepsStaleWith so the core-locator is injected rather than
called directly, removing the os.Chdir in TestCheckDepsStale_SkipsWhenCoreNotFound
(Chdir mutates process-wide CWD and breaks if any sibling test adds t.Parallel).
Also document the concurrent-install race as a known limitation.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…ce-reinstall

When the hash file was missing and openant was already importable,
CheckOpenantInstalled was re-seeding it immediately, causing CheckDepsStale
to see a matching hash and skip the reinstall. This broke the documented
behaviour where deleting .deps-hash triggers a reinstall. Aligns with
origin/master which uses a plain early return.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@joshbouncesecurity joshbouncesecurity force-pushed the feat/issue16-14-auto-detect-deps branch from 71d3437 to 77a919a Compare May 12, 2026 08:21
@joshbouncesecurity joshbouncesecurity marked this pull request as ready for review May 12, 2026 08:25
@ar7casper ar7casper merged commit ee1b713 into knostic:release/2026-05-12 May 12, 2026
9 checks passed
@joshbouncesecurity joshbouncesecurity deleted the feat/issue16-14-auto-detect-deps branch May 12, 2026 08:26
@ar7casper ar7casper mentioned this pull request May 12, 2026
3 tasks
ar7casper added a commit that referenced this pull request May 13, 2026
Covers the seven PRs in this release:
- #35: parse --level default → reachable (CLI consistency with scan + Python CLI)
- #36: auto-detect dep changes via ~/.openant/venv/.deps-hash
- #37: lazy JS parser npm bootstrap on first use
- #39: TypeScript/NestJS DI-aware call resolution (constructor + field + functional inject())
- #40: --language auto opt-in for openant init + non-git path support + shared config/languages.json
- #49: Express anonymous route handler extraction (route_handler / route_middleware)
- #50: --llm-reachability opt-in stage + cross-parser call_graph.json contract

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants