# Quickstart: Safety, Reliability & Idiomatic Refactor **Feature Branch**: `001-safety-reliability-refactor` **Date**: 2026-03-03 ## Prerequisites - **Go 1.20** toolchain installed (must be exactly 1.20.x, not newer) - Administrator/root privileges (required to write the hosts file) - Git ## Setup ```bash # Clone and switch to feature branch git checkout 001-safety-reliability-refactor # Verify Go version go version # Expected: go version go1.20.x ... # Download dependencies go mod download # Run all tests go test ./... # Build go build -o dns-helper . ``` ## Project Structure After Refactor ``` dns-helper/ ├── main.go # Entry point, CLI parsing, os.Exit ├── resolver/ │ ├── resolver.go # DNS resolution via golang.org/x/net/dns/dnsmessage │ └── resolver_test.go ├── hostfile/ │ ├── hostfile.go # Hosts file read/write (atomic pattern) │ ├── hostfile_test.go │ ├── managed.go # Managed block parsing, add, remove │ └── managed_test.go ├── platform/ │ ├── platform.go # Interface definition │ ├── platform_windows.go # Windows hosts file path │ ├── platform_linux.go # Linux hosts file path │ ├── platform_darwin.go # macOS hosts file path │ └── platform_test.go ├── lockfile/ │ ├── lockfile.go # Lock file acquisition/release │ └── lockfile_test.go ├── go.mod # go 1.20, golang.org/x/net v0.35.0 └── go.sum ``` ## Key Implementation Patterns ### TDD Workflow (Constitution Principle VI) Every change follows Red-Green-Refactor: 1. **Red**: Write a failing test that specifies the desired behavior. 2. **Green**: Write the minimum code to make the test pass. 3. **Refactor**: Clean up while keeping tests green. ```bash # Run tests for a specific package go test ./resolver/ go test ./hostfile/ go test ./lockfile/ # Run all tests go test ./... ``` ### Error Handling (Constitution Principle IV) All functions return errors. Only `main()` calls `os.Exit()`: ```go // WRONG — do not do this in any package func doSomething() { if err != nil { fmt.Println(err) os.Exit(1) // PROHIBITED outside main() } } // CORRECT — return errors to caller func doSomething() error { if err != nil { return fmt.Errorf("doing something: %w", err) } return nil } ``` ### Testable Interfaces (Constitution Principle VI) Functions that interact with filesystem or DNS accept interfaces: ```go // Production: uses real OS calls manager := hostfile.NewManager(hostfile.NewOSFileSystem()) // Test: uses in-memory fake manager := hostfile.NewManager(fakeFS) ``` ### Atomic Write Sequence ``` 1. Backup: copy hosts → /hosts.bak.- 2. Write: assemble content → temp file (same dir as hosts) 3. Sync: temp.Sync() 4. Chmod: match original permissions 5. Close: temp.Close() 6. Rename: os.Rename(temp, hosts) [retry on Windows] 7. Clean: delete backup on success ``` ## Usage Examples ```bash # Add DNS entries dns-helper add -host myapp.example.com -server 10.0.0.53 # Add multiple hosts dns-helper add -host host1.example.com,host2.example.com -server dns.internal # Delete specific host entries dns-helper delete -host myapp.example.com # Delete all managed entries dns-helper delete all ``` ## Build for All Platforms ```bash # Windows GOOS=windows GOARCH=amd64 go build -o bin/windows/dns-helper.exe . # Linux GOOS=linux GOARCH=amd64 go build -o bin/linux/dns-helper . # macOS GOOS=darwin GOARCH=amd64 go build -o bin/macos/dns-helper . ``` ## Dependency Management ```bash # After removing miekg/dns and adding dnsmessage usage: go mod tidy # Verify no unapproved dependencies go list -m all # Should only show: golang.org/x/net, golang.org/x/sys (transitive) ```