Skip to content

Commit bec759d

Browse files
committed
feat!: go sdk v2
Signed-off-by: Roman Dmytrenko <rdmytrenko@gmail.com>
1 parent 1972034 commit bec759d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+3990
-4878
lines changed

AGENTS.md

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
# AGENTS.md - OpenFeature Go SDK
2+
3+
This document provides guidelines for agents working on this codebase.
4+
5+
## Build Commands
6+
7+
```bash
8+
# Run unit tests (short mode, skips slow e2e tests)
9+
make test
10+
# Equivalent: go test --short -tags testtools -cover -timeout 1m ./...
11+
12+
# Run end-to-end tests (includes e2e tests with race detection)
13+
make e2e-test
14+
# Equivalent: git submodule update --init --recursive && go test -tags testtools -race -cover -timeout 1m ./e2e/...
15+
16+
# Run linter
17+
make lint
18+
# Equivalent: golangci-lint run ./...
19+
20+
# Auto-fix linting issues
21+
make fix
22+
# Equivalent: golangci-lint run ./... --fix
23+
24+
# Generate mocks (requires mockgen)
25+
make mockgen
26+
27+
# Generate API documentation
28+
make docs
29+
```
30+
31+
### Running a Single Test
32+
33+
```bash
34+
# Run specific test in current package
35+
go test -tags testtools -run TestMyFunction ./...
36+
37+
# Run test in specific file/package
38+
go test -tags testtools -run TestMyFunction ./path/to/package/...
39+
40+
# Run with verbose output
41+
go test -tags testtools -v -run TestMyFunction ./...
42+
```
43+
44+
## Developer Certificate of Origin (DCO)
45+
46+
This project requires all commits to include a Signed-off-by line to certify adherence to the [Developer Certificate of Origin](https://developercertificate.org/).
47+
48+
### Signing Off Commits
49+
50+
Add the `-s` flag to your commit command:
51+
52+
```bash
53+
git commit -s -m "your commit message"
54+
```
55+
56+
This adds a line like `Signed-off-by: Name <email@example.com>` to your commit message.
57+
58+
### Amending to Add DCO
59+
60+
If you forgot to sign off a commit:
61+
62+
```bash
63+
git commit --amend -s
64+
```
65+
66+
### Verifying DCO Status
67+
68+
Check if your commits are signed:
69+
70+
```bash
71+
git log --pretty=format:%H,%s | head -5
72+
```
73+
74+
Or use the DCO bot to check PRs (the bot will flag unsigned commits).
75+
76+
## Conventional Commits
77+
78+
This project uses [Conventional Commits](https://www.conventionalcommits.org/) for commit messages.
79+
80+
### Format
81+
82+
```
83+
<type>[optional scope]: <description>
84+
85+
[optional body]
86+
87+
[optional footer(s)]
88+
```
89+
90+
### Types
91+
92+
- **feat**: A new feature
93+
- **fix**: A bug fix
94+
- **docs**: Documentation only changes
95+
- **style**: Changes that do not affect the meaning of the code (white-space, formatting, etc)
96+
- **refactor**: A code change that neither fixes a bug nor adds a feature
97+
- **perf**: A code change that improves performance
98+
- **test**: Adding missing tests or correcting existing tests
99+
- **chore**: Changes to the build process or auxiliary tools
100+
101+
### Examples
102+
103+
```
104+
feat(provider): add new flag evaluation method
105+
106+
fix(api): resolve nil pointer in evaluation context
107+
108+
docs: update installation instructions
109+
```
110+
111+
## Code Style Guidelines
112+
113+
### Formatting & Imports
114+
115+
- Use `gofumpt` for formatting (stricter than gofmt)
116+
- Use `gci` for import sorting (stdlib first, then external)
117+
- Run `make fix` before committing to auto-format
118+
119+
### Linting
120+
121+
This project uses golangci-lint with the following linters:
122+
123+
- **staticcheck**: All checks enabled (SAxxxx rules)
124+
- **errcheck**: Error checking enabled
125+
- **govet**: All checks except fieldalignment and shadow
126+
- **usetesting**: Enforces testing best practices
127+
- **nolintlint**: Requires specific linter annotations (no unused nolint directives)
128+
- **modernize**: Suggests modern Go idioms and language features
129+
- **copyloopvar**: Detects loop variable copying bugs
130+
- **intrange**: Suggests using `for range` for integer loops
131+
132+
Excluded rules:
133+
134+
- G101 (hardcoded credentials detection - too noisy)
135+
- G404 (weak random number generation - used in tests)
136+
137+
### Naming Conventions
138+
139+
- **Variables**: camelCase (e.g., `clientMetadata`, `evalCtx`)
140+
- **Exported Types/Functions**: PascalCase (e.g., `Client`, `NewClient`)
141+
- **Interfaces**: PascalCase, typically I-prefixed (e.g., `IClient`, `IFeatureProvider`) or role-based (e.g., `FeatureProvider`)
142+
- **Constants**: PascalCase
143+
144+
### Error Handling
145+
146+
- Use `fmt.Errorf` with `%w` for error wrapping
147+
- Return errors with descriptive messages (lowercase, no punctuation)
148+
- Use sentinel errors from this package when applicable
149+
- Check errors explicitly: `if err != nil { ... }`
150+
151+
### Context Usage
152+
153+
- Context is the first parameter in functions that need it
154+
- Use `context.Background()` for top-level entry points
155+
- Pass context through call chains (don't store in structs)
156+
- Support cancellation where operations may be slow
157+
158+
### Mutex Patterns
159+
160+
- Use `sync.RWMutex` for read-heavy workloads
161+
- `RLock/RUnlock` for reads, `Lock/Unlock` for writes
162+
- Always defer unlock after locking
163+
- Never hold locks across function calls or goroutines
164+
165+
### Documentation
166+
167+
- Document all exported types and functions with // comments
168+
- Use proper Go doc comments starting with type/function name
169+
- Example: `// Client implements the behaviour required of an openfeature client`
170+
- Include usage examples in example test files (\*\_example_test.go)
171+
172+
### Go Examples
173+
174+
- Go examples are a critical part of documentation and testing
175+
- Place in `*_example_test.go` files next to the code they document
176+
- Naming convention: `Example<Type>_<Method>` for method examples, `Example<Type>` for type examples
177+
- Example function signature: `func ExampleClient_Boolean()`
178+
- Use `// Output:` comment to specify expected output (verified by `go test`)
179+
- Use `fmt.Println` for output to verify example behavior
180+
- External examples use package `openfeature_test` to test public API usage
181+
- Examples serve dual purpose: test correctness and generate godoc examples
182+
- Run examples with: `go test -tags testtools -run Example ./...`
183+
184+
### Testing
185+
186+
- Use standard `testing` package with `testtools` build tag
187+
- Use `t.Cleanup()` for cleanup operations
188+
- Use table-driven tests where appropriate
189+
- Place tests in `*_test.go` files next to implementation
190+
- E2E tests are in `/e2e` directory with `testtools` tag
191+
192+
### Modern Go Guidelines
193+
194+
#### Standard Library Packages
195+
196+
- **`slices` package**: Use modern slice operations instead of manual implementations
197+
- **`maps` package**: Use modern map operations
198+
199+
#### Modern Language Features
200+
201+
- **For loop variable scoping**: Variables declared in `for` loops are created anew for each iteration
202+
- **Ranging over integers**: Use `for i := range n` instead of `for i := 0; i < n; i++`
203+
- **Generics**: Use type parameters for reusable, type-safe functions and types
204+
- **Type inference**: Leverage automatic type inference with `:=` when possible
205+
206+
#### Modernization Tools
207+
208+
- **`go fix`**: Automatically modernize code to use current Go features
209+
210+
```bash
211+
go fix ./...
212+
```
213+
214+
- **`modernize` analyzer**: Integrated in golangci-lint (enabled by default)
215+
- Run `make fix` to apply modernize suggestions automatically
216+
217+
#### Best Practices
218+
219+
- **Slice initialization**: Prefer `var s []T` over `s := []T{}` or `make([]T, 0)` for nil slices
220+
221+
```go
222+
// Good
223+
var results []string
224+
results = append(results, "item")
225+
226+
// Avoid
227+
results := []string{}
228+
```
229+
230+
- **Preallocation**: Preallocate slice capacity when size is known
231+
232+
```go
233+
// Good
234+
items := make([]Item, 0, len(source))
235+
for _, s := range source {
236+
items = append(items, Item(s))
237+
}
238+
```
239+
240+
- **Error handling**: Use `fmt.Errorf` with `%w` for wrapping errors
241+
- **Context**: Pass context as first parameter, support cancellation
242+
- **Concurrency**: Use `sync/errgroup` for managing goroutines with error handling
243+
- **Testing**: Use table-driven tests with `t.Cleanup()` for resource cleanup
244+
245+
### General
246+
247+
- Go version: 1.25
248+
- Module: `go.openfeature.dev/openfeature/v2`
249+
- Mock generation: `make mockgen`
250+
- Run `make test && make lint` before committing

0 commit comments

Comments
 (0)