Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,13 @@ repos:
- id: actionlint
types_or: [yaml]
args: [-shellcheck='' -pyflakes='']

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.15.20
hooks:
# Run the linter.
- id: ruff-check
args: [ --fix ]
# Run the formatter.
- id: ruff-format
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.103.0] - 2026-07-02

### Changed

- migrate python scripts to use ruff

## [1.102.1] - 2026-07-01

### Changed
Expand Down
44 changes: 29 additions & 15 deletions scripts/cargo_metadata_dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@


def save_app_params(device: str, app_build_path: Path, json_path: Path) -> None:
metadata = run_cmd("cargo metadata --no-deps --format-version 1 --offline -q",
cwd=app_build_path)
metadata = run_cmd(
"cargo metadata --no-deps --format-version 1 --offline -q", cwd=app_build_path
)
metadata = json.loads(metadata)

rust_target = device
Expand All @@ -19,7 +20,16 @@ def save_app_params(device: str, app_build_path: Path, json_path: Path) -> None:

# find package with metadata.ledger
packages = metadata.get("packages", [])
package = next((pkg for pkg in packages if "metadata" in pkg and pkg["metadata"] is not None and "ledger" in pkg["metadata"]),None)
package = next(
(
pkg
for pkg in packages
if "metadata" in pkg
and pkg["metadata"] is not None
and "ledger" in pkg["metadata"]
),
None,
)

variant = package["name"]
appname = package["metadata"]["ledger"]["name"]
Expand Down Expand Up @@ -52,9 +62,9 @@ def save_app_params(device: str, app_build_path: Path, json_path: Path) -> None:
"ICONNAME": iconname,
"TARGET": c_target,
"APPNAME": appname,
"APPVERSION": appversion
"APPVERSION": appversion,
}
}
},
}

with open(json_path, "w") as f:
Expand All @@ -64,16 +74,20 @@ def save_app_params(device: str, app_build_path: Path, json_path: Path) -> None:
if __name__ == "__main__":
parser = ArgumentParser()

parser.add_argument("--device",
help="device model",
required=True,
choices=["nanos", "nanox", "nanosp", "stax", "flex", "apex_m", "apex_p"])
parser.add_argument("--app_build_path",
help="App build path, e.g. <app-boilerplate/app>",
required=True)
parser.add_argument("--json_path",
help="Json path to store the output",
required=True)
parser.add_argument(
"--device",
help="device model",
required=True,
choices=["nanos", "nanox", "nanosp", "stax", "flex", "apex_m", "apex_p"],
)
parser.add_argument(
"--app_build_path",
help="App build path, e.g. <app-boilerplate/app>",
required=True,
)
parser.add_argument(
"--json_path", help="Json path to store the output", required=True
)

args = parser.parse_args()

Expand Down
42 changes: 31 additions & 11 deletions scripts/coverage_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ def line_links(path, ranges, slug, sha):
label = f"{start}" if start == end else f"{start}–{end}"
if slug and sha:
anchor = f"L{start}" if start == end else f"L{start}-L{end}"
parts.append(f"[{label}](https://github.com/{slug}/blob/{sha}/{path}#{anchor})")
parts.append(
f"[{label}](https://github.com/{slug}/blob/{sha}/{path}#{anchor})"
)
else:
parts.append(label)
return ", ".join(parts)
Expand Down Expand Up @@ -192,7 +194,7 @@ def main():
def rel(path):
"""Strip the workspace prefix from an absolute source path, if present."""
if workspace and path.startswith(workspace + "/"):
return path[len(workspace) + 1:]
return path[len(workspace) + 1 :]
return path

# Project-wide totals: sum each counter across every file record.
Expand All @@ -210,9 +212,15 @@ def rel(path):
out.append("### Overall\n")
out.append("| Metric | Coverage | Covered / Total |")
out.append("|---|---|---|")
out.append(f"| Lines | {pct_cell(tot['LH'], tot['LF'])} | {ratio_cell(tot['LH'], tot['LF'])} |")
out.append(f"| Functions | {pct_cell(tot['FNH'], tot['FNF'])} | {ratio_cell(tot['FNH'], tot['FNF'])} |")
out.append(f"| Branches | {pct_cell(tot['BRH'], tot['BRF'])} | {ratio_cell(tot['BRH'], tot['BRF'])} |")
out.append(
f"| Lines | {pct_cell(tot['LH'], tot['LF'])} | {ratio_cell(tot['LH'], tot['LF'])} |"
)
out.append(
f"| Functions | {pct_cell(tot['FNH'], tot['FNF'])} | {ratio_cell(tot['FNH'], tot['FNF'])} |"
)
out.append(
f"| Branches | {pct_cell(tot['BRH'], tot['BRF'])} | {ratio_cell(tot['BRH'], tot['BRF'])} |"
)
out.append("")

# Note: only files compiled into the unit-test binary appear in the
Expand All @@ -224,7 +232,9 @@ def rel(path):
out.append("")
if uncovered:
# Collapsible list so a long set of files does not flood the summary.
out.append(f"<details><summary>Files with no line covered ({len(uncovered)})</summary>\n")
out.append(
f"<details><summary>Files with no line covered ({len(uncovered)})</summary>\n"
)
for rec in sorted(uncovered, key=lambda r: r["file"]):
out.append(f"- `{rel(rec['file'])}`")
out.append("\n</details>\n")
Expand All @@ -244,14 +254,18 @@ def rel(path):
# Missing or empty list: the collection step was skipped or failed
# (a real PR always changes at least one file). Make it explicit
# rather than implying that nothing was modified.
out.append("_Changed-file list unavailable; skipping per-file PR coverage._\n")
out.append(
"_Changed-file list unavailable; skipping per-file PR coverage._\n"
)
else:
# Keep source files, dropping those excluded from coverage (test
# sources, SDK, submodules) so they are not reported as "not
# exercised".
patterns = exclude_patterns()
changed_src = [
c for c in changed if c.endswith(SRC_EXT) and not is_excluded(c, patterns)
c
for c in changed
if c.endswith(SRC_EXT) and not is_excluded(c, patterns)
]

def match(changed_file):
Expand All @@ -262,7 +276,9 @@ def match(changed_file):
Returns the record, or ``None`` if the file is not in the report.
"""
for rec in records:
if rec["file"] == changed_file or rec["file"].endswith("/" + changed_file):
if rec["file"] == changed_file or rec["file"].endswith(
"/" + changed_file
):
return rec
return None

Expand Down Expand Up @@ -298,14 +314,18 @@ def match(changed_file):
# collapsed so a long list never inflates the section.
slug = os.environ.get("APP_REPOSITORY", "")
sha = os.environ.get("HEAD_SHA", "")
uncovered_rows = [(c, rec) for c, rec in in_cov if rec["uncovered_lines"]]
uncovered_rows = [
(c, rec) for c, rec in in_cov if rec["uncovered_lines"]
]
if uncovered_rows:
out.append(
f"<details><summary>Uncovered lines in modified files "
f"({len(uncovered_rows)})</summary>\n"
)
for c, rec in sorted(uncovered_rows):
links = line_links(c, to_ranges(rec["uncovered_lines"]), slug, sha)
links = line_links(
c, to_ranges(rec["uncovered_lines"]), slug, sha
)
out.append(f"- `{c}`: {links}")
out.append("\n</details>\n")
else:
Expand Down
Loading
Loading