


























@@ -27,28 +27,30 @@ type docResult struct {
2727}
28282929type runConfig struct {
30-targetLang string
31-sourceLang string
32-docsRoot string
33-tmPath string
34-mode string
35-thinking string
36-overwrite bool
37-maxFiles int
38-parallel int
30+targetLang string
31+sourceLang string
32+docsRoot string
33+tmPath string
34+mode string
35+thinking string
36+overwrite bool
37+allowPartial bool
38+maxFiles int
39+parallel int
3940}
40414142func main() {
4243var (
43-targetLang = flag.String("lang", "zh-CN", "target language (e.g., zh-CN)")
44-sourceLang = flag.String("src", "en", "source language")
45-docsRoot = flag.String("docs", "docs", "docs root")
46-tmPath = flag.String("tm", "", "translation memory path")
47-mode = flag.String("mode", "segment", "translation mode (segment|doc)")
48-thinking = flag.String("thinking", "high", "thinking level (low|medium|high|xhigh)")
49-overwrite = flag.Bool("overwrite", false, "overwrite existing translations")
50-maxFiles = flag.Int("max", 0, "max files to process (0 = all)")
51-parallel = flag.Int("parallel", 1, "parallel workers for doc mode")
44+targetLang = flag.String("lang", "zh-CN", "target language (e.g., zh-CN)")
45+sourceLang = flag.String("src", "en", "source language")
46+docsRoot = flag.String("docs", "docs", "docs root")
47+tmPath = flag.String("tm", "", "translation memory path")
48+mode = flag.String("mode", "segment", "translation mode (segment|doc)")
49+thinking = flag.String("thinking", "high", "thinking level (low|medium|high|xhigh)")
50+overwrite = flag.Bool("overwrite", false, "overwrite existing translations")
51+allowPartial = flag.Bool("allow-partial", false, "write successful doc-mode outputs even when another file fails")
52+maxFiles = flag.Int("max", 0, "max files to process (0 = all)")
53+parallel = flag.Int("parallel", 1, "parallel workers for doc mode")
5254 )
5355flag.Parse()
5456files := flag.Args()
@@ -57,15 +59,16 @@ func main() {
5759 }
58605961if err := runDocsI18N(context.Background(), runConfig{
60-targetLang: *targetLang,
61-sourceLang: *sourceLang,
62-docsRoot: *docsRoot,
63-tmPath: *tmPath,
64-mode: *mode,
65-thinking: *thinking,
66-overwrite: *overwrite,
67-maxFiles: *maxFiles,
68-parallel: *parallel,
62+targetLang: *targetLang,
63+sourceLang: *sourceLang,
64+docsRoot: *docsRoot,
65+tmPath: *tmPath,
66+mode: *mode,
67+thinking: *thinking,
68+overwrite: *overwrite,
69+allowPartial: *allowPartial,
70+maxFiles: *maxFiles,
71+parallel: *parallel,
6972 }, files, func(srcLang, tgtLang string, glossary []GlossaryEntry, thinking string) (docsTranslator, error) {
7073return NewCodexTranslator(srcLang, tgtLang, glossary, thinking)
7174 }); err != nil {
@@ -127,7 +130,7 @@ func runDocsI18N(ctx context.Context, cfg runConfig, files []string, newTranslat
127130processed := 0
128131skipped := 0
129132localizedFiles := []string{}
130-var runErr error
133+var translationErr error
131134132135log.Printf("docs-i18n: mode=%s total=%d pending=%d pre_skipped=%d overwrite=%t thinking=%s parallel=%d", cfg.mode, totalFiles, len(ordered), preSkipped, cfg.overwrite, cfg.thinking, parallel)
133136switch cfg.mode {
@@ -138,7 +141,7 @@ func runDocsI18N(ctx context.Context, cfg runConfig, files []string, newTranslat
138141skipped += skip
139142localizedFiles = append(localizedFiles, outputs...)
140143if err != nil {
141-runErr = err
144+translationErr = err
142145 }
143146 } else {
144147translator, err := newTranslator(cfg.sourceLang, cfg.targetLang, glossary, cfg.thinking)
@@ -151,7 +154,7 @@ func runDocsI18N(ctx context.Context, cfg runConfig, files []string, newTranslat
151154skipped += skip
152155localizedFiles = append(localizedFiles, outputs...)
153156if err != nil {
154-runErr = err
157+translationErr = err
155158 }
156159 }
157160case "segment":
@@ -167,21 +170,25 @@ func runDocsI18N(ctx context.Context, cfg runConfig, files []string, newTranslat
167170processed += proc
168171localizedFiles = append(localizedFiles, outputs...)
169172if err != nil {
170-runErr = err
173+translationErr = err
171174 }
172175default:
173176return fmt.Errorf("unknown mode: %s", cfg.mode)
174177 }
175178176-if err := tm.Save(); err != nil && runErr == nil {
177-runErr = err
179+if err := tm.Save(); err != nil {
180+return err
178181 }
179-if err := postprocessLocalizedDocs(resolvedDocsRoot, cfg.targetLang, localizedFiles); err != nil && runErr == nil {
180-runErr = err
182+if err := postprocessLocalizedDocs(resolvedDocsRoot, cfg.targetLang, localizedFiles); err != nil {
183+return err
181184 }
182185elapsed := time.Since(start).Round(time.Millisecond)
183186log.Printf("docs-i18n: completed processed=%d skipped=%d elapsed=%s", processed, skipped, elapsed)
184-return runErr
187+if translationErr != nil && cfg.allowPartial && cfg.mode == "doc" && processed > 0 {
188+log.Printf("docs-i18n: allowing partial doc output after translation error: %v", translationErr)
189+return nil
190+ }
191+return translationErr
185192}
186193187194func runDocSequential(ctx context.Context, ordered []string, translator docsTranslator, docsRoot, srcLang, tgtLang string, overwrite bool) (int, int, []string, error) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。