Skip to content

Commit 7dafe80

Browse files
committed
Update README with detailed usage, features, and examples
Expanded the README to include comprehensive documentation, such as features, installation instructions, advanced configuration, use cases, testing guidelines, and comparison with similar libraries. This improves accessibility and usability for developers using the GoEnv library.
1 parent e86a6f4 commit 7dafe80

1 file changed

Lines changed: 345 additions & 12 deletions

File tree

README.md

Lines changed: 345 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,366 @@
1-
# Go env
1+
# GoEnv
22

3-
A lightweight Go package that loads environment variables from an .env file, which can be located anywhere within the
4-
project's structure.
3+
A lightweight, intelligent Go library for loading environment variables from `.env` files with advanced features and robust error handling.
54

6-
This package has no external dependencies.
5+
[![Go Version](https://img.shields.io/badge/Go-%3E%3D%201.19-blue.svg)](https://golang.org/)
6+
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
7+
[![Go Report Card](https://goreportcard.com/badge/github.com/raiesbo/goenv)](https://goreportcard.com/report/github.com/raiesbo/goenv)
78

8-
## Install
9+
## Features
910

10-
```shell
11+
- **Smart Discovery**: Recursively searches directories for `.env` files
12+
- **Flexible Configuration**: Support for multiple file patterns and loading strategies
13+
- **Type Safety**: Built-in converters for strings, integers, floats, and booleans
14+
- **Quoted Values**: Handles single and double-quoted strings with spaces
15+
- **Cycle Detection**: Prevents infinite loops with symbolic links
16+
- **Depth Limiting**: Configurable search depth for performance
17+
- **Error Context**: Detailed error messages with file and line information
18+
- **Zero Dependencies**: Pure Go implementation with no external dependencies
19+
20+
## Quick Start
21+
22+
### Installation
23+
24+
```bash
1125
go get github.com/raiesbo/goenv
1226
```
1327

14-
## Examples
28+
### Basic Usage
29+
30+
Create a `.env` file in your project:
31+
32+
```env
33+
# Database configuration
34+
DB_HOST=localhost
35+
DB_PORT=5432
36+
DB_NAME=myapp
37+
DB_SSL=true
38+
39+
# API settings
40+
API_KEY="your-secret-api-key"
41+
API_TIMEOUT=30
42+
DEBUG_MODE=false
43+
44+
# Complex values with quotes
45+
MESSAGE='Hello, World!'
46+
DESCRIPTION="This is a quoted string with spaces"
47+
```
1548

16-
As easy as:
49+
Load and use environment variables in your Go application:
1750

1851
```go
1952
package main
2053

2154
import (
22-
"goenv"
55+
"fmt"
56+
"log"
57+
58+
"github.com/raiesbo/goenv"
2359
)
2460

2561
func main() {
62+
// Load .env file automatically
2663
if err := goenv.Load(); err != nil {
27-
panic(err)
64+
log.Fatal("Error loading .env file:", err)
65+
}
66+
67+
// Get values with type conversion and fallbacks
68+
dbHost := goenv.GetString("DB_HOST", "localhost")
69+
dbPort := goenv.GetInt("DB_PORT", 3306)
70+
sslEnabled := goenv.GetBool("DB_SSL", false)
71+
timeout := goenv.GetFloat("API_TIMEOUT", 10.0)
72+
73+
fmt.Printf("Connecting to %s:%d (SSL: %v)\n", dbHost, dbPort, sslEnabled)
74+
fmt.Printf("API timeout: %.1fs\n", timeout)
75+
76+
// Get required variables (panics if not found)
77+
apiKey := goenv.MustGetString("API_KEY")
78+
fmt.Printf("API Key loaded: %s...\n", apiKey[:8])
79+
}
80+
```
81+
82+
## Advanced Configuration
83+
84+
### Custom Configuration
85+
86+
```go
87+
package main
88+
89+
import (
90+
"log"
91+
"github.com/raiesbo/goenv"
92+
)
93+
94+
func main() {
95+
config := &goenv.Config{
96+
EnvFiles: []string{".env", ".env.local", ".env.production"},
97+
MaxDepth: 5,
98+
StopOnFirst: false, // Load all matching files
99+
}
100+
101+
if err := goenv.LoadWithConfig(config); err != nil {
102+
log.Fatal("Failed to load environment:", err)
28103
}
104+
}
105+
```
106+
107+
### Loading Specific Files
108+
109+
```go
110+
// Load a specific .env file
111+
if err := goenv.LoadFile(".env.production"); err != nil {
112+
log.Fatal("Failed to load production config:", err)
113+
}
114+
```
115+
116+
### Environment-Specific Loading
117+
118+
```go
119+
package main
120+
121+
import (
122+
"os"
123+
"github.com/raiesbo/goenv"
124+
)
125+
126+
func main() {
127+
env := os.Getenv("GO_ENV")
128+
if env == "" {
129+
env = "development"
130+
}
131+
132+
config := &goenv.Config{
133+
EnvFiles: []string{".env", ".env." + env},
134+
StopOnFirst: false, // Load both base and environment-specific
135+
}
136+
137+
goenv.LoadWithConfig(config)
138+
}
139+
```
140+
141+
## Supported File Formats
142+
143+
GoEnv supports various `.env` file formats:
144+
145+
```env
146+
# Comments are supported
147+
# Empty lines are ignored
148+
149+
# Basic key-value pairs
150+
DATABASE_URL=postgres://localhost/mydb
151+
PORT=8080
152+
153+
# Quoted strings (single or double quotes)
154+
SECRET_KEY="my-secret-key-with-spaces"
155+
MESSAGE='Hello, "World"!'
156+
157+
# Boolean values
158+
DEBUG=true
159+
PRODUCTION=false
160+
161+
# Numeric values
162+
MAX_CONNECTIONS=100
163+
TIMEOUT=30.5
164+
165+
# Empty values
166+
OPTIONAL_CONFIG=
167+
```
168+
169+
## API Reference
170+
171+
### Loading Functions
172+
173+
| Function | Description |
174+
|----------|-------------|
175+
| `Load()` | Load `.env` file using default configuration |
176+
| `LoadWithConfig(config *Config)` | Load with custom configuration |
177+
| `LoadFile(path string)` | Load a specific file |
178+
179+
### Type Conversion Functions
180+
181+
| Function | Description | Example |
182+
|----------|-------------|---------|
183+
| `GetString(key, fallback string)` | Get string value | `GetString("API_URL", "http://localhost")` |
184+
| `GetInt(key string, fallback int)` | Get integer value | `GetInt("PORT", 8080)` |
185+
| `GetBool(key string, fallback bool)` | Get boolean value | `GetBool("DEBUG", false)` |
186+
| `GetFloat(key string, fallback float64)` | Get float value | `GetFloat("RATE", 1.5)` |
187+
| `MustGetString(key string)` | Get required string (panics if missing) | `MustGetString("DATABASE_URL")` |
188+
189+
### Configuration Options
190+
191+
```go
192+
type Config struct {
193+
EnvFiles []string // File patterns to search for
194+
MaxDepth int // Maximum directory depth to search
195+
StopOnFirst bool // Stop after finding first file
196+
}
197+
```
198+
199+
## Use Cases
200+
201+
### Web Applications
202+
203+
```go
204+
package main
205+
206+
import (
207+
"fmt"
208+
"net/http"
209+
"github.com/raiesbo/goenv"
210+
)
211+
212+
func main() {
213+
goenv.Load()
214+
215+
port := goenv.GetString("PORT", "8080")
216+
dbURL := goenv.MustGetString("DATABASE_URL")
29217

30-
// After loading, the environment variables are ready to be used.
31-
// Example: addr := os.Getenv("ADDR")
218+
fmt.Printf("Starting server on port %s\n", port)
219+
fmt.Printf("Database: %s\n", dbURL)
220+
221+
http.ListenAndServe(":" + port, nil)
222+
}
223+
```
224+
225+
### Microservices Configuration
226+
227+
```go
228+
type Config struct {
229+
ServiceName string
230+
Port int
231+
DatabaseURL string
232+
RedisURL string
233+
LogLevel string
234+
Debug bool
235+
}
236+
237+
func LoadConfig() *Config {
238+
goenv.Load()
239+
240+
return &Config{
241+
ServiceName: goenv.GetString("SERVICE_NAME", "unknown"),
242+
Port: goenv.GetInt("PORT", 8080),
243+
DatabaseURL: goenv.MustGetString("DATABASE_URL"),
244+
RedisURL: goenv.GetString("REDIS_URL", "redis://localhost:6379"),
245+
LogLevel: goenv.GetString("LOG_LEVEL", "info"),
246+
Debug: goenv.GetBool("DEBUG", false),
247+
}
32248
}
33249
```
250+
251+
### Docker Integration
252+
253+
```dockerfile
254+
# Dockerfile
255+
FROM golang:1.21-alpine
256+
WORKDIR /app
257+
COPY . .
258+
RUN go build -o myapp
259+
260+
# Use .env file in development
261+
CMD ["./myapp"]
262+
```
263+
264+
```yaml
265+
# docker-compose.yml
266+
version: '3.8'
267+
services:
268+
app:
269+
build: .
270+
env_file:
271+
- .env
272+
- .env.local
273+
ports:
274+
- "${PORT:-8080}:8080"
275+
```
276+
277+
## Testing
278+
279+
GoEnv includes comprehensive tests covering all functionality:
280+
281+
```bash
282+
# Run tests
283+
go test -v
284+
285+
# Run tests with coverage
286+
go test -cover
287+
288+
# Run benchmarks
289+
go test -bench=.
290+
```
291+
292+
## Error Handling
293+
294+
GoEnv provides detailed error messages for debugging:
295+
296+
```go
297+
if err := goenv.Load(); err != nil {
298+
// Errors include file path and line numbers
299+
fmt.Printf("Failed to load .env: %v\n", err)
300+
// Example: "invalid format in /path/.env at line 5: INVALID_LINE"
301+
}
302+
```
303+
304+
## Comparison with Other Libraries
305+
306+
| Feature | GoEnv | godotenv | viper |
307+
|---------|-------|----------|-------|
308+
| File Discovery | ✅ Recursive | ❌ Manual path | ✅ Multiple sources |
309+
| Type Conversion | ✅ Built-in | ❌ Manual | ✅ Comprehensive |
310+
| Quoted Strings | ✅ Yes | ✅ Yes | ✅ Yes |
311+
| Error Context | ✅ Detailed | ❌ Basic | ✅ Good |
312+
| Zero Dependencies | ✅ Yes | ✅ Yes | ❌ Many deps |
313+
| Configuration | ✅ Flexible | ❌ Limited | ✅ Extensive |
314+
| Performance | ✅ Fast | ✅ Fast | ⚠️ Moderate |
315+
316+
## Best Practices
317+
318+
1. **Environment-Specific Files**: Use `.env.development`, `.env.production`, etc.
319+
2. **Never Commit Secrets**: Add `.env*` to your `.gitignore`
320+
3. **Provide Fallbacks**: Always use fallback values for non-critical settings
321+
4. **Validate Required Variables**: Use `MustGetString()` for essential configuration
322+
5. **Document Variables**: Create a `.env.example` file with all required variables
323+
324+
### Example `.env.example`
325+
326+
```env
327+
# Database Configuration
328+
DATABASE_URL=postgres://username:password@localhost:5432/dbname
329+
330+
# API Keys
331+
API_KEY=your-api-key-here
332+
SECRET_KEY=your-secret-key-here
333+
334+
# Application Settings
335+
PORT=8080
336+
DEBUG=false
337+
LOG_LEVEL=info
338+
339+
# External Services
340+
REDIS_URL=redis://localhost:6379
341+
SMTP_HOST=smtp.example.com
342+
SMTP_PORT=587
343+
```
344+
345+
## 🤝 Contributing
346+
347+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
348+
349+
1. Fork the repository
350+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
351+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
352+
4. Push to the branch (`git push origin feature/amazing-feature`)
353+
5. Open a Pull Request
354+
355+
## 📄 License
356+
357+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
358+
359+
## 🙏 Acknowledgments
360+
361+
- Inspired by the Node.js [dotenv](https://github.com/motdotla/dotenv) library
362+
- Thanks to the Go community for feedback and contributions
363+
364+
---
365+
366+
**GoEnv** - Making environment configuration simple and reliable for Go applications.

0 commit comments

Comments
 (0)