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
475 lines
16 KiB
Makefile
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: %
|
|
%: ; |