Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Senior Go developer skill covering concurrency patterns, gRPC microservices, generics, pprof optimization, and idiomatic testing.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/project-structure.md
1# Project Structure and Module Management23## Standard Project Layout45```6myproject/7├── cmd/ # Main applications8│ ├── server/9│ │ └── main.go # Entry point for server10│ └── cli/11│ └── main.go # Entry point for CLI tool12├── internal/ # Private application code13│ ├── api/ # API handlers14│ ├── service/ # Business logic15│ └── repository/ # Data access layer16├── pkg/ # Public library code17│ └── models/ # Shared models18├── api/ # API definitions19│ ├── openapi.yaml # OpenAPI spec20│ └── proto/ # Protocol buffers21├── web/ # Web assets22│ ├── static/23│ └── templates/24├── scripts/ # Build and install scripts25├── configs/ # Configuration files26├── deployments/ # Docker, K8s configs27├── test/ # Additional test data28├── docs/ # Documentation29├── go.mod # Module definition30├── go.sum # Dependency checksums31├── Makefile # Build automation32└── README.md33```3435## go.mod Basics3637```go38// Initialize module39// go mod init github.com/user/project4041module github.com/user/myproject4243go 1.214445require (46github.com/gin-gonic/gin v1.9.147github.com/lib/pq v1.10.948go.uber.org/zap v1.26.049)5051require (52// Indirect dependencies (automatically managed)53github.com/bytedance/sonic v1.9.1 // indirect54github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect55)5657// Replace directive for local development58replace github.com/user/mylib => ../mylib5960// Retract directive to mark bad versions61retract v1.0.1 // Contains critical bug62```6364## Module Commands6566```bash67# Initialize module68go mod init github.com/user/project6970# Add missing dependencies71go mod tidy7273# Download dependencies74go mod download7576# Verify dependencies77go mod verify7879# Show module graph80go mod graph8182# Show why package is needed83go mod why github.com/user/package8485# Vendor dependencies (copy to vendor/)86go mod vendor8788# Update dependency89go get -u github.com/user/package9091# Update to specific version92go get github.com/user/[email protected]9394# Update all dependencies95go get -u ./...9697# Remove unused dependencies98go mod tidy99```100101## Internal Packages102103```go104// internal/ packages can only be imported by code in the parent tree105106myproject/107├── internal/108│ ├── auth/ # Can only be imported by myproject109│ │ └── jwt.go110│ └── database/111│ └── postgres.go112└── pkg/113└── models/ # Can be imported by anyone114└── user.go115116// This works (same project):117import "github.com/user/myproject/internal/auth"118119// This fails (different project):120import "github.com/other/project/internal/auth" // Error!121122// Internal subdirectories123myproject/124└── api/125└── internal/ # Can only be imported by code in api/126└── helpers.go127```128129## Package Organization130131```go132// user/user.go - Domain package133package user134135import (136"context"137"time"138)139140// User represents a user entity141type User struct {142ID string143Email string144CreatedAt time.Time145}146147// Repository defines data access interface148type Repository interface {149Create(ctx context.Context, user *User) error150GetByID(ctx context.Context, id string) (*User, error)151Update(ctx context.Context, user *User) error152Delete(ctx context.Context, id string) error153}154155// Service handles business logic156type Service struct {157repo Repository158}159160// NewService creates a new user service161func NewService(repo Repository) *Service {162return &Service{repo: repo}163}164165func (s *Service) RegisterUser(ctx context.Context, email string) (*User, error) {166user := &User{167ID: generateID(),168Email: email,169CreatedAt: time.Now(),170}171return user, s.repo.Create(ctx, user)172}173```174175## Multi-Module Repository (Monorepo)176177```178monorepo/179├── go.work # Workspace file180├── services/181│ ├── api/182│ │ ├── go.mod183│ │ └── main.go184│ └── worker/185│ ├── go.mod186│ └── main.go187└── shared/188└── models/189├── go.mod190└── user.go191192// go.work193go 1.21194195use (196./services/api197./services/worker198./shared/models199)200201// Commands:202// go work init ./services/api ./services/worker203// go work use ./shared/models204// go work sync205```206207## Build Tags and Constraints208209```go210// +build integration211// integration_test.go212213package myapp214215import "testing"216217func TestIntegration(t *testing.T) {218// Integration test code219}220221// Build: go test -tags=integration222223// File-level build constraints (Go 1.17+)224//go:build linux && amd64225226package myapp227228// Multiple constraints229//go:build linux || darwin230//go:build amd64231232// Negation233//go:build !windows234235// Common tags:236// linux, darwin, windows, freebsd237// amd64, arm64, 386, arm238// cgo, !cgo239```240241## Makefile Example242243```makefile244# Makefile245.PHONY: build test lint clean run246247# Variables248BINARY_NAME=myapp249BUILD_DIR=bin250GO=go251GOFLAGS=-v252253# Build the application254build:255$(GO) build $(GOFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME) ./cmd/server256257# Run tests258test:259$(GO) test -v -race -coverprofile=coverage.out ./...260261# Run tests with coverage report262test-coverage: test263$(GO) tool cover -html=coverage.out264265# Run linters266lint:267golangci-lint run ./...268269# Format code270fmt:271$(GO) fmt ./...272goimports -w .273274# Run the application275run:276$(GO) run ./cmd/server277278# Clean build artifacts279clean:280rm -rf $(BUILD_DIR)281rm -f coverage.out282283# Install dependencies284deps:285$(GO) mod download286$(GO) mod tidy287288# Build for multiple platforms289build-all:290GOOS=linux GOARCH=amd64 $(GO) build -o $(BUILD_DIR)/$(BINARY_NAME)-linux-amd64 ./cmd/server291GOOS=darwin GOARCH=amd64 $(GO) build -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-amd64 ./cmd/server292GOOS=windows GOARCH=amd64 $(GO) build -o $(BUILD_DIR)/$(BINARY_NAME)-windows-amd64.exe ./cmd/server293294# Run with race detector295run-race:296$(GO) run -race ./cmd/server297298# Generate code299generate:300$(GO) generate ./...301302# Docker build303docker-build:304docker build -t $(BINARY_NAME):latest .305306# Help307help:308@echo "Available targets:"309@echo " build - Build the application"310@echo " test - Run tests"311@echo " test-coverage - Run tests with coverage report"312@echo " lint - Run linters"313@echo " fmt - Format code"314@echo " run - Run the application"315@echo " clean - Clean build artifacts"316@echo " deps - Install dependencies"317```318319## Dockerfile Multi-Stage Build320321```dockerfile322# Build stage323FROM golang:1.21-alpine AS builder324325WORKDIR /app326327# Copy go mod files328COPY go.mod go.sum ./329RUN go mod download330331# Copy source code332COPY . .333334# Build binary335RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o server ./cmd/server336337# Final stage338FROM alpine:latest339340RUN apk --no-cache add ca-certificates341342WORKDIR /root/343344# Copy binary from builder345COPY --from=builder /app/server .346347# Copy config files if needed348COPY --from=builder /app/configs ./configs349350EXPOSE 8080351352CMD ["./server"]353```354355## Version Information356357```go358// version/version.go359package version360361import "runtime"362363var (364// Set via ldflags during build365Version = "dev"366GitCommit = "none"367BuildTime = "unknown"368)369370// Info returns version information371func Info() map[string]string {372return map[string]string{373"version": Version,374"git_commit": GitCommit,375"build_time": BuildTime,376"go_version": runtime.Version(),377"os": runtime.GOOS,378"arch": runtime.GOARCH,379}380}381382// Build with version info:383// go build -ldflags "-X github.com/user/project/version.Version=1.0.0 \384// -X github.com/user/project/version.GitCommit=$(git rev-parse HEAD) \385// -X github.com/user/project/version.BuildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)"386```387388## Go Generate389390```go391// models/user.go392//go:generate mockgen -source=user.go -destination=../mocks/user_mock.go -package=mocks393394package models395396type UserRepository interface {397GetUser(id string) (*User, error)398SaveUser(user *User) error399}400401// tools.go - Track tool dependencies402//go:build tools403404package tools405406import (407_ "github.com/golang/mock/mockgen"408_ "golang.org/x/tools/cmd/stringer"409)410411// Install tools:412// go install github.com/golang/mock/mockgen@latest413414// Run generate:415// go generate ./...416```417418## Configuration Management419420```go421// config/config.go422package config423424import (425"os"426"time"427428"github.com/kelseyhightower/envconfig"429)430431type Config struct {432Server ServerConfig433Database DatabaseConfig434Redis RedisConfig435}436437type ServerConfig struct {438Host string `envconfig:"SERVER_HOST" default:"0.0.0.0"`439Port int `envconfig:"SERVER_PORT" default:"8080"`440ReadTimeout time.Duration `envconfig:"SERVER_READ_TIMEOUT" default:"10s"`441WriteTimeout time.Duration `envconfig:"SERVER_WRITE_TIMEOUT" default:"10s"`442}443444type DatabaseConfig struct {445URL string `envconfig:"DATABASE_URL" required:"true"`446MaxOpenConns int `envconfig:"DB_MAX_OPEN_CONNS" default:"25"`447MaxIdleConns int `envconfig:"DB_MAX_IDLE_CONNS" default:"5"`448}449450type RedisConfig struct {451Addr string `envconfig:"REDIS_ADDR" default:"localhost:6379"`452Password string `envconfig:"REDIS_PASSWORD"`453DB int `envconfig:"REDIS_DB" default:"0"`454}455456// Load loads configuration from environment457func Load() (*Config, error) {458var cfg Config459if err := envconfig.Process("", &cfg); err != nil {460return nil, err461}462return &cfg, nil463}464```465466## Quick Reference467468| Command | Description |469|---------|-------------|470| `go mod init` | Initialize module |471| `go mod tidy` | Add/remove dependencies |472| `go mod download` | Download dependencies |473| `go get package@version` | Add/update dependency |474| `go build -ldflags "-X ..."` | Set version info |475| `go generate ./...` | Run code generation |476| `GOOS=linux go build` | Cross-compile |477| `go work init` | Initialize workspace |478