lean-runtime 4.23.0__tar.gz → 4.24.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-4.23.0 → lean_runtime-4.24.0}/CHANGELOG.md +13 -0
- {lean_runtime-4.23.0/lean_runtime.egg-info → lean_runtime-4.24.0}/PKG-INFO +1 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/cli.py +30 -2
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/environments.py +17 -4
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/health.py +15 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/lake_cache.py +2 -2
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/oci.py +18 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/project_execution.py +7 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/project_sharing.py +36 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/projects.py +1 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/references.py +1 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/resolver.py +1 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/runtime.py +25 -21
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/shared_projects.py +125 -13
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/store.py +58 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/toolchain_oci.py +11 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/toolchains.py +68 -17
- {lean_runtime-4.23.0 → lean_runtime-4.24.0/lean_runtime.egg-info}/PKG-INFO +1 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/pyproject.toml +1 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/cleanup-v1.schema.json +2 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_bundles.py +45 -2
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_events_health.py +1 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_header_cache.py +4 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_interactive.py +3 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_lake_cache.py +9 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_projects.py +124 -14
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_references.py +3 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_runtime.py +3 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_store.py +25 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_toolchain_oci.py +3 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_toolchain_slim.py +2 -9
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_toolchains.py +74 -1
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/LICENSE +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/MANIFEST.in +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/README.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/environments.toml +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/locks/core-v4.32.2.lock.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/locks/leancert-v4.30.0.5.lock.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/locks/leancert-v4.31.0.lock.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/locks/leancert-v4.32.2.4.lock.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/locks/leancert-v4.33.0.lock.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/locks/mathlib-v4.30.0.lock.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/locks/mathlib-v4.31.0.lock.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/locks/mathlib-v4.32.2.lock.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/locks/mathlib-v4.33.0.lock.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/catalog/locks/mathlib-v4.33.1.lock.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/compatibility/README.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/compatibility/lake-artifact-cache-4.33.0.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/compatibility/mathlib-4.32.2.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/compatibility/mathlib-4.32.2.toml +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/compatibility/mathlib-4.33.0.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/compatibility/mathlib-4.33.0.toml +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/docs/concepts/context-selection.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/docs/index.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/docs/reference/commands.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/docs/reference/python-advanced.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/docs/reference/python-api.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/docs/reference/storage.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/docs/trust.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/docs/tutorial.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/docs/workflows/check-files.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/docs/workflows/lake-projects.md +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/examples/mathlib.toml +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/__init__.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/__main__.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/_git.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/_paths.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/backends.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/bundles.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/capsules.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/comparison.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/console.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/context_resolution.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/decisions.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/declaration_index.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/declaration_index_build.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/declaration_index_oci.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/diagnostics.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/__init__.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/analyzer.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/api.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/candidate.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/catalog.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/catalog_build.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/catalog_cli.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/catalog_manifest.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/data/catalog.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/defaults.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/engine.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/errors.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/history.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/memo.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/module_inventory.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/planner.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/policy.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/probe.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/py.typed +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/result.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/schema_resources.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/schemas/catalog-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/schemas/plan-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/discovery/schemas/result-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/errors.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/events.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/facade.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/frontmatter.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/header_cache.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/identifier_resolver.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/import_syntax.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/lake.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/lockfiles.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/locking.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/matrix.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/models.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/oci_protocol.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/packs.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/policies.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/profiling.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/programs.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/publisher_verification.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/py.typed +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/run_cli.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/schema_resources.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/serialization.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/specs.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/timings.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/toolchain_slim.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/verification.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime/wire.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime.egg-info/SOURCES.txt +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime.egg-info/dependency_links.txt +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime.egg-info/entry_points.txt +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime.egg-info/requires.txt +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/lean_runtime.egg-info/top_level.txt +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/mkdocs.yml +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/attestation-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/check-batch-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/comparison-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/execution-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/inspect-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/matrix-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/plan-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/profile-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/publication-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/schemas/verify-v1.schema.json +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/scripts/announcement_gate.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/scripts/catalog_update.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/scripts/lake_cache_gate.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/scripts/prepare_declaration_index.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/scripts/publish_declaration_index.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/scripts/registry_preflight.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/scripts/run_compatibility.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/scripts/run_v1_case_study.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/scripts/smoke_wheel.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/setup.cfg +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/conftest.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/discovery/e2e/test_real_discovery.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/discovery/test_analyzer.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/discovery/test_catalog.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/discovery/test_catalog_build.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/discovery/test_discovery_schema_resources.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/discovery/test_engine.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/discovery/test_memo.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/discovery/test_planner.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/discovery/test_policy.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_announcement_gate.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_backend.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_capsules.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_cli.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_console.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_context_resolution.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_declaration_index.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_diagnostics.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_environment_integration.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_facade.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_frontmatter.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_git.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_identifier_resolver.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_lockfiles.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_locking.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_models.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_multifile.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_oci_protocol.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_packs.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_paths.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_prebuilt_policy.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_programs.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_project_bootstrap.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_project_publish.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_run_cli.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_schema_resources.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_schemas.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_signatures.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_specs.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_v1_precision.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_verification_inventory.py +0 -0
- {lean_runtime-4.23.0 → lean_runtime-4.24.0}/tests/test_verification_probe.py +0 -0
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 4.24.0 - 2026-08-26
|
|
6
|
+
|
|
7
|
+
- Key shared Lake package artifacts by the exact installed Lean and Lake
|
|
8
|
+
executable digests. Existing `/1` package artifacts are source-only donors;
|
|
9
|
+
the first build of each project re-shares artifacts under the `/2` key.
|
|
10
|
+
- Let an exact registered dependency graph donate source across toolchain
|
|
11
|
+
versions, while stripping its build tree, and refresh existing project
|
|
12
|
+
attachments when their computed workspace identity changes.
|
|
13
|
+
- Report obsolete `/1` project artifacts in `doctor`, reclaim them through
|
|
14
|
+
`clean`, and refuse publishing moving toolchain spellings such as `master`
|
|
15
|
+
or undated `nightly`. Publication also fails early when its input is an
|
|
16
|
+
acquired sparse capsule rather than a source build.
|
|
17
|
+
|
|
5
18
|
## 4.23.0 - 2026-08-24
|
|
6
19
|
|
|
7
20
|
## 4.22.0 - 2026-08-23
|
|
@@ -179,6 +179,7 @@ def _render_cleanup(
|
|
|
179
179
|
environments: CleanupReport,
|
|
180
180
|
downloads: DownloadCleanupReport | None,
|
|
181
181
|
scratch: CleanupReport | None = None,
|
|
182
|
+
project_artifacts: CleanupReport | None = None,
|
|
182
183
|
) -> None:
|
|
183
184
|
style = styler_for(sys.stdout)
|
|
184
185
|
retained_note = style.dim(
|
|
@@ -220,6 +221,17 @@ def _render_cleanup(
|
|
|
220
221
|
)
|
|
221
222
|
else:
|
|
222
223
|
print("No abandoned workspaces to remove.")
|
|
224
|
+
if project_artifacts is not None:
|
|
225
|
+
if project_artifacts.candidates:
|
|
226
|
+
anything = True
|
|
227
|
+
print(
|
|
228
|
+
style.bold(
|
|
229
|
+
f"Would remove {len(project_artifacts.candidates)} obsolete project "
|
|
230
|
+
f"artifact tree(s) · {format_byte_size(project_artifacts.candidate_bytes)}"
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
else:
|
|
234
|
+
print("No obsolete /1 project artifacts to remove.")
|
|
223
235
|
print(retained_note)
|
|
224
236
|
if anything:
|
|
225
237
|
print()
|
|
@@ -228,10 +240,13 @@ def _render_cleanup(
|
|
|
228
240
|
reclaimed = environments.reclaimed_bytes + (downloads.reclaimed_bytes if downloads else 0)
|
|
229
241
|
if scratch is not None:
|
|
230
242
|
reclaimed += scratch.reclaimed_bytes
|
|
243
|
+
if project_artifacts is not None:
|
|
244
|
+
reclaimed += project_artifacts.reclaimed_bytes
|
|
231
245
|
removed = (
|
|
232
246
|
len(environments.removed)
|
|
233
247
|
+ (len(downloads.removed) if downloads else 0)
|
|
234
248
|
+ (len(scratch.removed) if scratch else 0)
|
|
249
|
+
+ (len(project_artifacts.removed) if project_artifacts else 0)
|
|
235
250
|
)
|
|
236
251
|
if removed:
|
|
237
252
|
parts = [f"{len(environments.removed)} environment(s)"]
|
|
@@ -239,6 +254,8 @@ def _render_cleanup(
|
|
|
239
254
|
parts.append(f"{len(downloads.removed)} cached download(s)")
|
|
240
255
|
if scratch is not None:
|
|
241
256
|
parts.append(f"{len(scratch.removed)} abandoned workspace(s)")
|
|
257
|
+
if project_artifacts is not None:
|
|
258
|
+
parts.append(f"{len(project_artifacts.removed)} obsolete project artifact tree(s)")
|
|
242
259
|
print(
|
|
243
260
|
style.green(f"Removed {' and '.join(parts)} · reclaimed {format_byte_size(reclaimed)}")
|
|
244
261
|
)
|
|
@@ -2460,12 +2477,19 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
2460
2477
|
dry_run=True,
|
|
2461
2478
|
minimum_age_seconds=min(args.minimum_age_hours * 3600, 3600),
|
|
2462
2479
|
)
|
|
2480
|
+
preview_project_artifacts = runtime.clean_legacy_project_artifacts(dry_run=True)
|
|
2463
2481
|
if not args.json:
|
|
2464
|
-
_render_cleanup(
|
|
2482
|
+
_render_cleanup(
|
|
2483
|
+
cleanup_preview,
|
|
2484
|
+
preview_downloads,
|
|
2485
|
+
preview_scratch,
|
|
2486
|
+
preview_project_artifacts,
|
|
2487
|
+
)
|
|
2465
2488
|
has_candidates = bool(
|
|
2466
2489
|
cleanup_preview.candidates
|
|
2467
2490
|
or (preview_downloads and preview_downloads.candidates)
|
|
2468
2491
|
or preview_scratch.candidates
|
|
2492
|
+
or preview_project_artifacts.candidates
|
|
2469
2493
|
)
|
|
2470
2494
|
if has_candidates and not args.dry_run:
|
|
2471
2495
|
execute_cleanup = _confirm("Remove these files?", yes=args.yes, json_mode=args.json)
|
|
@@ -2486,11 +2510,15 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
2486
2510
|
dry_run=not execute_cleanup,
|
|
2487
2511
|
minimum_age_seconds=min(args.minimum_age_hours * 3600, 3600),
|
|
2488
2512
|
)
|
|
2513
|
+
gc_project_artifacts = runtime.clean_legacy_project_artifacts(
|
|
2514
|
+
dry_run=not execute_cleanup
|
|
2515
|
+
)
|
|
2489
2516
|
if args.json:
|
|
2490
2517
|
gc_payload: dict[str, Any] = {
|
|
2491
2518
|
"environments": gc_report.to_dict(),
|
|
2492
2519
|
"downloaded_files": gc_downloads.to_dict() if gc_downloads else None,
|
|
2493
2520
|
"scratch": gc_scratch.to_dict(),
|
|
2521
|
+
"project_artifacts": gc_project_artifacts.to_dict(),
|
|
2494
2522
|
}
|
|
2495
2523
|
_json(
|
|
2496
2524
|
envelope(
|
|
@@ -2500,7 +2528,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
2500
2528
|
)
|
|
2501
2529
|
)
|
|
2502
2530
|
elif execute_cleanup:
|
|
2503
|
-
_render_cleanup(gc_report, gc_downloads, gc_scratch)
|
|
2531
|
+
_render_cleanup(gc_report, gc_downloads, gc_scratch, gc_project_artifacts)
|
|
2504
2532
|
return 0
|
|
2505
2533
|
if args.command == "check":
|
|
2506
2534
|
if args.across is not None:
|
|
@@ -766,7 +766,11 @@ class Environment:
|
|
|
766
766
|
spawn(
|
|
767
767
|
resolved_command,
|
|
768
768
|
cwd=instance,
|
|
769
|
-
environment=
|
|
769
|
+
environment=(
|
|
770
|
+
self.manager.toolchains.environment_for(self.lock.toolchain)
|
|
771
|
+
if requested_command[0] == "lake"
|
|
772
|
+
else self.manager.toolchains.environment
|
|
773
|
+
),
|
|
770
774
|
policy=selected_policy,
|
|
771
775
|
),
|
|
772
776
|
)
|
|
@@ -905,7 +909,12 @@ class Environment:
|
|
|
905
909
|
preliminary: list[BackendResult] = []
|
|
906
910
|
path_map = {str(instance / name): name for name in files}
|
|
907
911
|
staging_started = time.monotonic()
|
|
908
|
-
execution_environment =
|
|
912
|
+
execution_environment = (
|
|
913
|
+
self.manager.toolchains.environment_for(self.lock.toolchain)
|
|
914
|
+
if operation == "build"
|
|
915
|
+
or (requested_command and requested_command[0] == "lake")
|
|
916
|
+
else self.manager.toolchains.environment
|
|
917
|
+
)
|
|
909
918
|
if operation == "check":
|
|
910
919
|
assert entrypoint is not None
|
|
911
920
|
for name, source in files.items():
|
|
@@ -1301,7 +1310,11 @@ class EnvironmentManager:
|
|
|
1301
1310
|
result = self.backend.execute(
|
|
1302
1311
|
command,
|
|
1303
1312
|
cwd=workspace,
|
|
1304
|
-
environment=
|
|
1313
|
+
environment=(
|
|
1314
|
+
self.toolchains.environment_for(lock.toolchain)
|
|
1315
|
+
if requested_command[0] == "lake"
|
|
1316
|
+
else self.toolchains.environment
|
|
1317
|
+
),
|
|
1305
1318
|
policy=build_policy,
|
|
1306
1319
|
cancel=cancel,
|
|
1307
1320
|
)
|
|
@@ -1327,7 +1340,7 @@ class EnvironmentManager:
|
|
|
1327
1340
|
result = self.backend.execute(
|
|
1328
1341
|
command,
|
|
1329
1342
|
cwd=workspace,
|
|
1330
|
-
environment=self.toolchains.
|
|
1343
|
+
environment=self.toolchains.environment_for(lock.toolchain),
|
|
1331
1344
|
policy=build_policy,
|
|
1332
1345
|
cancel=cancel,
|
|
1333
1346
|
)
|
|
@@ -107,6 +107,20 @@ def diagnose(toolchains: ToolchainManager, store: EnvironmentStore) -> DoctorRep
|
|
|
107
107
|
)
|
|
108
108
|
else:
|
|
109
109
|
checks.append(DoctorCheck("scratch", "pass", "No abandoned workspaces"))
|
|
110
|
+
legacy_artifacts = store.clean_legacy_project_artifacts(dry_run=True)
|
|
111
|
+
if legacy_artifacts.candidates:
|
|
112
|
+
checks.append(
|
|
113
|
+
DoctorCheck(
|
|
114
|
+
"project-artifacts-v1",
|
|
115
|
+
"warning",
|
|
116
|
+
f"{len(legacy_artifacts.candidates)} package artifact tree(s) use the obsolete "
|
|
117
|
+
"toolchain-insensitive /1 key; reclaim them with `lean-runtime clean --yes`",
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
else:
|
|
121
|
+
checks.append(
|
|
122
|
+
DoctorCheck("project-artifacts-v1", "pass", "No obsolete /1 project artifacts")
|
|
123
|
+
)
|
|
110
124
|
store_status = store.status()
|
|
111
125
|
cutoff = datetime.now(timezone.utc).timestamp() - STALE_ENVIRONMENT_AGE_HOURS * 3600
|
|
112
126
|
stale = tuple(
|
|
@@ -145,6 +159,7 @@ def repair(toolchains: ToolchainManager, store: EnvironmentStore) -> DoctorRepor
|
|
|
145
159
|
include_legacy=True,
|
|
146
160
|
legacy_minimum_age_seconds=LEGACY_SCRATCH_MINIMUM_AGE_SECONDS,
|
|
147
161
|
)
|
|
162
|
+
store.clean_legacy_project_artifacts(dry_run=False)
|
|
148
163
|
with suppress(ToolchainError):
|
|
149
164
|
toolchains.elan_path(bootstrap=True)
|
|
150
165
|
return diagnose(toolchains, store)
|
|
@@ -160,7 +160,7 @@ class LakeArtifactCache:
|
|
|
160
160
|
try:
|
|
161
161
|
process = subprocess.run(
|
|
162
162
|
self.toolchains.command(toolchain, "lake", *arguments),
|
|
163
|
-
env=self.toolchains.
|
|
163
|
+
env=self.toolchains.environment_for(toolchain),
|
|
164
164
|
text=True,
|
|
165
165
|
stdout=subprocess.PIPE,
|
|
166
166
|
stderr=subprocess.STDOUT,
|
|
@@ -183,7 +183,7 @@ class LakeArtifactCache:
|
|
|
183
183
|
|
|
184
184
|
def environment(self, context: ProjectContext) -> dict[str, str]:
|
|
185
185
|
"""Return root-only cache settings without caching dependency packages."""
|
|
186
|
-
environment = self.toolchains.
|
|
186
|
+
environment = self.toolchains.environment_for(context.toolchain)
|
|
187
187
|
if not self.project_opted_in(context):
|
|
188
188
|
return environment
|
|
189
189
|
self.capabilities(context.toolchain)
|
|
@@ -28,7 +28,7 @@ from .bundles import (
|
|
|
28
28
|
EnvironmentBundles,
|
|
29
29
|
_capsule_config_object,
|
|
30
30
|
)
|
|
31
|
-
from .capsules import CapsuleManifest
|
|
31
|
+
from .capsules import CAPSULE_MANIFEST, CapsuleManifest
|
|
32
32
|
from .errors import (
|
|
33
33
|
CredentialAcquisitionError,
|
|
34
34
|
DownloadLimitExceeded,
|
|
@@ -62,6 +62,7 @@ from .store import (
|
|
|
62
62
|
platform_compatibility,
|
|
63
63
|
platform_record,
|
|
64
64
|
)
|
|
65
|
+
from .toolchains import immutable_toolchain_spelling
|
|
65
66
|
|
|
66
67
|
_REPOSITORY = re.compile(r"[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)+")
|
|
67
68
|
_BEARER_PARAMETER = re.compile(r'([a-zA-Z]+)="([^"]*)"')
|
|
@@ -1458,6 +1459,22 @@ class OCIEnvironmentPublisher:
|
|
|
1458
1459
|
) -> PublicationInfo:
|
|
1459
1460
|
if profile != "check-capsule":
|
|
1460
1461
|
raise ValueError("publication profile must be 'check-capsule'")
|
|
1462
|
+
root = self.store.environment_path(environment_id)
|
|
1463
|
+
try:
|
|
1464
|
+
metadata = json.loads((root / "metadata.json").read_text(encoding="utf-8"))
|
|
1465
|
+
lock = self.store.load_lock(str(metadata["lock_id"]))
|
|
1466
|
+
except (OSError, KeyError, TypeError, json.JSONDecodeError) as exc:
|
|
1467
|
+
raise EnvironmentError("publication input has invalid environment metadata") from exc
|
|
1468
|
+
if (root / "workspace" / CAPSULE_MANIFEST).is_file():
|
|
1469
|
+
raise EnvironmentError(
|
|
1470
|
+
"publication input must be source-built; sparse acquired capsules cannot be "
|
|
1471
|
+
"republished"
|
|
1472
|
+
)
|
|
1473
|
+
if not immutable_toolchain_spelling(lock.toolchain):
|
|
1474
|
+
raise EnvironmentError(
|
|
1475
|
+
f"refusing to publish mutable toolchain spelling {lock.toolchain!r}; "
|
|
1476
|
+
"use an immutable release or dated nightly"
|
|
1477
|
+
)
|
|
1461
1478
|
self.check_access()
|
|
1462
1479
|
with tempfile.TemporaryDirectory(prefix="lean-runtime-publish-") as temporary:
|
|
1463
1480
|
temporary_root = Path(temporary)
|
|
@@ -214,6 +214,7 @@ class ProjectExecutor:
|
|
|
214
214
|
project=provenance,
|
|
215
215
|
packages=context.package_provenance(),
|
|
216
216
|
logical_command=("lake", "env", "lean", relative),
|
|
217
|
+
environment=self.runtime.toolchains.environment_for(context.toolchain),
|
|
217
218
|
cancel=cancel,
|
|
218
219
|
)
|
|
219
220
|
|
|
@@ -260,6 +261,7 @@ class ProjectExecutor:
|
|
|
260
261
|
packages=context.package_provenance(),
|
|
261
262
|
logical_command=("lake", "env", "lean", safe_filename),
|
|
262
263
|
path_map={relative: safe_filename, str(source_path): safe_filename},
|
|
264
|
+
environment=self.runtime.toolchains.environment_for(context.toolchain),
|
|
263
265
|
cancel=cancel,
|
|
264
266
|
)
|
|
265
267
|
|
|
@@ -349,6 +351,10 @@ class ProjectExecutor:
|
|
|
349
351
|
shared: bool | None = None,
|
|
350
352
|
restore_artifacts: bool = False,
|
|
351
353
|
) -> ExecutionResult:
|
|
354
|
+
# Shared preparation may select compiled donors before Lake is invoked.
|
|
355
|
+
# Establish the exact full build toolchain first so the entire operation,
|
|
356
|
+
# including nested Lake/Lean subprocesses, has one toolchain boundary.
|
|
357
|
+
self.runtime.toolchains.ensure_full(context.toolchain, cancel=cancel)
|
|
352
358
|
selected_shared = project_sharing_enabled(context.root) if shared is None else shared
|
|
353
359
|
workspace = (
|
|
354
360
|
self.runtime.shared_projects.prepare(context, cancel=cancel)
|
|
@@ -501,7 +507,7 @@ class ProjectExecutor:
|
|
|
501
507
|
process = subprocess.run(
|
|
502
508
|
command,
|
|
503
509
|
cwd=context.root,
|
|
504
|
-
env=self.runtime.toolchains.
|
|
510
|
+
env=self.runtime.toolchains.environment_for(context.toolchain),
|
|
505
511
|
text=True,
|
|
506
512
|
stdout=subprocess.PIPE,
|
|
507
513
|
stderr=subprocess.STDOUT,
|
|
@@ -465,6 +465,7 @@ def plan_adoption(
|
|
|
465
465
|
entry=entry,
|
|
466
466
|
source_package=source_package,
|
|
467
467
|
effective_entries=effective_entries,
|
|
468
|
+
toolchain_identity=None,
|
|
468
469
|
)
|
|
469
470
|
key = sha256_id("project_package", identity)
|
|
470
471
|
else:
|
|
@@ -558,6 +559,41 @@ class ProjectAdopter:
|
|
|
558
559
|
lake_dir = context.root / ".lake"
|
|
559
560
|
lake_dir.mkdir(parents=True, exist_ok=True)
|
|
560
561
|
packages_dir = _packages_directory(context)
|
|
562
|
+
marker = lake_dir / ATTACHMENT_RECORD
|
|
563
|
+
try:
|
|
564
|
+
attachment = json.loads(marker.read_text(encoding="utf-8"))
|
|
565
|
+
except (OSError, json.JSONDecodeError):
|
|
566
|
+
attachment = None
|
|
567
|
+
links_match = isinstance(attachment, dict) and (
|
|
568
|
+
attachment.get("schema") == ATTACHMENT_SCHEMA
|
|
569
|
+
and attachment.get("workspace_id") == workspace.workspace_id
|
|
570
|
+
)
|
|
571
|
+
if links_match:
|
|
572
|
+
for entry in manifest_packages:
|
|
573
|
+
if entry["type"] != "git":
|
|
574
|
+
continue
|
|
575
|
+
name = str(entry["name"])
|
|
576
|
+
package_dir = override_package_dirs.get(name)
|
|
577
|
+
link = packages_dir / name
|
|
578
|
+
if package_dir is None or not link.is_symlink():
|
|
579
|
+
links_match = False
|
|
580
|
+
break
|
|
581
|
+
subdir = _package_subdir(entry)
|
|
582
|
+
target = package_dir
|
|
583
|
+
if subdir is not None:
|
|
584
|
+
for _part in subdir.parts:
|
|
585
|
+
target = target.parent
|
|
586
|
+
if link.resolve() != target.resolve():
|
|
587
|
+
links_match = False
|
|
588
|
+
break
|
|
589
|
+
if links_match:
|
|
590
|
+
return AdoptionResult(
|
|
591
|
+
context.root,
|
|
592
|
+
"already-attached",
|
|
593
|
+
len(workspace.package_ids),
|
|
594
|
+
0,
|
|
595
|
+
workspace.workspace_id,
|
|
596
|
+
)
|
|
561
597
|
if packages_dir.parent != lake_dir:
|
|
562
598
|
packages_dir.parent.mkdir(parents=True, exist_ok=True)
|
|
563
599
|
token = f"{os.getpid()}.{uuid.uuid4().hex}"
|
|
@@ -567,7 +603,6 @@ class ProjectAdopter:
|
|
|
567
603
|
staging.mkdir()
|
|
568
604
|
swapped = False
|
|
569
605
|
had_original = packages_dir.exists() or packages_dir.is_symlink()
|
|
570
|
-
marker = lake_dir / ATTACHMENT_RECORD
|
|
571
606
|
config = context.root / PROJECT_CONFIG
|
|
572
607
|
try:
|
|
573
608
|
self.shared.events.emit(
|
|
@@ -101,7 +101,7 @@ def _lake_metadata(path: Path, toolchain: str, runtime: Runtime) -> tuple[str, t
|
|
|
101
101
|
process = subprocess.run(
|
|
102
102
|
command,
|
|
103
103
|
cwd=path,
|
|
104
|
-
env=runtime.toolchains.
|
|
104
|
+
env=runtime.toolchains.environment_for(toolchain),
|
|
105
105
|
text=True,
|
|
106
106
|
stdout=subprocess.PIPE,
|
|
107
107
|
stderr=subprocess.STDOUT,
|
|
@@ -127,7 +127,7 @@ class EnvironmentResolver:
|
|
|
127
127
|
process = self.backend.execute(
|
|
128
128
|
command,
|
|
129
129
|
cwd=workspace,
|
|
130
|
-
environment=self.toolchains.
|
|
130
|
+
environment=self.toolchains.environment_for(toolchain),
|
|
131
131
|
policy=ExecutionPolicy(timeout_seconds=timeout, max_output_bytes=10_000_000),
|
|
132
132
|
cancel=cancel,
|
|
133
133
|
)
|
|
@@ -118,7 +118,7 @@ from .store import (
|
|
|
118
118
|
platform_record,
|
|
119
119
|
)
|
|
120
120
|
from .toolchain_oci import OCIToolchainLibrary, OCIToolchainPublisher, ToolchainPublication
|
|
121
|
-
from .toolchains import ToolchainManager, normalize_toolchain
|
|
121
|
+
from .toolchains import ToolchainManager, immutable_toolchain_spelling, normalize_toolchain
|
|
122
122
|
from .verification import (
|
|
123
123
|
VerificationCheck,
|
|
124
124
|
VerificationReport,
|
|
@@ -254,7 +254,7 @@ class Runtime:
|
|
|
254
254
|
self.home = self.toolchains.home
|
|
255
255
|
self.backend = backend or LocalBackend()
|
|
256
256
|
self.store = EnvironmentStore(self.home)
|
|
257
|
-
self.shared_projects = SharedProjectManager(self.home, self.events)
|
|
257
|
+
self.shared_projects = SharedProjectManager(self.home, self.events, self.toolchains)
|
|
258
258
|
self.lake_cache = LakeArtifactCache(self.home, self.toolchains, self.events)
|
|
259
259
|
self.header_cache = LeanHeaderCache(self.home, self.toolchains, self.events)
|
|
260
260
|
self.identifier_resolver = IdentifierResolver(self.home)
|
|
@@ -800,6 +800,16 @@ class Runtime:
|
|
|
800
800
|
if sign and not finalize:
|
|
801
801
|
raise ValueError("platform-only publishing cannot sign a lock index")
|
|
802
802
|
environment = self.environment(identifier)
|
|
803
|
+
if environment.sparse:
|
|
804
|
+
raise EnvironmentError(
|
|
805
|
+
"publication input must be source-built; sparse acquired capsules cannot be "
|
|
806
|
+
"republished"
|
|
807
|
+
)
|
|
808
|
+
if not immutable_toolchain_spelling(environment.lock.toolchain):
|
|
809
|
+
raise EnvironmentError(
|
|
810
|
+
f"refusing to publish mutable toolchain spelling "
|
|
811
|
+
f"{environment.lock.toolchain!r}; use an immutable release or dated nightly"
|
|
812
|
+
)
|
|
803
813
|
repository = OCIRepository.parse(library)
|
|
804
814
|
selected_publisher = publisher or OCIEnvironmentPublisher(
|
|
805
815
|
repository, self.store, self.bundles, self.events
|
|
@@ -1531,7 +1541,7 @@ class Runtime:
|
|
|
1531
1541
|
process = subprocess.run(
|
|
1532
1542
|
command,
|
|
1533
1543
|
cwd=context.root,
|
|
1534
|
-
env=self.toolchains.
|
|
1544
|
+
env=self.toolchains.environment_for(context.toolchain),
|
|
1535
1545
|
text=True,
|
|
1536
1546
|
stdout=subprocess.PIPE,
|
|
1537
1547
|
stderr=subprocess.STDOUT,
|
|
@@ -1569,18 +1579,6 @@ class Runtime:
|
|
|
1569
1579
|
results: list[AdoptionResult] = []
|
|
1570
1580
|
failures: list[tuple[Path, str]] = []
|
|
1571
1581
|
for project in selected_plan.projects:
|
|
1572
|
-
if project.attached:
|
|
1573
|
-
workspace_id = discover_project(project.root).provenance().workspace_id
|
|
1574
|
-
results.append(
|
|
1575
|
-
AdoptionResult(
|
|
1576
|
-
project.root,
|
|
1577
|
-
"already-attached",
|
|
1578
|
-
len(project.packages),
|
|
1579
|
-
0,
|
|
1580
|
-
workspace_id,
|
|
1581
|
-
)
|
|
1582
|
-
)
|
|
1583
|
-
continue
|
|
1584
1582
|
if not project.ready:
|
|
1585
1583
|
continue
|
|
1586
1584
|
context = discover_project(project.root)
|
|
@@ -2210,12 +2208,7 @@ class Runtime:
|
|
|
2210
2208
|
plan.project_name or target.name,
|
|
2211
2209
|
"lib",
|
|
2212
2210
|
)
|
|
2213
|
-
|
|
2214
|
-
command_environment = (
|
|
2215
|
-
environment_for(plan.toolchain)
|
|
2216
|
-
if callable(environment_for)
|
|
2217
|
-
else self.toolchains.environment
|
|
2218
|
-
)
|
|
2211
|
+
command_environment = self.toolchains.environment_for(plan.toolchain)
|
|
2219
2212
|
process = subprocess.run(
|
|
2220
2213
|
command,
|
|
2221
2214
|
cwd=staging,
|
|
@@ -2472,6 +2465,14 @@ class Runtime:
|
|
|
2472
2465
|
"""Reclaim abandoned disposable execution and resolution workspaces."""
|
|
2473
2466
|
return self.store.clean_scratch(dry_run=dry_run, minimum_age_seconds=minimum_age_seconds)
|
|
2474
2467
|
|
|
2468
|
+
def clean_legacy_project_artifacts(
|
|
2469
|
+
self, *, dry_run: bool = True, minimum_age_seconds: float = 0
|
|
2470
|
+
) -> CleanupReport:
|
|
2471
|
+
return self.store.clean_legacy_project_artifacts(
|
|
2472
|
+
dry_run=dry_run,
|
|
2473
|
+
minimum_age_seconds=minimum_age_seconds,
|
|
2474
|
+
)
|
|
2475
|
+
|
|
2475
2476
|
def clean_downloads(
|
|
2476
2477
|
self, *, dry_run: bool = True, minimum_age_seconds: float = 2_592_000
|
|
2477
2478
|
) -> DownloadCleanupReport:
|
|
@@ -2576,6 +2577,9 @@ class Runtime:
|
|
|
2576
2577
|
source_digest=sha256_text(source),
|
|
2577
2578
|
policy=policy,
|
|
2578
2579
|
path_map={str(source_path): safe_filename},
|
|
2580
|
+
environment=(
|
|
2581
|
+
self.toolchains.environment_for(selected) if project_root is not None else None
|
|
2582
|
+
),
|
|
2579
2583
|
cancel=cancel,
|
|
2580
2584
|
)
|
|
2581
2585
|
|