# Design Document: Go Version Management

## Overview

本设计文档描述了为 PHPer 开发环境管理器添加 Go 版本管理功能的技术实现方案。该功能将允许用户安装、管理和切换不同版本的 Go 语言开发环境，与现有的 Node.js 和 Python 版本管理功能保持一致的架构和用户体验。

## Architecture

### 系统架构图

```mermaid
graph TB
    subgraph "Frontend (Vue 3)"
        A[GoManager.vue] --> B[Service Store]
        A --> C[UI Components]
    end
    
    subgraph "Electron Main Process"
        D[IPC Handler] --> E[GoManager.ts]
        E --> F[ConfigStore.ts]
        E --> G[File System]
        E --> H[Process Management]
    end
    
    subgraph "External Services"
        I[golang.org API] --> E
        J[Go Downloads] --> E
    end
    
    A -.->|IPC| D
    E --> K[Environment Variables]
    E --> L[Local Storage]
```

### 核心架构原则

1. **一致性**: 与现有 NodeManager 和 PythonManager 保持相同的架构模式
2. **模块化**: 独立的 GoManager 服务类，便于维护和测试
3. **可扩展性**: 支持未来添加更多 Go 相关功能
4. **用户体验**: 统一的界面风格和交互模式

## Components and Interfaces

### 1. GoManager Service (Backend)

**文件位置**: `electron/services/GoManager.ts`

**主要职责**:
- 管理 Go 版本的安装、卸载和切换
- 处理环境变量配置
- 与 golang.org API 交互获取版本信息
- 文件系统操作和下载管理

**核心接口**:

```typescript
interface GoVersion {
  version: string        // 版本号，如 "1.21.5"
  path: string          // 安装路径
  isActive: boolean     // 是否为当前活动版本
  goroot: string        // GOROOT 路径
  gopath?: string       // GOPATH 路径（可选）
}

interface AvailableGoVersion {
  version: string       // 版本号
  stable: boolean       // 是否为稳定版本
  downloadUrl: string   // Windows 64位下载链接
  size: number         // 文件大小（字节）
  sha256: string       // SHA256 校验和
}

class GoManager {
  // 获取已安装版本
  async getInstalledVersions(): Promise<GoVersion[]>
  
  // 获取可用版本列表
  async getAvailableVersions(): Promise<AvailableGoVersion[]>
  
  // 安装指定版本
  async install(version: string, downloadUrl: string): Promise<{success: boolean, message: string}>
  
  // 卸载指定版本
  async uninstall(version: string): Promise<{success: boolean, message: string}>
  
  // 设置活动版本
  async setActive(version: string): Promise<{success: boolean, message: string}>
  
  // 验证 Go 安装
  async validateInstallation(version: string): Promise<boolean>
  
  // 获取 Go 环境信息
  async getGoInfo(version: string): Promise<GoInfo>
}
```

### 2. GoManager Vue Component (Frontend)

**文件位置**: `src/views/GoManager.vue`

**主要功能**:
- 显示已安装的 Go 版本列表
- 提供版本安装、卸载和切换操作
- 显示下载进度和操作状态
- 版本信息展示和管理

**组件结构**:
```vue
<template>
  <!-- 页面头部 -->
  <div class="page-header">
    <h1>Go 管理</h1>
    <p>管理本地 Go 版本，支持多版本切换</p>
  </div>
  
  <!-- 下载进度条 -->
  <div v-if="downloadProgress.percent > 0" class="download-progress">
    <!-- 进度显示 -->
  </div>
  
  <!-- 已安装版本卡片 -->
  <div class="version-grid">
    <div v-for="version in versions" class="version-card">
      <!-- 版本信息和操作按钮 -->
    </div>
  </div>
  
  <!-- 安装新版本对话框 -->
  <el-dialog v-model="showInstallDialog">
    <!-- 可用版本列表 -->
  </el-dialog>
</template>
```

### 3. IPC Communication Layer

**主进程注册**:
```typescript
// electron/main.ts
ipcMain.handle('go:getVersions', () => goManager.getInstalledVersions())
ipcMain.handle('go:getAvailableVersions', () => goManager.getAvailableVersions())
ipcMain.handle('go:install', (_, version, url) => goManager.install(version, url))
ipcMain.handle('go:uninstall', (_, version) => goManager.uninstall(version))
ipcMain.handle('go:setActive', (_, version) => goManager.setActive(version))
```

**预加载脚本**:
```typescript
// electron/preload.ts
contextBridge.exposeInMainWorld('electronAPI', {
  go: {
    getVersions: () => ipcRenderer.invoke('go:getVersions'),
    getAvailableVersions: () => ipcRenderer.invoke('go:getAvailableVersions'),
    install: (version: string, url: string) => ipcRenderer.invoke('go:install', version, url),
    uninstall: (version: string) => ipcRenderer.invoke('go:uninstall', version),
    setActive: (version: string) => ipcRenderer.invoke('go:setActive', version)
  }
})
```

## Data Models

### 1. Go Version Data Model

```typescript
interface GoVersion {
  version: string        // 版本号，格式如 "1.21.5"
  path: string          // 本地安装路径
  isActive: boolean     // 是否为当前活动版本
  goroot: string        // GOROOT 环境变量值
  gopath?: string       // GOPATH 环境变量值（可选）
  installDate?: Date    // 安装日期
  size?: number         // 安装大小（字节）
}

interface GoInfo {
  version: string       // Go 版本
  goroot: string       // GOROOT 路径
  gopath: string       // GOPATH 路径
  goversion: string    // go version 命令输出
  goos: string         // 目标操作系统
  goarch: string       // 目标架构
}
```

### 2. Available Version Data Model

```typescript
interface AvailableGoVersion {
  version: string       // 版本号
  stable: boolean       // 是否为稳定版本
  downloadUrl: string   // Windows 64位 ZIP 下载链接
  size: number         // 文件大小（字节）
  sha256: string       // SHA256 校验和
  releaseDate?: string // 发布日期
}

interface GoRelease {
  version: string
  stable: boolean
  files: GoFile[]
}

interface GoFile {
  filename: string
  os: string
  arch: string
  version: string
  sha256: string
  size: number
  kind: 'archive' | 'installer' | 'source'
}
```

### 3. Configuration Data Model

```typescript
interface GoConfig {
  activeVersion: string           // 当前活动版本
  installedVersions: string[]     // 已安装版本列表
  gopath: string                 // 全局 GOPATH 设置
  downloadSource: 'official'     // 下载源（目前仅支持官方）
  autoSetGopath: boolean         // 是否自动设置 GOPATH
}
```

## Implementation Details

### 1. Version Discovery and Download

**版本获取策略**:
1. **主要来源**: 使用 `https://golang.org/dl/?mode=json` API
2. **备用来源**: 硬编码的最新稳定版本列表
3. **缓存机制**: 5分钟本地缓存，减少 API 调用

**下载实现**:
```typescript
private async fetchGoVersions(): Promise<AvailableGoVersion[]> {
  try {
    const response = await fetch('https://golang.org/dl/?mode=json')
    const releases: GoRelease[] = await response.json()
    
    return releases
      .filter(release => release.stable)
      .map(release => {
        const windowsFile = release.files.find(f => 
          f.os === 'windows' && f.arch === 'amd64' && f.kind === 'archive'
        )
        
        if (!windowsFile) return null
        
        return {
          version: release.version,
          stable: release.stable,
          downloadUrl: `https://golang.org/dl/${windowsFile.filename}`,
          size: windowsFile.size,
          sha256: windowsFile.sha256
        }
      })
      .filter(Boolean)
      .slice(0, 20) // 限制显示最新 20 个版本
  } catch (error) {
    return this.getFallbackVersions()
  }
}
```

### 2. Installation Process

**安装流程**:
1. 验证版本是否已安装
2. 创建临时下载目录
3. 下载 Go ZIP 文件（显示进度）
4. 验证 SHA256 校验和
5. 解压到目标目录
6. 验证安装完整性
7. 更新配置文件
8. 清理临时文件

**目录结构**:
```
[PHPer安装目录]/go/
├── go-1.21.5/          # Go 1.21.5 安装目录
│   ├── bin/
│   │   ├── go.exe
│   │   ├── gofmt.exe
│   │   └── ...
│   ├── src/
│   ├── pkg/
│   └── ...
├── go-1.20.12/         # Go 1.20.12 安装目录
└── workspace/          # 默认 GOPATH 工作空间
    ├── src/
    ├── pkg/
    └── bin/
```

### 3. Environment Variable Management

**环境变量配置**:
```typescript
private async updateEnvironmentVariables(goVersion: string): Promise<void> {
  const goRoot = this.getGoPath(goVersion)
  const goBin = join(goRoot, 'bin')
  const goPath = this.getDefaultGoPath()
  
  // 使用 PowerShell 脚本更新用户环境变量
  const psScript = `
    # 设置 GOROOT
    [Environment]::SetEnvironmentVariable('GOROOT', '${goRoot}', 'User')
    
    # 设置 GOPATH
    [Environment]::SetEnvironmentVariable('GOPATH', '${goPath}', 'User')
    
    # 更新 PATH
    $userPath = [Environment]::GetEnvironmentVariable('PATH', 'User')
    $pathArray = $userPath -split ';' | Where-Object { $_ -ne '' }
    
    # 移除旧的 Go 路径
    $filteredPaths = $pathArray | Where-Object { 
      -not ($_ -like '*\\go\\go-*\\bin' -or $_ -like '*\\go-*\\bin')
    }
    
    # 添加新的 Go 路径
    $newPathArray = @('${goBin}') + $filteredPaths
    $finalPath = ($newPathArray | Select-Object -Unique) -join ';'
    
    [Environment]::SetEnvironmentVariable('PATH', $finalPath, 'User')
  `
  
  await this.executePowerShellScript(psScript)
}
```

### 4. Installation Validation

**验证检查项**:
1. `go.exe` 文件存在且可执行
2. `go version` 命令返回正确版本
3. `go env` 命令正常工作
4. 标准库文件完整性检查

```typescript
private async validateInstallation(version: string): Promise<boolean> {
  const goPath = this.getGoPath(version)
  const goExe = join(goPath, 'bin', 'go.exe')
  
  try {
    // 检查可执行文件
    if (!existsSync(goExe)) return false
    
    // 验证版本
    const { stdout } = await execAsync(`"${goExe}" version`)
    if (!stdout.includes(version)) return false
    
    // 验证环境
    await execAsync(`"${goExe}" env GOROOT`)
    
    return true
  } catch {
    return false
  }
}
```

## Correctness Properties

*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*

### Property Reflection

After analyzing all acceptance criteria, I identified several areas where properties can be consolidated to eliminate redundancy:

- **Installation validation properties** (5.1, 5.2, 5.3, 5.4) can be combined into a comprehensive installation validation property
- **Environment variable management properties** (6.1, 6.2, 6.3) can be consolidated into a single environment update property
- **Error handling properties** (8.1, 8.2, 8.3, 8.4, 8.5) share common patterns and can be grouped
- **Version list management properties** (2.4, 4.1, 4.2) can be combined into state consistency properties

### Core Properties

Property 1: **API Version Fetching Consistency**
*For any* valid API response from golang.org, the Go_Manager should correctly parse and return version information with all required fields (version, downloadUrl, size, sha256)
**Validates: Requirements 1.1**

Property 2: **Download URL Construction**
*For any* valid Go version, the Go_Manager should construct the correct Windows 64-bit download URL and initiate the download process
**Validates: Requirements 1.2**

Property 3: **Download Progress Reporting**
*For any* download operation, progress events should be emitted with valid data structures containing percentage (0-100), downloaded bytes, and total bytes
**Validates: Requirements 1.3**

Property 4: **Installation Validation Completeness**
*For any* successfully installed Go version, the validation should confirm that go.exe exists, go version returns the correct version, gofmt.exe exists, and go mod commands work
**Validates: Requirements 1.4, 5.1, 5.2, 5.3, 5.4**

Property 5: **Duplicate Installation Prevention**
*For any* Go version that is already installed, attempting to install it again should return an error message indicating the version is already installed
**Validates: Requirements 1.5**

Property 6: **File System Cleanup on Uninstall**
*For any* installed Go version, uninstalling it should completely remove the version directory and all its contents
**Validates: Requirements 2.2**

Property 7: **Active Version Environment Management**
*For any* Go version being set as active, the environment variables (PATH, GOROOT, GOPATH) should be updated correctly, and old Go paths should be removed from PATH
**Validates: Requirements 3.1, 6.1, 6.2, 6.3**

Property 8: **Version State Consistency**
*For any* operation that changes installed versions (install/uninstall), the installed versions list should be updated to reflect the current state accurately
**Validates: Requirements 2.4, 4.1**

Property 9: **Version Information Completeness**
*For any* installed Go version, the version information should include all required fields: version number, installation path, active status, GOROOT, and GOPATH
**Validates: Requirements 4.2, 4.3**

Property 10: **System Go Detection**
*For any* system with an existing Go installation, the Go_Manager should detect and display the system version information
**Validates: Requirements 4.5**

Property 11: **Environment Variable Validation**
*For any* Go version set as active, executing 'go version' in a new process should return the expected version string
**Validates: Requirements 3.2, 3.4**

Property 12: **Error Message Descriptiveness**
*For any* failed operation (network error, disk space, permissions, installation failure), the error message should be descriptive and include actionable suggestions
**Validates: Requirements 5.5, 6.5, 8.1, 8.2, 8.3, 8.5**

Property 13: **Success Message Completeness**
*For any* successful operation, the success message should include relevant details about what was accomplished
**Validates: Requirements 8.4**

Property 14: **GOPATH Default Configuration**
*For any* Go installation, when configuring GOPATH, it should be set to the user's home directory + '/go' workspace
**Validates: Requirements 6.4**

<function_calls>
<invoke name="prework">
<parameter name="featureName">go-version-management

## Error Handling

### Error Categories and Handling Strategies

#### 1. Network Errors
- **Connection failures**: Retry mechanism with exponential backoff
- **API unavailable**: Fallback to cached version list
- **Download interruption**: Resume capability where possible
- **Timeout errors**: Configurable timeout with user feedback

#### 2. File System Errors
- **Insufficient disk space**: Pre-installation space check
- **Permission denied**: Clear guidance for administrator privileges
- **File corruption**: SHA256 verification and re-download
- **Path conflicts**: Automatic path resolution

#### 3. Installation Errors
- **Incomplete installation**: Automatic cleanup and retry option
- **Version conflicts**: Clear conflict resolution guidance
- **Environment variable failures**: Manual configuration instructions
- **Tool validation failures**: Detailed diagnostic information

#### 4. User Input Errors
- **Invalid version selection**: Input validation and user feedback
- **Concurrent operations**: Operation queuing and status indication
- **Configuration errors**: Validation with helpful error messages

### Error Recovery Mechanisms

```typescript
interface ErrorRecovery {
  // 自动重试机制
  autoRetry: {
    maxAttempts: number
    backoffStrategy: 'exponential' | 'linear'
    retryableErrors: string[]
  }
  
  // 用户引导
  userGuidance: {
    errorCode: string
    message: string
    suggestedActions: string[]
    documentationLink?: string
  }
  
  // 状态恢复
  stateRecovery: {
    rollbackOnFailure: boolean
    cleanupTempFiles: boolean
    restoreEnvironment: boolean
  }
}
```

## Testing Strategy

### Dual Testing Approach

本项目采用单元测试和基于属性的测试相结合的方法，确保全面的代码覆盖和正确性验证。

#### Unit Testing
- **特定示例验证**: 测试具体的用例和边界条件
- **集成点测试**: 验证组件间的交互
- **错误条件测试**: 测试各种错误场景的处理
- **UI 交互测试**: 验证用户界面的响应和状态更新

#### Property-Based Testing
- **通用属性验证**: 验证在所有输入下都应该成立的属性
- **随机输入覆盖**: 通过随机化输入发现边界情况
- **状态一致性检查**: 验证系统状态的一致性
- **不变量验证**: 确保系统不变量在所有操作中保持

### Testing Framework Configuration

**Property-Based Testing Library**: 使用 `fast-check` (JavaScript/TypeScript 的属性测试库)

**测试配置要求**:
- 每个属性测试最少运行 100 次迭代
- 每个测试必须引用对应的设计文档属性
- 标签格式: `**Feature: go-version-management, Property {number}: {property_text}**`

**示例测试结构**:
```typescript
// 属性测试示例
describe('Go Version Management Properties', () => {
  test('Property 1: API Version Fetching Consistency', async () => {
    // **Feature: go-version-management, Property 1: API Version Fetching Consistency**
    await fc.assert(fc.asyncProperty(
      fc.array(fc.record({
        version: fc.string(),
        files: fc.array(fc.record({
          os: fc.constantFrom('windows'),
          arch: fc.constantFrom('amd64'),
          kind: fc.constantFrom('archive'),
          filename: fc.string(),
          size: fc.nat(),
          sha256: fc.hexaString({ minLength: 64, maxLength: 64 })
        }))
      })),
      async (mockApiResponse) => {
        const result = await goManager.parseApiResponse(mockApiResponse)
        // 验证所有返回的版本都包含必需字段
        result.forEach(version => {
          expect(version).toHaveProperty('version')
          expect(version).toHaveProperty('downloadUrl')
          expect(version).toHaveProperty('size')
          expect(version).toHaveProperty('sha256')
        })
      }
    ), { numRuns: 100 })
  })
})
```

### Test Coverage Requirements

- **代码覆盖率**: 最低 85% 的行覆盖率
- **分支覆盖率**: 最低 80% 的分支覆盖率
- **属性覆盖率**: 所有定义的正确性属性都必须有对应的测试
- **集成测试**: 覆盖主要的用户工作流程

### Continuous Integration

- **自动化测试**: 每次代码提交都运行完整测试套件
- **性能测试**: 监控关键操作的性能指标
- **兼容性测试**: 在不同 Windows 版本上验证功能
- **回归测试**: 确保新功能不破坏现有功能

## Implementation Phases

### Phase 1: Core Backend Implementation
1. 创建 `GoManager.ts` 服务类
2. 实现版本获取和解析逻辑
3. 实现下载和安装功能
4. 添加环境变量管理
5. 实现基本的错误处理

### Phase 2: Frontend Integration
1. 创建 `GoManager.vue` 组件
2. 实现版本列表显示
3. 添加安装/卸载操作界面
4. 集成下载进度显示
5. 实现状态管理和用户反馈

### Phase 3: Advanced Features
1. 添加系统 Go 检测
2. 实现高级错误处理和恢复
3. 添加配置选项和偏好设置
4. 优化性能和用户体验
5. 完善文档和帮助信息

### Phase 4: Testing and Polish
1. 实现完整的测试套件
2. 进行性能优化
3. 用户体验改进
4. 文档完善
5. 发布准备

## Security Considerations

### Download Security
- **HTTPS 强制**: 所有下载必须使用 HTTPS
- **SHA256 验证**: 验证下载文件的完整性
- **签名验证**: 验证 Go 官方签名（如果可用）
- **沙箱下载**: 在临时目录中处理下载文件

### Environment Security
- **权限最小化**: 仅请求必要的系统权限
- **用户级配置**: 优先使用用户级环境变量
- **路径验证**: 验证所有文件路径的安全性
- **清理机制**: 及时清理临时文件和敏感数据

### Input Validation
- **版本号验证**: 严格验证版本号格式
- **路径注入防护**: 防止路径遍历攻击
- **命令注入防护**: 安全地执行系统命令
- **配置验证**: 验证所有用户配置输入

## Performance Considerations

### Optimization Strategies
- **缓存机制**: 缓存 API 响应和版本信息
- **懒加载**: 按需加载版本详细信息
- **并发控制**: 限制同时进行的下载数量
- **内存管理**: 及时释放大文件的内存占用

### Monitoring and Metrics
- **操作耗时**: 监控关键操作的执行时间
- **内存使用**: 跟踪内存使用情况
- **网络性能**: 监控下载速度和成功率
- **错误率**: 跟踪各类操作的错误率

## Future Enhancements

### Potential Features
1. **Go 模块管理**: 集成 Go 模块和依赖管理
2. **开发工具集成**: 集成常用的 Go 开发工具
3. **项目模板**: 提供 Go 项目模板和脚手架
4. **性能分析**: 集成 Go 性能分析工具
5. **云端同步**: 同步配置和偏好设置

### Extensibility Points
- **插件系统**: 支持第三方插件扩展
- **自定义下载源**: 支持企业内部下载源
- **配置导入导出**: 支持配置的备份和恢复
- **API 扩展**: 提供扩展 API 供其他工具使用