# 📋 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 的工作原理!** 🎯