Skip to content

Commit afc11b6

Browse files
authored
Auto-generate description labels and extend DEPENDENCIES schema (#1133)
1 parent 545f3a9 commit afc11b6

File tree

12 files changed

+1730
-498
lines changed

12 files changed

+1730
-498
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Toolchain Compatibility
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
jobs:
10+
test-toolchain:
11+
name: "Python ${{ matrix.python-version }}"
12+
runs-on: ubuntu-latest
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: actions/setup-python@v5
20+
with:
21+
python-version: ${{ matrix.python-version }}
22+
- name: Initialize MFC
23+
run: ./mfc.sh init
24+
- name: Lint and test toolchain
25+
run: ./mfc.sh lint

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ if (MFC_DOCUMENTATION)
665665
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/case_constraints.md"
666666
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/toolchain/mfc/gen_case_constraints_docs.py"
667667
"${CMAKE_CURRENT_SOURCE_DIR}/toolchain/mfc/case_validator.py"
668+
"${CMAKE_CURRENT_SOURCE_DIR}/toolchain/mfc/params/definitions.py"
668669
"${examples_DOCs}"
669670
COMMAND "bash" "${CMAKE_CURRENT_SOURCE_DIR}/docs/gen_constraints.sh"
670671
"${CMAKE_CURRENT_SOURCE_DIR}"
@@ -684,10 +685,12 @@ if (MFC_DOCUMENTATION)
684685
)
685686

686687
# Generate parameters.md from parameter registry
688+
# docs_gen.py now AST-parses case_validator.py, so it must be a dependency
687689
file(GLOB_RECURSE params_SRCs CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/toolchain/mfc/params/*.py")
688690
add_custom_command(
689691
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/parameters.md"
690692
DEPENDS "${params_SRCs}"
693+
"${CMAKE_CURRENT_SOURCE_DIR}/toolchain/mfc/case_validator.py"
691694
COMMAND "bash" "${CMAKE_CURRENT_SOURCE_DIR}/docs/gen_parameters.sh"
692695
"${CMAKE_CURRENT_SOURCE_DIR}"
693696
COMMENT "Generating parameters.md"

toolchain/mfc/case_validator.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
# pylint: disable=too-many-lines
1515
# Justification: Comprehensive validator covering all MFC parameter constraints
1616

17+
import re
1718
from typing import Dict, Any, List, Set
1819
from functools import lru_cache
1920
from .common import MFCException
21+
from .params.definitions import CONSTRAINTS
2022

2123

2224
@lru_cache(maxsize=1)
@@ -144,6 +146,10 @@ def check_model_eqns_and_num_fluids(self):
144146
def check_igr(self):
145147
"""Checks constraints regarding IGR order"""
146148
igr = self.get('igr', 'F') == 'T'
149+
igr_pres_lim = self.get('igr_pres_lim', 'F') == 'T'
150+
151+
self.prohibit(igr_pres_lim and not igr,
152+
"igr_pres_lim requires igr to be enabled")
147153

148154
if not igr:
149155
return
@@ -152,7 +158,6 @@ def check_igr(self):
152158
m = self.get('m', 0)
153159
n = self.get('n', 0)
154160
p = self.get('p', 0)
155-
156161
self.prohibit(igr_order not in [None, 3, 5],
157162
"igr_order must be 3 or 5")
158163
if igr_order:
@@ -191,6 +196,10 @@ def check_weno(self):
191196
def check_muscl(self):
192197
"""Check constraints regarding MUSCL order"""
193198
recon_type = self.get('recon_type', 1)
199+
int_comp = self.get('int_comp', 'F') == 'T'
200+
201+
self.prohibit(int_comp and recon_type != 2,
202+
"int_comp (THINC interface compression) requires recon_type = 2 (MUSCL)")
194203

195204
# MUSCL_TYPE = 2
196205
if recon_type != 2:
@@ -1201,6 +1210,10 @@ def check_probe_integral_output(self):
12011210
def check_hyperelasticity(self):
12021211
"""Checks hyperelasticity constraints"""
12031212
hyperelasticity = self.get('hyperelasticity', 'F') == 'T'
1213+
pre_stress = self.get('pre_stress', 'F') == 'T'
1214+
1215+
self.prohibit(pre_stress and not hyperelasticity,
1216+
"pre_stress requires hyperelasticity to be enabled")
12041217

12051218
if not hyperelasticity:
12061219
return
@@ -1911,14 +1924,27 @@ def _format_errors(self) -> str:
19111924
err_lower = err.lower()
19121925
if "must be positive" in err_lower or "must be set" in err_lower:
19131926
lines.append(" [dim]Check that this required parameter is defined in your case file[/dim]")
1914-
elif "weno_order" in err_lower:
1915-
lines.append(" [dim]Valid values: 1, 3, 5, or 7[/dim]")
1916-
elif "riemann_solver" in err_lower:
1917-
lines.append(" [dim]Valid values: 1 (HLL), 2 (HLLC), 3 (Exact), etc.[/dim]")
1918-
elif "model_eqns" in err_lower:
1919-
lines.append(" [dim]Valid values: 1, 2 (5-eq), 3 (6-eq), or 4[/dim]")
1920-
elif "boundary" in err_lower or "bc_" in err_lower:
1927+
continue
1928+
if "boundary" in err_lower or "bc_" in err_lower:
19211929
lines.append(" [dim]Common BC values: -1 (periodic), -2 (reflective), -3 (extrapolation)[/dim]")
1930+
continue
1931+
1932+
# Auto-generate hints from CONSTRAINTS with value_labels
1933+
for param_name, constraint in CONSTRAINTS.items():
1934+
if not re.search(r'\b' + re.escape(param_name.lower()) + r'\b', err_lower):
1935+
continue
1936+
choices = constraint.get("choices")
1937+
if not choices:
1938+
continue
1939+
labels = constraint.get("value_labels", {})
1940+
if labels:
1941+
items = [f"{v} ({labels[v]})" if v in labels else str(v)
1942+
for v in choices]
1943+
hint = f"Valid values: {', '.join(items)}"
1944+
else:
1945+
hint = f"Valid values: {choices}"
1946+
lines.append(f" [dim]{hint}[/dim]")
1947+
break
19221948

19231949
lines.append("")
19241950
lines.append("[dim]Tip: Run './mfc.sh validate case.py' for detailed validation[/dim]")

0 commit comments

Comments
 (0)