Moteur : corrections de relecture de la construction des arguments

buildServeArgs se disait pure, mais la traduction des drapeaux de chargement
qu'elle appelle écrivait encore sur stderr quand un --load-mode dio tombait sur
un moteur ancien. La note est désormais rendue comme les autres et affichée
par cmdServe, au même rang qu'avant (avant la note NGL).

- normalizeLoadFlags / downgradeLoadMode rendent la note au lieu de l'écrire.
- Table de tests : cas dio sur moteur ancien (drapeau retiré, une note), et
  TestNormalizeLoadFlags vérifie que seul ce cas produit une note.
- Aucun changement de ligne de commande.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Opus 5.5 committed 2026-10-03 22:27:04 +02:00
1 parent 76f5697487
commit 03eb56aee3
3 files changed
+28 -9

No files matched your search

+14 -8
View File
@@ -165,7 +165,10 @@ func hasAnyFlag(args []string, flags ...string) bool {
//
// none → --no-mmap · mlock → --mlock --no-mmap · mmap+mlock → --mlock
// auto, mmap, dio → rien (défaut de l'ancien moteur)
func normalizeLoadFlags(args []string, supportsLoadMode bool) []string {
//
// La note éventuelle (dio abandonné) est RENDUE, pas affichée : buildServeArgs
// reste pure et c'est cmdServe qui l'écrit, à sa place parmi les autres notes.
func normalizeLoadFlags(args []string, supportsLoadMode bool) ([]string, string) {
if !supportsLoadMode {
return downgradeLoadMode(args)
}
@@ -185,7 +188,7 @@ func normalizeLoadFlags(args []string, supportsLoadMode bool) []string {
}
}
if explicit || !(mlock || nommap || mmap) {
return out
return out, ""
}
mode := "mmap"
switch {
@@ -196,12 +199,12 @@ func normalizeLoadFlags(args []string, supportsLoadMode bool) []string {
case nommap:
mode = "none"
}
return append(out, "--load-mode", mode)
return append(out, "--load-mode", mode), ""
}
// downgradeLoadMode retraduit un --load-mode pour un moteur qui ne le connaît
// pas : le lui passer tel quel le ferait sortir en erreur au démarrage.
func downgradeLoadMode(args []string) []string {
func downgradeLoadMode(args []string) ([]string, string) {
mode, found := "", false
kept := make([]string, 0, len(args))
for i := 0; i < len(args); i++ {
@@ -221,7 +224,7 @@ func downgradeLoadMode(args []string) []string {
kept = append(kept, a)
}
if !found {
return args
return args, ""
}
add := func(flag string) {
for _, a := range kept {
@@ -240,9 +243,9 @@ func downgradeLoadMode(args []string) []string {
case "mmap+mlock":
add("--mlock")
case "dio":
fmt.Fprintf(os.Stderr, "[loki serve] ce moteur ne connaît pas --load-mode dio (DirectIO) : chargement par défaut\n")
return kept, "ce moteur ne connaît pas --load-mode dio (DirectIO) : chargement par défaut"
}
return kept
return kept, ""
}
// cmdServe replaces the historic start.sh: read config.env, build the
@@ -418,7 +421,10 @@ func buildServeArgs(cfg map[string]string, extra []string, bin string, si serveS
// l'utilisateur a écrit à la main décide des défauts que Loki a le droit
// d'ajouter (voir hasAnyFlag). Il est aussi traduit vers les drapeaux de
// chargement actuels quand le moteur les attend (voir normalizeLoadFlags).
extra = normalizeLoadFlags(extra, helpSupportsLoadMode(si.Help))
extra, loadNote := normalizeLoadFlags(extra, helpSupportsLoadMode(si.Help))
if loadNote != "" {
notes = append(notes, loadNote)
}
args = []string{bin,
"-m", si.Model,
+8
View File
@@ -148,6 +148,14 @@ func TestBuildServeArgs(t *testing.T) {
si: serveSysInfo{Help: helpOld},
want: with("--parallel", "1", "-ngl", "28", "--no-mmap"),
},
{
// dio n'existe pas sur l'ancien moteur : retiré, et dit par une note
// RENDUE (buildServeArgs n'écrit rien elle-même).
name: "--load-mode dio sur moteur ancien : retiré, une note",
cfg: map[string]string{"NGL": "28", "EXTRA_ARGS": "--load-mode dio -fa on"},
si: serveSysInfo{Help: helpOld},
want: with("--parallel", "1", "-ngl", "28", "-fa", "on"), wantNotes: 1,
},
{
name: "sélection GPU : variables d'environnement, ligne inchangée",
cfg: map[string]string{"NGL": "28", "CUDA_VISIBLE_DEVICES": "1,0"},
+6 -1
View File
@@ -60,10 +60,15 @@ func TestNormalizeLoadFlags(t *testing.T) {
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := normalizeLoadFlags(c.in, c.supports)
got, note := normalizeLoadFlags(c.in, c.supports)
if !reflect.DeepEqual(got, c.want) {
t.Fatalf("got %q, want %q", got, c.want)
}
// Seul « dio » abandonné sur un moteur ancien se signale : les autres
// traductions gardent le sens demandé.
if wantNote := c.name == "moteur ancien : dio abandonné"; (note != "") != wantNote {
t.Fatalf("note = %q, attendue : %v", note, wantNote)
}
})
}
}