feat: 初始提交 - Code Server Bridge完整实现

- OAuth认证系统(Gitea + Lua扩展)
- Git自动化操作(本地/SSH远程)
- 实时进度WebSocket推送
- 现代化Tab界面UI
- Cobra CLI命令行(init/version/serve)
- 完整构建系统(Makefile + Taskfile)
- UPX压缩支持(体积减少70%)
This commit is contained in:
2026-01-08 23:32:29 +08:00
commit 8265df0dcd
40 changed files with 3786 additions and 0 deletions

103
cmd/server/cmd/init.go Normal file
View File

@@ -0,0 +1,103 @@
package cmd
import (
"cs-bridge/internal/config"
"fmt"
"os"
"path/filepath"
"github.com/go-yaml/yaml"
"github.com/spf13/cobra"
)
var initCmd = &cobra.Command{
Use: "init",
Short: "初始化配置文件",
Long: `生成默认的config.yaml配置文件和scripts目录`,
Run: func(cmd *cobra.Command, args []string) {
configPath, _ := cmd.Flags().GetString("output")
force, _ := cmd.Flags().GetBool("force")
// 检查文件是否存在
if _, err := os.Stat(configPath); err == nil && !force {
fmt.Printf("❌ 配置文件已存在: %s\n", configPath)
fmt.Println("使用 --force 强制覆盖")
return
}
// 创建默认配置文件
cfg := config.DefaultConfig()
defaultConfig, err := yaml.Marshal(cfg)
if err != nil {
fmt.Printf("❌ 生成配置失败: %v\n", err)
return
}
// 写入配置文件
if err := os.WriteFile(configPath, defaultConfig, 0644); err != nil {
fmt.Printf("❌ 创建配置文件失败: %v\n", err)
return
}
fmt.Printf("✅ 配置文件已创建: %s\n", configPath)
// 创建scripts目录和示例Lua脚本
scriptsDir := "scripts/oauth"
if err := os.MkdirAll(scriptsDir, 0755); err != nil {
fmt.Printf("⚠️ 创建scripts目录失败: %v\n", err)
} else {
// 创建示例Lua脚本
luaScript := `-- Gitea OAuth Provider
-- 此脚本定义了Gitea OAuth认证流程
function auth_url(cfg, state)
local params = {
"client_id=" .. util.url_encode(cfg.client_id),
"redirect_uri=" .. util.url_encode(cfg.redirect_uri),
"response_type=code",
"scope=read:user",
"state=" .. util.url_encode(state)
}
return cfg.base_url .. "/login/oauth/authorize?" .. table.concat(params, "&")
end
function exchange(cfg, code)
local body = {
client_id = cfg.client_id,
client_secret = cfg.client_secret,
code = code,
grant_type = "authorization_code",
redirect_uri = cfg.redirect_uri
}
return util.http_post_json(cfg.base_url .. "/login/oauth/access_token", body)
end
function user_info(cfg, token)
local headers = {
Authorization = "Bearer " .. token
}
return util.http_get_json(cfg.base_url .. "/api/v1/user", headers)
end
`
luaPath := filepath.Join(scriptsDir, "gitea.lua")
if err := os.WriteFile(luaPath, []byte(luaScript), 0644); err != nil {
fmt.Printf("⚠️ 创建Lua脚本失败: %v\n", err)
} else {
fmt.Printf("✅ 示例Lua脚本已创建: %s\n", luaPath)
}
}
fmt.Println("\n📝 下一步:")
fmt.Printf("1. 编辑配置文件: %s\n", configPath)
fmt.Println("2. 配置OAuth客户端信息")
fmt.Println("3. 运行服务: code-server-bridge")
},
}
func init() {
initCmd.Flags().StringP("output", "o", "config.yaml", "配置文件输出路径")
initCmd.Flags().BoolP("force", "f", false, "强制覆盖已存在的文件")
rootCmd.AddCommand(initCmd)
}

42
cmd/server/cmd/root.go Normal file
View File

@@ -0,0 +1,42 @@
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
var (
// 版本信息,构建时注入
Version = "dev"
BuildTime = "unknown"
GitCommit = "unknown"
)
var rootCmd = &cobra.Command{
Use: "code-server-bridge",
Short: "Code Server Bridge - OAuth认证和Git仓库准备工具",
Long: `Code Server Bridge 是一个为code-server提供OAuth认证和Git仓库自动准备的桥接服务。
功能特性:
- OAuth认证 (支持Gitea等)
- Git仓库自动克隆/更新
- 实时进度显示
- Workspace自动管理
使用 'code-server-bridge serve' 启动服务器
使用 'code-server-bridge init' 初始化配置文件`,
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func init() {
// 全局flags
rootCmd.PersistentFlags().StringP("config", "c", "config.yaml", "配置文件路径")
}

80
cmd/server/cmd/serve.go Normal file
View File

@@ -0,0 +1,80 @@
package cmd
import (
"cs-bridge/internal/config"
"cs-bridge/internal/db"
"cs-bridge/internal/http"
"cs-bridge/internal/oauth"
"cs-bridge/pkg/httpclient"
"cs-bridge/pkg/logger"
"fmt"
"os"
"strings"
"github.com/spf13/cobra"
)
var serverCmd = &cobra.Command{
Use: "serve",
Short: "启动服务器",
Long: `启动Code Server Bridge服务器`,
Run: func(cmd *cobra.Command, args []string) {
configPath, _ := rootCmd.PersistentFlags().GetString("config")
// 加载配置
os.Setenv("CONFIG_PATH", configPath)
cfg := config.NewConfig()
logger.Init(cfg.Log)
db.InitDB(cfg.Database, logger.GetLogger())
httpclient.Init()
mgr := oauth.NewManager()
for _, p := range cfg.OAuth.Providers {
redirect := cfg.OAuth.BaseURL + "/oauth/" + p.Name + "/callback"
switch strings.ToLower(p.Type) {
case "gitea":
// 优先尝试使用Lua Provider
scriptPath := fmt.Sprintf("scripts/oauth/%s.lua", p.Name)
if _, err := os.Stat(scriptPath); err == nil {
// Lua脚本存在使用Lua Provider
logger.GetLogger().Info(fmt.Sprintf("使用Lua脚本加载OAuth Provider: %s (%s)", p.Name, scriptPath))
luaProvider, err := oauth.NewLuaProvider(
oauth.ProviderModel{
Name: p.Name,
Type: p.Type,
BaseURL: p.BaseURL,
ClientID: p.ClientID,
ClientSecret: p.ClientSecret,
AuthorizeURL: p.AuthorizeURL,
TokenURL: p.TokenURL,
UserURL: p.UserURL,
},
redirect,
scriptPath,
)
if err != nil {
logger.GetLogger().Error(fmt.Sprintf("加载Lua Provider失败: %v回退到原生实现", err))
mgr.Register(oauth.NewGitea(p, redirect))
} else {
mgr.Register(luaProvider)
}
} else {
// Lua脚本不存在使用原生Go实现
logger.GetLogger().Info(fmt.Sprintf("使用原生Go实现加载OAuth Provider: %s", p.Name))
mgr.Register(oauth.NewGitea(p, redirect))
}
}
}
r := http.NewRouter(cfg, mgr)
r.ListenAndServe()
},
}
func init() {
rootCmd.AddCommand(serverCmd)
}

23
cmd/server/cmd/version.go Normal file
View File

@@ -0,0 +1,23 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
var versionCmd = &cobra.Command{
Use: "version",
Short: "显示版本信息",
Long: `显示程序的版本号、构建时间和Git提交信息`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Code Server Bridge\n\n")
fmt.Printf("Version: %s\n", Version)
fmt.Printf("Build Time: %s\n", BuildTime)
fmt.Printf("Git Commit: %s\n", GitCommit)
},
}
func init() {
rootCmd.AddCommand(versionCmd)
}

25
cmd/server/main.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"cs-bridge/cmd/server/cmd"
"fmt"
)
// 版本信息编译时通过ldflags注入
var (
Version = "dev"
BuildTime = "unknown"
GitCommit = "unknown"
)
func main() {
// 设置版本信息到cmd包
cmd.Version = Version
cmd.BuildTime = BuildTime
cmd.GitCommit = GitCommit
// 启动信息
fmt.Printf("🚀 启动 code-server-bridge v%s by zhilv666\n", Version)
cmd.Execute()
}