Summary
hiroz-codegen's Python msgspec generator uses HashMap<String, Vec<&ResolvedMessage>> to group messages by package. HashMap iteration order is non-deterministic, so rebuilding produces a different class ordering in the generated crates/hiroz-msgs/python/hiroz_msgs_py/types/*.py files each time. This causes spurious diffs after any cargo build or cargo check run.
Root Cause
crates/hiroz-codegen/src/python_msgspec_generator.rs:
packages: HashMap<String, Vec<&ResolvedMessage>> — package iteration order is random
service_messages: HashMap<String, Vec<&ResolvedMessage>> — same
service_hashes: HashMap<String, HashMap<String, String>> — same
- The message vec within each package also reflects HashMap insertion order
Fix
Replace all HashMap<String, Vec<...>> keyed on String with BTreeMap<String, Vec<...>> in the generator. BTreeMap iterates in sorted key order, making the output fully deterministic. Also sort each message vec by name before generating (sort_by_key(|m| &m.parsed.name)).
Impact
- Dirty worktrees after any build that triggers codegen
- Noisy
git diff that looks like real changes
- Risk of accidentally committing a reshuffled file as if it were meaningful
Summary
hiroz-codegen's Python msgspec generator usesHashMap<String, Vec<&ResolvedMessage>>to group messages by package. HashMap iteration order is non-deterministic, so rebuilding produces a different class ordering in the generatedcrates/hiroz-msgs/python/hiroz_msgs_py/types/*.pyfiles each time. This causes spurious diffs after anycargo buildorcargo checkrun.Root Cause
crates/hiroz-codegen/src/python_msgspec_generator.rs:packages: HashMap<String, Vec<&ResolvedMessage>>— package iteration order is randomservice_messages: HashMap<String, Vec<&ResolvedMessage>>— sameservice_hashes: HashMap<String, HashMap<String, String>>— sameFix
Replace all
HashMap<String, Vec<...>>keyed onStringwithBTreeMap<String, Vec<...>>in the generator. BTreeMap iterates in sorted key order, making the output fully deterministic. Also sort each message vec by name before generating (sort_by_key(|m| &m.parsed.name)).Impact
git diffthat looks like real changes