| 100 | |
| 101 | |
| 102 | def _detect_module_changes(module: "PlainModule") -> list[FunctionalityChange]: |
| 103 | metadata = module.load_module_metadata() |
| 104 | old_frs: list[str] = metadata.get(MODULE_FUNCTIONALITIES_KEY, []) if metadata else [] |
| 105 | new_frs: list[str] = module._get_module_functional_requirements() |
| 106 | |
| 107 | if old_frs == new_frs: |
| 108 | return [] |
| 109 | |
| 110 | moves, edits, removed, added = _classify_changes(old_frs, new_frs) |
| 111 | |
| 112 | changes: list[FunctionalityChange] = [] |
| 113 | name = module.module_name |
| 114 | |
| 115 | for old_idx, new_idx in moves: |
| 116 | old_frid = _frid_from_index(old_idx) |
| 117 | new_frid = _frid_from_index(new_idx) |
| 118 | changes.append(FunctionalityChange(module=name, frid=old_frid, change_type="moved", detail=new_frid)) |
| 119 | |
| 120 | for idx in edits: |
| 121 | changes.append(FunctionalityChange(module=name, frid=_frid_from_index(idx), change_type="edited")) |
| 122 | |
| 123 | for idx in removed: |
| 124 | changes.append(FunctionalityChange(module=name, frid=_frid_from_index(idx), change_type="removed")) |
| 125 | |
| 126 | for idx in added: |
| 127 | changes.append(FunctionalityChange(module=name, frid=_frid_from_index(idx), change_type="added")) |
| 128 | |
| 129 | return changes |
| 130 | |
| 131 | |
| 132 | def _classify_changes( |