Initial commit
This commit is contained in:
456
commands/scaffold.md
Normal file
456
commands/scaffold.md
Normal file
@@ -0,0 +1,456 @@
|
||||
---
|
||||
name: golang-development:scaffold
|
||||
description: Scaffold new Go projects with modern structure, Go modules, testing setup, CI/CD pipelines, and best practices
|
||||
---
|
||||
|
||||
# Golang Development Scaffold Command
|
||||
|
||||
Create a new Go project with a production-ready structure, modern tooling, and best practices built-in.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
/golang-development:scaffold <project-name> [options]
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
- `$1` - Project name (required, will be used for module name)
|
||||
- `$2` - Project type: `service`, `cli`, `library`, or `microservice` (optional, defaults to `service`)
|
||||
- `$3` - Additional options as JSON (optional)
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Create a basic HTTP service
|
||||
/golang-development:scaffold my-api service
|
||||
|
||||
# Create a CLI application
|
||||
/golang-development:scaffold my-tool cli
|
||||
|
||||
# Create a library
|
||||
/golang-development:scaffold my-lib library
|
||||
|
||||
# Create a microservice with full features
|
||||
/golang-development:scaffold user-service microservice '{"with_grpc": true, "with_db": true}'
|
||||
```
|
||||
|
||||
## Project Structures
|
||||
|
||||
### Service (HTTP API)
|
||||
```
|
||||
my-api/
|
||||
├── cmd/
|
||||
│ └── server/
|
||||
│ └── main.go
|
||||
├── internal/
|
||||
│ ├── handler/
|
||||
│ │ └── health.go
|
||||
│ ├── middleware/
|
||||
│ │ └── logging.go
|
||||
│ └── service/
|
||||
│ └── user.go
|
||||
├── pkg/
|
||||
│ └── response/
|
||||
│ └── response.go
|
||||
├── api/
|
||||
│ └── openapi.yaml
|
||||
├── scripts/
|
||||
│ └── build.sh
|
||||
├── deployments/
|
||||
│ ├── Dockerfile
|
||||
│ └── k8s/
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
├── .gitignore
|
||||
├── .golangci.yml
|
||||
├── Makefile
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### CLI Application
|
||||
```
|
||||
my-tool/
|
||||
├── cmd/
|
||||
│ └── my-tool/
|
||||
│ └── main.go
|
||||
├── internal/
|
||||
│ ├── command/
|
||||
│ │ ├── root.go
|
||||
│ │ └── serve.go
|
||||
│ └── config/
|
||||
│ └── config.go
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
├── .gitignore
|
||||
├── .golangci.yml
|
||||
├── Makefile
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### Library
|
||||
```
|
||||
my-lib/
|
||||
├── example_test.go
|
||||
├── lib.go
|
||||
├── lib_test.go
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
├── .gitignore
|
||||
├── .golangci.yml
|
||||
├── LICENSE
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### Microservice (Full Features)
|
||||
```
|
||||
user-service/
|
||||
├── cmd/
|
||||
│ └── server/
|
||||
│ └── main.go
|
||||
├── internal/
|
||||
│ ├── domain/
|
||||
│ │ └── user.go
|
||||
│ ├── handler/
|
||||
│ │ ├── http/
|
||||
│ │ └── grpc/
|
||||
│ ├── repository/
|
||||
│ │ └── postgres/
|
||||
│ ├── service/
|
||||
│ │ └── user_service.go
|
||||
│ └── infrastructure/
|
||||
│ ├── database/
|
||||
│ ├── cache/
|
||||
│ └── messaging/
|
||||
├── api/
|
||||
│ ├── http/
|
||||
│ │ └── openapi.yaml
|
||||
│ └── grpc/
|
||||
│ └── user.proto
|
||||
├── pkg/
|
||||
│ ├── logger/
|
||||
│ ├── metrics/
|
||||
│ └── tracing/
|
||||
├── migrations/
|
||||
│ └── 001_create_users.sql
|
||||
├── deployments/
|
||||
│ ├── Dockerfile
|
||||
│ ├── docker-compose.yml
|
||||
│ └── k8s/
|
||||
├── scripts/
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
├── .gitignore
|
||||
├── .golangci.yml
|
||||
├── Makefile
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Generated Files
|
||||
|
||||
### main.go (Service)
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"{{.ModuleName}}/internal/handler"
|
||||
"{{.ModuleName}}/internal/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Setup router
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// Middleware
|
||||
handler := middleware.Logging(
|
||||
middleware.Recovery(mux),
|
||||
)
|
||||
|
||||
// Routes
|
||||
mux.HandleFunc("/health", handler.Health)
|
||||
mux.HandleFunc("/ready", handler.Ready)
|
||||
|
||||
// Server configuration
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "8080"
|
||||
}
|
||||
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf(":%s", port),
|
||||
Handler: handler,
|
||||
ReadTimeout: 15 * time.Second,
|
||||
WriteTimeout: 15 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
}
|
||||
|
||||
// Start server
|
||||
go func() {
|
||||
log.Printf("Server starting on port %s", port)
|
||||
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Fatalf("Server error: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Graceful shutdown
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-quit
|
||||
|
||||
log.Println("Shutting down server...")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
log.Fatalf("Server forced to shutdown: %v", err)
|
||||
}
|
||||
|
||||
log.Println("Server exited")
|
||||
}
|
||||
```
|
||||
|
||||
### Makefile
|
||||
```makefile
|
||||
.PHONY: build test lint run clean
|
||||
|
||||
# Variables
|
||||
APP_NAME := {{.ProjectName}}
|
||||
VERSION := $(shell git describe --tags --always --dirty)
|
||||
BUILD_TIME := $(shell date -u '+%Y-%m-%d_%H:%M:%S')
|
||||
LDFLAGS := -ldflags "-X main.Version=$(VERSION) -X main.BuildTime=$(BUILD_TIME)"
|
||||
|
||||
# Build
|
||||
build:
|
||||
go build $(LDFLAGS) -o bin/$(APP_NAME) ./cmd/server
|
||||
|
||||
# Test
|
||||
test:
|
||||
go test -v -race -coverprofile=coverage.out ./...
|
||||
|
||||
# Coverage
|
||||
coverage:
|
||||
go tool cover -html=coverage.out
|
||||
|
||||
# Lint
|
||||
lint:
|
||||
golangci-lint run
|
||||
|
||||
# Run
|
||||
run:
|
||||
go run ./cmd/server
|
||||
|
||||
# Clean
|
||||
clean:
|
||||
rm -rf bin/
|
||||
rm -f coverage.out
|
||||
|
||||
# Install tools
|
||||
tools:
|
||||
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
|
||||
# Docker
|
||||
docker-build:
|
||||
docker build -t $(APP_NAME):$(VERSION) .
|
||||
|
||||
docker-run:
|
||||
docker run -p 8080:8080 $(APP_NAME):$(VERSION)
|
||||
```
|
||||
|
||||
### Dockerfile
|
||||
```dockerfile
|
||||
# Build stage
|
||||
FROM golang:1.21-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy go mod files
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main ./cmd/server
|
||||
|
||||
# Runtime stage
|
||||
FROM alpine:latest
|
||||
|
||||
RUN apk --no-cache add ca-certificates
|
||||
|
||||
WORKDIR /root/
|
||||
|
||||
# Copy binary from builder
|
||||
COPY --from=builder /app/main .
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD ["./main"]
|
||||
```
|
||||
|
||||
### .golangci.yml
|
||||
```yaml
|
||||
linters:
|
||||
enable:
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- unused
|
||||
- gofmt
|
||||
- goimports
|
||||
- misspell
|
||||
- gocritic
|
||||
- gosec
|
||||
- revive
|
||||
|
||||
linters-settings:
|
||||
errcheck:
|
||||
check-blank: true
|
||||
govet:
|
||||
check-shadowing: true
|
||||
gofmt:
|
||||
simplify: true
|
||||
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
```
|
||||
|
||||
### GitHub Actions CI (.github/workflows/ci.yml)
|
||||
```yaml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.21'
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
- name: Run tests
|
||||
run: go test -v -race -coverprofile=coverage.out ./...
|
||||
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
files: ./coverage.out
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.21'
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: latest
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test, lint]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.21'
|
||||
|
||||
- name: Build
|
||||
run: go build -v ./cmd/server
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
|
||||
The command accepts a JSON configuration object:
|
||||
|
||||
```json
|
||||
{
|
||||
"with_grpc": true,
|
||||
"with_db": true,
|
||||
"with_redis": true,
|
||||
"with_kafka": true,
|
||||
"with_docker": true,
|
||||
"with_k8s": true,
|
||||
"with_ci": true,
|
||||
"db_driver": "postgres",
|
||||
"module_path": "github.com/user/project"
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
1. Parse arguments and configuration
|
||||
2. Create project directory structure
|
||||
3. Initialize Go module
|
||||
4. Generate main.go and core files
|
||||
5. Create Makefile and build scripts
|
||||
6. Add Dockerfile and Docker Compose
|
||||
7. Generate CI/CD configuration
|
||||
8. Create README with usage instructions
|
||||
9. Initialize git repository
|
||||
10. Run `go mod tidy`
|
||||
|
||||
## Features Included
|
||||
|
||||
- **Modern Project Structure**: Clean architecture with separation of concerns
|
||||
- **HTTP Server**: Production-ready with graceful shutdown
|
||||
- **Middleware**: Logging, recovery, CORS, authentication templates
|
||||
- **Health Checks**: Health and readiness endpoints
|
||||
- **Testing**: Test structure and examples
|
||||
- **Linting**: golangci-lint configuration
|
||||
- **CI/CD**: GitHub Actions workflow
|
||||
- **Docker**: Multi-stage Dockerfile
|
||||
- **Kubernetes**: Basic manifests (if requested)
|
||||
- **Documentation**: Comprehensive README
|
||||
|
||||
## Post-Scaffold Steps
|
||||
|
||||
After scaffolding, the command will suggest:
|
||||
|
||||
```bash
|
||||
cd {{.ProjectName}}
|
||||
go mod tidy
|
||||
make test
|
||||
make run
|
||||
```
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this command to:
|
||||
- Start new Go projects quickly
|
||||
- Ensure consistent project structure
|
||||
- Set up best practices from the start
|
||||
- Include modern tooling and CI/CD
|
||||
- Scaffold microservices or APIs
|
||||
- Create CLI tools with proper structure
|
||||
Reference in New Issue
Block a user