Kaynağa Gözat

feat(i18n): pluralize composed-dir messages via Fluent selectors

"1 files" was grammatically wrong. Replace the two hardcoded format!
strings (dry-run + built) in compose.rs with Fluent messages that use
{ $count -> [one] ... *[other] ... } selectors for both "sources" and
"files". Added composed-dir-dry-run / composed-dir-built keys to all
six locales (en one/other; ru one/few/many; es/it/fr/de one/other).

Verified: en "3 sources, 1 file"; ru "3 источника, 1 файл" (few+one)
/ "1 источник, 2 файла" (one+few).

Note: non-en strings currently only render on the main thread —
fluent_i18n's set_locale is thread-local, and most t! calls run inside
tokio::spawn worker threads that don't inherit it. en (the fallback)
renders everywhere. Fixing the thread-local propagation is a separate,
pre-existing concern across 16 spawn sites.
Alexander Korolev 2 ay önce
ebeveyn
işleme
283d2fa6d6

+ 14 - 0
locales/de/main.ftl

@@ -91,3 +91,17 @@ cluster-nodes-available = ✅ All nodes are now available
 cluster-nodes-not-available-timeout = ❌ Timeout waiting for nodes to become available
 ha-config-required-for-power-on = ❌ HA config required for power-on
 power-off-container-stop-failed = ⚠️ Failed to stop containers on node { $name }: { $error}
+composed-dir-dry-run = [Testlauf] Zusammengestelltes Modellverzeichnis '{ $host }' auf '{ $node }' würde erstellt (Mount: { $mount }, { $sources } { $sources ->
+        [one] Quelle
+       *[other] Quellen
+    }, { $files } { $files ->
+        [one] Datei
+       *[other] Dateien
+    })
+composed-dir-built = Zusammengestelltes Modellverzeichnis '{ $host }' auf '{ $node }' erstellt ({ $sources } { $sources ->
+        [one] Quelle
+       *[other] Quellen
+    }, { $files } { $files ->
+        [one] Datei
+       *[other] Dateien
+    })

+ 14 - 0
locales/en/main.ftl

@@ -130,3 +130,17 @@ health-recipe-line =   { $recipe } — { $nodes } node(s): { $list }
 tmux-ray-backend = 🐍 Ray backend detected — starting head node first...
 tmux-mp-backend = 🔗 MP backend detected — starting all nodes in parallel...
 tmux-following-logs = 📜 Following logs from '{ $sess }' on { $name }...
+composed-dir-dry-run = [dry-run] would build composed model dir '{ $host }' on '{ $node }' (mount: { $mount }, { $sources } { $sources ->
+        [one] source
+       *[other] sources
+    }, { $files } { $files ->
+        [one] file
+       *[other] files
+    })
+composed-dir-built = Built composed model dir '{ $host }' on '{ $node }' ({ $sources } { $sources ->
+        [one] source
+       *[other] sources
+    }, { $files } { $files ->
+        [one] file
+       *[other] files
+    })

+ 14 - 0
locales/es/main.ftl

@@ -91,3 +91,17 @@ cluster-nodes-available = ✅ All nodes are now available
 cluster-nodes-not-available-timeout = ❌ Timeout waiting for nodes to become available
 ha-config-required-for-power-on = ❌ HA config required for power-on
 power-off-container-stop-failed = ⚠️ Failed to stop containers on node { $name }: { $error}
+composed-dir-dry-run = [simulación] se crearía el directorio de modelo compuesto '{ $host }' en '{ $node }' (montaje: { $mount }, { $sources } { $sources ->
+        [one] fuente
+       *[other] fuentes
+    }, { $files } { $files ->
+        [one] archivo
+       *[other] archivos
+    })
+composed-dir-built = Creado directorio de modelo compuesto '{ $host }' en '{ $node }' ({ $sources } { $sources ->
+        [one] fuente
+       *[other] fuentes
+    }, { $files } { $files ->
+        [one] archivo
+       *[other] archivos
+    })

+ 14 - 0
locales/fr/main.ftl

@@ -91,3 +91,17 @@ cluster-nodes-available = ✅ All nodes are now available
 cluster-nodes-not-available-timeout = ❌ Timeout waiting for nodes to become available
 ha-config-required-for-power-on = ❌ HA config required for power-on
 power-off-container-stop-failed = ⚠️ Failed to stop containers on node { $name }: { $error}
+composed-dir-dry-run = [simulation] création du répertoire de modèle composé '{ $host }' sur '{ $node }' (montage : { $mount }, { $sources } { $sources ->
+        [one] source
+       *[other] sources
+    }, { $files } { $files ->
+        [one] fichier
+       *[other] fichiers
+    })
+composed-dir-built = Répertoire de modèle composé créé : '{ $host }' sur '{ $node }' ({ $sources } { $sources ->
+        [one] source
+       *[other] sources
+    }, { $files } { $files ->
+        [one] fichier
+       *[other] fichiers
+    })

+ 14 - 0
locales/it/main.ftl

@@ -91,3 +91,17 @@ cluster-nodes-available = ✅ All nodes are now available
 cluster-nodes-not-available-timeout = ❌ Timeout waiting for nodes to become available
 ha-config-required-for-power-on = ❌ HA config required for power-on
 power-off-container-stop-failed = ⚠️ Failed to stop containers on node { $name }: { $error}
+composed-dir-dry-run = [prova] verrebbe creata la directory del modello composto '{ $host }' su '{ $node }' (montaggio: { $mount }, { $sources } { $sources ->
+        [one] sorgente
+       *[other] sorgenti
+    }, { $files } { $files ->
+        [one] file
+       *[other] file
+    })
+composed-dir-built = Creata directory del modello composto '{ $host }' su '{ $node }' ({ $sources } { $sources ->
+        [one] sorgente
+       *[other] sorgenti
+    }, { $files } { $files ->
+        [one] file
+       *[other] file
+    })

+ 18 - 0
locales/ru/main.ftl

@@ -92,3 +92,21 @@ cluster-nodes-available = ✅ All nodes are now available
 cluster-nodes-not-available-timeout = ❌ Timeout waiting for nodes to become available
 ha-config-required-for-power-on = ❌ HA config required for power-on
 power-off-container-stop-failed = ⚠️ Failed to stop containers on node { $name }: { $error}
+composed-dir-dry-run = [пробный запуск] будет создан каталог составной модели '{ $host }' на '{ $node }' (точка монтирования: { $mount }, { $sources } { $sources ->
+        [one] источник
+        [few] источника
+       *[many] источников
+    }, { $files } { $files ->
+        [one] файл
+        [few] файла
+       *[many] файлов
+    })
+composed-dir-built = Создан каталог составной модели '{ $host }' на '{ $node }' ({ $sources } { $sources ->
+        [one] источник
+        [few] источника
+       *[many] источников
+    }, { $files } { $files ->
+        [one] файл
+        [few] файла
+       *[many] файлов
+    })

+ 15 - 12
src/docker/compose.rs

@@ -37,13 +37,14 @@ pub(crate) async fn build_composed_dir_on_node(
 
     if dry_run {
         println!(
-            "[dry-run] would build composed model dir '{}' on '{}' \
-             (mount: {}, {} sources, {} files)",
-            host_path,
-            node.name,
-            container_path,
-            composed.sources.len(),
-            composed.files.len()
+            "{}",
+            fluent_i18n::t!("composed-dir-dry-run", {
+                "host" => host_path,
+                "node" => node.name.clone(),
+                "mount" => container_path,
+                "sources" => composed.sources.len() as u32,
+                "files" => composed.files.len() as u32,
+            })
         );
         return Ok((host_path, container_path));
     }
@@ -76,11 +77,13 @@ pub(crate) async fn build_composed_dir_on_node(
     }
 
     info!(
-        "Built composed model dir '{}' on '{}' ({} sources, {} files)",
-        host_path,
-        node.name,
-        composed.sources.len(),
-        composed.files.len()
+        "{}",
+        fluent_i18n::t!("composed-dir-built", {
+            "host" => host_path,
+            "node" => node.name.clone(),
+            "sources" => composed.sources.len() as u32,
+            "files" => composed.files.len() as u32,
+        })
     );
 
     Ok((host_path, container_path))