feat: v0.4.0 — 配置架构重构 + 一键多端推送 + 项目级代理控制\n\n架构重构:\n- 配置从 Platform→User→Project 重构为扁平的 Projects+Groups+Credentials 模型\n- 侧边栏完全重写,适配新分组→项目树结构\n- 新增分组(Group)管理和凭据(Credential)管理\n\n新功能:\n- 一键多端推送:Push All 按钮,将当前分支/标签推送到所有远程仓库\n- 项目级代理控制:每个项目独立设置代理(跟随全局/强制开启/强制关闭)\n- GitClient 新增 RunWithProxy 方法,支持按调用级别覆盖全局代理\n- 所有网络操作(Pull/Push/Fetch)均支持项目级代理设置\n\n其他:\n- 新增 CHANGELOG.md 版本更新日志\n- 更新 README/README_CN 文档,反映最新 72+ API 方法\n- 版本号升级到 0.4.0(config.yml/info.json/Info.plist)
Some checks failed
Release / build-windows (push) Has been cancelled

This commit is contained in:
zyj
2026-03-12 11:41:26 +08:00
parent 3ec453cc38
commit c787c99622
17 changed files with 1443 additions and 727 deletions

View File

@@ -8,32 +8,41 @@ import (
"gopkg.in/yaml.v3"
)
type Project struct {
Name string `yaml:"name"`
Path string `yaml:"path"`
Enabled bool `yaml:"enabled"` // 可选,默认 true
// ProjectItem 项目配置(以路径为核心)
type ProjectItem struct {
Name string `yaml:"name"`
Path string `yaml:"path"`
Group string `yaml:"group,omitempty"` // 所属分组名,可为空表示"未分组"
UseProxy *bool `yaml:"use_proxy,omitempty"` // 是否走系统代理nil 表示跟随全局
}
type User struct {
Username string `yaml:"username"`
Token string `yaml:"token"` // 可选:未来扩展 API 功能
Projects []Project `yaml:"projects"`
// Group 项目分组
type Group struct {
Name string `yaml:"name"`
Icon string `yaml:"icon,omitempty"` // 可选图标标识
}
type Platform struct {
BaseURL string `yaml:"base_url"` // GitHub/Gitee 可为空Gitea 需要
Users []User `yaml:"users"`
// Credential 凭证信息(独立于项目)
type Credential struct {
Platform string `yaml:"platform"` // github / gitee / gitea / ...
BaseURL string `yaml:"base_url,omitempty"` // 自建平台地址
Username string `yaml:"username"`
Token string `yaml:"token,omitempty"`
}
// Settings 应用设置
type Settings struct {
Concurrency int `yaml:"concurrency"`
NetworkCheck bool `yaml:"network_check"`
LogLevel string `yaml:"log_level"`
}
// AppConfig 应用配置(扁平化结构)
type AppConfig struct {
Platforms map[string]Platform `yaml:"platforms"`
Settings Settings `yaml:"settings"`
Projects []ProjectItem `yaml:"projects"`
Groups []Group `yaml:"groups"`
Credentials []Credential `yaml:"credentials"`
Settings Settings `yaml:"settings"`
}
// configPath 返回 config.yaml 的绝对路径(与可执行文件同目录)
@@ -53,18 +62,26 @@ func LoadConfig() (*AppConfig, error) {
}
defer file.Close()
var appConfig *AppConfig
err = yaml.NewDecoder(file).Decode(&appConfig)
if err != nil {
var appConfig AppConfig
if err := yaml.NewDecoder(file).Decode(&appConfig); err != nil {
return nil, err
}
return appConfig, nil
if appConfig.Projects == nil {
appConfig.Projects = []ProjectItem{}
}
if appConfig.Groups == nil {
appConfig.Groups = []Group{}
}
if appConfig.Credentials == nil {
appConfig.Credentials = []Credential{}
}
return &appConfig, nil
}
// SaveConfig 将配置保存到 config.yaml 文件
func SaveConfig(config *AppConfig) error {
func SaveConfig(cfg *AppConfig) error {
file, err := os.OpenFile(configPath(), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil {
return err
@@ -72,10 +89,8 @@ func SaveConfig(config *AppConfig) error {
defer file.Close()
enc := yaml.NewEncoder(file)
enc.SetIndent(2)
if err := enc.Encode(config); err != nil {
if err := enc.Encode(cfg); err != nil {
return fmt.Errorf("写入配置文件失败: %w", err)
}
return enc.Close()
}