tan-cli 0.7.0__py3-none-any.whl
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.
- tan/__init__.py +0 -0
- tan/__main__.py +120 -0
- tan/cli.py +939 -0
- tan/command_table.py +265 -0
- tan/commands/__init__.py +8 -0
- tan/commands/bootstrap_cmd.py +4856 -0
- tan/commands/bootstrap_patches.py +164 -0
- tan/commands/bootstrap_toolchain_fetch.py +155 -0
- tan/commands/bootstrap_toolchain_pin.py +36 -0
- tan/commands/build/__init__.py +1 -0
- tan/commands/build/configure_inputs.py +277 -0
- tan/commands/build/execute.py +1852 -0
- tan/commands/build/host_python.py +59 -0
- tan/commands/build/link_stale.py +78 -0
- tan/commands/build/manifest.py +428 -0
- tan/commands/build/materialise.py +81 -0
- tan/commands/build/token_substitution.py +381 -0
- tan/commands/build/toolchain.py +482 -0
- tan/commands/build/user_defines_wipe.py +115 -0
- tan/commands/build/workspace_patches.py +65 -0
- tan/commands/build_cmd.py +2236 -0
- tan/commands/build_output.py +331 -0
- tan/commands/clean_cmd.py +1183 -0
- tan/commands/completion_cmd.py +786 -0
- tan/commands/debug_config_cmd.py +2425 -0
- tan/commands/diff_cmd.py +940 -0
- tan/commands/doctor_cmd.py +4767 -0
- tan/commands/examples_cmd.py +644 -0
- tan/commands/explain_cmd.py +1319 -0
- tan/commands/faultdecode_cmd.py +931 -0
- tan/commands/flash_atoc_guard.py +240 -0
- tan/commands/flash_cmd.py +5731 -0
- tan/commands/flash_mram_guard.py +150 -0
- tan/commands/flash_ram.py +578 -0
- tan/commands/flash_raw.py +583 -0
- tan/commands/generate_cmd.py +1456 -0
- tan/commands/image_cmd.py +753 -0
- tan/commands/init_cmd.py +1740 -0
- tan/commands/inspect_cmd.py +377 -0
- tan/commands/kconfig_cmd.py +734 -0
- tan/commands/model_cmd.py +1514 -0
- tan/commands/model_device_cmd.py +351 -0
- tan/commands/model_device_live.py +234 -0
- tan/commands/model_host_cmd.py +430 -0
- tan/commands/model_zoo_cmd.py +363 -0
- tan/commands/monitor_actions.py +125 -0
- tan/commands/monitor_cmd.py +626 -0
- tan/commands/monitor_session.py +505 -0
- tan/commands/new_som_cmd.py +1522 -0
- tan/commands/pinmux_cmd.py +568 -0
- tan/commands/presets_cmd.py +1123 -0
- tan/commands/probe_cmd.py +421 -0
- tan/commands/reset_cmd.py +354 -0
- tan/commands/reset_confirm.py +168 -0
- tan/commands/run_cmd.py +637 -0
- tan/commands/scaffold_cmd.py +490 -0
- tan/commands/sdk_cmd.py +1723 -0
- tan/commands/size_cmd.py +1020 -0
- tan/commands/support_bundle_cmd.py +1073 -0
- tan/commands/trace_cmd.py +341 -0
- tan/commands/validate_cmd.py +2009 -0
- tan/commands/west_forward_cmd.py +736 -0
- tan/commands/workspace_patch_check.py +296 -0
- tan/core/__init__.py +1 -0
- tan/core/alp_conf_pregen.py +100 -0
- tan/core/artifact_provenance.py +240 -0
- tan/core/atoc_guard.py +276 -0
- tan/core/atoc_guard_messages.py +232 -0
- tan/core/atoc_replacement.py +118 -0
- tan/core/atomic_write.py +178 -0
- tan/core/board_context.py +351 -0
- tan/core/board_diagnostic.py +111 -0
- tan/core/board_files.py +221 -0
- tan/core/board_validator.py +542 -0
- tan/core/board_validator_compat.py +196 -0
- tan/core/board_validator_run.py +129 -0
- tan/core/board_validator_schema.py +186 -0
- tan/core/board_validator_skew.py +46 -0
- tan/core/board_yaml_edit.py +295 -0
- tan/core/board_yaml_pos.py +118 -0
- tan/core/bootstrap.py +2572 -0
- tan/core/build_plan.py +625 -0
- tan/core/consent.py +104 -0
- tan/core/console_filter.py +245 -0
- tan/core/debug_launch.py +1803 -0
- tan/core/devicetree_lint.py +168 -0
- tan/core/dir_removal.py +229 -0
- tan/core/doctor_git.py +172 -0
- tan/core/doctor_libraries.py +253 -0
- tan/core/doctor_render.py +185 -0
- tan/core/doctor_scope.py +66 -0
- tan/core/doctor_setools.py +237 -0
- tan/core/doctor_stale.py +180 -0
- tan/core/document_guards.py +723 -0
- tan/core/dp_id.py +97 -0
- tan/core/elf_load.py +63 -0
- tan/core/error_catalog.py +171 -0
- tan/core/example_catalog.py +499 -0
- tan/core/example_facets.py +151 -0
- tan/core/faultdecode.py +521 -0
- tan/core/flash_plan.py +2501 -0
- tan/core/flow_d_report.py +381 -0
- tan/core/flow_d_uptime.py +164 -0
- tan/core/fs_confine.py +130 -0
- tan/core/global_flags.py +230 -0
- tan/core/host_python.py +210 -0
- tan/core/image_bundle.py +247 -0
- tan/core/inert.py +147 -0
- tan/core/jlink_binary.py +128 -0
- tan/core/jlink_probe.py +481 -0
- tan/core/jsonc_splice.py +404 -0
- tan/core/launch_provenance.py +257 -0
- tan/core/link_refusal.py +76 -0
- tan/core/metadata_schema.py +376 -0
- tan/core/model_check.py +227 -0
- tan/core/model_device.py +449 -0
- tan/core/model_doctor.py +198 -0
- tan/core/model_host.py +48 -0
- tan/core/model_list.py +112 -0
- tan/core/model_zoo.py +353 -0
- tan/core/module_template.py +340 -0
- tan/core/mram_link.py +87 -0
- tan/core/new_som_ospi.py +94 -0
- tan/core/os_class.py +159 -0
- tan/core/patch_paths.py +87 -0
- tan/core/pending.py +40 -0
- tan/core/plain_zephyr_plan.py +138 -0
- tan/core/plan_exec.py +373 -0
- tan/core/plan_tokens.py +600 -0
- tan/core/probe.py +155 -0
- tan/core/probe_plan.py +237 -0
- tan/core/proxy.py +168 -0
- tan/core/publish.py +31 -0
- tan/core/python_floor.py +178 -0
- tan/core/ram_run.py +694 -0
- tan/core/ram_watch.py +231 -0
- tan/core/raw_write.py +160 -0
- tan/core/reset_plan.py +56 -0
- tan/core/run.py +161 -0
- tan/core/scaffold.py +2203 -0
- tan/core/scaffold_selftest_identity.py +225 -0
- tan/core/sdk_default_registry.py +565 -0
- tan/core/sdk_discovery.py +996 -0
- tan/core/sdk_removal.py +465 -0
- tan/core/serial_actions.py +175 -0
- tan/core/serial_capture.py +185 -0
- tan/core/serial_url.py +45 -0
- tan/core/setools.py +608 -0
- tan/core/setools_scratch.py +243 -0
- tan/core/shapes.py +194 -0
- tan/core/size.py +610 -0
- tan/core/som_buildability.py +204 -0
- tan/core/som_schema_version.py +62 -0
- tan/core/subprocess_env.py +201 -0
- tan/core/sysbuild_image.py +94 -0
- tan/core/system_manifest.py +827 -0
- tan/core/text_layout.py +73 -0
- tan/core/timestamp.py +182 -0
- tan/core/tool_lookup.py +383 -0
- tan/core/toolchain_pin.py +117 -0
- tan/core/toolchain_provision.py +1224 -0
- tan/core/trusted_path.py +134 -0
- tan/core/uboot_breakin.py +154 -0
- tan/core/uri_reference.py +415 -0
- tan/core/user_defines.py +152 -0
- tan/core/venv.py +332 -0
- tan/core/west_patches.py +143 -0
- tan/core/west_workspace_refusal.py +159 -0
- tan/core/zephyr_env.py +124 -0
- tan/env.py +185 -0
- tan/envelope.py +647 -0
- tan/exit_codes.py +12 -0
- tan/lazy_typer.py +185 -0
- tan/model/__init__.py +2 -0
- tan/model/_gen_fixture.py +132 -0
- tan/model/adapters/__init__.py +116 -0
- tan/model/adapters/cpu.py +26 -0
- tan/model/adapters/deepx.py +94 -0
- tan/model/adapters/drpai.py +242 -0
- tan/model/adapters/ethos_u.py +951 -0
- tan/model/adapters/executorch.py +55 -0
- tan/model/analyze.py +694 -0
- tan/model/build.py +304 -0
- tan/model/check.py +682 -0
- tan/model/manifest.py +625 -0
- tan/model/measure.py +216 -0
- tan/model/npu_ops_validate.py +130 -0
- tan/model/package.py +125 -0
- tan/model/perf.py +635 -0
- tan/model/perf_apply.py +721 -0
- tan/model/prep.py +193 -0
- tan/model/sram_fit.py +502 -0
- tan/model/targets.py +374 -0
- tan/model/tensorio.py +287 -0
- tan/net.py +73 -0
- tan/output_format.py +213 -0
- tan/planner/__init__.py +219 -0
- tan/planner/aperture.py +202 -0
- tan/planner/buildplan.py +1092 -0
- tan/planner/camera_owner.py +192 -0
- tan/planner/cameras.py +132 -0
- tan/planner/carveout.py +755 -0
- tan/planner/cli.py +274 -0
- tan/planner/headers.py +315 -0
- tan/planner/kconfig.py +2435 -0
- tan/planner/kconfig_symbols.py +473 -0
- tan/planner/libraries.py +677 -0
- tan/planner/link_target.py +237 -0
- tan/planner/linux_ownership.py +216 -0
- tan/planner/loader.py +1525 -0
- tan/planner/manifest.py +116 -0
- tan/planner/memory.py +161 -0
- tan/planner/memregion.py +56 -0
- tan/planner/models.py +533 -0
- tan/planner/orchestrator.py +874 -0
- tan/planner/ownership.py +203 -0
- tan/planner/partition.py +1160 -0
- tan/planner/paths.py +32 -0
- tan/planner/plain_slice.py +139 -0
- tan/planner/project_emit/__init__.py +60 -0
- tan/planner/project_emit/bom_netlist.py +375 -0
- tan/planner/project_emit/dts.py +580 -0
- tan/planner/project_emit/hw_info.py +221 -0
- tan/planner/project_emit/native_sim.py +136 -0
- tan/planner/project_emit/west_libs.py +213 -0
- tan/planner/project_loader.py +264 -0
- tan/planner/sdk_capability.py +203 -0
- tan/planner/sdk_compat.py +395 -0
- tan/planner/secure.py +350 -0
- tan/planner/slugs.py +394 -0
- tan/planner/som_metadata.py +325 -0
- tan/planner/strict_loaders.py +131 -0
- tan/planner/template.py +1037 -0
- tan/planner/template_pins.py +535 -0
- tan/planner/template_rewrite.py +714 -0
- tan/planner/topology.py +208 -0
- tan/planner/validate.py +365 -0
- tan/planner/whole_device_alias.py +67 -0
- tan/planner/zephyr_board.py +3510 -0
- tan/planner_cli.py +97 -0
- tan/planner_emit.py +617 -0
- tan/planner_root.py +119 -0
- tan/soc_ref.py +58 -0
- tan/templates/__init__.py +34 -0
- tan/templates/vendored/MANIFEST.md +1862 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/testcase.yaml +53 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/testcase.yaml +53 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/testcase.yaml +62 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/board.yaml +37 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/testcase.yaml +62 -0
- tan/templates/vendored/iot/E1M-AEN801/CMakeLists.txt +14 -0
- tan/templates/vendored/iot/E1M-AEN801/README.md +103 -0
- tan/templates/vendored/iot/E1M-AEN801/board.yaml +69 -0
- tan/templates/vendored/iot/E1M-AEN801/prj.conf +15 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.c +196 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.h +173 -0
- tan/templates/vendored/iot/E1M-AEN801/src/main.c +262 -0
- tan/templates/vendored/iot/E1M-AEN801/testcase.yaml +68 -0
- tan/templates/vendored/minimal/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/README.md +108 -0
- tan/templates/vendored/minimal/E1M-AEN801/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-AEN801/testcase.yaml +49 -0
- tan/templates/vendored/minimal/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/README.md +108 -0
- tan/templates/vendored/minimal/E1M-V2N101/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-V2N101/testcase.yaml +49 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/README.md +120 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/boards/native_sim_native_64.overlay +40 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/CMakeLists.txt +13 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/main.c +171 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/prj.conf +17 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/testcase.yaml +23 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/prj.conf +22 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/src/main.c +185 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/testcase.yaml +26 -0
- tan/templates/vendored/sensor/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/sensor/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-AEN801/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-AEN801/testcase.yaml +52 -0
- tan/templates/vendored/sensor/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/sensor/E1M-V2N101/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-V2N101/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-V2N101/testcase.yaml +52 -0
- tan/version.py +102 -0
- tan_cli-0.7.0.dist-info/METADATA +125 -0
- tan_cli-0.7.0.dist-info/RECORD +330 -0
- tan_cli-0.7.0.dist-info/WHEEL +5 -0
- tan_cli-0.7.0.dist-info/entry_points.txt +2 -0
- tan_cli-0.7.0.dist-info/top_level.txt +1 -0
tan/planner_root.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Where the relocated planner finds the SDK -- bound once, before import.
|
|
3
|
+
|
|
4
|
+
`tan.planner` is alp-sdk's `scripts/alp_orchestrate/` relocated verbatim. In
|
|
5
|
+
alp-sdk its `paths.py` derived the repo root by walking up from its own
|
|
6
|
+
`__file__`; inside `tan` that walk lands on the `tan` package and every
|
|
7
|
+
`metadata/**` path would be wrong. So the root becomes an explicit binding.
|
|
8
|
+
|
|
9
|
+
**Binding must happen before `tan.planner` is imported.** `paths.py` evaluates
|
|
10
|
+
`REPO = sdk_root()` at module scope, and half the package takes
|
|
11
|
+
`metadata_root: Path = METADATA_ROOT` as a *default argument* -- both freeze at
|
|
12
|
+
import time. An unbound import therefore raises `PlannerRootError` loudly
|
|
13
|
+
rather than silently resolving `metadata/**` against the wrong tree; that is
|
|
14
|
+
the same refuse-don't-degrade posture the executor's token substitution takes
|
|
15
|
+
(`tan/commands/build/token_substitution.py`).
|
|
16
|
+
|
|
17
|
+
`metadata/**` stays in alp-sdk (ADR-0017): what relocated is the generators,
|
|
18
|
+
never the facts. The fact READERS relocated with them -- `resolve_memory_map`,
|
|
19
|
+
`resolve_capabilities`, `silicon_to_kconfig` and `som_unpopulated_capabilities`
|
|
20
|
+
now live in `tan/planner/som_metadata.py`, `peripheral_kconfig` in
|
|
21
|
+
`tan/planner/slugs.py`, `iter_schema_errors` in `tan/planner/loader.py`, the
|
|
22
|
+
SKU/board/pad-route resolvers in `tan/planner/project_loader.py`, and the
|
|
23
|
+
`alp_project.py`-owned emitters in `tan/planner/project_emit/` +
|
|
24
|
+
`tan/planner/zephyr_board.py` -- and every one of them reads the same files out
|
|
25
|
+
of the bound checkout. **No `tan.planner` module imports anything under
|
|
26
|
+
`<sdk_root>/scripts` any more**, which is what makes an in-process emit load zero
|
|
27
|
+
of alp-sdk's Python
|
|
28
|
+
(`tests/parity/test_planner_emit_parity.py::test_the_in_process_path_loads_none_of_the_sdks_python`
|
|
29
|
+
is the measurement, per mode across all twelve).
|
|
30
|
+
|
|
31
|
+
**Binding does NOT put `<sdk_root>/scripts` on `sys.path`, deliberately.** Nothing
|
|
32
|
+
in `tan`'s own execution needs it: every `tan generate` target renders
|
|
33
|
+
in-process, `tan build` plans in-process, and the one remaining SDK script --
|
|
34
|
+
`alp_project.py` under `TAN_GENERATE_EXECUTOR=subprocess` -- is SPAWNED, and a
|
|
35
|
+
spawned interpreter gets its own script directory regardless of this
|
|
36
|
+
process's `sys.path`. (The Kconfig dumper Zephyr's `EXTRA_KCONFIG_TARGET`
|
|
37
|
+
hook spawns is no longer an SDK edge either: `tan.planner.kconfig_symbols`
|
|
38
|
+
renders it into the run's own scratch tree.)
|
|
39
|
+
|
|
40
|
+
Removing the entry is what turns the zero closure from **measured** into
|
|
41
|
+
**structural**. With `<sdk_root>/scripts` importable, a re-introduced
|
|
42
|
+
`from alp_project import ...` would silently work and only a closure measurement
|
|
43
|
+
would catch it; without it, that import fails loudly at the moment it is written.
|
|
44
|
+
The measurement
|
|
45
|
+
(`tests/parity/test_planner_emit_parity.py::test_the_in_process_path_loads_none_of_the_sdks_python`)
|
|
46
|
+
stays as the belt to this braces.
|
|
47
|
+
|
|
48
|
+
A caller that genuinely needs an SDK module by name in tan's own process must put
|
|
49
|
+
the path there itself and own it. Exactly one does: the parity harness's oracle,
|
|
50
|
+
whose `planners` fixture inserts `<sdk>/scripts` explicitly so it can import
|
|
51
|
+
`alp_project` and diff the relocated planner against the original. That is a test
|
|
52
|
+
comparing two implementations, not `tan` depending on one.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
from __future__ import annotations
|
|
56
|
+
|
|
57
|
+
import sys
|
|
58
|
+
from pathlib import Path
|
|
59
|
+
|
|
60
|
+
__all__ = ["PlannerRootError", "bind_sdk_root", "sdk_root", "emit"]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class PlannerRootError(RuntimeError):
|
|
64
|
+
"""The planner's SDK root is unbound, or a rebind came too late."""
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
_BOUND: Path | None = None
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def bind_sdk_root(root: Path | str) -> Path:
|
|
71
|
+
"""Point the relocated planner at an alp-sdk checkout. Idempotent.
|
|
72
|
+
|
|
73
|
+
Rebinding to a *different* root once `tan.planner` is imported is an error,
|
|
74
|
+
not a no-op: the already-frozen module constants and default arguments would
|
|
75
|
+
keep reading the first root's `metadata/**` while callers believed the
|
|
76
|
+
second -- a silent wrong-SDK build, which is precisely the split-brain the
|
|
77
|
+
plan's `sdkCommit` guard exists to catch.
|
|
78
|
+
|
|
79
|
+
Binding touches `sys.path` not at all -- see the module docstring. The root is
|
|
80
|
+
a value the relocated planner reads, not an import route.
|
|
81
|
+
"""
|
|
82
|
+
global _BOUND
|
|
83
|
+
resolved = Path(root).resolve()
|
|
84
|
+
if (
|
|
85
|
+
_BOUND is not None
|
|
86
|
+
and _BOUND != resolved
|
|
87
|
+
and "tan.planner" in sys.modules
|
|
88
|
+
):
|
|
89
|
+
raise PlannerRootError(
|
|
90
|
+
f"the planner is already bound to `{_BOUND}` and imported; "
|
|
91
|
+
f"cannot rebind to `{resolved}` in the same process.")
|
|
92
|
+
_BOUND = resolved
|
|
93
|
+
return resolved
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def sdk_root() -> Path:
|
|
97
|
+
"""The bound alp-sdk checkout root. Raises if unbound."""
|
|
98
|
+
if _BOUND is None:
|
|
99
|
+
raise PlannerRootError(
|
|
100
|
+
"tan.planner was imported before `bind_sdk_root(<alp-sdk root>)`; "
|
|
101
|
+
"its metadata paths freeze at import time, so an unbound import "
|
|
102
|
+
"cannot be repaired -- bind first, then import.")
|
|
103
|
+
return _BOUND
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def emit(mode: str, *, root: Path | str, board_yaml: Path,
|
|
107
|
+
build_root: Path = Path("build"), core: str | None = None) -> str:
|
|
108
|
+
"""Bind, load `board_yaml`, and return one emit artefact as text.
|
|
109
|
+
|
|
110
|
+
The in-process twin of `python -m tan.planner --emit <mode>`; both route
|
|
111
|
+
through the same `tan.planner.cli.emit_artefact` dispatch so a mode can
|
|
112
|
+
never render differently depending on how it was reached.
|
|
113
|
+
"""
|
|
114
|
+
bind_sdk_root(root)
|
|
115
|
+
from tan.planner import load_board_yaml
|
|
116
|
+
from tan.planner.cli import emit_artefact
|
|
117
|
+
project = load_board_yaml(Path(board_yaml))
|
|
118
|
+
return emit_artefact(project, mode, board_yaml=Path(board_yaml),
|
|
119
|
+
build_root=Path(build_root), core=core)
|
tan/soc_ref.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Pure `silicon:` ref -> SoC-JSON path resolution.
|
|
3
|
+
|
|
4
|
+
A leaf module: no imports of `tan.planner` or anything else that reads real
|
|
5
|
+
files at import time. `tan.planner.som_metadata` imports `resolve_soc_path`
|
|
6
|
+
from here and re-exports it (its own four call sites keep working
|
|
7
|
+
unchanged); `tan.model.targets` imports it from here directly so that
|
|
8
|
+
`tan.model` stays importable without a bound alp-sdk checkout -- importing
|
|
9
|
+
`tan.planner` pulls in `tan/planner/__init__.py`, which transitively reads
|
|
10
|
+
real `metadata/registries/*` content at import time (`tan/planner/slugs.py`'s
|
|
11
|
+
module-scope `_PERIPHERAL_KCONFIG = peripheral_kconfig()`), a dependency
|
|
12
|
+
`tan.model` never had in alp-sdk and should not gain here.
|
|
13
|
+
|
|
14
|
+
One definition, re-exported -- alp-sdk spent issues #997/#1004/#1096
|
|
15
|
+
collapsing this resolution to a single source; do not create a second copy.
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def resolve_soc_path(silicon: str | None, metadata_root: Path) -> Path | None:
|
|
23
|
+
"""Resolve a `vendor:family:part` `silicon:` key to the SoC-JSON path
|
|
24
|
+
it names: `metadata/socs/<vendor>/<family>/<part>.json`.
|
|
25
|
+
|
|
26
|
+
Returns None when `silicon` is falsy or not exactly 3 colon-separated
|
|
27
|
+
parts -- does NOT check the path exists, callers decide what an
|
|
28
|
+
unresolved/missing SoC spec means for them (e.g. a SoM preset with no
|
|
29
|
+
`silicon:` at all is a valid, if incomplete, state; a `silicon:` that
|
|
30
|
+
names a spec that isn't on disk is not).
|
|
31
|
+
|
|
32
|
+
alp-sdk keeps its own copies of this resolution behind differing failure
|
|
33
|
+
shapes (`OrchestratorError`, `ZephyrBoardEmitError`, a diagnostic list);
|
|
34
|
+
`loader._silicon_to_soc_path` is the planner's raising variant. This is the
|
|
35
|
+
soft-fail one `tan.planner.som_metadata` and `tan.model.targets` share.
|
|
36
|
+
"""
|
|
37
|
+
if not isinstance(silicon, str) or not silicon:
|
|
38
|
+
# A non-string `silicon:` (e.g. a hand-authored `silicon: 7`) is
|
|
39
|
+
# "not exactly 3 colon-separated parts" exactly as much as a falsy
|
|
40
|
+
# one is -- the docstring above already promises None for that
|
|
41
|
+
# shape, `silicon.split(":")` below just didn't deliver on it
|
|
42
|
+
# (`AttributeError: 'int' object has no attribute 'split'`,
|
|
43
|
+
# tan-cli#967 review). This is a SHARED leaf (re-exported by
|
|
44
|
+
# `tan.planner.som_metadata`, imported directly by
|
|
45
|
+
# `tan.model.targets`) -- fixing it here, once, fixes every caller
|
|
46
|
+
# identically rather than needing a matching guard at each call
|
|
47
|
+
# site. Every existing caller already treats a None return as
|
|
48
|
+
# "unresolved" and reports it through its own error message
|
|
49
|
+
# (`_load_soc_spec` -> `ZephyrBoardEmitError("... is not a
|
|
50
|
+
# triple-colon string")`, `resolve_targets` -> `ValueError`), so
|
|
51
|
+
# this changes a crash into the SAME clean diagnostic those callers
|
|
52
|
+
# already produce for a malformed-but-string ref, not a new
|
|
53
|
+
# behaviour.
|
|
54
|
+
return None
|
|
55
|
+
parts = silicon.split(":")
|
|
56
|
+
if len(parts) != 3:
|
|
57
|
+
return None
|
|
58
|
+
return metadata_root / "socs" / parts[0] / parts[1] / f"{parts[2]}.json"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""tan's OWN copy of the SDK scaffold trees `tan init` lays down.
|
|
3
|
+
|
|
4
|
+
``vendored/`` is ``alp-sdk --emit scaffold`` output captured byte-for-byte (LF,
|
|
5
|
+
no retouching) -- a verbatim copy of ``crates/tan-core/src/wizard/vendored/``,
|
|
6
|
+
which the Rust binary bakes in with ``include_str!``. It is checked in for the
|
|
7
|
+
same reason it is checked in there: **I-32 -- `tan init` is SDK-free.** A
|
|
8
|
+
customer's first command must work with no alp-sdk checkout anywhere on the
|
|
9
|
+
machine, so the scaffold content cannot be fetched, and shelling the SDK's
|
|
10
|
+
scaffold emit would hand `tan init` a dependency it deliberately does not have.
|
|
11
|
+
|
|
12
|
+
Two consequences worth stating where the bytes live:
|
|
13
|
+
|
|
14
|
+
* **Re-vendor by re-running the emit, never by hand-editing these files.**
|
|
15
|
+
``vendored/MANIFEST.md`` carries the exact source commit and the template x
|
|
16
|
+
SKU matrix. ``tests/core/test_scaffold.py`` byte-diffs this tree against the
|
|
17
|
+
Rust one, so a re-vendor that updates only one language fails there.
|
|
18
|
+
* **LF is load-bearing.** These bytes are written to the customer's files
|
|
19
|
+
verbatim, and the byte-diff above compares them to an LF capture. The repo
|
|
20
|
+
root's ``.gitattributes`` pins ``text eol=lf`` for this path; without it a
|
|
21
|
+
Windows checkout with ``autocrlf=true`` silently rewrites every one.
|
|
22
|
+
|
|
23
|
+
The tree ships in the frozen binary via ``--add-data`` (``scripts/
|
|
24
|
+
build_binary.sh``). It is data, not code, so PyInstaller's static import graph
|
|
25
|
+
does NOT pull it in on its own -- when it is missing, `tan init` reports
|
|
26
|
+
``init.template-unreadable`` rather than raising (``tan.core.scaffold``).
|
|
27
|
+
"""
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
#: Root of the vendored scaffold trees: ``vendored/<sdk-template-id>/<SKU>/``.
|
|
31
|
+
#: Derived from ``__file__`` so it resolves both from source and from a frozen
|
|
32
|
+
#: onefile bundle, where PyInstaller sets ``__file__`` under ``sys._MEIPASS``
|
|
33
|
+
#: and ``--add-data`` has placed the tree at the same package-relative path.
|
|
34
|
+
VENDORED_ROOT = Path(__file__).resolve().parent / "vendored"
|