goschtalt

package module
v0.25.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 13, 2024 License: Apache-2.0 Imports: 23 Imported by: 9

README

goschtalt

Build Status codecov.io Go Report Card GitHub Release GoDoc

A customizable configuration library that supports multiple files and formats.

Goals & Themes

  • Make support for multiple configuration files and sources easy to use and extend.
  • Simplify tracing the origin of a configuration value.
  • Favor user customization options over building everything in, keeping dependencies to a minimum.
  • Embrace patterns that make using other powerful libraries (kong, fx, etc) simple.

API Stability

This package has not yet released to 1.x yet, so APIs are subject to change for a bit longer.

After v1 is released, SemVer will be followed.

Installation

go get github.com/goschtalt/goschtalt

Extensions

Instead of trying to build everything in, goschtalt tries to only build in what is absolutely necessary and favor extensions. This enables a diversity of ecosystem while not bloating your code with a bunch of dependencies.

The following are popular goschtalt extensions:

Examples

Coming soon.

Dependencies

There are only two production dependencies in the core goschtalt code beyond the go standard library. The rest are testing dependencies.

Production dependencies:

Compilation of a Configuration

This is more detailed overview of how the configuration is compiled.

stateDiagram-v2
    direction TB

    state Gather_Inputs {
        direction TB
        AddBuffer() --> New()
        AddFile() --> New()
        AddValue(AsDefault()) --> New()
    }

    state Sequence {
        direction TB
        Defaults:Defaults by order added.
        Records:Records sorted using record label.
        ex:Expand instructions by order added.

        Defaults --> Records
        Records --> ex
    }

    state Compile {
        calc:Calculate configuration<br/>tree at this point.
        eval:Apply all Expand()<br/>and ExpandEnv()<br/>to configuration<br/>tree in order.
        fetch:Call any user<br/>provided funcs with<br/>configuration tree.
        next:Next<br/>Configuration<br/>Tree Part
        merge:Merge the new<br/>configuration tree part<br/>with the current tree
        Empty:Empty<br/>Configuration<br/>Tree


        Empty --> calc
        calc --> eval:If a user func<br/>is provided
        calc --> next:If no user func<br/>is provided
        eval --> fetch
        fetch --> next
        next --> merge
        merge --> calc
    }

    state Expand {
        exp:Apply all Expand()<br/>and ExpandEnv()<br/>to configuration<br/>tree in order.
    }

    state Active {
        active:Active Configuration
        unmarshal:Unmarshal()
        active --> unmarshal
        unmarshal --> active
    }
    New() --> Sequence
    Sequence --> Compile
    Compile --> Expand
    Expand --> Active
    Active --> Sequence:With() or Compile() called<br/>resequences the lists and<br/>recalculates the <br/>configuration tree.

Documentation

Overview

Package goschtalt is a lightweight and flexible configuration registry that makes it easy to configure an application.

Goschtalt is a fresh take on application configuration now that Go has improved filesystem abstraction, modules, and the Option pattern. At its core, Goschtalt is a low dependency library that provides configuration values via a small and customizable API. The configuration values can be merged using either the default semantics or specified on a parameter by parameter basis.

What problems is Goschtalt trying to solve?

  • Merging of multiple configuration files and configuration sources allow for better flexibility for deployment.
  • Configuration is incrementally compiled allowing later configuration to use earlier configuration.
  • Clear explanation how the configuration was derived.
  • User customizable via Options.

Features

  • Users choose which configuration file decoders they want.
  • Configuration fields may be labeled as 'secret' to enable secret redaction during output of portions of the configuration tree.
  • Configuration fields may instruct the merge process of how the new field should merge with the existing field. ('replace', 'keep', 'fail', 'append', 'prepend', 'clear')
  • Configuration file groups include a reference to the specific io.fs, so configuration may come from anything that implements that interface.
  • Package defaults are set via goschtalt.DefaultOptions, but can be replaced when invoking a new goschtalt.Config object.
  • Default values are supported at runtime.
  • Variable expansion in the configuration tree is supported for both environment variables as well as custom values.
  • No singleton objects.
  • Low dependency count.

Where do I find configuration file encoders/decoders?

The project contains several related packages that are isolated from the core goschtalt package to keep the dependencies low. They are all maintained by the same group of people, but are not required to be used together, and are otherwise independent (different go modules). They can be found here:

How do I decorate my configuration files to take full advantage of goschtalt?

For most of the decoders you can specify instructions for goschtalt's handling of the data fields by annotating the key portion. Here's a simple example in yaml:

foo:
  bar((prepend)):
    - 1
    - 2

If this configuration data is merged with an existing configuration set:

foo:
  bar:
    - 3
    - 4

The resulting configuration will be:

foo:
  bar:
    - 1
    - 2
    - 3
    - 4

The commands available are consistent, but vary based on the type of the value being defined.

All types (maps, arrays, values) support:

  • replace - replaces any existing values encountered by this merge
  • keep - keeps the existing values encountered by this merge
  • fail - causes the merge to return an error and stop processing
  • clear - causes all of the existing configuration tree to be deleted
  • secret - this special command marks the field as secret

Maps support the following instructions:

  • splice - merge the leaf nodes if possible instead of replacing the map entirely

Arrays support the following instructions:

  • append - append this array to the existing array
  • prepend - prepend this array to the existing array

Default merging behaviors:

  • maps - splice when possible, replace if splicing isn't possible
  • arrays - append
  • values - replace

An example showing using a secret:

foo:
  bar ((append secret)):
    - 3
    - 4

The order of the instructions doesn't matter, nor does extra spaces around the instructions. You may comma separate them, or you may just use a space. But you can only have one or two instructions (one MUST be secret if there are two.

A bit more on secrets.

Secrets are primarily there so that if you want to output your configuration and everything is marked as secret correctly, you can get a redacted configuration file with minimal work. It's also handy if you output your configuration values into a log so you don't accidentally leak your secrets.

How do I write my own configuration decoder?

Examples of decoders exist in the extensions/decoders directory. Of interest are the `env` decoder that provides an Option, and the `yaml` decoder that is simply a decoder.

What's with the name?

In psychology, gestalt is a way of thinking about data via patterns and configuration. It's a also somewhat common word. gostalt is pretty good, except there were still several things that used it, including a go framework. This goschtalt project is the only response google returned as of Aug 12, 2022.

Index

Examples

Constants

View Source
const Root = ""

Root provides a more descriptive name to use for the root node of the configuration tree than a naked "".

Variables

View Source
var (
	ErrAdaptFailure  = errors.New("at least one matching adapt function failed")
	ErrDecoding      = errors.New("decoding error")
	ErrEncoding      = errors.New("encoding error")
	ErrNotApplicable = errors.New("not applicable")
	ErrNotCompiled   = errors.New("the Compile() function must be called first")
	ErrCodecNotFound = errors.New("encoder/decoder not found")
	ErrInvalidInput  = errors.New("input is invalid")
	ErrFileMissing   = errors.New("required file is missing")
	ErrUnsupported   = errors.New("feature is unsupported")
	ErrHint          = errors.New("a hint found an issue")
)
View Source
var DefaultOptions = []Option{}

DefaultOptions allows a simple place where decoders can automatically register themselves, as well as a simple way to find what is configured by default. Most extensions will register themselves using init(). It is safe to change this value at pretty much any time & compile afterwards; just know this value is not mutex protected so if you are changing it after init() the synchronization is up to the caller.

To disable the use of this global variable, use the DisableDefaultPackageOptions option.

Functions

func Unmarshal

func Unmarshal[T any](c *Config, key string, opts ...UnmarshalOption) (T, error)

Unmarshal provides a generics based strict typed approach to fetching parts of the configuration tree.

To read the entire configuration tree, use goschtalt.Root Root instead of "" for more clarity.

Valid Option Types:

func UnmarshalFunc

func UnmarshalFunc[T any](key string, opts ...UnmarshalOption) func(*Config) (T, error)

UnmarshalFunc returns a function that takes a goschtalt Config structure and returns a function that allows for unmarshaling of a portion of the tree specified by the key into a zero value type.

This function is specifically helpful with DI frameworks like Uber's fx framework.

In this short example, the type myStruct is created and populated with the configuring values found under the "conf" key in the goschtalt configuration.

app := fx.New(
	fx.Provide(
		goschtalt.UnmarshalFunc[myStruct]("conf"),
	),
)

To read the entire configuration tree, use goschtalt.Root Root instead of "" for more clarity.

Valid Option Types:

Types

type AdapterFromCfg added in v0.17.0

type AdapterFromCfg interface {
	From(from, to reflect.Value) (any, error)
}

AdapterFromCfg provides a method that maps a value from the form stored in the configuration tree (and the configuration files) to the golang structure. If the mapping is not applicable, the ErrNotApplicable error is returned. Any other non-nil error fails the operation entirely.

type AdapterFromCfgFunc added in v0.18.0

type AdapterFromCfgFunc func(from, to reflect.Value) (any, error)

The AdapterFromCfgFunc type is an adapter to allow the use of ordinary functions as AdapterFromCfgs. If f is a function with the appropriate signature, AdapterFromCfgFunc(f) is a AdapterFromCfg that calls f.

func (AdapterFromCfgFunc) From added in v0.18.0

func (f AdapterFromCfgFunc) From(from, to reflect.Value) (any, error)

Get calls f(from, to)

type AdapterToCfg added in v0.17.0

type AdapterToCfg interface {
	To(from reflect.Value) (any, error)
}

AdapterToCfg provides a method that maps a golang struct object into the configuration form. It assumed that the converter knows best what that is.

If the mapping is not applicable, the ErrNotApplicable error is returned. Any other non-nil error fails the operation entirely.

type AdapterToCfgFunc added in v0.18.0

type AdapterToCfgFunc func(reflect.Value) (any, error)

The AdapterToCfgFunc type is an adapter to allow the use of ordinary functions as AdapterToCfgs. If f is a function with the appropriate signature, AdapterToCfgFunc(f) is a AdapterToCfg that calls f.

func (AdapterToCfgFunc) To added in v0.18.0

func (f AdapterToCfgFunc) To(from reflect.Value) (any, error)

Get calls f(rn, u)

type BufferGetter added in v0.17.0

type BufferGetter interface {
	// Get is called each time the configuration is compiled.  The recordName
	// and an Unmarshaler with the present stage of configuration and expanded
	// variables are provided to assist.  A slice of bytes or an error is
	// returned.
	Get(recordName string, u Unmarshaler) ([]byte, error)
}

BufferGetter provides the methods needed to get the buffer of bytes.

type BufferGetterFunc added in v0.18.0

type BufferGetterFunc func(string, Unmarshaler) ([]byte, error)

The BufferGetterFunc type is an adapter to allow the use of ordinary functions as BufferGetters. If f is a function with the appropriate signature, BufferGetterFunc(f) is a BufferGetter that calls f.

func (BufferGetterFunc) Get added in v0.18.0

func (f BufferGetterFunc) Get(rn string, u Unmarshaler) ([]byte, error)

Get calls f(rn, u)

type BufferOption added in v0.4.0

type BufferOption interface {
	fmt.Stringer
	// contains filtered or unexported methods
}

BufferOption provides the means to configure options for handling of the buffer configuration values.

type BufferValueOption added in v0.7.0

type BufferValueOption interface {
	fmt.Stringer

	BufferOption
	ValueOption
}

BufferValueOption can be used as a BufferOption or a ValueOption.

func AsDefault

func AsDefault(asDefault ...bool) BufferValueOption

AsDefault specifies that this value is a default value & is applied prior to any other configuration values. Default values are applied in the order the options are specified.

The unused bool value is optional & assumed to be `true` if omitted. The first specified value is used if provided. A value of `false` disables the option.

type Config

type Config struct {
	// contains filtered or unexported fields
}

Config is a configurable, prioritized, merging configuration registry.

func New

func New(opts ...Option) (*Config, error)

New creates a new goschtalt configuration instance with any number of options.

func (*Config) Compile

func (c *Config) Compile() error

Compile reads in all the files configured using the options provided, and merges the configuration trees into a single map for later use.

func (*Config) CompiledAt

func (c *Config) CompiledAt() time.Time

CompiledAt returns when the configuration was compiled.

func (*Config) Explain

func (c *Config) Explain() Explanation

Explain returns a human focused explanation of how the configuration was arrived at. Each time the options change or the configuration is compiled the explanation will be updated.

func (*Config) GetTree added in v0.12.0

func (c *Config) GetTree() meta.Object

GetTree returns a copy of the compiled tree. This is useful for debugging what the configuration tree looks like with a tool like k0kubun/pp.

The value returned is a deep clone & has nothing to do with the original that still resides inside the Config object.

func (*Config) Hash

func (c *Config) Hash() []byte

Hash returns the hash of the configuration; even if the configuration is empty. SetHasher() needs to be set to get a useful (non-empty) value.

func (*Config) Marshal

func (c *Config) Marshal(opts ...MarshalOption) ([]byte, error)

Marshal renders the into the format specified ('json', 'yaml' or other extensions the Codecs provide and if adding comments should be attempted. If a format does not support comments, an error is returned. The result of the call is a slice of bytes with the information rendered into it.

Valid Option Types:

func (*Config) OrderList

func (c *Config) OrderList(list []string) []string

OrderList is a helper function that sorts a caller provided list of filenames exactly the same way the Config object would sort them when reading and merging the records when the configuration is being compiled. It also filters the list based on the decoders present.

Example
// SPDX-FileCopyrightText: 2022 Weston Schmidt <weston_schmidt@alumni.purdue.edu>
// SPDX-License-Identifier: Apache-2.0

package main

import (
	"fmt"

	"github.com/goschtalt/goschtalt"
	"github.com/goschtalt/goschtalt/pkg/decoder"
	"github.com/goschtalt/goschtalt/pkg/meta"
)

// This is a fake decoder that allows the OrderList() to correctly work without
// needing to bring any external decoders into goschtalt.
type fake struct{}

func (f fake) Decode(_ decoder.Context, _ []byte, _ *meta.Object) error { return nil }
func (f fake) Extensions() []string                                     { return []string{"yml", "yaml", "json"} }

func main() {
	g, err := goschtalt.New(goschtalt.WithDecoder(fake{}))
	if err != nil {
		panic(err)
	}

	err = g.Compile()
	if err != nil {
		panic(err)
	}

	files := []string{
		"file_2.json",
		"file_1.yml",
		"file_1.txt",
		"S99_file.yml",
		"S58_file.json",
	}
	list := g.OrderList(files)

	fmt.Println("files:")
	for _, file := range list {
		fmt.Printf("\t%s\n", file)
	}

}
Output:

files:
	S58_file.json
	S99_file.yml
	file_1.yml
	file_2.json

func (*Config) Unmarshal

func (c *Config) Unmarshal(key string, result any, opts ...UnmarshalOption) error

Unmarshal performs the act of looking up the specified section of the tree and decoding the tree into the result. Additional options can be specified to adjust the behavior.

To read the entire configuration tree, use goschtalt.Root Root instead of "" for more clarity.

Valid Option Types:

func (*Config) With

func (c *Config) With(opts ...Option) error

With takes a list of options and applies them. Use of With() is optional as New() can take all the same options as well. If AutoCompile() is not specified Compile() will need to be called to see changes in the configuration based on the new options.

See also: AutoCompile, [Compile], New

type ExpandOption

type ExpandOption interface {
	// contains filtered or unexported methods
}

ExpandOption provides the means to configure options around variable expansion.

func WithDelimiters

func WithDelimiters(start, end string) ExpandOption

WithDelimiters provides a way to define different delimiters for the start and end of a variable for matching purposes.

func WithMaximum

func WithMaximum(maximum int) ExpandOption

WithMaximum provides a way to overwrite the maximum number of times variables are expanded. Any value less than 1 will default to 10000 as a precaution against getting trapped in an infinite loop.

func WithOrigin

func WithOrigin(origin string) ExpandOption

WithOrigin provides the origin name to add showing where a value in the configuration tree originates from.

type Expander added in v0.17.0

type Expander interface {

	// Expand maps the incoming string to a new string.  The string passed in
	// will not contain the start and end delimiters.  If the string is not
	// found, return the bool value of false, otherwise return true.
	Expand(string) (string, bool)
}

Expander provides a method that can expand variables in values.

type ExpanderFunc added in v0.18.0

type ExpanderFunc func(string) (string, bool)

The ExpanderFunc type is an adapter to allow the use of ordinary functions as Expanders. If f is a function with the appropriate signature, ExpanderFunc(f) is a Expander that calls f.

func (ExpanderFunc) Expand added in v0.18.0

func (f ExpanderFunc) Expand(s string) (string, bool)

Get calls f(s)

type Explanation added in v0.22.0

type Explanation struct {

	// Options is the ordered list of Options in effect.
	Options []string

	// FileExtensions is the list of file extensions supported in the
	// configuration provided.
	FileExtensions []string

	// CompileStartedAt is the start time when the most recent compile was
	// performed.
	CompileStartedAt time.Time

	// CompileFinishedAt is the completion time when the most recent compile was
	// performed.
	CompileFinishedAt time.Time

	// Records is the ordered list of records processed.
	Records []ExplanationRecord

	// VariableExpansions is the ordered list of variable expansion instructions
	// applied.
	VariableExpansions []string

	// CompileErrors is the ordered list of compilation errors encountered during
	// the last compilation.
	CompileErrors []error

	// Keyremapping collects the key remapping that happens when values are
	// added or used.  This helps address problems when a name may not be
	// converted the way you would expect or like.
	//
	// Not available if DisableDefaultPackageOptions() is specified.
	Keyremapping debug.Collect
}

Explanation is the structure that represents what happened last time the Config object was altered, compiled or used.

Calling New() or With() will clear out all the values present.

func (Explanation) String added in v0.22.0

func (e Explanation) String() string

type ExplanationRecord added in v0.22.0

type ExplanationRecord struct {
	Name     string        // The name of the record.
	Default  bool          // If the record was marked as a 'default' record.
	Duration time.Duration // The time needed to process the record.
}

ExplanationRecord is the structure that represents a specific record that was processed.

func (ExplanationRecord) String added in v0.22.0

func (er ExplanationRecord) String() string

type GlobalOption added in v0.7.0

GlobalOption options implement all option interfaces.

func WithError

func WithError(err error) GlobalOption

WithError provides a way for plugins to return an error during option processing. This option will always produce the specified error; including if the err value is nil.

type Hasher added in v0.22.0

type Hasher interface {
	Hash(any) ([]byte, error)
}

Hasher provides the methods needed to hash the object tree.

type HasherFunc added in v0.22.0

type HasherFunc func(any) ([]byte, error)

HasherFunc is an adapter to allow the use of ordinary functions as Hashers. If f is a function with the appropriate signature, HasherFunc(f) is a Hasher that calls f.

func (HasherFunc) Hash added in v0.22.0

func (f HasherFunc) Hash(o any) ([]byte, error)

Hash calls f(o)

type KeymapReporter added in v0.16.0

type KeymapReporter interface {
	// Report is called with the `from` and `to` strings when a key mapping
	// takes place.
	Report(from, to string)
}

KeymapReporter is the interface that provides a way to report what was mapped to what. This is designed to help make debugging mapping mistakes easier.

The github.com/goschtalt/goschtalt/pkg/debug/Collect package implements KeymapReporter for easy use.

type Level added in v0.10.0

type Level string

A Level represents a specific degree in which a configuration matches a structure's fields.

const (
	NONE     Level = "NONE"
	SUBSET   Level = "SUBSET"
	COMPLETE Level = "COMPLETE"
	EXACT    Level = "EXACT"
)

type Mapper added in v0.9.0

type Mapper interface {
	// Map takes a golang structure field string and outputs a goschtalt
	// configuration tree name string that is one of the following:
	//   - "" indicating this mapper was unable to perform the remapping, continue
	//     calling mappers in the chain
	//   - "-"  indicating this value should be dropped entirely
	//   - anything else indicates the new full name
	Map(s string) string
}

Mapper provides a method that can map from a golang structure field name to a goschtalt configuration tree name.

type MarshalOption

type MarshalOption interface {
	fmt.Stringer
	// contains filtered or unexported methods
}

MarshalOption provides specific configuration for the process of producing a document based on the present information in the goschtalt object.

func FormatAs

func FormatAs(extension string) MarshalOption

FormatAs specifies the final document format extension to use when performing the operation.

func IncludeOrigins

func IncludeOrigins(origins ...bool) MarshalOption

IncludeOrigins enables or disables providing the origin for each configuration value present.

Default

Origins are not included by default.

func RedactSecrets

func RedactSecrets(redact ...bool) MarshalOption

RedactSecrets enables the replacement of secret portions of the tree with REDACTED. Passing a redact value of false disables this behavior.

The unused bool value is optional & assumed to be `true` if omitted. The first specified value is used if provided. A value of `false` disables the option.

Default

Secret values are redacted.

type Option

type Option interface {
	fmt.Stringer
	// contains filtered or unexported methods
}

Option configures specific behavior of Config as well as the locations used for the configurations compiled. There are 3 basic groups of options:

  • Configuration of locations where to collect configuration
  • Addition of encoders/decoders
  • Define default behaviors

func AddBuffer

func AddBuffer(recordName string, in []byte, opts ...BufferOption) Option

AddBuffer adds a buffer of bytes for inclusion when compiling the configuration. The format of the bytes is determined by the extension of the recordName field. The recordName field is also used for sorting this configuration value relative to other configuration values.

Valid Option Types:

func AddBufferGetter added in v0.17.0

func AddBufferGetter(recordName string, getter BufferGetter, opts ...BufferOption) Option

AddBufferGetter adds a function that is called during compile time of the configuration. The recordName of this record is passed into the getter, as well as an Unmarshaler that represents the existing state of the merged configuration prior to adding the buffer that results in the call to getter.

The format of the bytes is determined by the extension of the recordName field. The recordName field is also used for sorting this configuration value relative to other configuration values.

Valid Option Types:

func AddDir

func AddDir(fs fs.FS, path string) Option

AddDir adds a directory (excluding all subdirectories) for inclusion when compiling the configuration. Any files that cannot be processed will be ignored. It is not an error if any files are missing, or if all the files cannot be processed.

Use AddFile() if you need to require a file to be present.

All the files that can be processed with a decoder will be compiled into the configuration.

func AddDirs

func AddDirs(fs fs.FS, paths ...string) Option

AddDirs adds a list of directories (excluding all subdirectories) for inclusion when compiling the configuration. Any files that cannot be processed will be ignored. It is not an error if any files are missing, or if all the files cannot be processed.

Use AddFile() if you need to require a file to be present.

All the files that can be processed with a decoder will be compiled into the configuration.

func AddFile

func AddFile(fs fs.FS, filename string) Option

AddFile adds exactly one file to the list of files to be compiled into a configuration. The filename must be relative to the fs. If the file specified cannot be processed it is considered an error.

func AddFileAs added in v0.24.0

func AddFileAs(fs fs.FS, asType, filename string) Option

AddFileAs is the same as AddFile() except the file is decoded as the specified type.

func AddFiles

func AddFiles(fs fs.FS, filenames ...string) Option

AddFiles adds any number of files to the list of files to be compiled into a configuration. The filenames must be relative to the fs. Any files that cannot be processed will be ignored. It is not an error if any files are missing or if all the files cannot be processed.

Use AddFile() if you need to require a file to be present.

All the files that can be processed with a decoder will be compiled into the configuration.

func AddFilesAs added in v0.24.0

func AddFilesAs(fs fs.FS, asType string, filenames ...string) Option

AddFilesAs is the same as AddFiles() except the files are decoded as the specified type.

func AddFilesHalt added in v0.19.0

func AddFilesHalt(fs fs.FS, filenames ...string) Option

AddFilesHalt adds any number of files to the list of files to be compiled into a configuration and if any are added halts the process of adding more file records.

This option works the same as AddFiles() except no further files are processed if this group added any files.

This is generally going to be useful for configuring a set of paths to search for configuration and stopping when it is found.

func AddFilesHaltAs added in v0.24.0

func AddFilesHaltAs(fs fs.FS, asType string, filenames ...string) Option

AddFilesHaltAs is the same as AddFilesHalt() except the files are decoded as the specified type.

func AddJumbled added in v0.3.6

func AddJumbled(abs, rel fs.FS, paths ...string) Option

AddJumbled adds any number of files or directories (excluding all subdirectories) for inclusion when compiling the configuration. The files and directories are sorted into either a relative based filesystem or an absolute path based filesystem. Any files or directories that cannot be processed will be ignored. It is not an error if any files are missing or if all the files cannot be processed.

Note: The paths are expected to use the fs.FS path separator ("/") and format.

Use AddFile() if you need to require a file to be present.

Generally this option is useful when processing files from the same filesystem but some are absolute path based and others are relative path based. Instead of needing to sort the files into two buckets, this option will handle that for you.

func AddJumbledHalt added in v0.19.0

func AddJumbledHalt(abs, rel fs.FS, paths ...string) Option

AddJumbledHalt adds any number of files or directories (excluding all subdirectories) for inclusion when compiling the configurationm, and if any are added halts the process of adding more file records.

Note: The paths are expected to use the fs.FS path separator ("/") and format.

This option works the same as AddJumbled() except no further files are processed if this group added any files.

This is generally going to be useful for configuring a set of paths to search for configuration and stopping when it is found.

func AddTree

func AddTree(fs fs.FS, path string) Option

AddTree adds a directory tree (including all subdirectories) for inclusion when compiling the configuration. Any files that cannot be processed will be ignored. It is not an error if any files are missing, or if all the files cannot be processed.

Use AddFile() if you need to require a file to be present.

All the files that can be processed with a decoder will be compiled into the configuration.

func AddTreeHalt added in v0.19.0

func AddTreeHalt(fs fs.FS, path string) Option

AddTreeHalt adds a directory tree (including all subdirectories) for inclusion when compiling the configuration, and if any are added halts the process of adding more file records.

This option works the same as AddTree() except no further files are processed if this group added any files.

This is generally going to be useful for configuring a set of paths to search for configuration and stopping when it is found.

func AddTrees

func AddTrees(fs fs.FS, paths ...string) Option

AddTrees adds a list of directory trees (including all subdirectories) for inclusion when compiling the configuration. Any files that cannot be processed will be ignored. It is not an error if any files are missing, or if all the files cannot be processed.

Use AddFile() if you need to require a file to be present.

All the files that can be processed with a decoder will be compiled into the configuration.

func AddValue

func AddValue(recordName, key string, val any, opts ...ValueOption) Option

AddValues provides a simple way to set additional configuration values at runtime.

To place the configuration at the root use `goschtalt.Root` (Root) instead of "" for more clarity.

Valid Option Types:

func AddValueGetter added in v0.17.0

func AddValueGetter(recordName, key string, getter ValueGetter, opts ...ValueOption) Option

AddValueGetter provides a simple way to set additional configuration values at runtime via a function call. Note that the provided ValueGetter will be called each time the configuration is compiled, allowing the value returned to change if desired.

To place the configuration at the root use `goschtalt.Root` (Root) instead of "" for more clarity.

Valid Option Types:

func AutoCompile

func AutoCompile(enable ...bool) Option

AutoCompile instructs New() and [With]() to also compile the configuration after all the options are applied if enable is true or omitted. Passing an enable value of false disables the extra behavior.

The enable bool value is optional & assumed to be `true` if omitted. The first specified value is used if provided. A value of `false` disables the option.

Default

AutoCompile is enabled.

func ConfigIs added in v0.21.0

func ConfigIs(format string, overrides ...map[string]string) Option

ConfigIs provides a strict field/key mapper that converts the config values from the specified nomenclature into the go structure name.

Since the names of the different formatting styles are not standardized, only a few of the common ones have consts defined. The complete list is below:

  • "two words" aliases: "lower case"
  • "two-words" aliases: "kebab-case"
  • "two-Words" aliases: "camel-Kebab-Case"
  • "two_words" aliases: "snake_case"
  • "two_Words" aliases: "camel_Snake_Case"
  • "twowords" aliases: "flatcase"
  • "twoWords" aliases: "camelCase"
  • "Two Words" aliases: "Title Case"
  • "Two-Words" aliases: "Pascal-Kebab-Case", "Title-Kebab-Case"
  • "Two_Words" aliases: "Pascal_Snake_Case", "Title_Snake_Case"
  • "TwoWords" aliases: "PascalCase"
  • "TWO WORDS" aliases: "SCREAMING CASE"
  • "TWO-WORDS" aliases: "SCREAMING-KEBAB-CASE"
  • "TWO_WORDS" aliases: "SCREAMING_SNAKE_CASE"
  • "TWOWORDS" aliases: "UPPERCASE"

This option provides a KeymapMapper based option that will convert every input string, ending the chain 100% of the time.

To make adjustments pass in a map (or many) with keys being the golang structure field names and values being the configuration name.

func DefaultMarshalOptions

func DefaultMarshalOptions(opts ...MarshalOption) Option

DefaultMarshalOptions allows customization of the desired options for all invocations of the [Marshal]() function. This should make consistent use use of the Marshal() call easier.

Valid Option Types:

func DefaultUnmarshalOptions

func DefaultUnmarshalOptions(opts ...UnmarshalOption) Option

DefaultUnmarshalOptions allows customization of the desired options for all invocations of the Unmarshal() function. This should make consistent use use of the Unmarshal() call easier.

Valid Option Types:

func DefaultValueOptions

func DefaultValueOptions(opts ...ValueOption) Option

DefaultValueOptions allows customization of the desired options for all invocations of the AddValue() and [AddValueFunc]() functions. This should make consistent use use of these functions easier.

Valid Option Types:

func DisableDefaultPackageOptions

func DisableDefaultPackageOptions() Option

DisableDefaultPackageOptions provides a way to explicitly not use any preconfigured default values by this package and instead use just the options specified.

See: DefaultOptions

func Expand

func Expand(expander Expander, opts ...ExpandOption) Option

Expand provides a way to expand variables in values throughout the configuration tree. Expand() can be called multiple times to expand variables based on additional configurations and mappers.

The initial discovery of a variable to expand in the configuration tree value is determined by the Start and End delimiters options provided. The default delimiters are "${" and "}" respectively. Further expansions of values replaces ${var} or $var in the string based on the mapping function provided.

Expand() and ExpandEnv() directives are evaluated in the order specified.

Valid Option Types:

func ExpandEnv

func ExpandEnv(opts ...ExpandOption) Option

ExpandEnv is a simple way to add automatic environment variable expansion after the configuration has been compiled.

Expand() and ExpandEnv() directives are evaluated in the order specified.

Valid Option Types:

func HintDecoder added in v0.22.0

func HintDecoder(label, url string, exts ...string) Option

HintDecoder provides a way to suggest importing additional decoders without needing to include a specific one in goschtalt. Generally, this option is not needed unless you are creating pre-set option lists.

func HintEncoder added in v0.22.0

func HintEncoder(label, url string, exts ...string) Option

HintEncoder provides a way to suggest importing additional encoders without needing to include a specific one in goschtalt. Generally, this option is not needed unless you are creating pre-set option lists.

func NamedOptions added in v0.19.0

func NamedOptions(name string, opts ...Option) Option

NamedOptions provides a way to group multiple options together into an easy to use Option with a custom name in the output. This is helps users track down the actual option they called.

func Options added in v0.4.0

func Options(opts ...Option) Option

Options provides a way to group multiple options together into an easy to use Option.

func SetHasher added in v0.22.0

func SetHasher(h Hasher) Option

SetHasher provides a way to specify which hash algorithm to use on the object tree. If the provided Hasher is nil, then no hashing is done (default).

func SetKeyDelimiter

func SetKeyDelimiter(delimiter string) Option

SetKeyDelimiter provides the delimiter used for determining key parts. A string with length of at least 1 must be provided.

Default

The default value is '.'.

func SetMaxExpansions added in v0.25.0

func SetMaxExpansions(max int) Option

SetMaxExpansions provides a way to set the maximum number of expansions allowed before a recursion error is returned. The value must be greater than 0.

Default

The default value is 10000.

func SortRecords added in v0.17.0

func SortRecords(sorter RecordSorter) Option

SortRecords provides a way to specify how you want the files sorted prior to their merge. This function provides a way to provide a completely custom sorting algorithm.

See also: SortRecordsLexically, SortRecordsNaturally

Default

The default is SortRecordsNaturally.

func SortRecordsLexically

func SortRecordsLexically() Option

SortRecordsLexically provides a built in sorter based on lexical order.

See also: SortRecords, SortRecordsNaturally

Default

The default is SortRecordsNaturally.

func SortRecordsNaturally

func SortRecordsNaturally() Option

SortRecordsNaturally provides a built in sorter based on natural order. More information about natural sort order: https://en.wikipedia.org/wiki/Natural_sort_order

Notes:

  • Don't use floating point numbers. They are treated like 2 integers separated by the '.' rune.
  • Any leading 0 values are dropped from the number.

Example sort order:

01_foo.yml
2_foo.yml
98_foo.yml
99 dogs.yml
99_Abc.yml
99_cli.yml
99_mine.yml
100_alpha.yml

See also: SortRecords, SortRecordsLexically

Default

The default is SortRecordsNaturally.

func StdCfgLayout added in v0.19.0

func StdCfgLayout(appName string, files ...string) Option

StdCfgLayout takes a fairly opinionated view of where configuration files are typically found based on the operating system.

For non-windows implementations:

The first individual configuration file or 'conf.d' directory found is used. Once a set of configuration file(s) has been found any configuration files included afterward are ignored.

The order the files/directories are searched.

  1. The provided files in the argument list. If any are provided, configuration must be found exclusively here.

2. Any files matching this path (if it exists) and glob:

  • $HOME/.<appName>/<appName>.*

3. Any files found in this directory (if it exists):

  • $HOME/.<appName>/conf.d/

4. Any files matching this path (if it exists) and glob:

  • /etc/<appName>/<appName>.*

5. Any files found in this directory (if it exists):

  • /etc/<appName>/conf.d/

For windows implementations:

StdCfgLayout doesn't support a shared windows layout today. One is welcome.

func WithDecoder

func WithDecoder(d decoder.Decoder) Option

WithDecoder registers a Decoder for the specific file extensions provided. Attempting to register a duplicate extension is not supported.

See also: WithEncoder

func WithEncoder

func WithEncoder(enc encoder.Encoder) Option

WithEncoder registers a Encoder for the specific file extensions provided. Attempting to register a duplicate extension is not supported.

See also: WithDecoder

type RecordSorter added in v0.17.0

type RecordSorter interface {
	// Less reports whether a is before b.
	Less(a, b string) bool
}

RecordSorter provides the methods needed to sort records.

type RecordSorterFunc added in v0.18.0

type RecordSorterFunc func(string, string) bool

The RecordSorterFunc type is an adapter to allow the use of ordinary functions as RecordSorters. If f is a function with the appropriate signature, RecordSorterFunc(f) is a RecordSorter that calls f.

func (RecordSorterFunc) Less added in v0.18.0

func (f RecordSorterFunc) Less(a, b string) bool

Less calls f(a, b)

type UnmarshalOption

type UnmarshalOption interface {
	fmt.Stringer
	// contains filtered or unexported methods
}

UnmarshalOption provides specific configuration for the process of producing a document based on the present information in the goschtalt object.

func AdaptFromCfg added in v0.10.0

func AdaptFromCfg(adapter AdapterFromCfg, label ...string) UnmarshalOption

AdaptFromCfg converts a value from the configuration form into the golang form if possible.

If the combination of from and to are unknown or unsupported return ErrNotApplicable as the error with a nil value.

If ErrNotApplicable is returned the value returned will be ignored.

The optional label parameter allows you to provide the function name of the adapter so it is more clear which adapters are registered.

All AdapterFromCfg provided are called in the order provided until one returns no error or the end of the list is encountered.

func Optional

func Optional(optional ...bool) UnmarshalOption

Optional provides a way to allow the requested configuration to not be present and return an empty structure without an error instead of failing.

The optional bool value is optional & assumed to be true if omitted. The first specified value is used if provided. A value of false disables the option.

See also: Required

Default

The default behavior is to require the request to be present.

func Required

func Required(required ...bool) UnmarshalOption

Required provides a way to allow the requested configuration to be required and return an error if it is missing.

The required bool value is optional & assumed to be true if omitted. The first specified value is used if provided. A value of false disables the option.

See also: Optional

Default

The default behavior is to require the request to be present.

func Strictness added in v0.10.0

func Strictness(level Level) UnmarshalOption

Strictness defines the relationship between the configuration values and the structure fields. The level parameter defines which mode to use.

  • NONE - Any confiugration values are ok. Neither missing nor extra values is an error.
  • SUBSET - The configuration values are limited to the set defined by the structure fields or it is an error. Missing configuration is ok, but extra configuration values is an error.
  • COMPLETE - The configuration values must completely fill the structure fields or it is an error. Extra configuration is ok, but missing configuration values is an error.
  • EXACT - The configuration values must exactly fill the structure fields or it is an error. Extra or missing configuration are both errors.
  • NONE - (default) Both extra or too few configuration values as well as

Default

NONE

func WithValidator added in v0.5.0

func WithValidator(v Validator) UnmarshalOption

WithValidator provides a way to specify a validator to use after a structure has been unmarshaled, but prior to returning the data. This allows for an easy way to consistently validate configuration as it is being consumed. If the validator function returns an error the Unmarshal() operation will result in a failure and return the error.

Setting the value to nil disables validation.

Default

The default behavior is to not validate.

type UnmarshalValueOption added in v0.7.0

type UnmarshalValueOption interface {
	fmt.Stringer

	UnmarshalOption
	ValueOption
}

UnmarshalValueOption options are options shared between UnmarshalOption and ValueOption interfaces.

func Keymap added in v0.9.0

func Keymap(m map[string]string) UnmarshalValueOption

Keymap takes a map of strings to strings and adds it to the existing chain of keymaps. The key of the map is the golang structure field name and the value is the goschtalt configuration tree name string. The value of "-" means do not convert, and an empty string means call the next in the chain.

For example, the map below converts a structure field "FooBarIP" to "foobar_ip".

Keymap( map[string]string{
	"FooBarIP": "foobar_ip",
})

func KeymapMapper added in v0.17.0

func KeymapMapper(mapper Mapper) UnmarshalValueOption

KeymapMapper takes a Mapper function and adds it to the existing chain of mappers, in the front of the list.

This allows for multiple mappers to be specified instead of requiring a single mapper with full knowledge of how to map everything. This makes it easy to add logic to remap full keys without needing to re-implement the underlying converters.

func KeymapReport added in v0.16.0

func KeymapReport(r KeymapReporter) UnmarshalValueOption

KeymapReport takes an object that implements a KeymapReporter interface and adds it to the existing chain of reporters. A KeymapReporter provides a way to report on how the keys were actually mapped.

func TagName

func TagName(name string) UnmarshalValueOption

TagName defines which tag goschtalt honors when it unmarshals to/from structures. The name string defines the new tag name to read. If an empty string is passed in then the module default will be used.

Default

"goschtalt"

type Unmarshaler added in v0.14.0

type Unmarshaler func(key string, result any, opts ...UnmarshalOption) error

Unmarshaler provides a special use Unmarshal() function during [AddBufferFunc]() and [AddValueFunc]() option provided callbacks. This pattern allows the specified function access to the configuration values up to this point. Expansion of any Expand() or ExpandEnv() options is also applied to the configuration tree provided.

type Validator added in v0.17.0

type Validator interface {
	Validate(any) error
}

Validator provides a method that validates an arbitrary data object and returns an error if one is detected.

type ValidatorFunc added in v0.18.0

type ValidatorFunc func(any) error

The ValidatorFunc type is an adapter to allow the use of ordinary functions as Validators. If f is a function with the appropriate signature, ValidatorFunc(f) is a Validator that calls f.

func (ValidatorFunc) Validate added in v0.18.0

func (f ValidatorFunc) Validate(a any) error

Get calls f(a)

type ValueGetter added in v0.17.0

type ValueGetter interface {
	// Get is called each time the configuration is compiled.  The recordName
	// and an Unmarshaler with the present stage of configuration and expanded
	// variables are provided to assist.  A data structure (object, string, int, etc)
	// or an error is returned.
	Get(recordName string, u Unmarshaler) (any, error)
}

ValueGetter provides the methods needed to get the value.

type ValueGetterFunc added in v0.18.0

type ValueGetterFunc func(string, Unmarshaler) (any, error)

The ValueGetterFunc type is an adapter to allow the use of ordinary functions as ValueGetters. If f is a function with the appropriate signature, ValueGetterFunc(f) is a ValueGetter that calls f.

func (ValueGetterFunc) Get added in v0.18.0

func (f ValueGetterFunc) Get(rn string, u Unmarshaler) (any, error)

Get calls f(rn, u)

type ValueOption

type ValueOption interface {
	fmt.Stringer
	// contains filtered or unexported methods
}

ValueOption provides the means to configure options around variable mapping as well as if the specific value being added should be a default or a normal configuration value.

See also UnmarshalValueOption which can be used as ValueOption options.

func AdaptToCfg added in v0.10.0

func AdaptToCfg(adapter AdapterToCfg, label ...string) ValueOption

AdaptToCfg converts a value a golang struct object into the configuration form. It assumed that the converter knows best what the form should be.

If the combination of from and t are unknown or unsupported return ErrNotApplicable as the error with a nil value.

If ErrNotApplicable is returned the value returned will be ignored.

The optional label parameter allows you to provide the function name of the adapter so it is more clear which adapters are registered.

func FailOnNonSerializable added in v0.3.5

func FailOnNonSerializable(fail ...bool) ValueOption

FailOnNonSerializable specifies that an error should be returned if any non-serializable objects (channels, functions, unsafe pointers) are encountered in the resulting configuration tree. Non-serializable objects cannot be in the configuration sets that goschtalt works with.

The fail bool value is optional & assumed to be `true` if omitted. The first specified value is used if provided. A value of `false` disables the option.

The default behavior is to ignore and drop any non-serializable objects.

Directories

Path Synopsis
internal
casbab
Package casbab is a Go library for converting representation style of compound words or phrases.
Package casbab is a Go library for converting representation style of compound words or phrases.
structs
Package structs contains various utilities functions to work with structs.
Package structs contains various utilities functions to work with structs.
pkg
adapter
Provides adapters for built-in types and interfaces.
Provides adapters for built-in types and interfaces.
typical
Provides a simple way to get all the options you typically expect to be set out of the box in goschtalt.
Provides a simple way to get all the options you typically expect to be set out of the box in goschtalt.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL