feat(app): wire workspace module + integration test for ws closed loop

This commit is contained in:
2026-05-02 09:39:27 +08:00
parent 78e74c9734
commit 7429a817bc
9 changed files with 584 additions and 1 deletions
+24
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"log/slog"
"strings"
"time"
"github.com/spf13/viper"
)
@@ -34,6 +35,8 @@ type Config struct {
HTTP HTTPConfig `mapstructure:"http"`
DB DBConfig `mapstructure:"db"`
Bootstrap BootstrapConfig `mapstructure:"bootstrap"`
Workspace Workspace `mapstructure:"workspace"`
Git Git `mapstructure:"git"`
}
// HTTPConfig 描述 HTTP 服务监听参数。
@@ -52,6 +55,21 @@ type BootstrapConfig struct {
AdminPassword string `mapstructure:"admin_password"`
}
// Workspace 控制 workspace 模块的磁盘与超时(数据目录、每个 git verb 的超时)。
// DataDir 是 workspace clone/worktree 落盘根目录;五个 timeout 直接灌进 git.Config。
type Workspace struct {
DataDir string `mapstructure:"data_dir"`
CloneTimeout time.Duration `mapstructure:"clone_timeout"`
FetchTimeout time.Duration `mapstructure:"fetch_timeout"`
PushTimeout time.Duration `mapstructure:"push_timeout"`
OpsTimeout time.Duration `mapstructure:"ops_timeout"`
}
// Git 控制 git CLI 二进制位置(默认 "git")。
type Git struct {
Binary string `mapstructure:"binary"`
}
// Load 从(按优先级递增)默认值 → 配置文件(如有)→ 环境变量 加载配置。
// configFile 可为空字符串,仅用环境变量。
func Load(configFile string) (*Config, error) {
@@ -61,6 +79,12 @@ func Load(configFile string) (*Config, error) {
v.SetDefault("env", "development")
v.SetDefault("data_dir", "./data")
v.SetDefault("http.addr", ":8080")
v.SetDefault("workspace.data_dir", "./data")
v.SetDefault("workspace.clone_timeout", "30m")
v.SetDefault("workspace.fetch_timeout", "5m")
v.SetDefault("workspace.push_timeout", "5m")
v.SetDefault("workspace.ops_timeout", "60s")
v.SetDefault("git.binary", "git")
if configFile != "" {
v.SetConfigFile(configFile)
+15
View File
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/require"
)
@@ -50,6 +51,20 @@ func TestLoad_MasterKeyNotHex(t *testing.T) {
require.Contains(t, err.Error(), "invalid hex")
}
func TestLoad_WorkspaceDefaults(t *testing.T) {
// 验证 workspace.* 与 git.* 的默认值(含 string→time.Duration 自动解析)。
t.Setenv("APP_DB_DSN", "postgres://x")
t.Setenv("APP_MASTER_KEY", "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff")
cfg, err := Load("")
require.NoError(t, err)
require.Equal(t, "./data", cfg.Workspace.DataDir)
require.Equal(t, 30*time.Minute, cfg.Workspace.CloneTimeout)
require.Equal(t, 5*time.Minute, cfg.Workspace.FetchTimeout)
require.Equal(t, 5*time.Minute, cfg.Workspace.PushTimeout)
require.Equal(t, 60*time.Second, cfg.Workspace.OpsTimeout)
require.Equal(t, "git", cfg.Git.Binary)
}
func TestMasterKey_Redaction(t *testing.T) {
k := MasterKey([]byte{0x01, 0x02, 0x03})
require.Equal(t, "[REDACTED 32B]", k.String())