Python tools¶
Auto-generated reference for the Python tools under tools/. Module
docstrings are the authoritative spec for CLI behaviour and output
contracts; the prose pages link here for symbol-level detail.
select_assignments¶
The matrix-selection driver. Reads workspace/assignment.txt, diffs
the push, and emits the GitHub Actions matrix.
Compute the autograder matrix for a student push.
Reads workspace/assignment.txt and a list of paths changed in the push,
emits a JSON array [{id, folder, source}, ...] of assignments that need
re-grading. source is one of: "changed" (folder touched), "manifest"
(assignment.txt itself changed), "force" (force-all flag), "first-push"
(no before SHA available).
Manifest format — one entry per line:
HW1 HW1mj
HW2 HW2mj HW2_main.c # optional 3rd column = explicit main file
Blank lines and # comments are ignored.
CLI::
select_assignments.py --manifest <path> --workspace <dir>
--before <sha> --head <sha>
[--force-all] [--changed-from-stdin]
[--output github|json]
The --changed-from-stdin flag reads newline-separated paths from stdin
instead of running git diff (used by tests and by the workflow when it
has already collected the diff).
The --output github form prints matrix=<json> for $GITHUB_OUTPUT
consumption.
Run with --self-test to execute the in-file unit tests (stdlib only).
render_report¶
The post-grade renderer. Aggregates per-slot results into per-folder detail pages, ID-level aggregate pages, and a top-level index with clickable folder + commit links.
Render grader JSON results into student-facing markdown + JSON.
Inputs (CLI): --results-dir
<repo-url>/tree/<sha>/<workspace>/<folder>)
and each commit SHA into a link to the commit
(<repo-url>/commit/<sha>). Optional.
--workspace workspace).
--step-summary The manifest may contain duplicate IDs (e.g. two HW1 rows pointing at
different folders). Each row produces an independent grader run keyed by
its slot (unique per row, see select_assignments.py). For an ID with
multiple rows we emit:
- one detail file per row:
/ .md / .json - an aggregate
.md (per-folder rows + total pass/fail) - an aggregate
.json (machine-readable summary of all rows) - history/
.jsonl (one JSONL per row, recording commit + folder)
When an ID has only one manifest row, slot == id, so the layout collapses to the historical single-file form.
Each
The grader does not know its own slot/folder/commit; the workflow is
expected to drop a sidecar <slot>.meta.json next to the result with at
least {"id": ..., "folder": ..., "slot": ...}. Without the sidecar we
fall back to filename-stem heuristics (treating "
render_assignment_md ¶
Detail page for a single graded run (one slot).
render_aggregate_md ¶
Aggregate page for an ID that has multiple manifest rows.
The folder cell links to that folder at the commit it was graded against (each row may have its own commit, since unchanged siblings keep their original commit across partial regrades). The header commit links to the most recent run's commit.
patch_student_source¶
Build-time student-source rewriter. Injects the init-guard macro and
rewrites while(1) to the cooperative-driver loop. See
Cooperative driver for the
contract.
Patch a student firmware source file for the cooperative main-loop driver.
Two transformations are applied:
-
Inject
GRADER_MAIN_INIT_GUARDimmediately after the opening{ofmain(). The macro (defined in include/ti_stubs.h under AUTO_GRADER) uses a static flag plus a goto to skip the init code on every re-entry into temp_main() after the first one. This is what makesgrader::step_main_loop()cheap (no re-init, no re-running of any busy-waits the student's setup helpers may contain). -
Replace
while(1)with_grader_loop_start: ; GRADER_MAIN_LOOP. The label is the goto target from (1); GRADER_MAIN_LOOP expands to a for-loop bounded bygrader_main_loop_iterations().
Usage: patch_student_source.py
Codegen tools¶
These three tools regenerate the auto-generated src/checks/generated.cpp,
src/checks/compare_generated.cpp, and the body of
HardwareStateValidator::populate_all_zero() from TI peripheral
register headers. Run them when a TI header changes or a new
peripheral is added.
validation¶
generate_zero_checks ¶
Parses a C/C++ header file containing register structure definitions and generates C++ templates to verify all registers are zero.
compare_validation¶
generate_zero_checks ¶
Parses a C/C++ header file containing register structure definitions and generates C++ templates to verify all registers are zero.
hash_map_setter¶
generate_hashmap_initializer ¶
Parses a C++ header file containing 'extern volatile struct' declarations and generates C++ code to populate a std::unordered_map for zero-checking.