@@ -47,36 +47,60 @@ write_hooks() → UvPyprojectUpdater.write()
4747
4848### 1. Filter-/Transform-Funktion (rein, testbar)
4949
50- ` _constraints_to_uv(constraints: list[str]) -> list[str] ` im uv-Modul:
51-
52- 1 . Über jede Zeile aus ` state.constraints ` iterieren.
53- 2 . Überspringen: Leerzeilen, ` #### ` -Trennlinien, alle mit ` # ` beginnenden Kommentarzeilen
54- (das schließt die ` # begin/end constraints from ... ` -Header ** und** die
55- ` # <pkg> -> mxdev disabled (...) ` -Zeilen ein). Dadurch fallen aus-Source-entwickelte und
56- per Override ersetzte Pakete automatisch raus — korrekt, da diese über ` [tool.uv.sources] `
57- bzw. ` override-dependencies ` kommen.
58- 3 . Verbleibende Zeilen mit ` packaging.requirements.Requirement ` parsen. Nicht-parsebare
59- Zeilen (z.B. ` --hash ` , ` --index-url ` , ` -e ... ` ) verwerfen und auf DEBUG loggen.
60- 4 . ** Kein Dedupe, keine Konfliktauflösung** — konsistent mit dem klassischen Pfad
50+ Leitidee: Das ` constraint-dependencies ` -Array wird ein ** TOML-Spiegel von
51+ ` constraints-mxdev.txt ` ** — gleiche ** Quell-Reihenfolge** , Herkunfts-Kommentare erhalten.
52+ Specifier-Zeilen werden zu Array-Einträgen, Kommentarzeilen zu Array-internen Kommentaren.
53+
54+ ` _constraints_to_uv(constraints: list[str]) -> list[ConstraintItem] ` im uv-Modul, wobei
55+ ` ConstraintItem ` ein kleines, geordnetes Element ist, das ** entweder** einen Kommentar
56+ ** oder** einen Specifier trägt (z.B. ` ("comment", text) ` / ` ("entry", specifier) ` ). So bleibt
57+ die Funktion rein und testbar und der Writer kann Kommentare + Einträge in Reihenfolge
58+ emittieren.
59+
60+ Pro Zeile aus ` state.constraints ` , in Original-Reihenfolge:
61+
62+ 1 . ** Specifier-Zeilen** mit ` packaging.requirements.Requirement ` parsen → als ` entry `
63+ übernehmen. Environment-Markers (` ; python_version >= "3.9" ` ) bleiben erhalten.
64+ Nicht-parsebare „Zeilen, die wie Specifier aussehen" (z.B. ` --hash ` , ` --index-url ` ,
65+ ` -e ... ` ) verwerfen und auf DEBUG loggen.
66+ 2 . ** Herkunfts-Kommentare** (` # begin constraints from: <url> ` / ` # end constraints from: <url> ` )
67+ als ` comment ` erhalten — sie liefern die Nachvollziehbarkeit, die der txt-Pfad bietet.
68+ 3 . ** ` # <pkg> -> mxdev disabled (...) ` -Zeilen** als ` comment ` erhalten (1:1 wie in
69+ ` constraints-mxdev.txt ` ). Sie dokumentieren, * warum* ein Pin hier fehlt (das Paket kommt
70+ über ` [tool.uv.sources] ` bzw. ` override-dependencies ` ). → ** Auf Review verifizieren** , ob
71+ gewünscht; Alternative wäre, sie wegzulassen.
72+ 4 . ** Dekorative ` ####… ` -Trennlinien und Leerzeilen** verwerfen (reines visuelles Rauschen;
73+ die begin/end-Header liefern die Gruppierung).
74+ 5 . ** Kein Dedupe, keine Konfliktauflösung** — konsistent mit dem klassischen Pfad
6175 (` constraints-mxdev.txt ` ist reiner Passthrough; pip/uv behandelt Konflikte). Konfligierende
6276 Versionen desselben Pakets bleiben beide erhalten.
63- 5 . ** Alphabetisch sortieren** , case-insensitive nach Paketname (diff-freundlich).
64- Environment-Markers (` ; python_version >= "3.9" ` ) bleiben am Specifier erhalten.
65- 6 . Rückgabe: Liste sortierter Specifier-Strings.
77+ 6 . ** Keine Sortierung** — Quell-Reihenfolge wird beibehalten (Gruppen-Kohärenz vor
78+ Diff-Minimierung).
6679
6780### 2. Schreiben nach pyproject.toml
6881
6982Erweiterung von ` _update_pyproject ` in [ src/mxdev/uv.py] ( ../../../src/mxdev/uv.py ) :
7083
7184- Ziel: ` [tool.uv] constraint-dependencies ` als multiline-Array (analog zum bestehenden
72- ` override-dependencies ` -Block, ` uv.py:152-156 ` ).
85+ ` override-dependencies ` -Block, ` uv.py:152-156 ` ), aber mit ** Array-internen Kommentaren**
86+ in Quell-Reihenfolge.
7387- ** Ersetzen + Marker:** Das Array wird vollständig von mxdev verwaltet und bei jedem Lauf
74- überschrieben. Kennzeichnung „managed by mxdev“ — bevorzugt als Array-interner Kommentar
75- via tomlkit; falls tomlkit das nicht stabil serialisiert, als Kommentarzeile direkt über
76- dem Array (` # managed by mxdev — do not edit ` ). ** Im Plan zu verifizieren.**
88+ überschrieben. Eine ` # managed by mxdev — do not edit ` -Kommentarzeile als erstes Element.
7789- Leeres Filterergebnis → Key nicht schreiben; ein bestehender, mxdev-verwalteter Key wird in
7890 dem Fall geleert/entfernt, damit kein veralteter Stand stehen bleibt.
7991
92+ ### ⚠️ Technisches Hauptrisiko: tomlkit & Array-interne Kommentare
93+
94+ Array-interne Kommentare über viele Zeilen sind die heikelste tomlkit-Stelle. ** Früh im Plan
95+ verifizieren** (kleiner Spike), dass tomlkit interspersed comments in einem multiline-Array
96+ korrekt ** und idempotent** serialisiert (zweiter Lauf = byte-identisch).
97+
98+ Falls tomlkit das nicht sauber round-trippt, ** Fallback** (Reihenfolge bleibt erhalten):
99+ Herkunft als ** Inline-Kommentar pro Eintrag** statt als eigene Kommentarzeile, z.B.
100+ ` "Zope==6.0", # from <url> ` . Das unterstützt tomlkit zuverlässig. Die begin/end-Blockheader
101+ werden dann zu einem Inline-` # from <url> ` -Suffix pro Eintrag verdichtet; die disabled-Marker
102+ entfallen in diesem Fallback.
103+
80104### 3. Opt-out
81105
82106- Default ** an** , sobald ` [tool.uv] managed = true ` (konsistent mit ` sources ` /` override-dependencies ` ).
@@ -96,9 +120,11 @@ Erweiterung von `_update_pyproject` in [src/mxdev/uv.py](../../../src/mxdev/uv.p
96120## Tests (TDD)
97121
98122Reine Funktion ` _constraints_to_uv ` :
99- - Kommentare, ` #### ` -Trenner, ` # ... -> mxdev disabled ` -Zeilen werden gefiltert.
123+ - Specifier-Zeilen → ` entry ` , in ** Quell-Reihenfolge** (keine Sortierung).
124+ - ` # begin/end constraints from ` -Header → als ` comment ` erhalten.
125+ - ` # ... -> mxdev disabled ` -Zeilen → als ` comment ` erhalten.
126+ - ` #### ` -Trenner und Leerzeilen werden verworfen.
100127- Nicht-parsebare Zeilen (` --hash ` , ` -e ` , ` --index-url ` ) werden verworfen.
101- - Alphabetische Sortierung (case-insensitive).
102128- Environment-Markers bleiben erhalten.
103129- Konfligierende/doppelte Versionen bleiben beide erhalten (Passthrough).
104130
@@ -107,12 +133,13 @@ Hook-Integration:
107133- ` managed=false ` /fehlend → nicht geschrieben.
108134- Opt-out-Setting ` uv-constraint-dependencies = false ` greift.
109135- Bestehendes Array wird ersetzt (nicht gemerged).
110- - Idempotenz: zweiter Lauf erzeugt identisches Ergebnis.
136+ - Herkunfts-Kommentare landen in Quell-Reihenfolge im Array.
137+ - Idempotenz: zweiter Lauf erzeugt ** byte-identisches** Ergebnis (deckt das tomlkit-Risiko ab).
111138- Leeres Ergebnis → kein/leerer Key.
112139
113140Ende-zu-Ende:
114- - ` -c URL ` -Kette via httpretty-Fixture (wie in bestehenden Tests) → korrekt aufgelöste,
115- sortierte ` constraint-dependencies ` .
141+ - ` -c URL ` -Kette via httpretty-Fixture (wie in bestehenden Tests) → korrekt aufgelöste
142+ ` constraint-dependencies ` in Quell-Reihenfolge mit Herkunfts-Kommentaren .
116143
117144## Bewusst ausgeklammert (YAGNI)
118145
@@ -121,3 +148,4 @@ Ende-zu-Ende:
121148- Keine separate ` uv-constraints = URL ` -Konfiguration (die bestehende ` requirements-in ` -Kette
122149 ist die einzige Quelle der Wahrheit).
123150- Keine Konflikt-/Dedupe-Logik (Konsistenz mit dem klassischen Pfad).
151+ - Keine alphabetische Sortierung (Quell-Reihenfolge + Gruppen-Header gewählt).
0 commit comments