(repo_root: Path, cfg: ToolConfig, targets: list[str] | None = None)
| 604 | |
| 605 | |
| 606 | def scan_files(repo_root: Path, cfg: ToolConfig, targets: list[str] | None = None) -> list[FileRecord]: |
| 607 | today = _iso_today() |
| 608 | paths = glob_paths(repo_root, cfg.scan.include) |
| 609 | records: list[FileRecord] = [] |
| 610 | target_specs = compile_target_specs(targets, repo_root) |
| 611 | |
| 612 | for p in paths: |
| 613 | rel = str(p.resolve().relative_to(repo_root)).replace(os.sep, "/") |
| 614 | if is_excluded(rel, cfg.scan.exclude): |
| 615 | continue |
| 616 | if not target_matches(rel, target_specs): |
| 617 | continue |
| 618 | kind = file_kind(p) |
| 619 | rec = FileRecord(path=rel, kind=kind) |
| 620 | |
| 621 | rec.last_git_touched = git_last_touched(repo_root, rel) |
| 622 | rec.last_content_updated, used_fallback = git_last_content_updated(repo_root, rel) |
| 623 | rec.days_since_content_update = compute_days_since(rec.last_content_updated, today) |
| 624 | if used_fallback: |
| 625 | rec.warnings.append("content_date_fallback_to_git_touched") |
| 626 | |
| 627 | try: |
| 628 | if kind == "ipynb": |
| 629 | nb, raw_meta, has_dlc = read_ipynb_meta(p) |
| 630 | |
| 631 | try: |
| 632 | nbformat.validate(nb) |
| 633 | except NotebookValidationError as e: |
| 634 | rec.errors.append(f"nbformat_invalid: {e}") |
| 635 | |
| 636 | try: |
| 637 | if not notebook_is_normalized(p, nb): |
| 638 | rec.warnings.append("notebook_not_normalized") |
| 639 | except Exception as e: |
| 640 | rec.errors.append(f"notebook_normalization_check_failed: {e}") |
| 641 | |
| 642 | if not has_dlc: |
| 643 | rec.meta = None |
| 644 | rec.warnings.append("missing_metadata") |
| 645 | else: |
| 646 | rec.meta, valid = parse_dlc_meta(raw_meta) |
| 647 | if not valid: |
| 648 | rec.meta = None |
| 649 | rec.warnings.append("invalid_metadata") |
| 650 | |
| 651 | elif kind == "md": |
| 652 | text = p.read_text(encoding="utf-8") |
| 653 | fm, _body, fm_error = read_md_frontmatter(text) |
| 654 | |
| 655 | if fm_error: |
| 656 | rec.meta = None |
| 657 | rec.warnings.append("invalid_metadata") |
| 658 | rec.errors.append(f"markdown_frontmatter_invalid: {fm_error}") |
| 659 | else: |
| 660 | fm = fm or {} |
| 661 | has_dlc = DLC_NAMESPACE in fm |
| 662 | raw = fm.get(DLC_NAMESPACE) |
| 663 |
no test coverage detected