init
This commit is contained in:
751
docs/ARCHITECTURE.md
Normal file
751
docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,751 @@
|
||||
# DevPack 架构设计文档
|
||||
|
||||
> 版本:v1.0.0-draft
|
||||
> 更新日期:2026-03-03
|
||||
> 作者:DevPack Team
|
||||
|
||||
---
|
||||
|
||||
## 1. 架构概览
|
||||
|
||||
### 1.1 设计原则
|
||||
|
||||
| 原则 | 说明 |
|
||||
|------|------|
|
||||
| **单一二进制** | 编译为无依赖的单一可执行文件 |
|
||||
| **插件化** | 采集器通过接口抽象,支持扩展 |
|
||||
| **安全优先** | 敏感数据加密,操作可回滚 |
|
||||
| **平台适配** | 通过平台适配层处理 OS 差异 |
|
||||
| **幂等性** | 同一 Pack 多次还原结果一致 |
|
||||
| **最小侵入** | 只修改用户级配置,不修改系统级设置(除非明确授权) |
|
||||
|
||||
### 1.2 高层架构图
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ CLI Layer (Cobra) │
|
||||
│ ┌──────┐ ┌───────┐ ┌─────────┐ ┌────────┐ ┌──────┐ ┌────────┐ │
|
||||
│ │ init │ │ scan │ │ capture │ │restore │ │ diff │ │export/ │ │
|
||||
│ │ │ │ │ │ │ │ │ │ │ │import │ │
|
||||
│ └──┬───┘ └───┬───┘ └────┬────┘ └───┬────┘ └──┬───┘ └───┬────┘ │
|
||||
└─────┼─────────┼──────────┼──────────┼─────────┼─────────┼──────┘
|
||||
│ │ │ │ │ │
|
||||
┌─────┴─────────┴──────────┴──────────┴─────────┴─────────┴──────┐
|
||||
│ Core Engine Layer │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │
|
||||
│ │ Collector │ │ Pack Engine │ │ Restore Engine │ │
|
||||
│ │ Registry │ │ │ │ │ │
|
||||
│ └──────┬───────┘ └──────┬───────┘ └────────────┬─────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ ┌──────┴───────┐ ┌──────┴───────┐ ┌────────────┴─────────────┐ │
|
||||
│ │ Profile │ │ Crypto │ │ Dependency Resolver │ │
|
||||
│ │ Manager │ │ Module │ │ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────────────────┘ │
|
||||
└─────────────────────────┬───────────────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────────┴───────────────────────────────────────┐
|
||||
│ Platform Abstraction Layer │
|
||||
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
|
||||
│ │ Windows │ │ macOS │ │ Linux │ │
|
||||
│ │ Adapter │ │ Adapter │ │ Adapter │ │
|
||||
│ └────────────┘ └────────────┘ └────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────────┴───────────────────────────────────────┐
|
||||
│ Collector Plugins │
|
||||
│ ┌─────────┐ ┌─────────┐ ┌────────┐ ┌───────┐ ┌─────┐ ┌─────┐ │
|
||||
│ │ Runtime │ │ Package │ │ Editor │ │ Shell │ │ Git │ │ Env │ │
|
||||
│ └─────────┘ └─────────┘ └────────┘ └───────┘ └─────┘ └─────┘ │
|
||||
│ ┌─────────┐ ┌─────────┐ │
|
||||
│ │ Font │ │ SSH/GPG │ │
|
||||
│ └─────────┘ └─────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 核心模块设计
|
||||
|
||||
### 2.1 采集器系统 (Collector System)
|
||||
|
||||
采集器是 DevPack 的核心,负责扫描和收集环境信息。所有采集器实现统一的接口。
|
||||
|
||||
#### 2.1.1 Collector 接口
|
||||
|
||||
```go
|
||||
// Collector 定义了所有采集器必须实现的接口
|
||||
type Collector interface {
|
||||
// Name 返回采集器名称(唯一标识)
|
||||
Name() string
|
||||
|
||||
// DisplayName 返回采集器的显示名称
|
||||
DisplayName() string
|
||||
|
||||
// Description 返回采集器的描述信息
|
||||
Description() string
|
||||
|
||||
// Category 返回采集器所属分类
|
||||
Category() Category
|
||||
|
||||
// IsAvailable 检测当前系统是否支持此采集器
|
||||
IsAvailable(ctx context.Context) bool
|
||||
|
||||
// Scan 扫描当前环境,返回扫描结果
|
||||
Scan(ctx context.Context, opts ScanOptions) (*ScanResult, error)
|
||||
|
||||
// Capture 捕获环境数据,写入到指定目录
|
||||
Capture(ctx context.Context, targetDir string, opts CaptureOptions) error
|
||||
|
||||
// Restore 从指定目录还原环境
|
||||
Restore(ctx context.Context, sourceDir string, opts RestoreOptions) error
|
||||
|
||||
// Verify 验证还原后的环境是否正确
|
||||
Verify(ctx context.Context) (*VerifyResult, error)
|
||||
}
|
||||
|
||||
// Category 采集器分类
|
||||
type Category string
|
||||
|
||||
const (
|
||||
CategoryRuntime Category = "runtime" // 编程语言运行时
|
||||
CategoryPackage Category = "package" // 包管理器
|
||||
CategoryEditor Category = "editor" // 编辑器/IDE
|
||||
CategoryShell Category = "shell" // Shell 配置
|
||||
CategoryGit Category = "git" // Git 配置
|
||||
CategoryEnv Category = "env" // 环境变量
|
||||
CategoryFont Category = "font" // 字体
|
||||
CategorySSH Category = "ssh" // SSH/GPG 密钥
|
||||
CategoryCustom Category = "custom" // 自定义
|
||||
)
|
||||
|
||||
// ScanResult 扫描结果
|
||||
type ScanResult struct {
|
||||
Collector string `json:"collector"`
|
||||
Category Category `json:"category"`
|
||||
Items []ScanItem `json:"items"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Platform PlatformInfo `json:"platform"`
|
||||
}
|
||||
|
||||
// ScanItem 单个扫描项
|
||||
type ScanItem struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
Properties map[string]string `json:"properties,omitempty"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
Children []ScanItem `json:"children,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.1.2 采集器注册中心
|
||||
|
||||
```go
|
||||
// Registry 采集器注册中心
|
||||
type Registry struct {
|
||||
collectors map[string]Collector
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// Register 注册一个采集器
|
||||
func (r *Registry) Register(c Collector) error
|
||||
|
||||
// Get 获取指定名称的采集器
|
||||
func (r *Registry) Get(name string) (Collector, bool)
|
||||
|
||||
// List 列出所有已注册的采集器
|
||||
func (r *Registry) List() []Collector
|
||||
|
||||
// ListByCategory 按分类列出采集器
|
||||
func (r *Registry) ListByCategory(cat Category) []Collector
|
||||
|
||||
// ScanAll 使用所有可用的采集器扫描
|
||||
func (r *Registry) ScanAll(ctx context.Context, opts ScanOptions) ([]*ScanResult, error)
|
||||
```
|
||||
|
||||
#### 2.1.3 内置采集器实现示例
|
||||
|
||||
以 Go 运行时采集器为例:
|
||||
|
||||
```go
|
||||
type GoCollector struct{}
|
||||
|
||||
func (c *GoCollector) Name() string { return "go" }
|
||||
func (c *GoCollector) DisplayName() string { return "Go Runtime" }
|
||||
func (c *GoCollector) Category() Category { return CategoryRuntime }
|
||||
|
||||
func (c *GoCollector) Scan(ctx context.Context, opts ScanOptions) (*ScanResult, error) {
|
||||
result := &ScanResult{
|
||||
Collector: c.Name(),
|
||||
Category: c.Category(),
|
||||
}
|
||||
|
||||
// 检测 Go 版本
|
||||
version, err := exec.CommandContext(ctx, "go", "version").Output()
|
||||
// ... 解析版本信息
|
||||
|
||||
// 获取 go env 信息
|
||||
envJSON, err := exec.CommandContext(ctx, "go", "env", "-json").Output()
|
||||
// ... 解析环境变量
|
||||
|
||||
// 获取全局安装的工具
|
||||
// ... 扫描 GOPATH/bin
|
||||
|
||||
return result, nil
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 打包引擎 (Pack Engine)
|
||||
|
||||
#### 2.2.1 Pack 文件格式
|
||||
|
||||
`.devpack` 文件本质上是一个经过组织的 tar.gz 归档文件:
|
||||
|
||||
```
|
||||
my-env.devpack (tar.gz)
|
||||
├── manifest.json # Pack 清单(元数据)
|
||||
├── checksum.sha256 # 文件校验和
|
||||
├── collectors/ # 各采集器数据
|
||||
│ ├── runtime/
|
||||
│ │ ├── go/
|
||||
│ │ │ ├── metadata.json # Go 环境元数据
|
||||
│ │ │ └── data/ # Go 相关数据文件
|
||||
│ │ ├── node/
|
||||
│ │ │ ├── metadata.json
|
||||
│ │ │ └── data/
|
||||
│ │ └── python/
|
||||
│ │ ├── metadata.json
|
||||
│ │ └── data/
|
||||
│ ├── editor/
|
||||
│ │ └── vscode/
|
||||
│ │ ├── metadata.json
|
||||
│ │ ├── extensions.json # 扩展列表
|
||||
│ │ └── data/ # 设置文件
|
||||
│ │ ├── settings.json
|
||||
│ │ ├── keybindings.json
|
||||
│ │ └── snippets/
|
||||
│ ├── shell/
|
||||
│ │ ├── powershell/
|
||||
│ │ │ ├── metadata.json
|
||||
│ │ │ └── data/
|
||||
│ │ └── bash/
|
||||
│ │ ├── metadata.json
|
||||
│ │ └── data/
|
||||
│ ├── package/
|
||||
│ │ └── scoop/
|
||||
│ │ ├── metadata.json
|
||||
│ │ └── data/
|
||||
│ ├── git/
|
||||
│ │ ├── metadata.json
|
||||
│ │ └── data/
|
||||
│ └── env/
|
||||
│ ├── metadata.json
|
||||
│ └── data/
|
||||
└── encrypted/ # 加密数据(可选)
|
||||
└── ssh/
|
||||
└── data.enc # 加密的 SSH 密钥
|
||||
```
|
||||
|
||||
#### 2.2.2 Manifest 结构
|
||||
|
||||
```go
|
||||
// Manifest Pack 清单
|
||||
type Manifest struct {
|
||||
// 元信息
|
||||
Version string `json:"version"` // DevPack 版本
|
||||
FormatVer string `json:"format_ver"` // Pack 格式版本
|
||||
Name string `json:"name"` // Pack 名称
|
||||
Description string `json:"description"` // 描述
|
||||
Author string `json:"author"` // 作者
|
||||
CreatedAt time.Time `json:"created_at"` // 创建时间
|
||||
PackID string `json:"pack_id"` // 唯一 ID (UUID)
|
||||
|
||||
// 源环境信息
|
||||
Source SourceInfo `json:"source"`
|
||||
|
||||
// 采集器数据索引
|
||||
Collectors []CollectorEntry `json:"collectors"`
|
||||
|
||||
// 加密信息
|
||||
Encryption *EncryptionInfo `json:"encryption,omitempty"`
|
||||
|
||||
// 校验信息
|
||||
Checksum string `json:"checksum"` // 整包校验和
|
||||
}
|
||||
|
||||
// SourceInfo 源环境信息
|
||||
type SourceInfo struct {
|
||||
Hostname string `json:"hostname"`
|
||||
OS string `json:"os"` // windows, darwin, linux
|
||||
OSVersion string `json:"os_version"`
|
||||
Arch string `json:"arch"` // amd64, arm64
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
// CollectorEntry 采集器条目
|
||||
type CollectorEntry struct {
|
||||
Name string `json:"name"`
|
||||
Category Category `json:"category"`
|
||||
ItemCount int `json:"item_count"`
|
||||
DataPath string `json:"data_path"`
|
||||
DataSize int64 `json:"data_size"`
|
||||
Checksum string `json:"checksum"`
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2.3 打包流程
|
||||
|
||||
```
|
||||
用户执行 capture 命令
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 加载 Profile │ ─── 确定需要运行哪些采集器
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 运行采集器 │ ─── 并行扫描 → 收集数据 → 写入临时目录
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 生成 Manifest │ ─── 创建清单文件、计算校验和
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 加密敏感数据 │ ─── 对标记为敏感的数据进行加密(可选)
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 压缩归档 │ ─── tar.gz 打包
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 输出 .devpack │ ─── 写入最终文件
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
### 2.3 还原引擎 (Restore Engine)
|
||||
|
||||
#### 2.3.1 还原流程
|
||||
|
||||
```
|
||||
用户执行 restore 命令
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 校验 Pack 文件 │ ─── 检查完整性、版本兼容性
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 解析 Manifest │ ─── 读取清单,确定还原内容
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 平台兼容检查 │ ─── 确认目标平台与源平台匹配
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 冲突检测 │ ─── 检测与现有环境的冲突
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────┐
|
||||
│ 创建还原点(可选) │ ─── 备份当前环境用于回滚
|
||||
└────────┬────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 依赖排序 │ ─── 按依赖关系排序安装顺序
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐ ┌──────────────┐
|
||||
│ 执行还原 │ ──▶ │ 逐项安装/配置 │
|
||||
└────────┬────────┘ └──────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 验证还原结果 │ ─── 运行各采集器的验证逻辑
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ 生成还原报告 │ ─── 成功/失败/跳过的项目清单
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
#### 2.3.2 冲突处理策略
|
||||
|
||||
```go
|
||||
// ConflictStrategy 冲突处理策略
|
||||
type ConflictStrategy int
|
||||
|
||||
const (
|
||||
ConflictSkip ConflictStrategy = iota // 跳过(保留现有)
|
||||
ConflictOverwrite // 覆盖(使用 Pack 中的)
|
||||
ConflictMerge // 合并
|
||||
ConflictPrompt // 询问用户
|
||||
ConflictNewest // 使用较新版本
|
||||
)
|
||||
|
||||
// ConflictItem 冲突项
|
||||
type ConflictItem struct {
|
||||
Collector string
|
||||
ItemName string
|
||||
CurrentVer string
|
||||
PackVer string
|
||||
Type ConflictType // VersionMismatch, AlreadyExists, DependencyConflict
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 配置文件管理 (Profile Manager)
|
||||
|
||||
#### 2.4.1 Profile 格式
|
||||
|
||||
使用 YAML 格式定义 Profile:
|
||||
|
||||
```yaml
|
||||
# ~/.devpack/profiles/golang-dev.yaml
|
||||
name: golang-dev
|
||||
description: "Go 全栈开发环境"
|
||||
version: "1.0"
|
||||
|
||||
# 采集器配置
|
||||
collectors:
|
||||
runtime:
|
||||
enabled: true
|
||||
include:
|
||||
- go
|
||||
- node
|
||||
exclude: []
|
||||
options:
|
||||
go:
|
||||
capture_gopath_bin: true # 捕获 GOPATH/bin 下的工具
|
||||
capture_go_env: true # 捕获 go env 配置
|
||||
|
||||
editor:
|
||||
enabled: true
|
||||
include:
|
||||
- vscode
|
||||
options:
|
||||
vscode:
|
||||
capture_extensions: true
|
||||
capture_settings: true
|
||||
capture_keybindings: true
|
||||
capture_snippets: true
|
||||
# 排除的扩展
|
||||
exclude_extensions:
|
||||
- "ms-vsliveshare.vsliveshare"
|
||||
|
||||
shell:
|
||||
enabled: true
|
||||
include:
|
||||
- powershell
|
||||
- bash
|
||||
|
||||
package:
|
||||
enabled: true
|
||||
include:
|
||||
- scoop
|
||||
|
||||
git:
|
||||
enabled: true
|
||||
options:
|
||||
capture_aliases: true
|
||||
capture_hooks: false
|
||||
|
||||
env:
|
||||
enabled: true
|
||||
options:
|
||||
# 只捕获匹配的环境变量
|
||||
include_patterns:
|
||||
- "GOPATH"
|
||||
- "GOROOT"
|
||||
- "PATH"
|
||||
- "NODE_*"
|
||||
exclude_patterns:
|
||||
- "*_KEY"
|
||||
- "*_SECRET"
|
||||
- "*_TOKEN"
|
||||
|
||||
ssh:
|
||||
enabled: false
|
||||
|
||||
# 还原选项
|
||||
restore:
|
||||
conflict_strategy: prompt # skip, overwrite, merge, prompt, newest
|
||||
create_restore_point: true
|
||||
dry_run_first: false
|
||||
```
|
||||
|
||||
### 2.5 平台适配层 (Platform Abstraction Layer)
|
||||
|
||||
```go
|
||||
// Platform 平台适配接口
|
||||
type Platform interface {
|
||||
// OS 返回操作系统标识
|
||||
OS() string
|
||||
|
||||
// Arch 返回架构标识
|
||||
Arch() string
|
||||
|
||||
// HomeDir 返回用户主目录
|
||||
HomeDir() string
|
||||
|
||||
// ConfigDir 返回配置文件目录
|
||||
ConfigDir() string
|
||||
|
||||
// DataDir 返回数据目录
|
||||
DataDir() string
|
||||
|
||||
// GetEnvVar 获取环境变量
|
||||
GetEnvVar(key string) string
|
||||
|
||||
// SetEnvVar 设置用户级环境变量
|
||||
SetEnvVar(key, value string) error
|
||||
|
||||
// AddToPath 添加目录到 PATH
|
||||
AddToPath(dir string) error
|
||||
|
||||
// IsAdmin 是否以管理员身份运行
|
||||
IsAdmin() bool
|
||||
|
||||
// PackageManagers 返回可用的包管理器
|
||||
PackageManagers() []string
|
||||
|
||||
// DefaultShell 返回默认 Shell
|
||||
DefaultShell() string
|
||||
|
||||
// InstallFont 安装字体文件
|
||||
InstallFont(fontPath string) error
|
||||
|
||||
// RunAsAdmin 以管理员权限运行命令
|
||||
RunAsAdmin(cmd string, args ...string) error
|
||||
}
|
||||
```
|
||||
|
||||
各平台实现:
|
||||
|
||||
```go
|
||||
// Windows 平台实现
|
||||
type WindowsPlatform struct{}
|
||||
|
||||
func (p *WindowsPlatform) OS() string { return "windows" }
|
||||
func (p *WindowsPlatform) HomeDir() string { return os.Getenv("USERPROFILE") }
|
||||
func (p *WindowsPlatform) ConfigDir() string { return os.Getenv("APPDATA") }
|
||||
func (p *WindowsPlatform) DefaultShell() string { return "powershell" }
|
||||
func (p *WindowsPlatform) PackageManagers() []string {
|
||||
var pms []string
|
||||
if _, err := exec.LookPath("scoop"); err == nil { pms = append(pms, "scoop") }
|
||||
if _, err := exec.LookPath("choco"); err == nil { pms = append(pms, "chocolatey") }
|
||||
if _, err := exec.LookPath("winget"); err == nil { pms = append(pms, "winget") }
|
||||
return pms
|
||||
}
|
||||
|
||||
// macOS 平台实现
|
||||
type DarwinPlatform struct{}
|
||||
|
||||
// Linux 平台实现
|
||||
type LinuxPlatform struct{}
|
||||
```
|
||||
|
||||
### 2.6 加密模块 (Crypto Module)
|
||||
|
||||
```go
|
||||
// Encryptor 加密器接口
|
||||
type Encryptor interface {
|
||||
// Encrypt 使用密码加密数据
|
||||
Encrypt(data []byte, password string) ([]byte, error)
|
||||
|
||||
// Decrypt 使用密码解密数据
|
||||
Decrypt(encrypted []byte, password string) ([]byte, error)
|
||||
}
|
||||
|
||||
// AESGCMEncryptor AES-256-GCM 加密实现
|
||||
type AESGCMEncryptor struct{}
|
||||
|
||||
// 密钥派生使用 Argon2id
|
||||
func deriveKey(password string, salt []byte) []byte {
|
||||
return argon2.IDKey([]byte(password), salt, 1, 64*1024, 4, 32)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 数据流
|
||||
|
||||
### 3.1 扫描 → 打包数据流
|
||||
|
||||
```
|
||||
┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────┐
|
||||
│ 用户系统 │ ──▶ │ Collectors │ ──▶ │ ScanResult │ ──▶ │ 临时目录 │
|
||||
│ (实际环境) │ │ (扫描采集) │ │ (结构化数据)│ │ (文件数据)│
|
||||
└────────────┘ └────────────┘ └────────────┘ └────┬─────┘
|
||||
│
|
||||
┌────────────┐ ┌────────────┐ │
|
||||
│ .devpack │ ◀── │ Pack 引擎 │ ◀────────┘
|
||||
│ (归档文件) │ │ (压缩打包) │
|
||||
└────────────┘ └────────────┘
|
||||
```
|
||||
|
||||
### 3.2 导入 → 还原数据流
|
||||
|
||||
```
|
||||
┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────┐
|
||||
│ .devpack │ ──▶ │ 解压校验 │ ──▶ │ Manifest │ ──▶ │ 还原计划 │
|
||||
│ (归档文件) │ │ │ │ 解析 │ │ 生成 │
|
||||
└────────────┘ └────────────┘ └────────────┘ └────┬─────┘
|
||||
│
|
||||
┌────────────┐ ┌────────────┐ │
|
||||
│ 目标系统 │ ◀── │ Restore │ ◀────────┘
|
||||
│ (已还原) │ │ Engine │
|
||||
└────────────┘ └────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 技术选型
|
||||
|
||||
### 4.1 核心依赖
|
||||
|
||||
| 依赖 | 用途 | 选型理由 |
|
||||
|------|------|---------|
|
||||
| [cobra](https://github.com/spf13/cobra) | CLI 框架 | Go 生态最流行的 CLI 框架 |
|
||||
| [viper](https://github.com/spf13/viper) | 配置管理 | 支持多种配置格式 |
|
||||
| [zerolog](https://github.com/rs/zerolog) | 日志 | 高性能结构化日志 |
|
||||
| [color](https://github.com/fatih/color) | 终端着色 | 美化 CLI 输出 |
|
||||
| [progressbar](https://github.com/schollz/progressbar) | 进度条 | 长时操作反馈 |
|
||||
| [survey](https://github.com/AlecAivazis/survey) | 交互式提示 | 用户交互 |
|
||||
| [archiver](https://github.com/mholt/archiver) | 压缩归档 | 支持多种归档格式 |
|
||||
| [go-yaml](https://github.com/go-yaml/yaml) | YAML 解析 | Profile 文件解析 |
|
||||
| [uuid](https://github.com/google/uuid) | UUID 生成 | Pack ID 生成 |
|
||||
| [golang.org/x/crypto](https://golang.org/x/crypto) | 加密库 | Argon2, AES |
|
||||
|
||||
### 4.2 构建工具
|
||||
|
||||
| 工具 | 用途 |
|
||||
|------|------|
|
||||
| Go 1.22+ | 编程语言 |
|
||||
| Make / Task | 构建脚本 |
|
||||
| GoReleaser | 多平台发布 |
|
||||
| golangci-lint | 代码检查 |
|
||||
| GitHub Actions | CI/CD |
|
||||
|
||||
---
|
||||
|
||||
## 5. 错误处理策略
|
||||
|
||||
### 5.1 错误分级
|
||||
|
||||
```go
|
||||
// ErrorLevel 错误级别
|
||||
type ErrorLevel int
|
||||
|
||||
const (
|
||||
ErrorFatal ErrorLevel = iota // 致命错误,必须终止
|
||||
ErrorCritical // 严重错误,当前采集器失败
|
||||
ErrorWarning // 警告,可继续但需告知用户
|
||||
ErrorInfo // 信息,记录但不影响流程
|
||||
)
|
||||
|
||||
// CollectorError 采集器错误
|
||||
type CollectorError struct {
|
||||
Collector string
|
||||
Level ErrorLevel
|
||||
Message string
|
||||
Cause error
|
||||
Hint string // 给用户的建议
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 错误处理原则
|
||||
|
||||
1. **采集阶段** — 单个采集器失败不影响其他采集器
|
||||
2. **打包阶段** — 失败的采集器数据不包含在 Pack 中,但 Pack 仍然生成
|
||||
3. **还原阶段** — 根据策略决定是继续还是终止
|
||||
4. **所有操作** — 详细日志记录,用户友好的错误信息
|
||||
|
||||
---
|
||||
|
||||
## 6. 安全设计
|
||||
|
||||
### 6.1 敏感数据识别
|
||||
|
||||
| 数据类型 | 敏感级别 | 处理方式 |
|
||||
|---------|---------|---------|
|
||||
| SSH 私钥 | 高 | AES-256 加密 |
|
||||
| GPG 私钥 | 高 | AES-256 加密 |
|
||||
| API Token | 高 | AES-256 加密或排除 |
|
||||
| 环境变量中的密码 | 高 | 默认排除 |
|
||||
| Git 凭证 | 高 | 默认排除 |
|
||||
| IDE 设置 | 低 | 明文存储 |
|
||||
| Shell 配置 | 中 | 扫描并警告内嵌 Token |
|
||||
|
||||
### 6.2 加密流程
|
||||
|
||||
```
|
||||
用户密码 ──▶ Argon2id ──▶ 派生密钥 (256-bit)
|
||||
│
|
||||
▼
|
||||
敏感数据 ──▶ AES-256-GCM 加密 ──▶ 加密数据 + Nonce + Salt
|
||||
│
|
||||
▼
|
||||
存入 encrypted/ 目录
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 可扩展性设计
|
||||
|
||||
### 7.1 插件系统(远期规划)
|
||||
|
||||
未来计划支持外部插件:
|
||||
|
||||
```go
|
||||
// Plugin 外部插件接口
|
||||
type Plugin interface {
|
||||
Collector
|
||||
|
||||
// PluginInfo 返回插件元信息
|
||||
PluginInfo() PluginMeta
|
||||
}
|
||||
|
||||
type PluginMeta struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Author string `json:"author"`
|
||||
MinDevPack string `json:"min_devpack_version"`
|
||||
}
|
||||
```
|
||||
|
||||
插件发现机制:
|
||||
1. `~/.devpack/plugins/` 目录下的可执行文件
|
||||
2. 通过 Go Plugin 机制加载 `.so` / `.dll`
|
||||
3. 通过 gRPC/JSON-RPC 与外部进程通信(推荐,跨语言)
|
||||
|
||||
---
|
||||
|
||||
## 8. 测试策略
|
||||
|
||||
### 8.1 测试层级
|
||||
|
||||
| 层级 | 范围 | 工具 |
|
||||
|------|------|------|
|
||||
| 单元测试 | 各模块独立逻辑 | Go testing + testify |
|
||||
| 集成测试 | 模块间协作 | Go testing |
|
||||
| 端到端测试 | 完整的 capture → restore 流程 | 脚本 + Docker/VM |
|
||||
| 平台测试 | 各操作系统适配 | GitHub Actions Matrix |
|
||||
|
||||
### 8.2 测试环境
|
||||
|
||||
- CI 环境使用 GitHub Actions 矩阵构建(Windows/macOS/Linux)
|
||||
- 端到端测试使用虚拟机或容器模拟真实环境
|
||||
- Mock 框架用于隔离外部依赖(如包管理器)
|
||||
Reference in New Issue
Block a user