Skip to content

Commit 38948f3

Browse files
authored
Merge branch 'master' into feature/non-newtonian-viscosity
2 parents 4bb5646 + 0d84ed4 commit 38948f3

5 files changed

Lines changed: 44 additions & 15 deletions

File tree

.github/workflows/test.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ on:
88
workflow_dispatch:
99

1010
concurrency:
11-
group: ${{ github.workflow }}-${{ github.ref }}
12-
cancel-in-progress: true
11+
# PRs: group by branch (new push cancels old). Push to master: unique per SHA (never cancelled).
12+
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
13+
cancel-in-progress: ${{ github.event_name != 'push' }}
1314

1415
jobs:
1516
lint-gate:
@@ -162,11 +163,12 @@ jobs:
162163
# (which can take 20-240 minutes). Only test_coverage_cache.json.gz
163164
# is changed, so rebase conflicts are essentially impossible.
164165
git fetch origin master
165-
git rebase origin/master
166+
git rebase origin/master || { git rebase --abort; echo "Rebase conflict — cache will be regenerated on the next trigger."; exit 0; }
166167
# Push using admin token to bypass branch protection rulesets.
167168
# The default GITHUB_TOKEN lacks the Repository Admin role needed
168-
# to push directly to master.
169-
git push https://x-access-token:${CACHE_PUSH_TOKEN}@github.com/MFlowCode/MFC.git HEAD:refs/heads/master
169+
# to push directly to master. Use credential helper to avoid
170+
# leaking the token in git error messages.
171+
git -c "http.https://github.com/.extraheader=Authorization: basic $(echo -n "x-access-token:${CACHE_PUSH_TOKEN}" | base64)" push origin HEAD:refs/heads/master
170172
fi
171173
172174
github:

toolchain/mfc/lint_source.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,33 @@ def check_junk_comments(repo_root: Path) -> list[str]:
312312
return errors
313313

314314

315+
def check_pylint_directives(repo_root: Path) -> list[str]:
316+
"""Flag ``# pylint:`` directives in Python files.
317+
318+
MFC uses ruff for linting; leftover pylint directives are dead code.
319+
"""
320+
errors: list[str] = []
321+
pylint_re = re.compile(r"#\s*pylint\s*:", re.IGNORECASE)
322+
self_path = Path(__file__).resolve()
323+
324+
for subdir in ["examples", "benchmarks", "toolchain"]:
325+
d = repo_root / subdir
326+
if not d.exists():
327+
continue
328+
for py in sorted(d.rglob("*.py")):
329+
if py.resolve() == self_path:
330+
continue
331+
lines = py.read_text(encoding="utf-8").splitlines()
332+
rel = py.relative_to(repo_root)
333+
334+
for i, line in enumerate(lines):
335+
match = pylint_re.search(line)
336+
if match:
337+
errors.append(f" {rel}:{i + 1} pylint directive. Fix: remove (use ruff noqa comments if needed)")
338+
339+
return errors
340+
341+
315342
def main():
316343
repo_root = Path(__file__).resolve().parents[2]
317344

@@ -324,6 +351,7 @@ def main():
324351
all_errors.extend(check_fypp_list_duplicates(repo_root))
325352
all_errors.extend(check_duplicate_lines(repo_root))
326353
all_errors.extend(check_hardcoded_byte_size(repo_root))
354+
all_errors.extend(check_pylint_directives(repo_root))
327355

328356
if all_errors:
329357
print("Source lint failed:")

toolchain/mfc/test/coverage.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def _compute_gcov_prefix_strip(root_dir: str) -> str:
206206
return str(len(Path(real_root).parts) - 1) # -1 excludes root '/'
207207

208208

209-
def _collect_single_test_coverage( # pylint: disable=too-many-locals
209+
def _collect_single_test_coverage(
210210
uuid: str,
211211
test_gcda: str,
212212
root_dir: str,
@@ -286,7 +286,7 @@ def _collect_single_test_coverage( # pylint: disable=too-many-locals
286286
return uuid, sorted(coverage)
287287

288288

289-
def _run_single_test_direct(test_info: dict, gcda_dir: str, strip: str) -> tuple: # pylint: disable=too-many-locals
289+
def _run_single_test_direct(test_info: dict, gcda_dir: str, strip: str) -> tuple:
290290
"""
291291
Run a single test by invoking Fortran executables directly.
292292
@@ -352,7 +352,7 @@ def _run_single_test_direct(test_info: dict, gcda_dir: str, strip: str) -> tuple
352352
return uuid, test_gcda, failures
353353

354354

355-
def _prepare_test(case) -> dict: # pylint: disable=too-many-locals
355+
def _prepare_test(case) -> dict:
356356
"""
357357
Prepare a test for direct execution: create directory, generate .inp
358358
files, and resolve binary paths. All Python/toolchain overhead happens
@@ -445,7 +445,7 @@ def _prepare_test(case) -> dict: # pylint: disable=too-many-locals
445445
}
446446

447447

448-
def build_coverage_cache( # pylint: disable=too-many-locals,too-many-statements
448+
def build_coverage_cache(
449449
root_dir: str,
450450
cases: list,
451451
n_jobs: Optional[int] = None,
@@ -490,7 +490,7 @@ def build_coverage_cache( # pylint: disable=too-many-locals,too-many-statements
490490
for i, case in enumerate(cases):
491491
try:
492492
test_infos.append(_prepare_test(case))
493-
except Exception as exc: # pylint: disable=broad-except
493+
except Exception as exc:
494494
cons.print(f" [yellow]Warning: skipping {case.get_uuid()} — prep failed: {exc}[/yellow]")
495495
if (i + 1) % 100 == 0 or (i + 1) == len(cases):
496496
cons.print(f" [{i + 1:3d}/{len(cases):3d}] prepared")
@@ -507,7 +507,7 @@ def build_coverage_cache( # pylint: disable=too-many-locals,too-many-statements
507507
for i, future in enumerate(as_completed(futures)):
508508
try:
509509
uuid, test_gcda, failures = future.result()
510-
except Exception as exc: # pylint: disable=broad-except
510+
except Exception as exc:
511511
info = futures[future]
512512
cons.print(f" [yellow]Warning: {info['uuid']} failed to run: {exc}[/yellow]")
513513
continue
@@ -560,7 +560,7 @@ def build_coverage_cache( # pylint: disable=too-many-locals,too-many-statements
560560
for future in as_completed(futures):
561561
try:
562562
uuid, coverage = future.result()
563-
except Exception as exc: # pylint: disable=broad-except
563+
except Exception as exc:
564564
uuid = futures[future]
565565
cons.print(f" [yellow]Warning: {uuid} coverage failed: {exc}[/yellow]")
566566
# Do NOT store entry — absent entries are conservatively

toolchain/mfc/test/test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def __filter(cases_) -> typing.Tuple[typing.List[TestCase], typing.List[TestCase
113113

114114
# --only-changes: filter based on file-level gcov coverage
115115
if ARG("only_changes"):
116-
from .coverage import ( # pylint: disable=import-outside-toplevel
116+
from .coverage import (
117117
filter_tests_by_coverage,
118118
get_changed_files,
119119
load_coverage_cache,
@@ -234,7 +234,7 @@ def test():
234234
return
235235

236236
if ARG("build_coverage_cache"):
237-
from .coverage import build_coverage_cache # pylint: disable=import-outside-toplevel
237+
from .coverage import build_coverage_cache
238238

239239
all_cases = [b.to_case() for b in cases]
240240

toolchain/mfc/test/test_coverage_unit.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
These tests are fully offline (no build, no git, no gcov binary required).
88
They use mocks and in-memory data structures to verify logic.
99
"""
10-
# pylint: disable=protected-access,exec-used,too-few-public-methods,wrong-import-position
1110

1211
import gzip
1312
import hashlib

0 commit comments

Comments
 (0)