Claude-skill-registry go
Write Go code following best practices. Use when developing Go applications. Covers error handling, concurrency, and project structure.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/go" ~/.claude/skills/majiayu000-claude-skill-registry-go && rm -rf "$T"
manifest:
skills/data/go/SKILL.mdsource content
Go Development
Project Structure
myproject/ ├── cmd/ │ └── server/ │ └── main.go ├── internal/ │ ├── handler/ │ ├── service/ │ └── repository/ ├── pkg/ │ └── shared/ ├── go.mod └── go.sum
Error Handling
// Custom error types type NotFoundError struct { Resource string ID string } func (e *NotFoundError) Error() string { return fmt.Sprintf("%s not found: %s", e.Resource, e.ID) } // Error wrapping func GetUser(id string) (*User, error) { user, err := db.FindUser(id) if err != nil { return nil, fmt.Errorf("GetUser(%s): %w", id, err) } return user, nil } // Error checking if errors.Is(err, sql.ErrNoRows) { return nil, &NotFoundError{Resource: "user", ID: id} }
Concurrency
// Goroutines with errgroup func fetchAll(ctx context.Context, urls []string) ([]Response, error) { g, ctx := errgroup.WithContext(ctx) results := make([]Response, len(urls)) for i, url := range urls { i, url := i, url // capture loop variables g.Go(func() error { resp, err := fetch(ctx, url) if err != nil { return err } results[i] = resp return nil }) } if err := g.Wait(); err != nil { return nil, err } return results, nil } // Channels func producer(ch chan<- int) { for i := 0; i < 10; i++ { ch <- i } close(ch) } func consumer(ch <-chan int) { for v := range ch { fmt.Println(v) } }
HTTP Handler
func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request) { ctx := r.Context() id := chi.URLParam(r, "id") user, err := h.service.GetUser(ctx, id) if err != nil { var notFound *NotFoundError if errors.As(err, ¬Found) { http.Error(w, err.Error(), http.StatusNotFound) return } http.Error(w, "Internal error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(user) }
Testing
func TestGetUser(t *testing.T) { t.Parallel() tests := []struct { name string id string want *User wantErr bool }{ { name: "existing user", id: "123", want: &User{ID: "123", Email: "test@example.com"}, }, { name: "non-existent user", id: "999", wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := service.GetUser(context.Background(), tt.id) if (err != nil) != tt.wantErr { t.Errorf("error = %v, wantErr %v", err, tt.wantErr) } if !reflect.DeepEqual(got, tt.want) { t.Errorf("got = %v, want %v", got, tt.want) } }) } }
Tooling
# Format gofmt -w . goimports -w . # Lint golangci-lint run # Test go test -v -race -cover ./...