Neustart-Erkennung: Zeilenenden zaehlen nicht als Aenderung

Am echten Update-Weg gemessen: die installierte Fassung lag mit CRLF auf der
Platte, das Gitea-Archiv liefert LF. Drei .py-Dateien galten dadurch als
geaendert, obwohl sie nach Entfernen der CR byteweise identisch waren - die
Erkennung verlangte einen Neustart fuer einen rein kosmetischen Unterschied.

Textdateien werden jetzt vor dem Hashen auf LF normalisiert. Binaerdateien
(Schriften, Bilder, das OTA-Zip) bleiben roh, dort waere 0x0D0A echter Inhalt.
Drei neue Testfaelle: reiner Zeilenenden-Unterschied, echte Aenderung trotz
verschiedener Zeilenenden, Binaerdatei. 26 Tests der Suite gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-05 13:51:02 +02:00
parent ecea8a0c22
commit 7c96bc8304
3 changed files with 61 additions and 6 deletions
@@ -253,6 +253,34 @@ class NeustartNoetig(unittest.TestCase):
self._schreiben(self.neu, "__pycache__/x.cpython-312.pyc", "egal")
self.assertFalse(a.neustart_noetig(self.alt, self.neu))
def test_zeilenenden_zaehlen_nicht_als_aenderung(self):
"""Am 05.09.2026 am echten Update-Weg gemessen.
Die installierte Fassung lag mit CRLF auf der Platte, das Gitea-Archiv
liefert LF - drei .py-Dateien galten dadurch als geaendert, obwohl sie
nach Entfernen der CR byteweise identisch waren, und die Erkennung
verlangte einen Neustart fuer einen rein kosmetischen Unterschied."""
with open(os.path.join(self.alt, "__init__.py"), "w", newline="\r\n", encoding="utf-8") as datei:
datei.write("x = 1\ny = 2\n")
with open(os.path.join(self.neu, "__init__.py"), "w", newline="\n", encoding="utf-8") as datei:
datei.write("x = 1\ny = 2\n")
self.assertFalse(a.neustart_noetig(self.alt, self.neu))
def test_echte_aenderung_bleibt_erkannt_trotz_zeilenenden(self):
with open(os.path.join(self.alt, "__init__.py"), "w", newline="\r\n", encoding="utf-8") as datei:
datei.write("x = 1\n")
with open(os.path.join(self.neu, "__init__.py"), "w", newline="\n", encoding="utf-8") as datei:
datei.write("x = 2\n")
self.assertTrue(a.neustart_noetig(self.alt, self.neu))
def test_binaerdatei_wird_nicht_normalisiert(self):
# Bei einer Schriftdatei ist 0x0D0A echter Inhalt - hier darf nicht
# normalisiert werden, sonst verschwaende ein echter Unterschied.
for ordner, inhalt in ((self.alt, b"\x00\r\n\x01"), (self.neu, b"\x00\n\x01")):
with open(os.path.join(ordner, "schrift.woff2"), "wb") as datei:
datei.write(inhalt)
self.assertTrue(a.neustart_noetig(self.alt, self.neu))
def test_unlesbarer_ordner_gilt_als_neustart(self):
self.assertTrue(a.neustart_noetig(os.path.join(self.basis, "gibtsnicht"), self.neu))