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