lean-runtime 2.6.2__tar.gz → 2.7.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.
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/CHANGELOG.md +17 -0
- {lean_runtime-2.6.2/lean_runtime.egg-info → lean_runtime-2.7.0}/PKG-INFO +3 -1
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/README.md +2 -0
- lean_runtime-2.7.0/compatibility/README.md +14 -0
- lean_runtime-2.7.0/compatibility/lake-artifact-cache-4.33.0.json +32 -0
- lean_runtime-2.7.0/compatibility/mathlib-4.32.2.json +8 -0
- lean_runtime-2.7.0/compatibility/mathlib-4.33.0.json +8 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/architecture.md +16 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/getting-started.md +4 -1
- lean_runtime-2.7.0/docs/lake-artifact-cache-design.md +154 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/local-projects.md +18 -1
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/bundles.py +16 -65
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/cli.py +44 -11
- lean_runtime-2.7.0/lean_runtime/lake_cache.py +212 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/oci.py +14 -37
- lean_runtime-2.7.0/lean_runtime/oci_protocol.py +116 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/programs.py +18 -20
- lean_runtime-2.7.0/lean_runtime/project_execution.py +192 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/projects.py +9 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/runtime.py +57 -78
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/toolchain_oci.py +21 -22
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/toolchains.py +48 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0/lean_runtime.egg-info}/PKG-INFO +3 -1
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime.egg-info/SOURCES.txt +8 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/mkdocs.yml +1 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/pyproject.toml +1 -1
- lean_runtime-2.7.0/scripts/lake_cache_gate.py +77 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/scripts/run_compatibility.py +13 -4
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_planner.py +13 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_cli.py +78 -0
- lean_runtime-2.7.0/tests/test_lake_cache.py +86 -0
- lean_runtime-2.7.0/tests/test_oci_protocol.py +59 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_projects.py +26 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_toolchains.py +45 -0
- lean_runtime-2.6.2/compatibility/README.md +0 -13
- lean_runtime-2.6.2/compatibility/mathlib-4.32.2.json +0 -15
- lean_runtime-2.6.2/compatibility/mathlib-4.33.0.json +0 -15
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/LICENSE +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/MANIFEST.in +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/environments.toml +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/core-v4.32.2.lock.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/leancert-v4.30.0.5.lock.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/leancert-v4.31.0.lock.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/leancert-v4.32.2.4.lock.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/leancert-v4.33.0.lock.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/mathlib-v4.30.0.lock.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/mathlib-v4.31.0.lock.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/mathlib-v4.32.2.lock.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/catalog/locks/mathlib-v4.33.0.lock.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/compatibility/mathlib-4.32.2.toml +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/compatibility/mathlib-4.33.0.toml +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/captures.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/case-study-v1.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/cli.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/development.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/environments.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/index.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/portable-copies.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/project-publishing.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/python-api.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/ready-programs.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/standalone-files.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/trust-and-limitations.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/docs/v1-precision.md +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/examples/mathlib.toml +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/__init__.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/__main__.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/_git.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/_paths.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/backends.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/capsules.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/comparison.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/console.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/decisions.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/diagnostics.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/__init__.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/analyzer.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/api.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/candidate.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/catalog.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/catalog_build.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/catalog_cli.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/catalog_manifest.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/data/catalog.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/defaults.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/engine.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/errors.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/module_inventory.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/planner.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/policy.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/probe.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/py.typed +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/result.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/schema_resources.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/schemas/catalog-v1.schema.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/schemas/plan-v1.schema.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/discovery/schemas/result-v1.schema.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/environments.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/errors.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/events.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/facade.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/frontmatter.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/health.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/lake.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/lockfiles.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/locking.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/matrix.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/models.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/packs.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/policies.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/profiling.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/project_sharing.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/publisher_verification.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/py.typed +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/references.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/resolver.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/run_cli.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/schema_resources.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/serialization.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/shared_projects.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/specs.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/store.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/timings.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/toolchain_slim.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/verification.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime/wire.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime.egg-info/dependency_links.txt +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime.egg-info/entry_points.txt +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime.egg-info/requires.txt +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/lean_runtime.egg-info/top_level.txt +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/cleanup-v1.schema.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/comparison-v1.schema.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/execution-v1.schema.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/inspect-v1.schema.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/matrix-v1.schema.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/profile-v1.schema.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/schemas/verify-v1.schema.json +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/scripts/announcement_gate.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/scripts/registry_preflight.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/scripts/run_v1_case_study.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/scripts/smoke_wheel.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/setup.cfg +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/conftest.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/e2e/test_real_discovery.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_analyzer.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_catalog.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_catalog_build.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_discovery_schema_resources.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_engine.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/discovery/test_policy.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_backend.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_bundles.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_capsules.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_console.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_diagnostics.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_environment_integration.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_events_health.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_facade.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_frontmatter.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_git.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_interactive.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_lockfiles.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_models.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_multifile.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_packs.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_paths.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_prebuilt_policy.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_programs.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_project_publish.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_references.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_run_cli.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_runtime.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_schema_resources.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_schemas.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_signatures.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_specs.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_store.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_toolchain_oci.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_toolchain_slim.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_v1_precision.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_verification_inventory.py +0 -0
- {lean_runtime-2.6.2 → lean_runtime-2.7.0}/tests/test_verification_probe.py +0 -0
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 2.7.0 - 2026-08-14
|
|
6
|
+
|
|
7
|
+
- Keep newly initialized project roots narrow: the generated root imports its
|
|
8
|
+
local `Basic` module without redundantly importing the all-Mathlib umbrella,
|
|
9
|
+
and the completion hint points to the fast first-file check.
|
|
10
|
+
- Render stdin diagnostics as `<stdin>` in the CLI instead of exposing the
|
|
11
|
+
disposable `.lake/lean-runtime` staging path.
|
|
12
|
+
- Add fileless `lean-runtime check` and `ProjectEnvironment.check_all()` to
|
|
13
|
+
check every declared local library through Lake's `leanArts` facets, retaining
|
|
14
|
+
correct intra-project dependency ordering without building executables.
|
|
15
|
+
- Integrate an ABI- and toolchain-isolated root-project Lake artifact cache for
|
|
16
|
+
projects created by `init`. Capability support is probed and persisted rather
|
|
17
|
+
than version-gated; dependencies remain in the verified shared workspace.
|
|
18
|
+
- Keep remote Lake mappings fail-closed until artifacts have a verified SHA-256
|
|
19
|
+
inventory and lazy restoration participates in acquisition planning and
|
|
20
|
+
download limits.
|
|
21
|
+
|
|
5
22
|
## 2.6.2 - 2026-08-14
|
|
6
23
|
|
|
7
24
|
- Keep an existing initialization target's directory inode alive, so running
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lean-runtime
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: Run Lean 4 proofs from Python or standalone files
|
|
5
5
|
Author: Alejandro Radisic
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -188,6 +188,8 @@ default, and exact dependencies are shared automatically:
|
|
|
188
188
|
lean-runtime init MyProof
|
|
189
189
|
cd MyProof
|
|
190
190
|
lean-runtime check MyProof/Basic.lean
|
|
191
|
+
# Check every declared local library, in Lake dependency order:
|
|
192
|
+
lean-runtime check
|
|
191
193
|
lean-runtime build
|
|
192
194
|
```
|
|
193
195
|
|
|
@@ -152,6 +152,8 @@ default, and exact dependencies are shared automatically:
|
|
|
152
152
|
lean-runtime init MyProof
|
|
153
153
|
cd MyProof
|
|
154
154
|
lean-runtime check MyProof/Basic.lean
|
|
155
|
+
# Check every declared local library, in Lake dependency order:
|
|
156
|
+
lean-runtime check
|
|
155
157
|
lean-runtime build
|
|
156
158
|
```
|
|
157
159
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Compatibility profiles
|
|
2
|
+
|
|
3
|
+
Profiles exercise published environments rather than mocking Lake. The Mathlib
|
|
4
|
+
4.32.2 and 4.33.0 profiles independently acquire their bundled exact catalog
|
|
5
|
+
locks and import the public `Mathlib` root. Transitive packages remain attested
|
|
6
|
+
in the lock but are not advertised as independent catalog roots.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
python scripts/run_compatibility.py compatibility/mathlib-4.32.2.json
|
|
10
|
+
python scripts/run_compatibility.py compatibility/mathlib-4.33.0.json
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The first run downloads the verified sparse environment. Later runs reuse its
|
|
14
|
+
content-addressed artifacts and published workspace.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "lean-runtime.lake-cache-contract/v1",
|
|
3
|
+
"toolchain": "leanprover/lean4:v4.33.0",
|
|
4
|
+
"lake_version_observed": "5.0.0-src+d8b1897",
|
|
5
|
+
"capability_probes": {
|
|
6
|
+
"build_mappings": ["lake", "build", "--help"],
|
|
7
|
+
"cache_add": ["lake", "cache", "add", "--help"]
|
|
8
|
+
},
|
|
9
|
+
"configuration": {
|
|
10
|
+
"cache_root": "LAKE_CACHE_DIR",
|
|
11
|
+
"workspace_cache": "LAKE_ARTIFACT_CACHE",
|
|
12
|
+
"restore": "LAKE_RESTORE_ARTIFACTS",
|
|
13
|
+
"root_package_opt_in": "enableArtifactCache = true"
|
|
14
|
+
},
|
|
15
|
+
"observable_hit_signals": [
|
|
16
|
+
"found artifact in cache",
|
|
17
|
+
"restored artifact from cache",
|
|
18
|
+
"downloaded artifact"
|
|
19
|
+
],
|
|
20
|
+
"experiment": {
|
|
21
|
+
"broad_cache_bytes": 6500000000,
|
|
22
|
+
"explicit_library_jobs": 8708,
|
|
23
|
+
"root_only_cache_bytes": 396000,
|
|
24
|
+
"root_restore_seconds": 5.17,
|
|
25
|
+
"dependency_heavy_fixture": "mathlib consumer",
|
|
26
|
+
"focused_lake_env_lean_uses_artifact_cache": false
|
|
27
|
+
},
|
|
28
|
+
"security": {
|
|
29
|
+
"lake_remote_hash_cryptographic": false,
|
|
30
|
+
"remote_registration": "disabled_pending_attested_sha256_inventory"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -39,6 +39,22 @@ published environment identity includes platform and build-profile inputs.
|
|
|
39
39
|
Each execution attempt has a unique history identity. A separate stable request
|
|
40
40
|
digest includes the environment, input digest, operation, and requested policy.
|
|
41
41
|
|
|
42
|
+
## Internal ownership
|
|
43
|
+
|
|
44
|
+
The high-level `Runtime` is a compatibility facade rather than the owner of
|
|
45
|
+
every workflow. Environment resolution and materialization remain in their
|
|
46
|
+
dedicated managers. Mutable local-project checks and builds pass through
|
|
47
|
+
`ProjectExecutor`, which owns Lake command selection and shared-workspace build
|
|
48
|
+
locking. This is the integration boundary for Lake facilities such as its
|
|
49
|
+
artifact cache; `Runtime` should not grow a second project build planner.
|
|
50
|
+
|
|
51
|
+
Environment capsules, slim toolchains, and ready-to-run programs have distinct
|
|
52
|
+
payload schemas. Their common OCI descriptor, digest, JSON, and platform
|
|
53
|
+
selection contract lives in `oci_protocol`. Payload implementations must not
|
|
54
|
+
import another payload implementation's private protocol helpers. Existing
|
|
55
|
+
legacy bundle readers remain supported, but new transport behavior belongs to
|
|
56
|
+
the shared protocol or the current sparse capsule path.
|
|
57
|
+
|
|
42
58
|
## Public identities
|
|
43
59
|
|
|
44
60
|
Two lifecycle identities are central to the ordinary API:
|
|
@@ -21,12 +21,15 @@ shared exact dependencies:
|
|
|
21
21
|
lean-runtime init MyProof
|
|
22
22
|
cd MyProof
|
|
23
23
|
lean-runtime check MyProof/Basic.lean
|
|
24
|
+
lean-runtime check
|
|
24
25
|
lean-runtime build
|
|
25
26
|
```
|
|
26
27
|
|
|
27
28
|
By default, `init` writes an `AGENTS.md` explaining the project workflow and
|
|
28
29
|
shared-dependency safety rules to coding agents. Pass `--no-agents` to omit it.
|
|
29
|
-
An existing file is preserved.
|
|
30
|
+
An existing file is preserved. The generated root imports only the project's
|
|
31
|
+
local `Basic` module; add the narrow Mathlib imports each implementation file
|
|
32
|
+
needs rather than paying for the all-Mathlib umbrella on every root import.
|
|
30
33
|
|
|
31
34
|
Use `--mathlib 4.33.0` to select that release explicitly, or `--core` for a
|
|
32
35
|
core-only library. The root project remains an ordinary mutable Lake project;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Lake artifact-cache integration design
|
|
2
|
+
|
|
3
|
+
!!! note
|
|
4
|
+
|
|
5
|
+
The root-only local cache and project-wide check described below are
|
|
6
|
+
implemented. Remote mappings remain deliberately gated on strong artifact
|
|
7
|
+
verification and acquisition planning.
|
|
8
|
+
|
|
9
|
+
## Ownership
|
|
10
|
+
|
|
11
|
+
Lean Runtime should complement the standard Lean tools rather than replace
|
|
12
|
+
their build semantics:
|
|
13
|
+
|
|
14
|
+
- Elan selects and installs the toolchain pinned by `lean-toolchain`.
|
|
15
|
+
- Lake resolves packages and owns targets, facets, traces, executables, custom
|
|
16
|
+
build logic, and complete project builds.
|
|
17
|
+
- Mathlib's cache supplies prebuilt upstream artifacts but does not cache a
|
|
18
|
+
downstream project's own outputs.
|
|
19
|
+
- Lake's artifact cache shares input- and content-addressed outputs between
|
|
20
|
+
workspaces using the same toolchain and can register remote mappings for lazy
|
|
21
|
+
restoration.
|
|
22
|
+
- Lean Runtime selects, verifies, distributes, and shares an exact environment
|
|
23
|
+
with provenance and download policy.
|
|
24
|
+
|
|
25
|
+
Consequently, Lean Runtime must not implement a second general-purpose Lake
|
|
26
|
+
target scheduler.
|
|
27
|
+
|
|
28
|
+
## Public contract
|
|
29
|
+
|
|
30
|
+
The intended commands are:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
lean-runtime check Foo.lean
|
|
34
|
+
lean-runtime check
|
|
35
|
+
lean-runtime build
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`check Foo.lean` remains the focused development loop. A file-less `check`
|
|
39
|
+
will check all local Lean modules without producing executables or native
|
|
40
|
+
libraries. `build` remains a complete Lake-compatible build of declared local
|
|
41
|
+
targets; it must not silently become a partial build.
|
|
42
|
+
|
|
43
|
+
## Integration boundary
|
|
44
|
+
|
|
45
|
+
`ProjectExecutor` owns project command selection and execution policy. A future
|
|
46
|
+
`LakeArtifactCache` service should be injected into that executor and should
|
|
47
|
+
own only cache location, mappings, and restoration:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
published OCI environment
|
|
51
|
+
├── exact source and lock provenance
|
|
52
|
+
├── sparse check capsule
|
|
53
|
+
└── Lake input-to-output mappings
|
|
54
|
+
│
|
|
55
|
+
▼
|
|
56
|
+
toolchain-scoped Lake artifact cache
|
|
57
|
+
│
|
|
58
|
+
▼
|
|
59
|
+
ProjectExecutor ─────► ordinary Lake target graph
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The cache directory must be keyed by the exact Lean toolchain identity and
|
|
63
|
+
platform ABI. It must never mix artifacts across incompatible toolchains.
|
|
64
|
+
|
|
65
|
+
## Lake 4.33 experiment and decision
|
|
66
|
+
|
|
67
|
+
The experiment used one generated Mathlib 4.33 project and preserved the same
|
|
68
|
+
source and shared dependency graph for every measurement. The exact observed
|
|
69
|
+
interface is checked into `compatibility/lake-artifact-cache-4.33.0.json`.
|
|
70
|
+
|
|
71
|
+
Compare:
|
|
72
|
+
|
|
73
|
+
1. the current bare Lake build through `lean-runtime build`;
|
|
74
|
+
2. explicit root-package, local-library, root-module `leanArts`, and executable
|
|
75
|
+
targets;
|
|
76
|
+
3. the same targets with `LAKE_ARTIFACT_CACHE=true` and a toolchain-scoped
|
|
77
|
+
`LAKE_CACHE_DIR`;
|
|
78
|
+
4. the cache with publication mappings captured by `lake build -o` and
|
|
79
|
+
registered locally;
|
|
80
|
+
5. warm process-cache and cold filesystem-cache runs.
|
|
81
|
+
|
|
82
|
+
The broad workspace cache was rejected: it copied about 6.5 GB of dependency
|
|
83
|
+
artifacts into a second cache and an explicit `@/Library:leanArts` target still
|
|
84
|
+
traversed 8,708 jobs. A root package with `enableArtifactCache = true`, combined
|
|
85
|
+
with workspace-level `LAKE_ARTIFACT_CACHE=false`, cached only root artifacts
|
|
86
|
+
(about 396 KB in the fixture) and restored them in about five seconds. This is
|
|
87
|
+
the implemented mode.
|
|
88
|
+
|
|
89
|
+
Support is detected from command behavior and help surfaces, not a parsed Lake
|
|
90
|
+
version. The verdict is cached by exact toolchain identity and platform ABI.
|
|
91
|
+
Verbose Lake output provides deterministic hit markers such as `restored
|
|
92
|
+
artifact from cache`; timing alone is not treated as proof of a hit.
|
|
93
|
+
|
|
94
|
+
## Publication and acquisition
|
|
95
|
+
|
|
96
|
+
When the remaining integrity and performance gates succeed, environment publication should run the ordinary
|
|
97
|
+
verified build with a Lake mappings output. Publication should bind the mapping
|
|
98
|
+
digest to the same exact source revision, complete Lake graph, toolchain, and
|
|
99
|
+
platform record as the capsule.
|
|
100
|
+
|
|
101
|
+
Acquisition should:
|
|
102
|
+
|
|
103
|
+
1. verify the environment and mapping descriptors through the existing OCI
|
|
104
|
+
trust path;
|
|
105
|
+
2. install compatible artifacts into the toolchain-scoped Lake cache or add
|
|
106
|
+
mappings that point to a configured remote service;
|
|
107
|
+
3. leave Lake responsible for evaluating input traces and restoring outputs;
|
|
108
|
+
4. fail explicitly on corrupt mappings or artifacts instead of silently
|
|
109
|
+
treating them as verified environment content;
|
|
110
|
+
5. permit an ordinary source build when policy allows it.
|
|
111
|
+
|
|
112
|
+
Lake recomputes its artifact hash after a remote fetch, but that hash is not a
|
|
113
|
+
cryptographic integrity boundary. Lean Runtime therefore does not currently
|
|
114
|
+
register remote mappings. A future remote adapter must bind a SHA-256 artifact
|
|
115
|
+
inventory into the verified OCI record, verify every restored artifact, emit
|
|
116
|
+
`acquisition.planned`, and charge all bytes against `max_download_bytes` before
|
|
117
|
+
registration. Until then, remote object storage would be inside the trust
|
|
118
|
+
boundary and is rejected.
|
|
119
|
+
|
|
120
|
+
OCI remains the environment and provenance distribution format. Lake's cache
|
|
121
|
+
format remains the build-cache contract. Translation between them belongs in a
|
|
122
|
+
small adapter, not in capsule, registry, or project CLI code.
|
|
123
|
+
|
|
124
|
+
## Performance gate
|
|
125
|
+
|
|
126
|
+
The slice ships only if the same empty Mathlib project satisfies:
|
|
127
|
+
|
|
128
|
+
| Journey | Budget |
|
|
129
|
+
| --- | ---: |
|
|
130
|
+
| Focused warm file check | at most 3 seconds |
|
|
131
|
+
| Project-wide check | at most 10 seconds |
|
|
132
|
+
| First build with shared cache ready | at most 10 seconds |
|
|
133
|
+
| Warm no-op build | at most 3 seconds |
|
|
134
|
+
| Executable build | comparable to native Lake |
|
|
135
|
+
| Custom facet | handled unchanged by Lake |
|
|
136
|
+
|
|
137
|
+
Correctness gates must include libraries, executables, multiple local modules,
|
|
138
|
+
custom Lean options, Mathlib plus LeanCert, a supported custom facet, an
|
|
139
|
+
unsupported cache entry, corrupted cache content, and concurrent projects using
|
|
140
|
+
the same cache.
|
|
141
|
+
|
|
142
|
+
The scheduled compatibility workflow runs the root-cache correctness and
|
|
143
|
+
timing gate on macOS ARM and Linux x86. It verifies a first check, a warm check,
|
|
144
|
+
and restoration after removing the checkout-local build directory. Ordinary CI
|
|
145
|
+
also exercises toolchain/ABI key separation on both platforms. The cache does
|
|
146
|
+
not participate in the focused `lake env lean` path; that path consumes already
|
|
147
|
+
available imports directly.
|
|
148
|
+
|
|
149
|
+
Explicit targets and the native cache did not remove dependency-graph
|
|
150
|
+
traversal. The implemented fileless `check` therefore asks Lake to build only
|
|
151
|
+
local library `leanArts` facets, preserving correct intra-project ordering. The
|
|
152
|
+
next performance step is an opaque-prebuilt-dependency optimization in Lake.
|
|
153
|
+
A specialized local-module scheduler remains a last resort and would be called
|
|
154
|
+
`check`, never `build`.
|
|
@@ -46,12 +46,29 @@ each repository's `.lake/packages`. New projects can start in shared mode:
|
|
|
46
46
|
lean-runtime init MyProof
|
|
47
47
|
cd MyProof
|
|
48
48
|
lean-runtime check MyProof/Basic.lean
|
|
49
|
+
lean-runtime check
|
|
49
50
|
lean-runtime build
|
|
50
51
|
```
|
|
51
52
|
|
|
53
|
+
The fileless form asks Lake for the project's declared local libraries and
|
|
54
|
+
builds their `leanArts` facets. Lake therefore expands roots and submodules,
|
|
55
|
+
orders local imports, and creates any intermediate local `.olean` files; Lean
|
|
56
|
+
Runtime does not parse module globs or implement a second build scheduler. It
|
|
57
|
+
does not request executable or native-library targets. The Python equivalent is
|
|
58
|
+
`Runtime().project(".").check_all()`.
|
|
59
|
+
|
|
60
|
+
Projects created by `init` on a supported Lake also opt their root package into
|
|
61
|
+
Lake's native artifact cache. Lean Runtime capability-probes the resolved Lake executable
|
|
62
|
+
once, stores the result per exact toolchain and platform ABI, and otherwise
|
|
63
|
+
stays silent. Only root-project outputs enter this cache: locked dependencies
|
|
64
|
+
continue to use the verified shared workspace, avoiding a second multi-gigabyte
|
|
65
|
+
copy. `build` retains Lake's complete target semantics.
|
|
66
|
+
|
|
52
67
|
The generated files are a standard Lake project plus a small
|
|
53
68
|
`lean-runtime.toml`. Root build outputs stay local; exact dependencies are
|
|
54
|
-
shared. The
|
|
69
|
+
shared. The generated root imports only its local `Basic` module, leaving
|
|
70
|
+
implementation files free to select precise Mathlib modules. The newest stable
|
|
71
|
+
cataloged Mathlib is selected by default. Select a
|
|
55
72
|
release with `--mathlib 4.33.0`, or use `--core` for a core-only library.
|
|
56
73
|
`init` also creates an `AGENTS.md` describing the safe
|
|
57
74
|
build and dependency workflow unless `--no-agents` is passed; it never
|
|
@@ -5,7 +5,6 @@ from __future__ import annotations
|
|
|
5
5
|
import gzip
|
|
6
6
|
import hashlib
|
|
7
7
|
import io
|
|
8
|
-
import json
|
|
9
8
|
import os
|
|
10
9
|
import re
|
|
11
10
|
import shutil
|
|
@@ -38,6 +37,22 @@ from .events import EventEmitter
|
|
|
38
37
|
from .lake import ROOT_MODULE
|
|
39
38
|
from .lockfiles import EnvironmentLock, LockedPackage
|
|
40
39
|
from .locking import FileLock
|
|
40
|
+
from .oci_protocol import (
|
|
41
|
+
INDEX_MEDIA_TYPE,
|
|
42
|
+
MANIFEST_MEDIA_TYPE,
|
|
43
|
+
)
|
|
44
|
+
from .oci_protocol import (
|
|
45
|
+
blob_descriptor_path as _blob_descriptor_path,
|
|
46
|
+
)
|
|
47
|
+
from .oci_protocol import (
|
|
48
|
+
descriptor_blob_path as _descriptor_blob_path,
|
|
49
|
+
)
|
|
50
|
+
from .oci_protocol import (
|
|
51
|
+
json_object as _json_object,
|
|
52
|
+
)
|
|
53
|
+
from .oci_protocol import (
|
|
54
|
+
require_media_type as _require_media_type,
|
|
55
|
+
)
|
|
41
56
|
from .packs import (
|
|
42
57
|
PACK_MEDIA_TYPE,
|
|
43
58
|
SparsePack,
|
|
@@ -60,8 +75,6 @@ CAPSULE_BUNDLE_SCHEMA = "lean-runtime-oci-capsule/1"
|
|
|
60
75
|
CONFIG_MEDIA_TYPE = "application/vnd.lean-runtime.environment.config.v1+json"
|
|
61
76
|
CAPSULE_CONFIG_MEDIA_TYPE = "application/vnd.lean-runtime.capsule.config.v1+json+zstd"
|
|
62
77
|
LAYER_MEDIA_TYPE = "application/vnd.lean-runtime.environment.layer.v1.tar+gzip"
|
|
63
|
-
MANIFEST_MEDIA_TYPE = "application/vnd.oci.image.manifest.v1+json"
|
|
64
|
-
INDEX_MEDIA_TYPE = "application/vnd.oci.image.index.v1+json"
|
|
65
78
|
MAX_BUNDLE_BYTES = 20 * 1024**3
|
|
66
79
|
MAX_FILES = 2_000_000
|
|
67
80
|
SOURCE_TREE_INVENTORY = ".lean-runtime-source-tree.json"
|
|
@@ -84,18 +97,6 @@ class PortableCopyInfo:
|
|
|
84
97
|
}
|
|
85
98
|
|
|
86
99
|
|
|
87
|
-
def _digest(data: bytes) -> str:
|
|
88
|
-
return "sha256:" + hashlib.sha256(data).hexdigest()
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def _digest_path(path: Path) -> str:
|
|
92
|
-
digest = hashlib.sha256()
|
|
93
|
-
with path.open("rb") as handle:
|
|
94
|
-
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
|
|
95
|
-
digest.update(chunk)
|
|
96
|
-
return "sha256:" + digest.hexdigest()
|
|
97
|
-
|
|
98
|
-
|
|
99
100
|
def _capsule_config_bytes(value: Mapping[str, Any]) -> bytes:
|
|
100
101
|
return zstandard.ZstdCompressor(level=10, write_checksum=True).compress(
|
|
101
102
|
canonical_json_bytes(dict(value))
|
|
@@ -112,19 +113,6 @@ def _capsule_config_object(data: bytes) -> dict[str, Any]:
|
|
|
112
113
|
return _json_object(decoded, "capsule config")
|
|
113
114
|
|
|
114
115
|
|
|
115
|
-
def _blob_descriptor(data: bytes, media_type: str, **extra: Any) -> dict[str, Any]:
|
|
116
|
-
return {"mediaType": media_type, "digest": _digest(data), "size": len(data), **extra}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def _blob_descriptor_path(path: Path, media_type: str, **extra: Any) -> dict[str, Any]:
|
|
120
|
-
return {
|
|
121
|
-
"mediaType": media_type,
|
|
122
|
-
"digest": _digest_path(path),
|
|
123
|
-
"size": path.stat().st_size,
|
|
124
|
-
**extra,
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
116
|
def _normalized_info(name: str, *, mode: int, kind: bytes = tarfile.REGTYPE) -> tarfile.TarInfo:
|
|
129
117
|
info = tarfile.TarInfo(name)
|
|
130
118
|
info.type = kind
|
|
@@ -245,43 +233,6 @@ def _write_oci_archive(entries: dict[str, Path], output: Path) -> None:
|
|
|
245
233
|
archive.addfile(info, handle)
|
|
246
234
|
|
|
247
235
|
|
|
248
|
-
def _json_object(data: bytes, label: str) -> dict[str, Any]:
|
|
249
|
-
try:
|
|
250
|
-
value = json.loads(data)
|
|
251
|
-
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
|
|
252
|
-
raise EnvironmentError(f"bundle {label} is not valid JSON") from exc
|
|
253
|
-
if not isinstance(value, dict):
|
|
254
|
-
raise EnvironmentError(f"bundle {label} must be a JSON object")
|
|
255
|
-
return value
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
def _descriptor_blob(entries: dict[str, bytes], descriptor: dict[str, Any], label: str) -> bytes:
|
|
259
|
-
digest = descriptor.get("digest")
|
|
260
|
-
size = descriptor.get("size")
|
|
261
|
-
if not isinstance(digest, str) or not digest.startswith("sha256:"):
|
|
262
|
-
raise EnvironmentError(f"bundle {label} has an invalid digest")
|
|
263
|
-
data = entries.get("blobs/sha256/" + digest.removeprefix("sha256:"))
|
|
264
|
-
if data is None or len(data) != size or _digest(data) != digest:
|
|
265
|
-
raise EnvironmentError(f"bundle {label} digest mismatch")
|
|
266
|
-
return data
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
def _descriptor_blob_path(entries: dict[str, Path], descriptor: dict[str, Any], label: str) -> Path:
|
|
270
|
-
digest = descriptor.get("digest")
|
|
271
|
-
size = descriptor.get("size")
|
|
272
|
-
if not isinstance(digest, str) or not digest.startswith("sha256:"):
|
|
273
|
-
raise EnvironmentError(f"bundle {label} has an invalid digest")
|
|
274
|
-
path = entries.get("blobs/sha256/" + digest.removeprefix("sha256:"))
|
|
275
|
-
if path is None or path.stat().st_size != size or _digest_path(path) != digest:
|
|
276
|
-
raise EnvironmentError(f"bundle {label} digest mismatch")
|
|
277
|
-
return path
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
def _require_media_type(descriptor: dict[str, Any], expected: str, label: str) -> None:
|
|
281
|
-
if descriptor.get("mediaType") != expected:
|
|
282
|
-
raise EnvironmentError(f"bundle {label} has an unsupported media type")
|
|
283
|
-
|
|
284
|
-
|
|
285
236
|
def _safe_name(name: str) -> PurePosixPath:
|
|
286
237
|
path = PurePosixPath(name)
|
|
287
238
|
if (
|
|
@@ -248,14 +248,32 @@ def _cli_source_name(path: Path) -> str:
|
|
|
248
248
|
return path.as_posix()
|
|
249
249
|
|
|
250
250
|
|
|
251
|
-
def
|
|
251
|
+
def _display_result_text(text: str, result: ExecutionResult, display_path: str | None) -> str:
|
|
252
|
+
"""Rewrite only the staged entrypoint when the CLI has a logical input name."""
|
|
253
|
+
if display_path is None or not result.command:
|
|
254
|
+
return text
|
|
255
|
+
staged = result.command[-1]
|
|
256
|
+
candidates = {staged}
|
|
257
|
+
staged_path = Path(staged)
|
|
258
|
+
if not staged_path.is_absolute():
|
|
259
|
+
candidates.add(str(Path(result.cwd) / staged_path))
|
|
260
|
+
for candidate in sorted(candidates, key=len, reverse=True):
|
|
261
|
+
text = text.replace(candidate, display_path)
|
|
262
|
+
return text
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def _emit_result(
|
|
266
|
+
result: ExecutionResult, as_json: bool, *, display_path: str | None = None
|
|
267
|
+
) -> None:
|
|
252
268
|
if as_json:
|
|
253
269
|
_json(serialize_execution_v1(result))
|
|
254
270
|
return
|
|
255
271
|
if result.stdout:
|
|
256
|
-
|
|
272
|
+
stdout = _display_result_text(result.stdout, result, display_path)
|
|
273
|
+
print(stdout, end="" if stdout.endswith("\n") else "\n")
|
|
257
274
|
if result.stderr:
|
|
258
|
-
|
|
275
|
+
stderr = _display_result_text(result.stderr, result, display_path)
|
|
276
|
+
print(stderr, end="" if stderr.endswith("\n") else "\n", file=sys.stderr)
|
|
259
277
|
status = "accepted" if result.ok else "rejected"
|
|
260
278
|
environment = f" environment={result.environment_id}" if result.environment_id else ""
|
|
261
279
|
print(
|
|
@@ -435,11 +453,11 @@ def parser() -> argparse.ArgumentParser:
|
|
|
435
453
|
program_index.add_argument("--tag", action="append", default=[])
|
|
436
454
|
program_index.add_argument("--sign", action="store_true")
|
|
437
455
|
|
|
438
|
-
check = commands.add_parser("check", help="check one Lean file
|
|
456
|
+
check = commands.add_parser("check", help="check one Lean file or all local libraries")
|
|
439
457
|
check.add_argument(
|
|
440
458
|
"inputs",
|
|
441
|
-
nargs="
|
|
442
|
-
help="FILE,
|
|
459
|
+
nargs="*",
|
|
460
|
+
help="FILE, legacy ENVIRONMENT FILE, or omit inside a Lake project; FILE may be -",
|
|
443
461
|
)
|
|
444
462
|
check.add_argument(
|
|
445
463
|
"--with",
|
|
@@ -450,7 +468,9 @@ def parser() -> argparse.ArgumentParser:
|
|
|
450
468
|
help="repeatable github:owner/repository@tag-or-commit package reference",
|
|
451
469
|
)
|
|
452
470
|
check.add_argument("--toolchain", help="override the discovered file or package toolchain")
|
|
453
|
-
check.add_argument(
|
|
471
|
+
check.add_argument(
|
|
472
|
+
"--project", type=Path, help="explicit Lake project for FILE or project-wide check"
|
|
473
|
+
)
|
|
454
474
|
check.add_argument(
|
|
455
475
|
"--include", action="append", default=[], type=Path, help="additional Lean source file"
|
|
456
476
|
)
|
|
@@ -656,6 +676,7 @@ def parser() -> argparse.ArgumentParser:
|
|
|
656
676
|
def main(argv: list[str] | None = None) -> int:
|
|
657
677
|
args = parser().parse_args(argv)
|
|
658
678
|
operation_started = time.monotonic()
|
|
679
|
+
display_path: str | None = None
|
|
659
680
|
try:
|
|
660
681
|
selected_availability = (
|
|
661
682
|
"local" if args.command in {"init", "update"} and args.offline else args.availability
|
|
@@ -712,7 +733,10 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
712
733
|
print(f"Shared packages: {init_result.packages}")
|
|
713
734
|
if args.agents:
|
|
714
735
|
print(f"Agent guide: {init_result.root / 'AGENTS.md'}")
|
|
715
|
-
|
|
736
|
+
project_name = init_plan.project_name or init_result.root.name
|
|
737
|
+
print(
|
|
738
|
+
f"Next: cd {init_result.root} && lean-runtime check {project_name}/Basic.lean"
|
|
739
|
+
)
|
|
716
740
|
return 0
|
|
717
741
|
if args.command == "scan":
|
|
718
742
|
scan_result = runtime.scan_projects(args.path, recursive=args.recursive)
|
|
@@ -859,7 +883,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
859
883
|
print(f"Created {output}")
|
|
860
884
|
return 0
|
|
861
885
|
if args.command == "install":
|
|
862
|
-
print(runtime.toolchains.
|
|
886
|
+
print(runtime.toolchains.ensure_full(args.toolchain))
|
|
863
887
|
return 0
|
|
864
888
|
if args.command == "prepare":
|
|
865
889
|
lock = runtime.prepare(EnvironmentSpec.load(args.spec), timeout=args.timeout)
|
|
@@ -1195,7 +1219,14 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1195
1219
|
if args.command == "check":
|
|
1196
1220
|
if args.project is not None and args.package_refs:
|
|
1197
1221
|
raise ValueError("check cannot combine --project with --with")
|
|
1198
|
-
if args.
|
|
1222
|
+
if not args.inputs:
|
|
1223
|
+
if args.package_refs or args.include:
|
|
1224
|
+
raise ValueError("project-wide check does not accept --with or --include")
|
|
1225
|
+
result = runtime.check_project(
|
|
1226
|
+
args.project or Path("."), toolchain=args.toolchain, policy=_policy(args)
|
|
1227
|
+
)
|
|
1228
|
+
source_file = None
|
|
1229
|
+
elif args.package_refs:
|
|
1199
1230
|
if len(args.inputs) != 1:
|
|
1200
1231
|
raise ValueError("check with --with expects exactly one FILE")
|
|
1201
1232
|
environment = runtime.open_references(args.package_refs, toolchain=args.toolchain)
|
|
@@ -1205,6 +1236,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1205
1236
|
raise ValueError("local project checks do not accept --include")
|
|
1206
1237
|
source_file = Path(args.inputs[0])
|
|
1207
1238
|
if str(source_file) == "-":
|
|
1239
|
+
display_path = "<stdin>"
|
|
1208
1240
|
result = runtime.check(
|
|
1209
1241
|
sys.stdin.read(),
|
|
1210
1242
|
toolchain=args.toolchain,
|
|
@@ -1244,6 +1276,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1244
1276
|
)
|
|
1245
1277
|
elif args.command == "check-file":
|
|
1246
1278
|
if str(args.file) == "-":
|
|
1279
|
+
display_path = "<stdin>"
|
|
1247
1280
|
result = runtime.check(
|
|
1248
1281
|
sys.stdin.read(),
|
|
1249
1282
|
toolchain=args.toolchain,
|
|
@@ -1300,7 +1333,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1300
1333
|
else:
|
|
1301
1334
|
print(f"lean-runtime: {exc}", file=sys.stderr)
|
|
1302
1335
|
return 2
|
|
1303
|
-
_emit_result(result, args.json)
|
|
1336
|
+
_emit_result(result, args.json, display_path=display_path)
|
|
1304
1337
|
if args.timings:
|
|
1305
1338
|
print(render_timings(result.timings), file=sys.stderr)
|
|
1306
1339
|
return 0 if result.ok else 1
|