
go-options-gen
by metalagman
Agent Skills. A collection of specialized expertise, workflows, and resources for LLM agents.
SKILL.md
name: go-options-gen description: Expert in generating functional options for Go structs using the options-gen library. metadata: short-description: Functional options generation for Go.
go-options-gen
You are an expert in using the options-gen library (https://github.com/kazhuravlev/options-gen) to create robust, type-safe functional options for Go components. You prioritize unexported option fields to maintain encapsulation while providing a clean, exported API for configuration.
Core Mandates
- File Naming:
- Single Option Set: Struct definition MUST be in
options.go, and generated code MUST be inoptions_generated.go. - Multiple Option Sets: For a component named
MyService, the struct (e.g.,MyServiceOptions) MUST be inmyservice_options.go, and generated code MUST be inmyservice_options_generated.go.
- Single Option Set: Struct definition MUST be in
- Encapsulation:
- Options fields within the struct SHOULD be unexported (start with a lowercase letter) to prevent direct modification from outside the package.
- Tooling:
- Always run the tool using
go tool options-gen. - Install and track the tool in
go.modusing:go get -tool github.com/kazhuravlev/options-gen/cmd/options-gen@latest
- Always run the tool using
- Validation:
- Always include validation tags (using
go-playground/validatorsyntax) for configuration fields. - ALWAYS call the generated
Validate()method within the component's constructor.
- Always include validation tags (using
- Component Integration:
- Store the resulting options struct in an unexported field named
optswithin your component struct.
- Store the resulting options struct in an unexported field named
Developer Workflow
-
Installation: Ensure the tool is tracked in your project:
go get -tool github.com/kazhuravlev/options-gen/cmd/options-gen@latest -
Define Options (
options.go): Define your options struct with unexported fields. Use the//go:generatedirective to specify the output filename and the target struct.package mypackage import "time" //go:generate go tool options-gen -from-struct=Options -out-filename=options_generated.go type Options struct { timeout time.Duration `option:"mandatory" validate:"required"` maxRetries int `default:"3" validate:"min=1"` endpoints []string `option:"variadic=true"` } -
Generate: Run the generator:
go generate ./options.go -
Integration: Use the generated types in your component's constructor and store them in an
optsfield.type Component struct { opts Options } func New(setters ...OptionOptionsSetter) (*Component, error) { opts := NewOptions(setters...) if err := opts.Validate(); err != nil { return nil, fmt.Errorf("invalid options: %w", err) } return &Component{opts: opts}, nil }
Expert Guidance
Mandatory vs. Default
- Use
option:"mandatory"for fields that have no safe default (e.g., API keys, target URLs). These become required arguments inNewOptions(). - Use
default:"value"for sensible defaults.options-gensupports basic types andtime.Duration.
Advanced Defaults
For complex types (like maps or nested structs), use -defaults-from=func in the generate directive and define a provider function:
//go:generate go tool options-gen -from-struct=Options -out-filename=options_generated.go -defaults-from=func
func defaultOptions() Options {
return Options{
headers: map[string]string{"User-Agent": "my-client"},
}
}
Validation Best Practices
- Use
validate:"required"for any field that must not be zero-valued. - Use
validate:"oneof=tcp udp"for enum-like string fields. - Use
validate:"min=1"for counters or sizes.
Variadic Setters
For slice fields, use option:"variadic=true" to generate a setter that accepts multiple arguments (e.g., WithEndpoints("a", "b")) instead of a single slice (e.g., WithEndpoints([]string{"a", "b"})).
Avoiding Exported Fields
By keeping fields unexported in options.go, you ensure that the only way to configure the component is through the generated With* setters, which can include validation logic.
Multiple Options in One Package
When a package contains multiple components (e.g., Client and Server), use prefixes to avoid name collisions in generated types and functions.
- Filenames: Use
<prefix>_options.goand<prefix>_options_generated.go. - Generator Flag: Use
-out-prefixto prefix the generatedNewOptionsandOption...Settertypes.
Example for MyService (myservice_options.go):
//go:generate go tool options-gen -from-struct=MyServiceOptions -out-filename=myservice_options_generated.go -out-prefix=MyService
type MyServiceOptions struct {
timeout time.Duration `option:"mandatory"`
}
This will generate NewMyServiceOptions and OptionMyServiceOptionsSetter, allowing them to coexist with other options in the same package.
Resources
- Examples: Complete implementations showing unexported fields, validation, and component integration can be found in the assets directory.
スコア
総合スコア
リポジトリの品質指標に基づく評価
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
レビュー
レビュー機能は近日公開予定です