Files
tyapi-server/docs/Makefile使用指南.md

669 lines
16 KiB
Markdown
Raw Permalink Normal View History

2025-07-02 16:17:59 +08:00
# 📋 Makefile 命令详细执行逻辑指南
本文档详细说明了 TYAPI 项目中每个 Make 命令的**执行逻辑、具体步骤和背后原理**。
## 🚀 快速开始
```bash
# 查看所有可用命令
make help
# 设置开发环境
make setup
# 启动开发依赖服务
make dev-up
# 开发模式运行应用
make dev
```
---
## 📖 命令详细执行逻辑
### 🔍 **信息查看命令**
#### `make help`
**执行逻辑**:
```bash
# 1. 检测操作系统类型
# 2. 输出预定义的帮助信息
@echo "TYAPI Server Makefile"
@echo "Usage: make [target]"
@echo "Main targets:"
@echo " help Show this help message"
# ... 更多帮助信息
```
**实际效果**:
- 📄 直接打印硬编码的帮助文本
- 🚫 不执行任何文件操作
- ⚡ 瞬间完成,无依赖
#### `make version`
**执行逻辑**:
```bash
# 步骤1: 自动执行 make build (依赖检查)
# 步骤2: 执行构建好的二进制文件
./bin/tyapi-server -version
```
**详细步骤**:
1. **依赖检查**: 检查是否需要重新构建 (通过 make build)
2. **参数传递**: 向应用程序传递 `-version` 标志
3. **读取构建信息**: 应用程序输出编译时注入的版本信息
- `main.version` (来自 Makefile 的 VERSION 变量)
- `main.commit` (来自 git rev-parse --short HEAD)
- `main.date` (来自构建时间)
**相关文件**: `bin/tyapi-server`, `cmd/api/main.go`
---
### 🏗️ **构建相关命令**
#### `make build`
**执行逻辑**:
```bash
# 步骤1: 检测操作系统
ifeq ($(OS),Windows_NT)
# Windows: 创建bin目录 (如果不存在)
@if not exist "bin" mkdir "bin"
else
# Unix: 创建bin目录
@mkdir -p bin
endif
# 步骤2: 构建Go应用程序
go build -ldflags "-X main.version=1.0.0 -X main.commit=abc123 -X main.date=2025-01-01T00:00:00Z" -o bin/tyapi-server cmd/api/main.go
```
**详细步骤**:
1. **环境检测**: 通过 `$(OS)` 变量检测操作系统
2. **目录创建**:
- Windows: `if not exist "bin" mkdir "bin"`
- Unix: `mkdir -p bin`
3. **版本信息收集**:
- `BUILD_TIME`: PowerShell/date 命令获取当前时间
- `GIT_COMMIT`: git 命令获取当前 commit hash
- `VERSION`: 硬编码版本号 1.0.0
4. **编译执行**:
- 使用 `go build` 命令
- `-ldflags` 注入版本信息到可执行文件
- 输出文件到 `bin/tyapi-server`
**生成文件**: `bin/tyapi-server` (Windows 下为 `.exe`)
#### `make build-prod`
**执行逻辑**:
```bash
# 步骤1: 创建bin目录 (同build)
# 步骤2: 生产环境构建
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "..." -a -installsuffix cgo -o bin/tyapi-server-linux-amd64 cmd/api/main.go
```
**关键参数解析**:
- `CGO_ENABLED=0`: 禁用 CGO生成纯静态二进制
- `GOOS=linux GOARCH=amd64`: 强制 Linux 64 位平台
- `-a`: 重新构建所有包
- `-installsuffix cgo`: 避免缓存冲突
- **结果**: 生成可在任何 Linux x64 环境运行的静态二进制文件
#### `make build-all`
**执行逻辑**:
```bash
# 步骤1: 创建bin目录
# 步骤2: 循环构建5个平台
# Linux AMD64
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ... -o bin/tyapi-server-linux-amd64
# Linux ARM64
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build ... -o bin/tyapi-server-linux-arm64
# macOS Intel
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build ... -o bin/tyapi-server-darwin-amd64
# macOS Apple Silicon
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build ... -o bin/tyapi-server-darwin-arm64
# Windows
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build ... -o bin/tyapi-server-windows-amd64.exe
```
**生成的 5 个文件**:
- `bin/tyapi-server-linux-amd64`
- `bin/tyapi-server-linux-arm64`
- `bin/tyapi-server-darwin-amd64`
- `bin/tyapi-server-darwin-arm64`
- `bin/tyapi-server-windows-amd64.exe`
---
### ▶️ **运行相关命令**
#### `make run`
**执行逻辑**:
```bash
# 步骤1: 执行make build (依赖)
# 步骤2: 直接运行构建好的二进制文件
./bin/tyapi-server
```
**详细流程**:
1. **依赖检查**: Make 自动检查 build 目标是否需要重新执行
2. **文件存在性检查**: 确认 `bin/tyapi-server` 存在
3. **权限检查**: Unix 系统检查执行权限
4. **进程启动**: 启动 Gin HTTP 服务器
5. **端口监听**: 默认监听 8080 端口
**运行环境**: 需要 PostgreSQL 和 Redis 服务可用
#### `make dev`
**执行逻辑**:
```bash
# 直接执行 (已去掉air检查)
go run cmd/api/main.go
```
**详细步骤**:
1. **源码编译**: Go 编译器实时编译 main.go 及其依赖
2. **内存运行**: 不生成磁盘文件,直接在内存中运行
3. **依赖加载**: 自动下载并编译所有 import 的包
4. **服务启动**: 启动 HTTP 服务器监听 8080 端口
**与 build 的区别**:
- ✅ 无需预先构建
- ✅ 代码变更后需手动重启
- ❌ 每次启动都需要重新编译
---
### 🛠️ **开发工具命令**
#### `make deps`
**执行逻辑**:
```bash
# 步骤1: 下载依赖
go mod download
# 步骤2: 整理依赖
go mod tidy
```
**详细步骤**:
1. **go mod download**:
- 读取 `go.mod` 文件
- 下载所有依赖包到 `$GOPATH/pkg/mod/`
- 验证包的 checksum (通过 go.sum)
- 不修改 go.mod 文件
2. **go mod tidy**:
- 扫描所有.go 文件中的 import 语句
- 添加缺失的依赖到 go.mod
- 移除未使用的依赖
- 更新 go.sum 文件
**影响的文件**: `go.mod`, `go.sum`, `$GOPATH/pkg/mod/`
#### `make fmt`
**执行逻辑**:
```bash
go fmt ./...
```
**详细步骤**:
1. **递归扫描**: 扫描当前目录及所有子目录的.go 文件
2. **格式化规则应用**:
- 统一缩进 (tab)
- 统一换行
- 移除行尾空格
- 规范化大括号位置
3. **文件修改**: 直接修改源文件 (in-place)
4. **报告**: 输出被修改的文件列表
**影响的文件**: 所有.go 源码文件
#### `make lint`
**执行逻辑**:
```bash
# 检查golangci-lint是否安装
@if command -v golangci-lint >/dev/null 2>&1; then \
golangci-lint run; \
else \
echo "golangci-lint not installed, skipping lint check"; \
fi
```
**详细步骤**:
1. **工具检查**: 使用 `command -v` 检查 golangci-lint 是否在 PATH 中
2. **如果已安装**:
- 读取 `.golangci.yml` 配置 (如果存在)
- 运行多个 linter 检查 (默认包括: errcheck, gosimple, govet, ineffassign 等)
- 分析所有.go 文件
- 输出问题报告
3. **如果未安装**: 显示提示信息并跳过
**检查项目**: 代码质量、潜在 bug、性能问题、安全问题等
---
### 🧪 **测试相关命令**
#### `make test`
**执行逻辑**:
```bash
go test -v -race -coverprofile=coverage.out ./...
```
**参数详解**:
- `-v`: 详细输出,显示每个测试的名称和结果
- `-race`: 启用竞态条件检测器
- `-coverprofile=coverage.out`: 生成覆盖率数据文件
- `./...`: 递归测试所有包
**详细步骤**:
1. **包发现**: 递归扫描所有包含\*\_test.go 的目录
2. **编译测试**: 为每个包编译测试二进制文件
3. **竞态检测**: 启用 Go race detector
4. **执行测试**: 逐个运行 Test\*函数
5. **覆盖率收集**: 记录每行代码是否被执行
6. **生成报告**: 输出到 coverage.out 文件
**生成文件**: `coverage.out`
#### `make coverage`
**执行逻辑**:
```bash
# 步骤1: 执行make test (依赖)
# 步骤2: 生成HTML报告
go tool cover -html=coverage.out -o coverage.html
# 步骤3: 提示用户
@echo "Coverage report generated: coverage.html"
```
**详细步骤**:
1. **依赖检查**: 确保 coverage.out 文件存在
2. **HTML 生成**:
- 读取 coverage.out 二进制数据
- 生成带颜色标记的 HTML 页面
- 绿色 = 已覆盖,红色 = 未覆盖
3. **文件输出**: 生成 coverage.html 文件
**生成文件**: `coverage.html` (可在浏览器中打开)
---
### 🗂️ **环境管理命令**
#### `make env`
**执行逻辑**:
```bash
# Windows环境
ifeq ($(OS),Windows_NT)
@if not exist ".env" ( \
echo Creating .env file... && \
copy env.example .env && \
echo .env file created, please modify configuration as needed \
) else ( \
echo .env file already exists \
)
# Unix环境
else
@if [ ! -f .env ]; then \
echo "Creating .env file..."; \
cp env.example .env; \
echo ".env file created, please modify configuration as needed"; \
else \
echo ".env file already exists"; \
fi
endif
```
**详细步骤**:
1. **文件检查**: 检查.env 文件是否已存在
2. **如果不存在**:
- Windows: 使用 `copy` 命令复制
- Unix: 使用 `cp` 命令复制
- 复制 `env.example``.env`
3. **如果已存在**: 显示提示信息,不覆盖现有文件
**相关文件**: `env.example``.env`
#### `make setup`
**执行逻辑**:
```bash
# 依赖: make deps env
# 然后执行:
@echo "Setting up development environment..."
@echo "1. Dependencies installed"
@echo "2. .env file created"
@echo "3. Please ensure PostgreSQL and Redis are running"
@echo "4. Run 'make migrate' to create database tables"
@echo "5. Run 'make dev' to start development server"
```
**详细步骤**:
1. **执行 make deps**: 安装 Go 依赖
2. **执行 make env**: 创建环境配置文件
3. **输出设置指南**: 显示后续步骤提示
**完成后状态**: 开发环境基本就绪,需要手动启动数据库服务
---
### 🐳 **Docker 相关命令**
#### `make docker-build`
**执行逻辑**:
```bash
docker build -t tyapi-server:1.0.0 -t tyapi-server:latest .
```
**详细步骤**:
1. **读取 Dockerfile**: 从当前目录读取 Dockerfile
2. **构建上下文**: 将当前目录作为构建上下文发送给 Docker daemon
3. **镜像构建**:
- 执行 Dockerfile 中的每个指令
- 逐层构建镜像
- 缓存中间层以提高构建速度
4. **标签应用**: 同时打上版本标签和 latest 标签
**生成镜像**: `tyapi-server:1.0.0`, `tyapi-server:latest`
#### `make docker-run`
**执行逻辑**:
```bash
docker run -d --name tyapi-server -p 8080:8080 --env-file .env tyapi-server:latest
```
**详细步骤**:
1. **环境检查**: 确认.env 文件存在
2. **容器创建**: 基于 latest 镜像创建容器
3. **参数应用**:
- `-d`: 后台运行 (detached mode)
- `--name tyapi-server`: 设置容器名称
- `-p 8080:8080`: 端口映射 (主机:容器)
- `--env-file .env`: 加载环境变量文件
4. **容器启动**: 启动应用程序进程
**结果**: 后台运行的 Docker 容器,端口 8080 可访问
---
### 🔧 **服务管理命令**
#### `make services-up` / `make dev-up`
**执行逻辑**:
```bash
# 检查docker-compose.dev.yml文件
# Windows:
@if exist "docker-compose.dev.yml" ( \
docker-compose -f docker-compose.dev.yml up -d \
) else ( \
echo docker-compose.dev.yml not found \
)
```
**详细步骤**:
1. **文件检查**: 验证 docker-compose.dev.yml 文件存在
2. **Docker Compose 启动**:
- 读取 docker-compose.dev.yml 配置
- 拉取所需的 Docker 镜像 (如果本地不存在)
- 创建 Docker 网络 (tyapi-network)
- 创建数据卷 (postgres_data, redis_data 等)
- 按依赖顺序启动服务:
- PostgreSQL (端口 5432)
- Redis (端口 6379)
- pgAdmin (端口 5050)
- Prometheus (端口 9090)
- Grafana (端口 3000)
- Jaeger (端口 16686)
- MinIO (端口 9000/9001)
- MailHog (端口 8025)
**启动的 8 个服务**: 数据库、缓存、监控、管理工具等完整开发环境
#### `make services-down` / `make dev-down`
**执行逻辑**:
```bash
docker-compose -f docker-compose.dev.yml down
```
**详细步骤**:
1. **容器停止**: 优雅停止所有服务容器 (发送 SIGTERM)
2. **容器删除**: 删除所有相关容器
3. **网络清理**: 删除自定义网络
4. **数据保留**: 保留数据卷 (数据不丢失)
**保留的资源**: 数据卷、镜像
**删除的资源**: 容器、网络
---
### 🗃️ **数据库相关命令**
#### `make migrate`
**执行逻辑**:
```bash
# 步骤1: 执行make build (依赖)
# 步骤2: 运行迁移
./bin/tyapi-server -migrate
```
**详细步骤**:
1. **应用程序启动**: 以迁移模式启动应用
2. **数据库连接**: 连接到 PostgreSQL 数据库
3. **迁移文件扫描**: 扫描 migrations 目录下的 SQL 文件
4. **版本检查**: 检查数据库中的迁移版本表
5. **增量执行**: 只执行未应用的迁移文件
6. **版本更新**: 更新迁移版本记录
7. **应用退出**: 迁移完成后程序退出
**相关文件**: `internal/domains/user/migrations/`, PostgreSQL 数据库
#### `make health`
**执行逻辑**:
```bash
# 步骤1: 执行make build (依赖)
# 步骤2: 运行健康检查
./bin/tyapi-server -health
```
**详细步骤**:
1. **健康检查启动**: 以健康检查模式启动应用
2. **组件检查**:
- PostgreSQL 数据库连接
- Redis 缓存连接
- 关键配置项验证
- 必要文件存在性检查
3. **状态报告**: 输出每个组件的健康状态
4. **退出码**: 成功返回 0失败返回非零
**检查项目**: 数据库、缓存、配置、权限等
---
### 🧹 **清理命令**
#### `make clean`
**执行逻辑**:
```bash
# 步骤1: Go缓存清理
go clean
# 步骤2: 文件删除 (根据操作系统)
# Windows:
@if exist "bin" rmdir /s /q "bin" 2>nul || echo ""
@if exist "coverage.out" del /f /q "coverage.out" 2>nul || echo ""
@if exist "coverage.html" del /f /q "coverage.html" 2>nul || echo ""
```
**详细步骤**:
1. **Go 清理**:
- 清理编译缓存
- 删除临时构建文件
- 清理测试缓存
2. **目录删除**:
- 删除整个 bin 目录及内容
- Windows: `rmdir /s /q`
- Unix: `rm -rf`
3. **文件删除**:
- 删除 coverage.out 测试覆盖率文件
- 删除 coverage.html 覆盖率报告
4. **错误抑制**: 使用 `2>nul``2>/dev/null` 忽略"文件不存在"错误
**删除的内容**: `bin/`, `coverage.out`, `coverage.html`, Go 构建缓存
---
### 🚀 **流水线命令**
#### `make ci`
**执行逻辑**:
```bash
# 顺序执行5个步骤:
make deps # 安装依赖
make fmt # 代码格式化
make lint # 代码检查
make test # 运行测试
make build # 构建应用
```
**详细流程**:
1. **deps**: 确保所有依赖最新且完整
2. **fmt**: 统一代码格式,确保可读性
3. **lint**: 静态代码分析,发现潜在问题
4. **test**: 运行所有测试,确保功能正确
5. **build**: 验证代码可以成功编译
**失败策略**: 任何一步失败,立即停止后续步骤
#### `make release`
**执行逻辑**:
```bash
# 顺序执行3个步骤:
make ci # 完整CI检查
make build-all # 交叉编译所有平台
make docker-build # 构建Docker镜像
```
**详细流程**:
1. **CI 检查**: 确保代码质量和功能正确性
2. **多平台构建**: 生成 5 个平台的可执行文件
3. **Docker 镜像**: 构建容器化版本
**输出产物**:
- 5 个平台的二进制文件
- Docker 镜像 (2 个标签)
- 测试覆盖率报告
---
## 💡 **命令执行顺序和依赖关系**
### 🔗 **依赖关系图**
```
version ─────► build
health ──────► build
run ─────────► build
migrate ─────► build
coverage ────► test
ci ──────────► deps → fmt → lint → test → build
release ─────► ci → build-all → docker-build
setup ───────► deps → env
```
### ⚡ **执行时机建议**
#### **每次开发前**
```bash
make setup # 首次使用
make dev-up # 启动依赖服务
make dev # 开始开发
```
#### **提交代码前**
```bash
make ci # 完整检查
```
#### **发布版本前**
```bash
make release # 完整构建
```
---
**这个指南详细说明了每个命令背后的具体操作逻辑,帮助您完全理解 Makefile 的工作原理!** 🎯