11package main
22
33import (
4+ "os"
5+ "strings"
6+
47 "github.com/spf13/cobra"
58 "github.com/studyzy/codei18n/core/config"
9+ "github.com/studyzy/codei18n/core/workflow"
610 "github.com/studyzy/codei18n/internal/log"
711)
812
913var (
10- initSourceLang string
11- initTargetLang string
12- initProvider string
14+ initSourceLang string
15+ initTargetLang string
16+ initProvider string
17+ initWithTranslate bool
18+ initForce bool
1319)
1420
1521var initCmd = & cobra.Command {
1622 Use : "init" ,
1723 Short : "初始化项目配置" ,
24+ Long : `初始化项目配置,继承全局设置,并自动配置 Git 环境。可选执行初次扫描和翻译。` ,
1825 Run : func (cmd * cobra.Command , args []string ) {
19- runInit ()
26+ runInit (cmd )
2027 },
2128}
2229
@@ -25,19 +32,112 @@ func init() {
2532
2633 initCmd .Flags ().StringVar (& initSourceLang , "source-lang" , "en" , "源码语言" )
2734 initCmd .Flags ().StringVar (& initTargetLang , "target-lang" , "zh-CN" , "本地目标语言" )
28- // Default to using LLM-based remote translation (OpenAI-compatible protocol)
29- initCmd .Flags ().StringVar (& initProvider , "provider" , "openai" , "翻译提供商 (openai/llm/ollama)" )
35+ initCmd .Flags ().StringVar (& initProvider , "provider" , "" , "翻译提供商 (openai/llm/ollama)" )
36+ initCmd .Flags ().BoolVar (& initWithTranslate , "with-translate" , false , "初始化后立即执行翻译" )
37+ initCmd .Flags ().BoolVar (& initForce , "force" , false , "如果配置已存在,强制覆盖" )
3038}
3139
32- func runInit () {
33- cfg := config .DefaultConfig ()
34- cfg .SourceLanguage = initSourceLang
35- cfg .LocalLanguage = initTargetLang
36- cfg .TranslationProvider = initProvider
40+ func runInit (cmd * cobra.Command ) {
41+ // 1. Load effective config (Global + Defaults)
42+ cfg , err := config .LoadConfig ()
43+ if err != nil {
44+ log .Warn ("无法加载配置,使用默认值: %v" , err )
45+ cfg = config .DefaultConfig ()
46+ }
47+
48+ // 2. Apply flags
49+ // Note: Flags defined in init() act as overrides or defaults.
50+ // Cobra flags don't automatically populate cfg, we map them here.
51+ // But we need to distinguish between "default value" and "user provided value".
52+ // Since we set default values in flags, we might overwrite global config if we are not careful.
53+ // Actually, `initSourceLang` defaults to "en". If global config has "fr", `initSourceLang` will still be "en" if user didn't provide it?
54+ // No, cobra flags have default values.
55+ // We should only override if user EXPLICITLY provided the flag.
56+ // How to check if flag was changed? cmd.Flags().Changed("source-lang")
57+
58+ if cmd .Flags ().Changed ("source-lang" ) {
59+ cfg .SourceLanguage = initSourceLang
60+ }
61+ if cmd .Flags ().Changed ("target-lang" ) {
62+ cfg .LocalLanguage = initTargetLang
63+ }
64+ if cmd .Flags ().Changed ("provider" ) {
65+ cfg .TranslationProvider = initProvider
66+ }
67+
68+ // 3. Sanitize (Strip secrets inherited from global)
69+ // We create a new sanitized config object to save locally
70+ projectCfg := cfg .Sanitize ()
3771
38- if err := config .SaveConfig (cfg ); err != nil {
72+ // 4. Save Config
73+ if _ , err := os .Stat (".codei18n/config.json" ); err == nil && ! initForce {
74+ log .Fatal ("配置文件已存在 (使用 --force 覆盖)" )
75+ }
76+
77+ if err := config .SaveConfig (projectCfg ); err != nil {
3978 log .Fatal ("保存配置失败: %v" , err )
4079 }
80+ log .Success ("项目配置文件已生成" )
4181
42- log .Success ("项目初始化成功" )
82+ // 5. Git Integration
83+ setupGitIntegration ()
84+
85+ // 6. Map Update (Auto Scan)
86+ log .Info ("正在初始化注释映射..." )
87+ mapResult , err := workflow .MapUpdate (projectCfg , "." , false )
88+ if err != nil {
89+ log .Warn ("映射初始化失败: %v" , err )
90+ } else {
91+ log .Success ("已扫描 %d 条注释,生成初始映射" , mapResult .TotalComments )
92+ }
93+
94+ // 7. Conditional Translation
95+ if initWithTranslate {
96+ log .Info ("正在执行初次翻译..." )
97+ transResult , err := workflow .Translate (projectCfg , workflow.TranslateOptions {
98+ Concurrency : 5 ,
99+ // Use provider/model from config unless overridden (which we handled in step 2)
100+ })
101+ if err != nil {
102+ log .Warn ("翻译失败: %v" , err )
103+ } else {
104+ log .Success ("翻译完成!共处理 %d 条注释" , transResult .SuccessCount )
105+ }
106+ } else {
107+ log .Info ("提示: 运行 'codei18n translate' 可生成翻译" )
108+ }
109+
110+ log .Success ("项目初始化完成!" )
111+ }
112+
113+ func setupGitIntegration () {
114+ if _ , err := os .Stat (".git" ); os .IsNotExist (err ) {
115+ return // Not a git repo
116+ }
117+
118+ // 1. Update .gitignore
119+ gitignorePath := ".gitignore"
120+ content , _ := os .ReadFile (gitignorePath ) // ignore error, treat as empty if missing
121+ sContent := string (content )
122+ if ! strings .Contains (sContent , ".codei18n/" ) {
123+ f , err := os .OpenFile (gitignorePath , os .O_APPEND | os .O_CREATE | os .O_WRONLY , 0644 )
124+ if err != nil {
125+ log .Warn ("更新 .gitignore 失败: %v" , err )
126+ } else {
127+ if len (content ) > 0 && ! strings .HasSuffix (sContent , "\n " ) {
128+ f .WriteString ("\n " )
129+ }
130+ f .WriteString (".codei18n/\n " )
131+ f .Close ()
132+ log .Success ("已将 .codei18n/ 添加到 .gitignore" )
133+ }
134+ }
135+
136+ // 2. Install hook
137+ // Assuming installHook is available in package main (from hook.go)
138+ if err := installHook (); err != nil {
139+ log .Warn ("安装 git hook 失败: %v" , err )
140+ } else {
141+ log .Success ("Git Pre-commit Hook 已自动安装" )
142+ }
43143}
0 commit comments