@@ -111,10 +111,31 @@ def test_build_adds_required_core_without_adding_sibling_features(self):
111111 )
112112 self .assertEqual (result .patches , ("core" , "keyshift" ))
113113 plain = load_firmware_codec ().read_autoexec (result .output , key )
114- normalized = plain .replace (b"\r \n " , b"\n " )
115114
116- self .assertIn (b"compatibility\n core\n keyshift\n " , normalized )
117- self .assertNotIn (b"\n stems\n " , normalized )
115+ self .assertIn (b"compatibility\n core\n keyshift\n " , plain )
116+ self .assertNotIn (b"\n stems\n " , plain )
117+
118+ def test_the_module_index_is_written_with_unix_line_endings (self ):
119+ """The index is read line by line by /bin/sh on the player, where a
120+ trailing CR is part of the directory name and fails the module-name
121+ check. Python translates \\ n to os.linesep unless told not to, so a
122+ build made on Windows shipped an index no module could be loaded from.
123+ The source assertion carries the test on Linux and macOS, where that
124+ translation never happens and the built image cannot show the fault."""
125+ builder = (REPOSITORY / "tools/rx3_runtime/build.py" ).read_text ()
126+ self .assertRegex (
127+ builder , r'modules / "index"\)\.write_text\((?s:.*?)newline=""'
128+ )
129+
130+ with tempfile .TemporaryDirectory () as directory :
131+ directory = Path (directory )
132+ key = directory / "aes256.key"
133+ key .write_bytes (b"0123456789012345678901234567890\n " )
134+ result = build_runtime (
135+ "1.19" , ["keyshift" ], key , directory , root = REPOSITORY
136+ )
137+ plain = load_firmware_codec ().read_autoexec (result .output , key )
138+ self .assertNotIn (b"compatibility\r " , plain )
118139
119140 def test_the_session_log_ships_only_when_its_module_is_selected (self ):
120141 """say() runs before any module is loaded, so the orchestrator reads
@@ -133,14 +154,14 @@ def test_the_session_log_ships_only_when_its_module_is_selected(self):
133154 "1.19" , ["keyshift" ], key , directory , root = REPOSITORY
134155 )
135156 self .assertNotIn ("logging" , quiet .patches )
136- index = codec .read_autoexec (quiet .output , key ). replace ( b" \r \n " , b" \n " )
157+ index = codec .read_autoexec (quiet .output , key )
137158 self .assertNotIn (b"\n logging\n " , index )
138159
139160 verbose = build_runtime (
140161 "1.19" , ["keyshift" , "logging" ], key , directory , root = REPOSITORY
141162 )
142163 self .assertIn ("logging" , verbose .patches )
143- index = codec .read_autoexec (verbose .output , key ). replace ( b" \r \n " , b" \n " )
164+ index = codec .read_autoexec (verbose .output , key )
144165 self .assertIn (b"\n logging\n " , index )
145166
146167 def test_the_logging_module_warns_about_pulling_the_drive_out (self ):
0 commit comments