Files
subconverter-go/Makefile
Rogee 7fcabe0225
Some checks failed
CI/CD Pipeline / Test (push) Failing after 22m19s
CI/CD Pipeline / Security Scan (push) Failing after 5m57s
CI/CD Pipeline / Build (amd64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (amd64, linux) (push) Has been skipped
CI/CD Pipeline / Build (amd64, windows) (push) Has been skipped
CI/CD Pipeline / Build (arm64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (arm64, linux) (push) Has been skipped
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Create Release (push) Has been skipped
first commit
2025-09-28 10:05:07 +08:00

475 lines
16 KiB
Makefile

# SubConverter-Go Makefile
# This Makefile contains common commands for building, testing, and managing the SubConverter-Go project
# Project variables
PROJECT_NAME := subconverter-go
VERSION := 1.0.0
BUILD_TIME := $(shell date -u '+%Y-%m-%d %H:%M:%S')
GIT_COMMIT := $(shell git rev-parse --short HEAD)
GIT_DIRTY := $(shell test -n "`git status --porcelain`" && echo "+CHANGES" || true)
LDFLAGS := "-ldflags=-X 'main.Version=$(VERSION)' -X 'main.BuildTime=$(BUILD_TIME)' -X 'main.GitCommit=$(GIT_COMMIT)$(GIT_DIRTY)'"
# Build variables
GO := go
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
BUILD_DIR := build
DIST_DIR := dist
CONFIG_FILE := config.yaml
# Command variables
SHELL := /bin/bash
RM := rm -rf
MKDIR := mkdir -p
CP := cp -r
FIND := find
XARGS := xargs
# Default target
.PHONY: all
all: clean build test
# Help target - show available commands
.PHONY: help
help: ## Show this help message
@echo "SubConverter-Go Development Commands:"
@echo ""
@awk 'BEGIN {FS = ":.*##"; printf "%-20s %s\n", "Target", "Description"} /^[a-zA-Z_-]+:.*?##/ { printf "%-20s %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
# Build targets
.PHONY: build
build: ## Build the application for current platform
@echo "Building $(PROJECT_NAME) for $(GOOS)/$(GOARCH)..."
$(GO) build $(LDFLAGS) -o $(BUILD_DIR)/$(PROJECT_NAME) main.go
@echo "Build complete: $(BUILD_DIR)/$(PROJECT_NAME)"
.PHONY: build-all
build-all: ## Build the application for all supported platforms
@echo "Building $(PROJECT_NAME) for all platforms..."
$(MKDIR) $(DIST_DIR)
@for os in linux darwin windows; do \
for arch in amd64 arm64; do \
if [ "$$os" = "windows" ]; then \
ext=".exe"; \
else \
ext=""; \
fi; \
echo "Building for $$os/$$arch..."; \
GOOS=$$os GOARCH=$$arch $(GO) build $(LDFLAGS) \
-o $(DIST_DIR)/$(PROJECT_NAME)-$$os-$$arch$$ext main.go; \
done; \
done
@echo "All builds complete in $(DIST_DIR)/"
.PHONY: build-linux
build-linux: ## Build the application for Linux
@echo "Building $(PROJECT_NAME) for Linux..."
GOOS=linux GOARCH=amd64 $(GO) build $(LDFLAGS) -o $(BUILD_DIR)/$(PROJECT_NAME)-linux main.go
@echo "Build complete: $(BUILD_DIR)/$(PROJECT_NAME)-linux"
.PHONY: build-darwin
build-darwin: ## Build the application for macOS
@echo "Building $(PROJECT_NAME) for macOS..."
GOOS=darwin GOARCH=amd64 $(GO) build $(LDFLAGS) -o $(BUILD_DIR)/$(PROJECT_NAME)-darwin main.go
@echo "Build complete: $(BUILD_DIR)/$(PROJECT_NAME)-darwin"
.PHONY: build-windows
build-windows: ## Build the application for Windows
@echo "Building $(PROJECT_NAME) for Windows..."
GOOS=windows GOARCH=amd64 $(GO) build $(LDFLAGS) -o $(BUILD_DIR)/$(PROJECT_NAME)-windows.exe main.go
@echo "Build complete: $(BUILD_DIR)/$(PROJECT_NAME)-windows.exe"
# Development targets
.PHONY: dev
dev: ## Run the application in development mode
@echo "Starting $(PROJECT_NAME) in development mode..."
$(GO) run main.go --config $(CONFIG_FILE)
.PHONY: dev-watch
dev-watch: ## Run the application with file watching (requires air)
@echo "Starting $(PROJECT_NAME) with file watching..."
@if command -v air >/dev/null 2>&1; then \
air; \
else \
echo "Installing air for hot reload..."; \
$(GO) install github.com/cosmtrek/air@latest; \
air; \
fi
# Test targets
.PHONY: test
test: ## Run all tests
@echo "Running all tests..."
$(GO) test -v ./...
.PHONY: test-unit
test-unit: ## Run unit tests only
@echo "Running unit tests..."
$(GO) test -v ./tests/unit/...
.PHONY: test-integration
test-integration: ## Run integration tests only
@echo "Running integration tests..."
$(GO) test -v ./tests/integration/...
.PHONY: test-contract
test-contract: ## Run contract tests only
@echo "Running contract tests..."
$(GO) test -v ./tests/contract/...
.PHONY: test-coverage
test-coverage: ## Run tests with coverage report
@echo "Running tests with coverage..."
$(GO) test -v -coverprofile=coverage.out ./...
$(GO) tool cover -html=coverage.out -o coverage.html
@echo "Coverage report generated: coverage.html"
.PHONY: test-race
test-race: ## Run tests with race condition detection
@echo "Running tests with race detection..."
$(GO) test -race -v ./...
.PHONY: benchmark
benchmark: ## Run benchmarks
@echo "Running benchmarks..."
$(GO) test -bench=. -benchmem ./...
# Quality targets
.PHONY: lint
lint: ## Run linter to check code quality
@echo "Running linter..."
@if command -v golangci-lint >/dev/null 2>&1; then \
golangci-lint run; \
else \
echo "Installing golangci-lint..."; \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.54.2; \
golangci-lint run; \
fi
.PHONY: fmt
fmt: ## Format Go code
@echo "Formatting Go code..."
$(GO) fmt ./...
.PHONY: fmt-check
fmt-check: ## Check if Go code is properly formatted
@echo "Checking Go code formatting..."
@if [ $$($(GO) fmt ./... | wc -l) -gt 0 ]; then \
echo "Go code is not formatted. Run 'make fmt' to fix."; \
$(GO) fmt -d ./...; \
exit 1; \
else \
echo "Go code is properly formatted."; \
fi
.PHONY: vet
vet: ## Run go vet to check for common issues
@echo "Running go vet..."
$(GO) vet ./...
# Dependency management
.PHONY: deps
deps: ## Download and install dependencies
@echo "Downloading dependencies..."
$(GO) mod download
$(GO) mod tidy
.PHONY: deps-update
deps-update: ## Update dependencies to latest versions
@echo "Updating dependencies..."
$(GO) get -u ./...
$(GO) mod tidy
.PHONY: deps-check
deps-check: ## Check for security vulnerabilities in dependencies
@echo "Checking for security vulnerabilities..."
@if command -v govulncheck >/dev/null 2>&1; then \
govulncheck ./...; \
else \
echo "Installing govulncheck..."; \
$(GO) install golang.org/x/vuln/cmd/govulncheck@latest; \
govulncheck ./...; \
fi
# Documentation targets
.PHONY: docs
docs: ## Generate documentation
@echo "Generating documentation..."
@if command -v godoc >/dev/null 2>&1; then \
echo "Starting documentation server on :6060..."; \
godoc -http=:6060 & \
echo "Documentation available at http://localhost:6060/pkg/github.com/subconverter-go/"; \
else \
echo "godoc not available. Install with: go install golang.org/x/tools/cmd/godoc@latest"; \
fi
.PHONY: swagger
swagger: ## Generate Swagger documentation (requires swag)
@echo "Generating Swagger documentation..."
@if command -v swag >/dev/null 2>&1; then \
swag init -g ./main.go -o ./docs/swagger; \
echo "Swagger documentation generated in docs/swagger/"; \
else \
echo "Installing swag..."; \
$(GO) install github.com/swaggo/swag/cmd/swag@latest; \
swag init -g ./main.go -o ./docs/swagger; \
fi
# Docker targets
.PHONY: docker-build
docker-build: ## Build Docker image
@echo "Building Docker image..."
docker build -t $(PROJECT_NAME):$(VERSION) .
docker build -t $(PROJECT_NAME):latest .
.PHONY: docker-run
docker-run: ## Run Docker container
@echo "Running Docker container..."
docker run -p 25500:25500 -v $(PWD)/config.yaml:/app/config.yaml $(PROJECT_NAME):latest
.PHONY: docker-push
docker-push: ## Push Docker image to registry
@echo "Pushing Docker image..."
docker push $(PROJECT_NAME):$(VERSION)
docker push $(PROJECT_NAME):latest
# Installation targets
.PHONY: install
install: ## Install the application locally
@echo "Installing $(PROJECT_NAME)..."
$(GO) install $(LDFLAGS) .
.PHONY: uninstall
uninstall: ## Uninstall the application locally
@echo "Uninstalling $(PROJECT_NAME)..."
$(RM) $(shell go env GOPATH)/bin/$(PROJECT_NAME)
# Configuration targets
.PHONY: config
config: ## Generate default configuration file
@echo "Generating default configuration..."
@printf "# SubConverter-Go Configuration\n" > $(CONFIG_FILE)
@printf "server:\n" >> $(CONFIG_FILE)
@printf " port: 25500\n" >> $(CONFIG_FILE)
@printf " host: \"0.0.0.0\"\n" >> $(CONFIG_FILE)
@printf " read_timeout: 30\n" >> $(CONFIG_FILE)
@printf " write_timeout: 30\n" >> $(CONFIG_FILE)
@printf " max_request_size: 10485760\n" >> $(CONFIG_FILE)
@printf "\n" >> $(CONFIG_FILE)
@printf "logging:\n" >> $(CONFIG_FILE)
@printf " level: \"info\"\n" >> $(CONFIG_FILE)
@printf " format: \"json\"\n" >> $(CONFIG_FILE)
@printf " output: \"stdout\"\n" >> $(CONFIG_FILE)
@printf " file: \"logs/subconverter-go.log\"\n" >> $(CONFIG_FILE)
@printf " max_size: 100\n" >> $(CONFIG_FILE)
@printf " max_age: 7\n" >> $(CONFIG_FILE)
@printf " max_backups: 3\n" >> $(CONFIG_FILE)
@printf " compress: true\n" >> $(CONFIG_FILE)
@printf "\n" >> $(CONFIG_FILE)
@printf "security:\n" >> $(CONFIG_FILE)
@printf " access_tokens: []\n" >> $(CONFIG_FILE)
@printf " cors_origins: [\"*\"]\n" >> $(CONFIG_FILE)
@printf " rate_limit: 60\n" >> $(CONFIG_FILE)
@printf " timeout: 60\n" >> $(CONFIG_FILE)
@printf "\n" >> $(CONFIG_FILE)
@printf "conversion:\n" >> $(CONFIG_FILE)
@printf " default_target: \"clash\"\n" >> $(CONFIG_FILE)
@printf " supported_targets:\n" >> $(CONFIG_FILE)
@printf " - \"clash\"\n" >> $(CONFIG_FILE)
@printf " - \"surge\"\n" >> $(CONFIG_FILE)
@printf " - \"quantumult-x\"\n" >> $(CONFIG_FILE)
@printf " - \"loon\"\n" >> $(CONFIG_FILE)
@printf " - \"surfboard\"\n" >> $(CONFIG_FILE)
@printf " - \"v2ray\"\n" >> $(CONFIG_FILE)
@printf " default_emoji: false\n" >> $(CONFIG_FILE)
@printf " default_udp: false\n" >> $(CONFIG_FILE)
@printf " max_nodes: 0\n" >> $(CONFIG_FILE)
@printf " cache_timeout: 60\n" >> $(CONFIG_FILE)
@echo "Configuration file created: $(CONFIG_FILE)"
# Clean targets
.PHONY: clean
clean: ## Clean build artifacts
@echo "Cleaning build artifacts..."
$(RM) $(BUILD_DIR)
$(RM) $(DIST_DIR)
$(RM) coverage.out
$(RM) coverage.html
.PHONY: clean-cache
clean-cache: ## Clean Go module cache
@echo "Cleaning Go module cache..."
$(GO) clean -cache
$(GO) clean -modcache
$(RM) -rf $(shell go env GOPATH)/pkg/mod
.PHONY: clean-logs
clean-logs: ## Clean log files
@echo "Cleaning log files..."
$(RM) -rf logs/
# Release targets
.PHONY: release
release: clean build-all ## Create release package
@echo "Creating release package..."
$(MKDIR) $(DIST_DIR)/release
$(CP) $(CONFIG_FILE) $(DIST_DIR)/release/
$(CP) README.md $(DIST_DIR)/release/ 2>/dev/null || true
$(CP) LICENSE $(DIST_DIR)/release/ 2>/dev/null || true
cd $(DIST_DIR) && tar -czf $(PROJECT_NAME)-$(VERSION)-$(GOOS)-$(GOARCH).tar.gz release/*
@echo "Release package created: $(DIST_DIR)/$(PROJECT_NAME)-$(VERSION)-$(GOOS)-$(GOARCH).tar.gz"
# Monitoring and debugging
.PHONY: run
run: build ## Build and run the application
@echo "Building and running $(PROJECT_NAME)..."
$(BUILD_DIR)/$(PROJECT_NAME) --config $(CONFIG_FILE)
.PHONY: run-debug
run-debug: build ## Build and run the application in debug mode
@echo "Building and running $(PROJECT_NAME) in debug mode..."
DEBUG=true $(BUILD_DIR)/$(PROJECT_NAME) --config $(CONFIG_FILE)
.PHONY: profile
profile: ## Run application with profiling
@echo "Running $(PROJECT_NAME) with profiling..."
$(GO) run main.go --config $(CONFIG_FILE) --enable-profiling
# CI/CD targets
.PHONY: ci
ci: deps fmt-check vet test ## Run CI pipeline checks
@echo "Running CI pipeline..."
.PHONY: pre-commit
pre-commit: fmt-check vet lint test ## Run pre-commit checks
@echo "Running pre-commit checks..."
# Utility targets
.PHONY: version
version: ## Show version information
@echo "$(PROJECT_NAME) version $(VERSION)"
@echo "Build time: $(BUILD_TIME)"
@echo "Git commit: $(GIT_COMMIT)$(GIT_DIRTY)"
.PHONY: info
info: ## Show project information
@echo "Project: $(PROJECT_NAME)"
@echo "Version: $(VERSION)"
@echo "Go version: $(shell $(GO) version)"
@echo "GOOS: $(GOOS)"
@echo "GOARCH: $(GOARCH)"
@echo "Working directory: $(PWD)"
.PHONY: tree
tree: ## Show project directory tree
@echo "Project directory tree:"
@$(FIND) . -type f -name "*.go" -o -name "*.md" -o -name "*.yaml" -o -name "*.yml" -o -name "Makefile" | \
sort | sed 's|[^/]*/| |g'
# Development environment setup
.PHONY: setup
setup: deps config ## Setup development environment
@echo "Setting up development environment..."
@echo "Installing development tools..."
@if ! command -v golangci-lint >/dev/null 2>&1; then \
echo "Installing golangci-lint..."; \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.54.2; \
fi
@if ! command -v air >/dev/null 2>&1; then \
echo "Installing air (hot reload)..."; \
$(GO) install github.com/cosmtrek/air@latest; \
fi
@if ! command -v swag >/dev/null 2>&1; then \
echo "Installing swag (Swagger generator)..."; \
$(GO) install github.com/swaggo/swag/cmd/swag@latest; \
fi
@echo "Development environment setup complete!"
# Check if required files exist
.PHONY: check
check: ## Check if required files exist
@echo "Checking required files..."
@if [ ! -f "main.go" ]; then \
echo "❌ main.go not found"; \
exit 1; \
fi
@if [ ! -f "$(CONFIG_FILE)" ]; then \
echo "⚠️ $(CONFIG_FILE) not found. Run 'make config' to create it."; \
fi
@if [ ! -f "go.mod" ]; then \
echo "❌ go.mod not found"; \
exit 1; \
fi
@if [ ! -f "Makefile" ]; then \
echo "❌ Makefile not found"; \
exit 1; \
fi
@echo "✅ All required files are present"
# Create development scripts
.PHONY: scripts
scripts: ## Create development scripts
@echo "Creating development scripts..."
@mkdir -p scripts
@printf "#!/bin/bash\n" > scripts/dev.sh
@printf "# Development script for SubConverter-Go\n" >> scripts/dev.sh
@printf "set -e\n" >> scripts/dev.sh
@printf "\n" >> scripts/dev.sh
@printf "echo \"🚀 Starting SubConverter-Go in development mode...\"\n" >> scripts/dev.sh
@printf "go run main.go --config config.yaml\n" >> scripts/dev.sh
@chmod +x scripts/dev.sh
@printf "#!/bin/bash\n" > scripts/test.sh
@printf "# Test script for SubConverter-Go\n" >> scripts/test.sh
@printf "set -e\n" >> scripts/test.sh
@printf "\n" >> scripts/test.sh
@printf "echo \"🧪 Running all tests...\"\n" >> scripts/test.sh
@printf "go test -v ./...\n" >> scripts/test.sh
@printf "echo \"✅ All tests passed!\"\n" >> scripts/test.sh
@chmod +x scripts/test.sh
@printf "#!/bin/bash\n" > scripts/build.sh
@printf "# Build script for SubConverter-Go\n" >> scripts/build.sh
@printf "set -e\n" >> scripts/build.sh
@printf "\n" >> scripts/build.sh
@printf "echo \"🔨 Building SubConverter-Go...\"\n" >> scripts/build.sh
@printf "make build\n" >> scripts/build.sh
@printf "echo \"✅ Build complete!\"\n" >> scripts/build.sh
@chmod +x scripts/build.sh
@echo "Development scripts created in scripts/"
# Backup targets
.PHONY: backup
backup: ## Create backup of important files
@echo "Creating backup..."
@tar -czf backup-$(shell date +%Y%m%d-%H%M%S).tar.gz \
--exclude=node_modules \
--exclude=.git \
--exclude=$(BUILD_DIR) \
--exclude=$(DIST_DIR) \
--exclude=coverage* \
--exclude=logs \
. 2>/dev/null || true
@echo "Backup created successfully"
# Show project statistics
.PHONY: stats
stats: ## Show project statistics
@echo "📊 Project Statistics:"
@echo "Go files: $(shell find . -name '*.go' -not -path './vendor/*' | wc -l)"
@echo "Total lines: $(shell find . -name '*.go' -not -path './vendor/*' | xargs wc -l | tail -1 | awk '{print $$1}')"
@echo "Test files: $(shell find . -name '*_test.go' | wc -l)"
@echo "Package count: $(shell go list ./... | wc -l)"
@echo "Dependencies: $(shell go list -m all | wc -l)"
# Quick start (for new developers)
.PHONY: quickstart
quickstart: setup test build ## Quick start for new developers
@echo "🎉 Quick start complete!"
@echo "Run './subconverter-go --config config.yaml' to start the server"
@echo "Run 'make help' to see all available commands"
# Default target if no target is specified
.DEFAULT_GOAL := help
# Prevent accidental deletion of files
.PHONY: %
%: ;