Skip to content

Add public API for checking environment staleness - #10

Closed
yzx9 wants to merge 1 commit into
apposed:mainfrom
yzx9:check-up-to-date
Closed

yzx9 wants to merge 1 commit into
apposed:mainfrom
yzx9:check-up-to-date

Conversation

@yzx9

@yzx9 yzx9 commented Jun 2, 2026 •

Copy link
Copy Markdown
Contributor
  • Adds isUpToDate() and checkUpToDate() to Builder and Environment, enabling applications to check whether an environment needs syncing without triggering a build
  • Introduces CheckResult interface with isUpToDate(), description(), and verified(): the verified() flag indicates whether a real tool was invoked (vs. a fast config comparison)
  • UvBuilder supports verified checks via uv sync --dry-run for pyproject.toml-based projects; PixiBuilder and MambaBuilder fall back to config-level checks

close apposed/appose#34

Test plan

  • Unit tests pass: CheckResult factory methods, SimpleBuilder always up-to-date, BaseBuilder stale when no env / stale after config change, DynamicBuilder delegation
  • Integration tests (require uv + appose-python): build uv env → isUpToDate() returns true → modify config → returns false; checkUpToDate() returns verified=true for pyproject.toml projects

@yzx9
yzx9 force-pushed the check-up-to-date branch 2 times, most recently from 4d8b3ef to 5b872ab Compare June 2, 2026 12:48
@yzx9

yzx9 commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

The Windows CI failure is a flaky NDArrayTest.testPython2dCOrder shared-memory issue unrelated to this PR's changes (1 error out of 127 tests, all new tests passed on every platform)

Add isUpToDate() and checkUpToDate() to Builder and Environment,
enabling applications to check whether an environment needs syncing
without triggering a build. The fast isUpToDate() compares against
appose.json; checkUpToDate() may additionally invoke tool-specific
verification (e.g., uv sync --dry-run) and returns a CheckResult
with a verified() flag.
@ctrueden

ctrueden commented Oct 9, 2026

Copy link
Copy Markdown
Member

I compared this PR with the new Builder#status() method added today. Most of what this PR does is now covered by Builder#status(), but there is one thing this PR tries to do that status() doesn't: checking for changes that the config comparison cannot see—e.g. packages changed by hand or a corrupted venv. For uv pyproject.toml environments, this PR employs uv sync --dry-run and treating a nonzero exit as "stale". But (at least with uv 0.12.24) --dry-run exits 0 even when the environment is out of sync. Therefore, real drift is still reported as "up to date, verified". It also reports errors (e.g. network errors or resolution problems) as "stale, verified". The uv sync --check command is likely better: it exits 1 in response to drift and 0 once back in sync. But it may still need network access to resolve though, so it isn't a cheap, side-effect-free query like status() promises.

This idea of an optional, more expensive check for drift that can't be seen from the config may be worth including in Appose, but since it's a more expensive check, it should probably be its own method rather than including as part of status(). It could return something like STALE/CURRENT and use uv sync --check for uv and pixi install --locked/pixi list-style checks for pixi.

@yzx9 If you need such a drift check, let me know, and we can introduce API for it.

@ctrueden ctrueden closed this Oct 9, 2026
@yzx9

yzx9 commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

@ctrueden Thanks for reviewing this PR and for adding Builder#status()! I agree that deeper environment drift detection should remain a separate operation.

In my tests, uv sync --check typically completes in just 20–30 ms, although it may occasionally need to access the network to fetch package metadata.

> hyperfine --warmup 3 --runs 20 \
  'uv sync --check --locked --offline'
Benchmark 1: uv sync --check --locked --offline
  Time (mean ± σ):      29.0 ms ±   1.3 ms    [User: 13.8 ms, System: 12.1 ms]
  Range (min … max):    27.0 ms …  32.7 ms    20 runs

> ls .venv/lib/python3.12/site-packages/ | wc -l
813

The bigger concern is that uv seems to be the only one of the three package managers with a straightforward, read-only environment consistency check.

Perhaps a simpler, more consistent approach across package managers would be to just re-run the sync operation when needed. At least for uv, syncing an already up-to-date environment is nearly as fast as checking it:

> hyperfine --warmup 3 --runs 20 \
  'uv sync'
Benchmark 1: uv sync
  Time (mean ± σ):      30.7 ms ±   3.2 ms    [User: 14.5 ms, System: 12.7 ms]
  Range (min … max):    28.8 ms …  43.5 ms    20 runs

@yzx9
yzx9 deleted the check-up-to-date branch October 12, 2026 13:50
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.

Feature Request: Add public API for checking environment staleness

2 participants