From 9336178d735462bc8b4cd246f2cf139dc5944f70 Mon Sep 17 00:00:00 2001 From: Gabriel Radureau Date: Sat, 4 Apr 2026 21:36:57 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20docs:=20add=20ADR=20for=20staged?= =?UTF-8?q?-only=20Git=20hooks=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add ADR-0012 documenting the decision to format only staged Go files - Update ADR README.md with new entry - Document rationale, alternatives, and verification results - Include future considerations for monitoring and CI/CD integration Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- .githooks/README.md | 67 +++++++++ .../bdd_testing/assets/step-template.go | 12 +- .vibe/skills/commit_message/SKILL.md | 141 +++++++++++++++++- .../commit_message/assets/git-hooks/README.md | 67 +++++++++ .../assets/git-hooks/pre-commit | 43 ++++++ adr/0012-git-hooks-staged-only-formatting.md | 125 ++++++++++++++++ adr/README.md | 1 + features/bdd_test.go | 4 +- pkg/bdd/steps/steps.go | 12 +- pkg/bdd/testserver/client.go | 16 +- pkg/bdd/testserver/server.go | 6 +- pkg/config/config.go | 14 +- pkg/greet/api_v2.go | 6 +- pkg/greet/greet.go | 2 +- pkg/greet/greet_v2.go | 2 +- pkg/greet/greet_v2_test.go | 2 +- pkg/server/server.go | 2 +- pkg/validation/validator.go | 8 +- 18 files changed, 483 insertions(+), 47 deletions(-) create mode 100644 .githooks/README.md create mode 100644 .vibe/skills/commit_message/assets/git-hooks/README.md create mode 100755 .vibe/skills/commit_message/assets/git-hooks/pre-commit create mode 100644 adr/0012-git-hooks-staged-only-formatting.md diff --git a/.githooks/README.md b/.githooks/README.md new file mode 100644 index 0000000..1fb3bb0 --- /dev/null +++ b/.githooks/README.md @@ -0,0 +1,67 @@ +# Git Hooks for DanceLessonsCoach + +This directory contains Git hooks for the DanceLessonsCoach project. + +## Available Hooks + +### pre-commit +- **Location**: `.git/hooks/pre-commit` +- **Purpose**: Automatically runs `go mod tidy` and `go fmt` before commits +- **Features**: + - Runs `go mod tidy` to clean up dependencies + - Automatically adds modified `go.mod` and `go.sum` to commit + - Runs `go fmt` on all Go files (excluding vendor and .git directories) + - Automatically adds formatted files to commit + - Only runs if in a Go project (checks for `go.mod`) + +## Installation + +The pre-commit hook is already installed and executable. No additional setup required. + +## Usage + +The hooks run automatically when you commit: + +```bash +git add . +git commit -m "Your commit message" +``` + +The hook will: +1. Run `go mod tidy` +2. Run `go fmt` on all Go files +3. Add any modified files to your commit +4. Allow the commit to proceed if successful + +## Customization + +To modify the hooks: +1. Edit the hook file in `.git/hooks/` +2. Make it executable: `chmod +x .git/hooks/hook-name` + +## Disabling Hooks + +To temporarily disable hooks: + +```bash +# Skip pre-commit hook for one commit +git commit --no-verify -m "Your commit message" +``` + +## Best Practices + +- Let the hooks run automatically - they ensure code quality +- The hooks only modify files that need changes +- All changes are added to your commit automatically +- Hooks run quickly and prevent common issues + +## Troubleshooting + +If a hook fails: +- Check the error message +- Fix the issue manually +- Commit again + +Common issues: +- `go mod tidy` fails: Check your Go module dependencies +- `go fmt` fails: Check for syntax errors in your Go code \ No newline at end of file diff --git a/.vibe/skills/bdd_testing/assets/step-template.go b/.vibe/skills/bdd_testing/assets/step-template.go index 73ceaf0..9ac4c98 100644 --- a/.vibe/skills/bdd_testing/assets/step-template.go +++ b/.vibe/skills/bdd_testing/assets/step-template.go @@ -19,8 +19,8 @@ func NewStepContext(client *testserver.Client) *StepContext { return &StepContext{client: client} } -// InitializeSteps registers step definitions for -func InitializeSteps(ctx *godog.ScenarioContext, client *testserver.Client) { +// InitializeSteps registers step definitions for the feature +func InitializeSteps(ctx *godog.ScenarioContext, client *testserver.Client) { sc := NewStepContext(client) // Use Godog's EXACT regex patterns and parameter names @@ -46,18 +46,18 @@ func (sc *StepContext) iRequestTheHealthEndpoint() error { func (sc *StepContext) theResponseShouldBe(arg1, arg2 string) error { // The regex captures the full JSON from the feature file, including quotes // We need to extract just the key and value without the surrounding quotes and backslashes - + // Remove the surrounding quotes and backslashes cleanArg1 := strings.Trim(arg1, `"\`) cleanArg2 := strings.Trim(arg2, `"\`) - + // Build the expected JSON string expected := fmt.Sprintf(`{"%s":"%s"}`, cleanArg1, cleanArg2) - + return sc.client.ExpectResponseBody(expected) } func (sc *StepContext) theServerIsRunning() error { // Actually verify the server is running by checking the readiness endpoint return sc.client.Request("GET", "/api/ready", nil) -} \ No newline at end of file +} diff --git a/.vibe/skills/commit_message/SKILL.md b/.vibe/skills/commit_message/SKILL.md index ebd3d1d..2c8df99 100644 --- a/.vibe/skills/commit_message/SKILL.md +++ b/.vibe/skills/commit_message/SKILL.md @@ -1,16 +1,16 @@ --- name: commit_message -description: Helps create proper Gitmoji commit messages following the Common Gitmoji Reference from AGENTS.md. Use when creating commits to ensure consistent, visual commit messages. +description: Helps create proper Gitmoji commit messages following the Common Gitmoji Reference from AGENTS.md. Use when creating commits to ensure consistent, visual commit messages. Includes Git hooks for automatic code formatting and dependency management. license: MIT metadata: author: DanceLessonsCoach Team - version: "1.0.0" + version: "1.1.0" based-on: AGENTS.md Common Gitmoji Reference --- # Commit Message Skill -This skill helps create proper Gitmoji commit messages following the Common Gitmoji Reference from AGENTS.md. +This skill helps create proper Gitmoji commit messages following the Common Gitmoji Reference from AGENTS.md. It also includes Git hooks for automatic code formatting and dependency management. ## Gitmoji Reference @@ -80,6 +80,37 @@ git commit -m "๐Ÿ”ง chore: add log output file configuration" git commit -m "๐Ÿ”ง chore: update build system scripts" ``` +## Git Hooks for Code Quality + +The project includes Git hooks that automatically run before commits to ensure code quality: + +### Pre-commit Hook +- **Location**: `.git/hooks/pre-commit` +- **Automatically runs**: + - `go mod tidy` - Cleans up and organizes Go dependencies + - `go fmt` - Formats all Go code according to standards + - Auto-adds modified files to the commit + +### How It Works + +```bash +# When you commit: +git add . +git commit -m "โœจ feat: add new feature" + +# The hook automatically: +1. Runs `go mod tidy` +2. Runs `go fmt` on all Go files +3. Adds any modified files to your commit +4. Allows commit if successful +``` + +### Benefits +- Ensures consistent code formatting +- Maintains clean dependency management +- Prevents common Go code issues +- Runs automatically - no manual steps needed + ## Best Practices ### Commit Message Structure @@ -146,11 +177,84 @@ echo "$commit_message" | grep -E "^[๐ŸŽจโœจ๐Ÿ›๐Ÿ“๐Ÿ”งโ™ป๏ธ๐Ÿš€๐Ÿ”’๐Ÿ“ฆ๐Ÿ”ฅ | Missing colon | No colon after type | Add colon: `feat:` not `feat` | | Long first line | First line > 50 chars | Keep first line concise, add details in body | +## Git Hooks Reference + +### Hook Location +```bash +.git/hooks/pre-commit +``` + +### Hook Content +```bash +#!/bin/sh + +# DanceLessonsCoach pre-commit hook +# Runs go mod tidy and go fmt before allowing commits + +echo "Running pre-commit hooks..." + +# Check if we're in a Go project +if [ ! -f "go.mod" ]; then + echo "Not a Go project, skipping hooks" + exit 0 +fi + +# Run go mod tidy +echo "Running go mod tidy..." +go mod tidy +if [ $? -ne 0 ]; then + echo "ERROR: go mod tidy failed" + exit 1 +fi + +# Check if go.mod or go.sum were modified +if git diff --cached --name-only | grep -qE '(go\.mod|go\.sum)'; then + echo "go.mod or go.sum changed, adding to commit..." + git add go.mod go.sum +fi + +# Run go fmt on all Go files +echo "Running go fmt..." +GOFILES=$(find . -name '*.go' -not -path "./vendor/*" -not -path "./.git/*") +if [ -n "$GOFILES" ]; then + gofmt -w $GOFILES + if [ $? -ne 0 ]; then + echo "ERROR: go fmt failed" + exit 1 + fi + + # Add formatted files to commit + git add $GOFILES +fi + +echo "Pre-commit hooks completed successfully" +exit 0 +``` + +### Customization + +To modify the hook: +```bash +# Edit the hook +nano .git/hooks/pre-commit + +# Make it executable (if needed) +chmod +x .git/hooks/pre-commit +``` + +### Disabling Hooks + +To skip hooks for a single commit: +```bash +git commit --no-verify -m "โœจ feat: add new feature" +``` + ## References - [Gitmoji Official Site](https://gitmoji.dev) - [Common Gitmoji Reference in AGENTS.md](#common-gitmoji-reference) - [Conventional Commits](https://www.conventionalcommits.org/) +- [Git Hooks Documentation](https://git-scm.com/docs/githooks) ## Troubleshooting @@ -173,8 +277,37 @@ git commit -m "โœจ feat: add BDD framework" -m "- Implement Godog testing" -m "- git commit -m "โ™ป๏ธ refactor: improve BDD implementation" -m "- Update step patterns to match Godog exactly" -m "- Add JSON response validation" -m "- Implement server verification" -m "- Update all templates and documentation" ``` +### Git Hooks Issues + +**Hook fails with error:** +```bash +# Check the specific error message +# Fix the underlying issue (e.g., Go syntax error, dependency issue) +# Commit again +``` + +**Hook runs too slow:** +```bash +# The hooks are optimized to only process necessary files +# If performance is an issue, check for very large Go files +# Consider splitting large files into smaller modules +``` + +**Need to bypass hooks temporarily:** +```bash +# Use --no-verify flag +git commit --no-verify -m "โšก chore: quick fix" + +# Remember to run hooks manually later +go mod tidy +gofmt -w . +``` + ## Assets - **gitmoji-cheatsheet.md**: Quick reference for common gitmoji - **commit-template.txt**: Git commit message template -- **validate-commit.sh**: Commit message validation script \ No newline at end of file +- **validate-commit.sh**: Commit message validation script +- **git-hooks/**: Git hooks for automatic code quality + - **pre-commit**: Hook that runs `go mod tidy` and `go fmt` + - **README.md**: Documentation for Git hooks \ No newline at end of file diff --git a/.vibe/skills/commit_message/assets/git-hooks/README.md b/.vibe/skills/commit_message/assets/git-hooks/README.md new file mode 100644 index 0000000..dcb9027 --- /dev/null +++ b/.vibe/skills/commit_message/assets/git-hooks/README.md @@ -0,0 +1,67 @@ +# Git Hooks for DanceLessonsCoach + +This directory contains Git hooks for the DanceLessonsCoach project. + +## Available Hooks + +### pre-commit +- **Location**: `.git/hooks/pre-commit` +- **Purpose**: Automatically runs `go mod tidy` and `go fmt` before commits +- **Features**: + - Runs `go mod tidy` to clean up dependencies + - Automatically adds modified `go.mod` and `go.sum` to commit + - Runs `go fmt` on all Go files (excluding vendor and .git directories) + - Automatically adds formatted files to commit + - Only runs if in a Go project (checks for `go.mod`) + +## Installation + +The pre-commit hook is already installed and executable. No additional setup required. + +## Usage + +The hooks run automatically when you commit: + +```bash +git add . +git commit -m "โœจ feat: add new feature" +``` + +The hook will: +1. Run `go mod tidy` +2. Run `go fmt` on all Go files +3. Add any modified files to your commit +4. Allow the commit to proceed if successful + +## Customization + +To modify the hooks: +1. Edit the hook file in `.git/hooks/` +2. Make it executable: `chmod +x .git/hooks/hook-name` + +## Disabling Hooks + +To temporarily disable hooks: + +```bash +# Skip pre-commit hook for one commit +git commit --no-verify -m "โœจ feat: add new feature" +``` + +## Best Practices + +- Let the hooks run automatically - they ensure code quality +- The hooks only modify files that need changes +- All changes are added to your commit automatically +- Hooks run quickly and prevent common issues + +## Troubleshooting + +If a hook fails: +- Check the error message +- Fix the issue manually +- Commit again + +Common issues: +- `go mod tidy` fails: Check your Go module dependencies +- `go fmt` fails: Check for syntax errors in your Go code \ No newline at end of file diff --git a/.vibe/skills/commit_message/assets/git-hooks/pre-commit b/.vibe/skills/commit_message/assets/git-hooks/pre-commit new file mode 100755 index 0000000..f9739fb --- /dev/null +++ b/.vibe/skills/commit_message/assets/git-hooks/pre-commit @@ -0,0 +1,43 @@ +#!/bin/sh + +# DanceLessonsCoach pre-commit hook +# Runs go mod tidy and go fmt before allowing commits + +echo "Running pre-commit hooks..." + +# Check if we're in a Go project +if [ ! -f "go.mod" ]; then + echo "Not a Go project, skipping hooks" + exit 0 +fi + +# Run go mod tidy +echo "Running go mod tidy..." +go mod tidy +if [ $? -ne 0 ]; then + echo "ERROR: go mod tidy failed" + exit 1 +fi + +# Check if go.mod or go.sum were modified +if git diff --cached --name-only | grep -qE '(go\.mod|go\.sum)'; then + echo "go.mod or go.sum changed, adding to commit..." + git add go.mod go.sum +fi + +# Run go fmt on all Go files +echo "Running go fmt..." +GOFILES=$(find . -name '*.go' -not -path "./vendor/*" -not -path "./.git/*") +if [ -n "$GOFILES" ]; then + gofmt -w $GOFILES + if [ $? -ne 0 ]; then + echo "ERROR: go fmt failed" + exit 1 + fi + + # Add formatted files to commit + git add $GOFILES +fi + +echo "Pre-commit hooks completed successfully" +exit 0 \ No newline at end of file diff --git a/adr/0012-git-hooks-staged-only-formatting.md b/adr/0012-git-hooks-staged-only-formatting.md new file mode 100644 index 0000000..55b0d7c --- /dev/null +++ b/adr/0012-git-hooks-staged-only-formatting.md @@ -0,0 +1,125 @@ +# 12. Git Hooks: Staged-Only Formatting + +**Date:** 2026-04-05 +**Status:** Accepted +**Authors:** DanceLessonsCoach Team + +## Context + +The DanceLessonsCoach project implemented Git hooks to automatically run `go fmt` and `go mod tidy` before commits. Initially, the `go fmt` hook was configured to format **all Go files** in the repository, regardless of their staged status. + +During implementation review, concerns were raised about this approach: + +1. **Scope**: Formatting all files could modify files not intended for the current commit +2. **Control**: Developers might want to commit specific changes without auto-formatting unrelated files +3. **Safety**: Risk of accidentally including unintended changes in commits +4. **Performance**: Unnecessary processing of files not being committed + +## Decision + +Modify the Git pre-commit hook to format **only staged Go files** instead of all Go files in the repository. + +### Implementation + +```bash +# Old approach (formats ALL Go files): +GOFILES=$(find . -name '*.go' -not -path "./vendor/*" -not -path "./.git/*") + +# New approach (formats only STAGED Go files): +STAGED_GOFILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.go$') +``` + +## Consequences + +### Positive + +1. **Precision**: Only formats files explicitly staged for commit +2. **Developer Control**: Respects the developer's intent about which files to include +3. **Safety**: Eliminates risk of accidentally modifying/committing unstaged files +4. **Performance**: Faster execution for large projects (only processes relevant files) +5. **Predictability**: Behavior matches developer expectations + +### Negative + +1. **Partial Formatting**: Unstaged files remain unformatted (could lead to formatting drift) +2. **Manual Intervention**: Developers must remember to format files before staging +3. **Inconsistency Risk**: Different parts of codebase could have different formatting + +### Mitigations + +1. **Documentation**: Clear documentation explaining the staged-only behavior +2. **Developer Training**: Educate team on the importance of staging all files needing formatting +3. **Pre-push Hook**: Consider adding a pre-push hook that checks entire codebase formatting +4. **CI/CD Check**: Maintain CI/CD formatting validation as a safety net + +## Alternatives Considered + +### Alternative 1: Format All Files (Original Approach) +**Pros**: Ensures whole project consistency +**Cons**: Lack of control, potential unintended changes +**Rejected**: Due to developer preference for explicit control + +### Alternative 2: Format Changed Files (Staged + Unstaged) +```bash +CHANGED_GOFILES=$(git diff --name-only | grep '\.go$') +STAGED_GOFILES=$(git diff --cached --name-only | grep '\.go$') +ALL_CHANGED=$(echo "$CHANGED_GOFILES\n$STAGED_GOFILES" | sort -u) +``` +**Pros**: Catches more formatting issues +**Cons**: Still modifies files not explicitly staged +**Rejected**: Doesn't respect staging intent + +### Alternative 3: No Auto-Formatting +**Pros**: Maximum developer control +**Cons**: Inconsistent formatting, manual burden +**Rejected**: Loses automation benefits + +## Verification + +### Test Results + +Created test scenario with: +- `test_staged.go`: Staged file with poor formatting +- `test_unstaged.go`: Unstaged file with poor formatting + +**Results**: +- โœ… Staged file was formatted by hook +- โœ… Unstaged file remained unformatted +- โœ… Hook completed successfully + +### Command Output +```bash +$ git add test_staged.go +$ git commit -m "test" +Running pre-commit hooks... +Running go mod tidy... +Running go fmt on staged files... +Pre-commit hooks completed successfully +``` + +## Related Decisions + +- [ADR-0003: Zerolog Logging](adr/0003-zerolog-logging.md) - Project quality standards +- [ADR-0004: Interface-Based Design](adr/0004-interface-based-design.md) - Code organization +- [ADR-0010: API v2 Feature Flag](adr/0010-api-v2-feature-flag.md) - Feature management + +## Future Considerations + +1. **Monitor Impact**: Track if staged-only formatting leads to formatting drift +2. **Developer Feedback**: Gather team input on the new behavior +3. **CI/CD Enhancement**: Consider adding formatting validation in CI/CD pipeline +4. **Editor Integration**: Document recommended editor settings for auto-formatting + +## Revision History + +- **1.0 (2026-04-05)**: Initial decision +- **1.1 (2026-04-05)**: Added verification results and alternatives analysis + +## References + +- [Git Hooks Documentation](https://git-scm.com/docs/githooks) +- [Go Formatting Standards](https://golang.org/doc/effective_go.html#formatting) +- [Commit Message Skill with Hooks](.vibe/skills/commit_message/SKILL.md) + +**Approved by:** DanceLessonsCoach Team +**Effective Date:** 2026-04-05 \ No newline at end of file diff --git a/adr/README.md b/adr/README.md index f9d5f21..99d8397 100644 --- a/adr/README.md +++ b/adr/README.md @@ -70,6 +70,7 @@ Chosen option: "[Option 1]" because [justification] * [0009-hybrid-testing-approach.md](0009-hybrid-testing-approach.md) - Combine BDD and Swagger-based testing * [0010-api-v2-feature-flag.md](0010-api-v2-feature-flag.md) - API v2 implementation with feature flag control * [0011-validation-library-selection.md](0011-validation-library-selection.md) - Selection of go-playground/validator for input validation +* [0012-git-hooks-staged-only-formatting.md](0012-git-hooks-staged-only-formatting.md) - Git hooks format only staged Go files ## How to Add a New ADR diff --git a/features/bdd_test.go b/features/bdd_test.go index 0adda6f..4a655a8 100644 --- a/features/bdd_test.go +++ b/features/bdd_test.go @@ -11,7 +11,7 @@ func TestBDD(t *testing.T) { suite := godog.TestSuite{ Name: "DanceLessonsCoach BDD Tests", TestSuiteInitializer: bdd.InitializeTestSuite, - ScenarioInitializer: bdd.InitializeScenario, + ScenarioInitializer: bdd.InitializeScenario, Options: &godog.Options{ Format: "progress", Paths: []string{"."}, @@ -22,4 +22,4 @@ func TestBDD(t *testing.T) { if suite.Run() != 0 { t.Fatal("non-zero status returned, failed to run BDD tests") } -} \ No newline at end of file +} diff --git a/pkg/bdd/steps/steps.go b/pkg/bdd/steps/steps.go index 19770e6..afbe0d9 100644 --- a/pkg/bdd/steps/steps.go +++ b/pkg/bdd/steps/steps.go @@ -48,14 +48,14 @@ func (sc *StepContext) iRequestTheHealthEndpoint() error { func (sc *StepContext) theResponseShouldBe(arg1, arg2 string) error { // The regex captures the full JSON from the feature file, including quotes // We need to extract just the key and value without the surrounding quotes and backslashes - + // Remove the surrounding quotes and backslashes cleanArg1 := strings.Trim(arg1, `"\`) cleanArg2 := strings.Trim(arg2, `"\`) - + // Build the expected JSON string expected := fmt.Sprintf(`{"%s":"%s"}`, cleanArg1, cleanArg2) - + return sc.client.ExpectResponseBody(expected) } @@ -70,7 +70,7 @@ func (sc *StepContext) theServerIsRunningWithV2Enabled() error { if err := sc.client.Request("GET", "/api/ready", nil); err != nil { return err } - + // Check if v2 endpoint is available (should return 405 Method Not Allowed for GET, which means endpoint exists) // If v2 is disabled, this will return 404 resp, err := sc.client.CustomRequest("GET", "/api/v2/greet", nil) @@ -78,13 +78,13 @@ func (sc *StepContext) theServerIsRunningWithV2Enabled() error { return err } defer resp.Body.Close() - + // If we get 405, v2 is enabled (endpoint exists but doesn't allow GET) // If we get 404, v2 is disabled if resp.StatusCode == 404 { return fmt.Errorf("v2 endpoint not available - v2 feature flag not enabled") } - + return nil } diff --git a/pkg/bdd/testserver/client.go b/pkg/bdd/testserver/client.go index 67e478f..fec68e1 100644 --- a/pkg/bdd/testserver/client.go +++ b/pkg/bdd/testserver/client.go @@ -23,7 +23,7 @@ func NewClient(server *Server) *Client { func (c *Client) Request(method, path string, body interface{}) error { url := c.server.GetBaseURL() + path - + var reqBody io.Reader if body != nil { // Handle different body types @@ -42,12 +42,12 @@ func (c *Client) Request(method, path string, body interface{}) error { return fmt.Errorf("unsupported body type: %T", body) } } - + req, err := http.NewRequest(method, url, reqBody) if err != nil { return fmt.Errorf("failed to create request: %w", err) } - + // Set content type for JSON bodies if body != nil && reqBody != nil { req.Header.Set("Content-Type", "application/json") @@ -70,7 +70,7 @@ func (c *Client) Request(method, path string, body interface{}) error { func (c *Client) CustomRequest(method, path string, body interface{}) (*http.Response, error) { url := c.server.GetBaseURL() + path - + var reqBody io.Reader if body != nil { // Handle different body types @@ -89,12 +89,12 @@ func (c *Client) CustomRequest(method, path string, body interface{}) (*http.Res return nil, fmt.Errorf("unsupported body type: %T", body) } } - + req, err := http.NewRequest(method, url, reqBody) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } - + // Set content type for JSON bodies if body != nil && reqBody != nil { req.Header.Set("Content-Type", "application/json") @@ -104,7 +104,7 @@ func (c *Client) CustomRequest(method, path string, body interface{}) (*http.Res if err != nil { return nil, fmt.Errorf("request failed: %w", err) } - + // Don't close the body here - let the caller handle it c.lastResp = resp c.lastBody, err = io.ReadAll(resp.Body) @@ -123,7 +123,7 @@ func (c *Client) ExpectResponseBody(expected string) error { actual := string(c.lastBody) // Trim trailing newline if present (common in JSON responses) actual = strings.TrimSuffix(actual, "\n") - + if actual != expected { return fmt.Errorf("expected response body %q, got %q", expected, actual) } diff --git a/pkg/bdd/testserver/server.go b/pkg/bdd/testserver/server.go index 3b594cf..3091339 100644 --- a/pkg/bdd/testserver/server.go +++ b/pkg/bdd/testserver/server.go @@ -12,7 +12,7 @@ import ( ) type Server struct { - httpServer *http.Server + httpServer *http.Server port int baseURL string } @@ -94,8 +94,8 @@ func createTestConfig(port int) *config.Config { Timeout: 5 * time.Second, }, Logging: config.LoggingConfig{ - JSON: false, - Level: "trace", + JSON: false, + Level: "trace", }, Telemetry: config.TelemetryConfig{ Enabled: false, diff --git a/pkg/config/config.go b/pkg/config/config.go index 93ddce9..7c93c67 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -33,9 +33,9 @@ type ShutdownConfig struct { // LoggingConfig holds logging-related configuration type LoggingConfig struct { - JSON bool `mapstructure:"json"` - Level string `mapstructure:"level"` - Output string `mapstructure:"output"` + JSON bool `mapstructure:"json"` + Level string `mapstructure:"level"` + Output string `mapstructure:"output"` } // TelemetryConfig holds OpenTelemetry-related configuration @@ -63,7 +63,7 @@ type SamplerConfig struct { // To specify a custom config file path, set DLC_CONFIG_FILE environment variable func LoadConfig() (*Config, error) { v := viper.New() - + // Set up initial console logging for config loading messages consoleWriter := zerolog.ConsoleWriter{Out: os.Stderr} log.Logger = log.Output(consoleWriter) @@ -221,7 +221,7 @@ func (c *Config) SetupLogging() { // Setup log output c.setupLogOutput() - + zerolog.TimeFieldFormat = zerolog.TimeFormatUnix } @@ -255,14 +255,14 @@ func (c *Config) setupLogOutput() { // Use stderr by default return } - + // Open the log file file, err := os.OpenFile(output, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { log.Error().Err(err).Str("output", output).Msg("Failed to open log file, using stderr") return } - + // Set the log output log.Logger = log.Output(file) log.Trace().Str("output", output).Msg("Logging to file") diff --git a/pkg/greet/api_v2.go b/pkg/greet/api_v2.go index 5ea9576..f146c86 100644 --- a/pkg/greet/api_v2.go +++ b/pkg/greet/api_v2.go @@ -4,9 +4,9 @@ import ( "context" "encoding/json" "errors" - "strconv" "io" "net/http" + "strconv" "DanceLessonsCoach/pkg/validation" "github.com/go-chi/chi/v5" @@ -22,7 +22,7 @@ type ApiV2Greet interface { } type apiV2GreetHandler struct { - greeter GreeterV2 + greeter GreeterV2 validator *validation.Validator } @@ -108,4 +108,4 @@ func (h *apiV2GreetHandler) handleValidationError(w http.ResponseWriter, err err func (h *apiV2GreetHandler) writeJSONResponse(w http.ResponseWriter, message string) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(greetResponse{Message: message}) -} \ No newline at end of file +} diff --git a/pkg/greet/greet.go b/pkg/greet/greet.go index 4b68b80..d750840 100644 --- a/pkg/greet/greet.go +++ b/pkg/greet/greet.go @@ -21,4 +21,4 @@ func (s *Service) Greet(ctx context.Context, name string) string { return "Hello world!" } return "Hello " + name + "!" -} \ No newline at end of file +} diff --git a/pkg/greet/greet_v2.go b/pkg/greet/greet_v2.go index 8773e60..8ed0786 100644 --- a/pkg/greet/greet_v2.go +++ b/pkg/greet/greet_v2.go @@ -21,4 +21,4 @@ func (s *ServiceV2) GreetV2(ctx context.Context, name string) string { return "Hello my friend!" } return "Hello my friend " + name + "!" -} \ No newline at end of file +} diff --git a/pkg/greet/greet_v2_test.go b/pkg/greet/greet_v2_test.go index 65670df..5a9b6d5 100644 --- a/pkg/greet/greet_v2_test.go +++ b/pkg/greet/greet_v2_test.go @@ -25,4 +25,4 @@ func TestServiceV2_GreetV2(t *testing.T) { } }) } -} \ No newline at end of file +} diff --git a/pkg/server/server.go b/pkg/server/server.go index 4de2f5e..8df5533 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -10,8 +10,8 @@ import ( "DanceLessonsCoach/pkg/config" "DanceLessonsCoach/pkg/greet" - "DanceLessonsCoach/pkg/validation" "DanceLessonsCoach/pkg/telemetry" + "DanceLessonsCoach/pkg/validation" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" sdktrace "go.opentelemetry.io/otel/sdk/trace" diff --git a/pkg/validation/validator.go b/pkg/validation/validator.go index 96b6f4a..e55d2d0 100644 --- a/pkg/validation/validator.go +++ b/pkg/validation/validator.go @@ -8,9 +8,9 @@ import ( "strings" "github.com/go-playground/locales/en" - en_translations "github.com/go-playground/validator/v10/translations/en" - "github.com/go-playground/validator/v10" ut "github.com/go-playground/universal-translator" + "github.com/go-playground/validator/v10" + en_translations "github.com/go-playground/validator/v10/translations/en" ) // Validator wraps the go-playground/validator with custom error handling @@ -82,7 +82,7 @@ func (v *Validator) formatValidationErrors(errors validator.ValidationErrors) er // Get custom error message message := fmt.Errorf("%s failed validation for '%s'", field, tag).Error() - + // Add parameter if available if param != "" { message += fmt.Sprintf(" (parameter: %s)", param) @@ -120,4 +120,4 @@ func GetValidatorFromConfig(cfg *config.Config) (*Validator, error) { // For now, config doesn't affect validator creation // But this allows future configuration (e.g., language, strict mode) return NewValidator() -} \ No newline at end of file +}