Make Parsing & Contracts
Relevant source files
The following files were used as context for generating this wiki page:
- src/flext_tests/_utilities/make_parsing.py
- src/flext_tests/_utilities/make_contract.py
- src/flext_tests/_utilities/_make_parts/make_parsing_part_01.py
- src/flext_tests/_utilities/_make_parts/make_parsing_part_02.py
- src/flext_tests/_utilities/_make_parts/make_contract_part_01.py
- src/flext_tests/_models/make.py
The Make Parsing & Contracts system provides a robust infrastructure for defining, discovering, and validating custom commands within the FLEXT ecosystem. It utilizes TOML-based headers embedded in Python or Shell scripts to define command metadata, parameters, and mutation rules, ensuring that every make execution adheres to a predefined governance contract.
This system is central to the project's quality gates and operational flow, enabling a registry-driven approach where commands are promoted and validated before execution. It handles everything from metadata extraction via AST analysis to environment-backed parameter validation and mutation safety checks.
Sources: README.md:38-40, src/flext_tests/_models/make.py:16-18
Command Metadata Parsing
The parsing logic is responsible for extracting structured data from script headers. It scans the first 220 lines of a file to locate a flext-command TOML block delimited by specific header markers.
Header Extraction Process
The parser identifies lines starting with # and removes the comment symbol to reveal the underlying TOML payload. This payload is then validated against a Pydantic model (MAKE_TOML_TABLE_ADAPTER) to ensure type safety for fields like summary, aliases, and params.
Sources: src/flext_tests/_utilities/_make_parts/make_parsing_part_01.py:19-45
The diagram shows the sequence of operations for transforming a commented script header into a structured data table.
Sources: src/flext_tests/_utilities/_make_parts/make_parsing_part_01.py:20-51
AST Validation for Python Commands
For Python-based commands, the system uses the ast module to determine if a file contains executable code outside of the docstring and metadata. This distinguishes between "header-only" commands (which may point to a different Make target) and standard script commands.
Sources: src/flext_tests/_utilities/_make_parts/make_parsing_part_01.py:53-73
Contract Validation & Mutation Safety
The contract layer ensures that commands are correctly configured and that their execution environment meets the requirements defined in the metadata.
Parameter Contracts
Every MakeCommand can define a sequence of MakeParam objects. These parameters are environment-backed, meaning their values are resolved from the current OS environment variables with optional defaults.
Sources: src/flext_tests/_models/make.py:21-36
| Model Field | Type | Description |
|---|---|---|
name | str | The environment variable name (e.g., WHAT, APPLY). |
help | str | Human-readable description of the parameter. |
required | bool | If true, validation fails if the environment value is empty. |
choices | tuple[str] | A set of allowed values for the parameter. |
| Sources: src/flext_tests/_models/make.py:23-36, src/flext_tests/_utilities/_make_parts/make_contract_part_01.py:33-54 |
Mutation Rules
Mutation safety is a critical part of the contract. Commands that can modify the workspace state must declare mutates = true.
- APPLY Requirement: Mutating commands must include an
APPLYparameter where one of the choices isY. - Dry-Run Enforcement: If
APPLY=Yis not provided in the environment for a mutating command, the system typically renders a dry-run output rather than executing. - Required Params: Mutating commands often require specific parameters (like
WHAT) to be present and non-empty.
Sources: src/flext_tests/_utilities/_make_parts/make_contract_part_01.py:62-79, src/flext_tests/_utilities/_make_parts/make_rendering_part_02.py:165-175
Conditional Mutations
Commands may also define mutates_when predicates. This allows a command to be "read-only" in most cases but switch to "mutating" mode if specific environment variables contain certain values.
Sources: src/flext_tests/_utilities/_make_parts/make_contract_part_01.py:110-141
This flow illustrates the logic applied by make_validate_invocation to ensure environment safety before command dispatch.
Sources: src/flext_tests/_utilities/_make_parts/make_contract_part_01.py:33-54, src/flext_tests/_utilities/_make_parts/make_contract_part_01.py:110-125
Core Data Models
The system architecture is defined by typed Pydantic models that represent the command registry and individual command definitions.
MakeCommand Model
The MakeCommand model is the central entity discovered from source files.
Sources: src/flext_tests/_models/make.py:46-77
verb: The primary command name (e.g.,check,test).what: The specific action within that verb.domain: The functional area (e.g.,test,infra).path: The absolute path to the.pyor.shsource file.target: For header-only commands, specifies aMakefiletarget to invoke.target_env: Mapping of environment overrides passed to the Make target.
Sources: src/flext_tests/_models/make.py:48-77
MakeRegistry Model
The registry aggregates all discovered commands, keyed by verb and then by WHAT.
Sources: src/flext_tests/_models/make.py:79-88
The class diagram shows the hierarchical relationship between the registry, individual commands, and their associated metadata.
Sources: src/flext_tests/_models/make.py:21-88
Conclusion
The Make Parsing & Contracts module provides the necessary rigour for a large-scale testing and infrastructure ecosystem. By combining TOML metadata headers with AST-level script analysis and environment-aware validation, it ensures that every task performed via make is well-documented, type-safe, and governed by strict mutation rules. This system effectively bridges the gap between flexible scripting and formal operational contracts.
Sources: src/flext_tests/_utilities/_make_parts/make_contract_part_01.py:62-108, src/flext_tests/_models/make.py:16-18