Source code for matmelt.commands

"""The command layer: one module per CLI command (Phase 5).

Each module exposes a ``run_<command>(...) -> int`` function that does the
work and returns a process exit code; ``cli.py`` stays a thin Typer
dispatcher that parses options and raises ``typer.Exit`` with that code.
Dependency arrows point inward (``commands/`` -> ``core/`` / ``backends/`` /
``config/``); all human-facing output goes through ``ui/console.py``.

Shared exit-code convention (5.1b): **0** = success / all checks passed,
**1** = problems found or the command refused to proceed, **2** = config or
usage error.
"""

from __future__ import annotations

from pathlib import Path

from matmelt.ui.console import render_legacy_config_note

#: Where every command looks for the config file unless ``--config`` says
#: otherwise -- and the filename ``init`` scaffolds.
DEFAULT_CONFIG_FILENAME = "matmelt.yaml"

#: The pre-rename filename, scaffolded by ``materials-cli`` 0.1.x. A workspace
#: created before the MatMelt rename keeps working untouched: see
#: :func:`resolve_config_path`.
LEGACY_CONFIG_FILENAME = "materials-cli.yaml"

#: The run's state database, under ``run.work_dir``. ``run`` creates it;
#: ``status`` / ``results`` read it (WAL mode -- safe while a run is live).
STATE_DB_FILENAME = "state.sqlite"


[docs] def resolve_config_path(config_path: str) -> str: """Return the config file to read, honouring the pre-rename filename. The MatMelt rename changed the default config filename from ``materials-cli.yaml`` to ``matmelt.yaml``. A workspace scaffolded by ``materials-cli`` 0.1.x must not break, so when the caller took the default and no ``matmelt.yaml`` exists, an existing ``materials-cli.yaml`` beside it is used instead and a deprecation note is printed **once, on stderr** (``--json`` stdout stays parseable). An explicit ``--config`` is always honoured verbatim -- the fallback only ever fills in for the default, and never invents a file that is not there (a missing config still fails in ``load_config``, naming the new name). Parameters ---------- config_path The path the command was given -- the shared ``--config`` option. Returns ------- str ``config_path`` unchanged, or ``materials-cli.yaml`` when that legacy file is the only one present and the default was requested. """ if config_path != DEFAULT_CONFIG_FILENAME or Path(config_path).exists(): return config_path if not Path(LEGACY_CONFIG_FILENAME).is_file(): return config_path render_legacy_config_note(LEGACY_CONFIG_FILENAME, DEFAULT_CONFIG_FILENAME) return LEGACY_CONFIG_FILENAME