Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
# 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 → <exe-dir>/hosts.bak.<date>-<rand>
|
||||
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)
|
||||
```
|
||||
Reference in New Issue
Block a user