file

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2022 License: Unlicense Imports: 10 Imported by: 0

Documentation

Overview

Package file provides a flagr.Parser that is able to read config files and set the appropriate flags.

Example
package main

import (
	"encoding/json"
	"encoding/xml"
	"errors"
	"os"

	"github.com/flga/flagr"
	"github.com/flga/flagr/file"
)

func main() {
	var fs flagr.Set

	_ = flagr.Add(&fs, "child.flagName", flagr.Int(1), "usage")
	configFile := flagr.Add(&fs, "config", flagr.String("config.json"), "usage")

	if err := fs.Parse(
		os.Args[1:],
		file.Parse(
			file.Static("config.json"), // uses the static file "config.json" as a source
			file.Mux{
				".json": json.Unmarshal, // tells the parser how to handler ".json" files
			},
			file.IgnoreMissingFile(),         // makes the file optional, if it does not exist it is not considered an error
			file.WithFS(nil),                 // uses the given fs.FS to lookup the file
			file.WithMapper(file.NoopMapper), // map flag names to jsonpath (root.child.leaf) using the given mapper, since the flags are already in dot notation no mapping is necessary
		),
		file.Parse(
			configFile, // this time, use a dynamic config file
			file.Mux{
				".json": json.Unmarshal,
				".xml":  xml.Unmarshal, // we're able to parse xml now too
			},
		),
	); err != nil {
		if errors.Is(err, flagr.ErrHelp) {
			os.Exit(2)
		}
		os.Exit(1)
	}
}
Output:

Index

Examples

Constants

View Source
const KeyPathSeparator = "."

KeyPathSeparator is the value used to separate sub paths in path expressions. A typical KeyPath will look something like "root.inner.prop".

Variables

This section is empty.

Functions

func Parse added in v0.4.0

func Parse(path *string, mux Mux, options ...Option) flagr.Parser

Parse returns a flagr.FlagParser that parses the file stored in path and assigns the results to any flags that have not yet been set.

Flags cannot have complex values, only primitive values are allowed: strings, bools, ints etc. An exception is made for slices as flags can be repeatable.

This is a valid JSON declaration for a flag named "foo".

{
	"foo": 42
}

So is this (assuming that foo is repeatable, otherwise it will be set to the last value of the array):

{
	"foo": [1, 2, 3]
}

But this is not, as there is no way to map a json object to a flag value:

{
	"foo": {"bar": 42}
}

The file contents are read and decoded using the decoder mapped to the file's extension. If decoding fails it returns ErrDecode, if no suitable decoder is found it returns ErrUnsupported.

File decoding is controlled by Mux. At least one mapping must be provided.

If the file cannot be read an error is returned. If it cannot be found and IgnoreMissingFile has been set, the error is omitted and parsing stops.

After decoding, we will go trough all the flags that have not yet been set, and try to find their values in the decoded result. Mapping flag names to the decoded properties is done using the given Mapper. If no Mapper is provided it'll use NoopMapper.

If no corresponding value can be found, the flag will remain unset. If a value is found it is converted back to a string and fed trough flag.Value.Set, if this fails we will return the error. If we are unable to convert the value to a string (for example, if it's an object) ErrVal will be returned containing the key that failed and the error.

func Static added in v0.4.0

func Static(path string) *string

Static is a helper for calling Parse with a static path.

Types

type DecoderFunc

type DecoderFunc func(data []byte, v interface{}) error

DecoderFunc is a function that deserializes data into v. Functions like json.Unmarshal conform to this type.

type ErrDecode

type ErrDecode struct {
	Err error
}

ErrDecode is returned if deserialization fails.

func (ErrDecode) Error

func (e ErrDecode) Error() string

func (ErrDecode) Unwrap

func (e ErrDecode) Unwrap() error

type ErrUnsupported

type ErrUnsupported struct {
	Ext       Extension
	Available []Extension
}

ErrUnsupported is returned when we could not find a DecoderFunc in the given Mux with the provided file's extension.

func (ErrUnsupported) Error

func (e ErrUnsupported) Error() string

type ErrVal

type ErrVal struct {
	Key KeyPath
	Err error
}

ErrVal is returned when we're unable to convert a value to a string.

func (ErrVal) Error

func (e ErrVal) Error() string

func (ErrVal) Unwrap

func (e ErrVal) Unwrap() error

type Extension

type Extension string

Extension represents a file extension. Values must include the leading dot.

type KeyPath

type KeyPath string

KeyPath represents a path expression which is used to walk the values produced by the decoding of the config file. It is akin to jsonpath but we only support dot notation.

func NoopMapper added in v0.4.0

func NoopMapper(flagName string) KeyPath

NoopMapper returns the given flag name as is.

func (KeyPath) Split

func (k KeyPath) Split() []string

Split is a convenience method to split a KeyPath into sub paths.

type Mapper added in v0.4.0

type Mapper func(flagName string) KeyPath

Mapper converts a flag name into a KeyPath.

Sub paths must be separated by KeyPathSeparator and are not allowed to contain it within them.

Given a flag name like "api_http_address" and a json config file structured as

{
    "api": {
        "http": {
            "address": "0.0.0.0"
        }
    }
}

the corresponding KeyPath should be "api.http.address".

If the json file were flat, no mapping would be necessary as long as the field name and the flag name are equal:

{
	"api_http_address": "0.0.0.0"
}

the corresponding KeyPath should be "api_http_address".

type Mux

type Mux map[Extension]DecoderFunc

Mux maps Extension to DecoderFunc, it is valid for the same DecoderFunc to be used for multiple Extension. For example, if unmarshaling yaml it is encouraged to map both ".yaml" and ".yml" to yaml.Unmarshal.

type Option

type Option func(*Options)

Option is a function that mutates Options.

func IgnoreMissingFile

func IgnoreMissingFile() Option

IgnoreMissingFile makes it so that if the provided file doesn't exist, it is not considered an error.

func WithFS

func WithFS(fs fs.FS) Option

With FS configures the Parser such that the file is retrieved from the given fs instead of the primary filesystem.

func WithMapper added in v0.4.0

func WithMapper(n Mapper) Option

WithMapper configures Parser to use the given Mapper when mapping flag names to KeyPath.

type Options

type Options struct {
	Mapper            Mapper // Maps flag names to property paths
	IgnoreMissingFile bool   // If true, we don't treat [fs.ErrNotExist] as an error.
	FS                fs.FS  // If provided, this will be used instead of the primary filesystem.
}

Options contains all the options used to parse a config file.

Jump to

Keyboard shortcuts

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