Documentation
¶
Overview ¶
Package gogenconf provides a versioned declarative configuration format and schema system with generated strongly typed Go bindings.
The line-oriented document grammar is:
document = { blank | comment | version | entry | section }
version = "config_version" integer newline
section = "section" name newline { blank | comment | entry } "end" newline
entry = identifier [ expression ] newline
comment = "#" user-text | "##" schema-documentation
Expressions use bare or Go-quoted literals, or identifier "(" arguments ")". Arguments are recursively parsed expressions separated by commas. Commas in a top-level bare value remain literal for compatibility; quote punctuation in arguments. Quoted strings can encode arbitrary bytes, including NUL. Comments occupy their own lines. Indentation is insignificant. Section names may have a space-separated instance suffix; schemas decide their meaning.
Parse accepts unversioned documents as legacy v0. Schema version checks and comment ownership are version-aware: all v0 comments are user-owned, while versioned v1+ documents distinguish # user comments from ## managed docs. Legacy headings are escaped on upgrade so ownership survives a reload. Schema version checks and registered migrations are separate from syntax. Unknown fields/sections are ordinary nodes and survive formatting/editing. Duplicate fields/sections, nested sections and malformed delimiters fail rather than being discarded.
Registry uses Go result types only for service dispatch, never reflection to populate application structures. codegen emits those structures, explicit typed resolution calls, and application-owned dependency-free native runtimes.
Package gogenconf contains the reusable, unresolved configuration model.
Index ¶
- func Format(d *Document) string
- func FormatExpr(e Expr) string
- func Resolve[T any](ctx context.Context, r *Registry, expr Expr) (T, error)
- func ResolveField[T any](ctx context.Context, r *Registry, e Expr, path string, sensitive bool) (T, error)
- type Blank
- type Call
- type Comment
- type CommentKind
- type DisplayPolicy
- type Document
- type Entry
- type Expr
- type Field
- type Item
- type Literal
- type LookupEnv
- type Migration
- type Migrations
- type Provider
- type ProviderFunc
- type Raw
- type Registry
- type ResolutionPolicy
- type Resolver
- type Schema
- func (s Schema) CheckVersion(d *Document) error
- func (s Schema) Enrich(d *Document) error
- func (s Schema) Field(section, key string) (Field, bool)
- func (s Schema) Inspect(d *Document, section, key string, p DisplayPolicy) (string, bool)
- func (s Schema) InspectionDocument(d *Document, p DisplayPolicy) *Document
- func (s Schema) Sample() *Document
- func (s Schema) Seed() *Document
- func (s Schema) WritableField(section, key string) (Field, bool)
- type Section
- type SectionDefinition
- type Version
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Format ¶
Format never resolves values and retains the position of every root item, including comments between sections and trailing comments.
func FormatExpr ¶
FormatExpr renders an expression canonically without resolving it.
func Resolve ¶
Example ¶
package main
import (
"context"
"fmt"
"os"
m "github.com/arran4/gogenconf"
)
func main() {
f, err := os.CreateTemp("", "gogenconf-example-*")
if err != nil {
panic(err)
}
defer os.Remove(f.Name())
if _, err = f.Write([]byte(" \x00content\n")); err != nil {
panic(err)
}
if err = f.Close(); err != nil {
panic(err)
}
e := m.Call{Name: "from_file", Args: []m.Expr{m.Literal{Value: f.Name()}}}
r, err := m.NewStandardRegistry()
if err != nil {
panic(err)
}
text, err := m.Resolve[string](context.Background(), r, e)
if err != nil {
panic(err)
}
data, err := m.Resolve[[]byte](context.Background(), r, e)
if err != nil {
panic(err)
}
fmt.Printf("string: %q\nbytes: %v\n", text, data)
}
Output: string: " \x00content\n" bytes: [32 0 99 111 110 116 101 110 116 10]
Types ¶
type Comment ¶
type Comment struct {
Kind CommentKind
Text string
}
type CommentKind ¶
type CommentKind uint8
CommentKind records ownership rather than inferring it from prose.
const ( UserComment CommentKind = iota DocumentationComment )
type DisplayPolicy ¶
type DisplayPolicy map[string]func([]Expr, DisplayPolicy) bool
DisplayPolicy declares which call arguments identify sources rather than contain content. Unknown declarers fail closed. This is independent of typed resolver registration: registering a resolver does not authorize disclosure. Applications may explicitly add rules for their own declarers.
func StandardDisplayPolicy ¶
func StandardDisplayPolicy() DisplayPolicy
func (DisplayPolicy) SafeSource ¶
func (p DisplayPolicy) SafeSource(e Expr) bool
type Document ¶
func Parse ¶
Parse reads the native language. Section/field names are schema-independent. Versions are root metadata; unversioned input is explicitly legacy version 0. Duplicate fields/sections and malformed delimiters are rejected, not guessed.
func (*Document) AddSection ¶
type Expr ¶
type Expr interface {
// contains filtered or unexported methods
}
Expr is an unresolved value declaration. Parsing and formatting an Expr never performs I/O.
func BindingValue ¶
func BindingValue(d *Document, section, key string, fallback Expr, env string, nonempty bool, lookup LookupEnv) Expr
BindingValue encodes precedence explicitly: authored document, compatibility environment, schema default. Enriched defaults retain transient provenance.
func ParseExpr ¶
ParseExpr parses a literal or a nested declarer expression.
Example ¶
package main
import (
"fmt"
m "github.com/arran4/gogenconf"
)
func main() {
for _, source := range []string{
`literal`, `"quoted literal"`, `from_env(NAME)`,
`from_file("/a path/key")`, `from_file(from_env(KEY_FILE))`,
`from_json_file(from_env(CONFIG_FILE), ".nested.value")`,
} {
e, err := m.ParseExpr(source)
if err != nil {
panic(err)
}
fmt.Println(m.FormatExpr(e)) // canonical, unresolved; no source need exist
}
}
Output: literal "quoted literal" from_env(NAME) from_file("/a path/key") from_file(from_env(KEY_FILE)) from_json_file(from_env(CONFIG_FILE), .nested.value)
type Field ¶
type Field struct {
Key, GoName, GoType string
Default Expr
// Examples are documentation only: never defaults or runtime inputs.
Examples []Expr
Documentation []string
Required, Sensitive, RuntimeOnly, Deprecated bool
// InputOnly fields are accepted persisted inputs for compatibility/migration,
// not writable editing targets, runtime members, or ordinary binding targets.
InputOnly bool
Policy ResolutionPolicy
// Environment is a compatibility fallback below an explicit document value.
Environment string
EnvironmentNonEmpty bool
}
Field describes content and static Go mapping. RuntimeOnly fields belong to the generated struct but cannot be configured through the document.
type Item ¶
type Item interface {
// contains filtered or unexported methods
}
Item preserves ordered document structure. Adapters may add Raw items for syntax they intentionally do not interpret.
type Literal ¶
type Literal struct{ Value string }
Literal is the implicit declaration used by a bare configuration value.
type Migrations ¶
type Migrations struct {
// contains filtered or unexported fields
}
func NewMigrations ¶
func NewMigrations() *Migrations
type Provider ¶
Provider is an application-facing content boundary, separate from declarer services. No cache or invalidation policy is imposed on ordinary fields.
type ProviderFunc ¶
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
func NewRegistry ¶
func NewRegistry() *Registry
func NewStandardRegistry ¶
NewStandardRegistry provides a caller-owned registry with the built-in local declarers. It can be extended without changing the AST or parser.
func (*Registry) Register ¶
Example ¶
package main
import (
"context"
"fmt"
"strings"
m "github.com/arran4/gogenconf"
)
func main() {
r := m.NewRegistry()
err := r.Register("local_value", "", func(ctx context.Context, r *m.Registry, args []m.Expr) (any, error) {
if len(args) != 1 {
return nil, fmt.Errorf("local_value requires one argument")
}
name, err := m.Resolve[string](ctx, r, args[0])
if err != nil {
return nil, err
}
return strings.ToUpper(name), nil
})
if err != nil {
panic(err)
}
e, err := m.ParseExpr(`local_value(example)`)
if err != nil {
panic(err)
}
v, err := m.Resolve[string](context.Background(), r, e)
if err != nil {
panic(err)
}
fmt.Println(v)
}
Output: EXAMPLE
type ResolutionPolicy ¶
type ResolutionPolicy string
const ( Eager ResolutionPolicy = "" ProviderBacked ResolutionPolicy = "provider" )
type Schema ¶
type Schema struct {
Version int
Sections []SectionDefinition
}
func (Schema) CheckVersion ¶
func (Schema) Field ¶
Field looks up accepted persisted input, including InputOnly compatibility fields. Readers, migrations, inspection, and removal may use this lookup.
func (Schema) Inspect ¶
Inspect returns a declaration, never a resolved value. Sensitive literals and calls without an explicit source-only display contract are redacted.
func (Schema) InspectionDocument ¶
func (s Schema) InspectionDocument(d *Document, p DisplayPolicy) *Document
InspectionDocument is a redacted display copy, not a persistence round trip. Format/Save the original document to preserve authored declarations.
type SectionDefinition ¶
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
gogenconf
command
|
|
|
Package codegen turns a validated schema into static Go types and binders, and generates application-owned, dependency-free native configuration runtimes.
|
Package codegen turns a validated schema into static Go types and binders, and generates application-owned, dependency-free native configuration runtimes. |
|
internal/fixturegen
command
fixturegen regenerates the private compiled codegen fixtures.
|
fixturegen regenerates the private compiled codegen fixtures. |
|
internal/testschema
Package testschema provides a small neutral schema for generator fixtures.
|
Package testschema provides a small neutral schema for generator fixtures. |
|
examples
|
|
|
basic
command
|
|
|
codegen
command
|
|
|
codegen/internal/generate
command
|
|
|
migration
command
|
|
|
nested-sources
command
|
|
|
provider
command
|
|
|
internal
|
|
|
cli
Package cli implements syntax-only tooling.
|
Package cli implements syntax-only tooling. |
|
cligen
command
cligen pins CLI/help/man generation without adding runtime dependencies.
|
cligen pins CLI/help/man generation without adding runtime dependencies. |
|
docgen
command
docgen keeps the navigable site derived from the primary README manual.
|
docgen keeps the navigable site derived from the primary README manual. |
|
runtimegen
command
runtimegen writes the production native syntax runtime used by the gogenconf CLI.
|
runtimegen writes the production native syntax runtime used by the gogenconf CLI. |