Current section
Files
Jump to
Current section
Files
lib/dds.ex
defmodule Dds do
@moduledoc """
The dds toolchain, bundled. This module is a LOCATOR AND RUNNER,
nothing more — the instruments are the bundled Python (the same
bytes as the tagged toolchain repo), and all semantics live there.
Runtime resolution, best first:
1. **Pythonx** (embedded CPython, hermetic) — when the optional
`:pythonx` dep is present, `mix deps.get` is the ONLY
prerequisite: pythonx provisions a standalone interpreter and the
tree-sitter wheels itself (pinned below), in-process, no system
Python, no PATH. The mechanical witness and evidence replay work
out of the box.
2. `uv` on PATH — same hermetic properties via subprocess.
3. `python3` (>= 3.9) — stdlib legs directly; tree-sitter legs
degrade with the toolchain's own honest hints.
4. None — a clear error naming the options.
"""
@pythonx_project """
[project]
name = "dds-runner"
version = "0.0.0"
requires-python = ">=3.10"
dependencies = ["tree-sitter", "tree-sitter-elixir"]
"""
@tree_deps ["tree-sitter", "tree-sitter-elixir"]
@doc "Run the bundled CLI with `args`; exits the VM with its exit code on failure."
def run(args) when is_list(args) do
cli = Path.join(:code.priv_dir(:dds), "toolchain/cli.py")
status =
cond do
Code.ensure_loaded?(Pythonx) -> run_pythonx(cli, args)
uv = System.find_executable("uv") -> run_cmd(uv, uv_args(cli, args))
py = System.find_executable("python3") -> run_cmd(py, [cli | args])
true -> raise_no_runtime()
end
if status != 0, do: exit({:shutdown, status})
:ok
end
defp run_pythonx(cli, args) do
# embedded CPython: pythonx downloads/caches a standalone build and
# the pinned deps; the toolchain runs in-process. SystemExit is the
# CLI's normal exit path — catch it and surface the code.
{:ok, _} = Application.ensure_all_started(:pythonx)
Pythonx.uv_init(@pythonx_project)
{result, _globals} =
Pythonx.eval(
"""
import runpy, sys
sys.argv = ["dds", *[a.decode() for a in args]]
_code = 0
try:
runpy.run_path(cli.decode(), run_name="__main__")
except SystemExit as e:
_code = int(e.code or 0)
_code
""",
%{"args" => args, "cli" => cli}
)
result |> Pythonx.decode() |> trunc()
end
defp uv_args(cli, args) do
["run", "--quiet"] ++ Enum.flat_map(@tree_deps, &["--with", &1]) ++ ["--", cli | args]
end
defp run_cmd(cmd, argv) do
{_, status} =
System.cmd(cmd, argv, into: IO.stream(:stdio, :line), stderr_to_stdout: true)
status
end
defp raise_no_runtime do
raise """
dds needs a runtime. Any of:
- add {:pythonx, "~> 0.4"} to your deps (recommended — hermetic:
mix deps.get is the only prerequisite)
- uv on PATH (https://docs.astral.sh/uv/)
- python3 >= 3.9 on PATH (stdlib legs only, unless tree-sitter +
tree-sitter-elixir are importable)
"""
end
end