From 0b4d02d232b1e70e7f871695ef0f601e164042bf Mon Sep 17 00:00:00 2001 From: unclesam <2036253946@qq.com> Date: Mon, 17 Aug 2026 21:46:02 +0800 Subject: [PATCH] =?UTF-8?q?fix(config):=20=E8=B0=83=E6=95=B4=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=8A=A0=E8=BD=BD=E4=BC=98=E5=85=88=E7=BA=A7=E4=B8=8E?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E9=85=8D=E7=BD=AE=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 全局配置优先加载,项目级配置进行增量覆盖 - 环境变量保持最高优先级 - 移除项目根目录 config.yaml 与 configs/config.yaml 探测 - 根命令允许接收任意参数 --- cmd/config.go | 33 +++++++++++++++++---------------- cmd/root.go | 1 + 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/cmd/config.go b/cmd/config.go index d1dd96b..2940c8c 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -31,34 +31,35 @@ func getConfigPath() (string, error) { return filepath.Join(dir, "config.yaml"), nil } -// LoadConfig 读取全局配置(优先使用环境变量,其次读取 yaml 文件) +// LoadConfig 智能读取配置: +// 1. 先读取用户全局配置 ~/.git-air/config.yaml (保证 APIKey 等全局生效) +// 2. 若当前项目存在 .git-air.yaml 或 git-air.yaml,则进行项目级增量覆盖 +// 3. 环境变量最高优先级覆盖 func LoadConfig() (*AppConfig, error) { cfg := &AppConfig{ Provider: "gemini", Model: "gemini-3.7-flash", } - // 1. 优先探测当前项目根目录下的配置文件 - localCandidates := []string{"config.yaml", ".git-air.yaml", ".git-air.yml", "configs/config.yaml"} - loaded := false - - for _, name := range localCandidates { - if data, err := os.ReadFile(name); err == nil && len(data) > 0 { + // 1. 首先加载全局配置 ~/.git-air/config.yaml + configPath, err := getConfigPath() + if err == nil { + if data, err := os.ReadFile(configPath); err == nil && len(data) > 0 { if err := yaml.Unmarshal(data, cfg); err != nil { - return nil, fmt.Errorf("解析配置文件失败: %w", err) + // 全局配置错误可输出警告或直接返回错误 + return nil, fmt.Errorf("解析全局配置文件 [%s] 失败: %w", configPath, err) } - loaded = true - break } } - // 2. 如果项目根目录下没有,则回退读取用户全局配置 ~/.git-air/config.yaml - if !loaded { - configPath, err := getConfigPath() - if err == nil { - if data, err := os.ReadFile(configPath); err == nil { - _ = yaml.Unmarshal(data, cfg) + // 2. 检查当前项目是否有专属于 git-air 的配置文件 (.git-air.yaml / git-air.yaml) 进行增量覆盖 + localCandidates := []string{".git-air.yaml", ".git-air.yml", "git-air.yaml"} + for _, name := range localCandidates { + if data, err := os.ReadFile(name); err == nil && len(data) > 0 { + if err := yaml.Unmarshal(data, cfg); err != nil { + return nil, fmt.Errorf("解析项目配置文件 [%s] 失败: %w", name, err) } + break } } diff --git a/cmd/root.go b/cmd/root.go index a0f0261..24acb64 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -16,6 +16,7 @@ var rootCmd = &cobra.Command{ Short: "git-air: 极轻量、极速的 Git 原生 AI 代码评审工具", Long: `git-air 是一个纯 Go 编写的 Git AI 评审利器。 支持一键评审暂存区、指定 Commit、分支差异或单文件,无缝兼容 Gemini、DeepSeek、Ollama 和 OpenAI。`, + Args: cobra.ArbitraryArgs, Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context()