figtree

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Mar 30, 2025 License: MIT Imports: 19 Imported by: 0

README

Fig Tree

Fig Tree is a command line utility configuration manager that you can refer to as figs, as you conFIGure your application's runtime.

Figtree

This package is biblically inspired by YAHUAH, the only man who was mocked by the Jews for being crucified and came down from that cross to deliver the judgement of 70 AD. YAHUAH has returned.

Installation

To use figtree in your project, go get it...

go get -u github.com/andreimerlescu/figtree

Usage

To use figs package in your Go code, you need to import it:

import "github.com/andreimerlescu/figtree"
Using Fig Tree
Method Usage
figtree.New() Does not perform Mutation tracking.
figtree.Grow() Provides Mutation tracking.
figtree.With(figtree.Options{Tracking: true}) Provides Mutation tracking.

Configurable properties have whats called metagenesis to them, which are types, like String, Bool, Float64, etc.

New properties can be registered before calling Parse() using a metagenesis pattern of figs.New<Metagenesis>(), like figs.NewString() or figs.NewFloat64(), etc.

Only one validator per property is permitted, and additional WithValidator() calls with duplicate name entries will record an error in the Fig.Error property of the property's "fruit, aka *Fig{}".

Figtree keeps a withered copy of figs.New<Metagenesis>() property declarations and has an Options{Tracking: true} argument that can be passed into figs.New() that enables the figs.Mutations() receiver channel to receive anytime a property value changes, a new figtree.Mutation.

Figtree includes 36 different built-in figs.WithValidator(name, figtree.Assure<Rule>[()]) that can validate your various Mutageneses without needing to write every validation yourself. For larger or custom validations, the 2nd argument requires a func (interface{}) error signature in order use.

package main

import (
    "fmt"
    "log"
    "time"
    "github.com/andreimerlescu/figtree"
)

func main() {
	figs := figtree.Grow()
	figs.NewUnitDuration("minutes", 1, time.Minute, "minutes for timer")
    figs.WithValidator("minutes", figtree.AssureDurationLessThan(time.Hour))
	err := figs.Parse()
	if err != nil {
		log.Fatal(err)
	}
    log.Println(*figs.UnitDuration("minutes"))
}
Available Validators
Mutagenesis figtree.ValidatorFunc Notes
tString AssureStringLength Ensures a string is a specific length.
tString AssureStringSubstring Ensures a string contains a specific substring (case-sensitive).
tString AssureStringNotEmpty Ensures a string is not empty.
tString AssureStringContains Ensures a string contains a specific substring.
tBool AssureBoolTrue Ensures a boolean value is true.
tBool AssureBoolFalse Ensures a boolean value is false.
tInt AssurePositiveInt Ensures an integer is positive (greater than zero).
tInt AssureNegativeInt Ensures an integer is negative (less than zero).
tInt AssureIntGreaterThan Ensures an integer is greater than a specified value (exclusive).
tInt AssureIntLessThan Ensures an integer is less than a specified value (exclusive).
tInt AssureIntInRange Ensures an integer is within a specified range (inclusive).
tInt64 AssureInt64GreaterThan Ensures an int64 is greater than a specified value (exclusive).
tInt64 AssureInt64LessThan Ensures an int64 is less than a specified value (exclusive).
tInt64 AssurePositiveInt64 Ensures an int64 is positive (greater than zero).
tInt64 AssureInt64InRange Ensures an int64 is within a specified range (inclusive).
tFloat64 AssureFloat64Positive Ensures a float64 is positive (greater than zero).
tFloat64 AssureFloat64InRange Ensures a float64 is within a specified range (inclusive).
tFloat64 AssureFloat64GreaterThan Ensures a float64 is greater than a specified value (exclusive).
tFloat64 AssureFloat64LessThan Ensures a float64 is less than a specified value (exclusive).
tFloat64 AssureFloat64NotNaN Ensures a float64 is not NaN.
tDuration AssureDurationGreaterThan Ensures a time.Duration is greater than a specified value (exclusive).
tDuration AssureDurationLessThan Ensures a time.Duration is less than a specified value (exclusive).
tDuration AssureDurationPositive Ensures a time.Duration is positive (greater than zero).
tDuration AssureDurationMax Ensures a time.Duration does not exceed a maximum value.
tDuration AssureDurationMin Ensures a time.Duration is at least a minimum value.
tList AssureListNotEmpty Ensures a list (*ListFlag, *[]string, or []string) is not empty.
tList AssureListMinLength Ensures a list has at least a minimum number of elements.
tList AssureListContains Ensures a list contains a specific string value.
tList AssureListContainsKey Ensures a list contains a specific string.
tList AssureListLength Ensures a list has exactly the specified length.
tMap AssureMapNotEmpty Ensures a map (*MapFlag, *map[string]string, or map[string]string) is not empty.
tMap AssureMapHasKey Ensures a map contains a specific key.
tMap AssureMapValueMatches Ensures a map has a specific key with a matching value.
tMap AssureMapHasKeys Ensures a map contains all specified keys.
tMap AssureMapLength Ensures a map has exactly the specified length.
Complex Example Usage
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "os/signal"
    "path/filepath"
    "strings"
    "syscall"
    "time"

    "github.com/andreimerlescu/figtree"
)

func main() {
    // Create a context that can be canceled on SIGINT/SIGTERM
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    // Set up signal handling for graceful shutdown
    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

    // Plant the fig tree with mutation tracking enabled
    figs := figtree.Grow()
    // Note: Grow() sets Options{Tracking: true}, enabling mutation tracking via mutationsCh

    // Define all configuration types with initial values and validators
    figs.NewInt("workers", 10, "Number of workers")
    figs.WithValidator("workers", func(v interface{}) error {
        if val, ok := v.(int); ok && val < 1 {
            return fmt.Errorf("workers must be at least 1")
        }
        return nil
    })
    figs.NewInt64("maxRetries", 5, "Maximum retry attempts")
    figs.WithValidator("maxRetries", figtree.AssurePositiveInt64)
    figs.NewFloat64("threshold", 0.75, "Threshold value")
    figs.WithValidator("threshold", func(v interface{}) error {
        if val, ok := v.(float64); ok && (val < 0 || val > 1) {
            return fmt.Errorf("threshold must be between 0 and 1")
        }
        return nil
    })
    figs.NewString("endpoint", "http://example.com", "API endpoint")
    figs.WithValidator("endpoint", func(v interface{}) error {
        if val, ok := v.(string); ok && !strings.HasPrefix(val, "http") {
            return fmt.Errorf("endpoint must start with http")
        }
        return nil
    })
    figs.NewBool("debug", false, "Enable debug mode")
    figs.NewDuration("timeout", 30*time.Second, "Request timeout")
    figs.NewUnitDuration("interval", 1, time.Minute, "Polling interval in minutes")
    figs.WithValidator("interval", figtree.AssureDurationGreaterThan(30*time.Second))
    figs.NewList("servers", []string{"server1", "server2"}, "List of servers")
    figs.NewMap("metadata", map[string]string{"env": "prod", "version": "1.0"}, "Metadata key-value pairs")
    // Note: Each New* method registers a flag and initializes withered; WithValidator adds validation logic

    // Attempt to load from a config file, falling back to defaults
    configFile := filepath.Join(".", "config.yaml")
    if err := figs.ParseFile(configFile); err != nil {
        log.Printf("No config file at %s, using defaults: %v", configFile, err)
        err := figs.Parse() // Parse command-line flags and environment variables
        if err != nil {
            log.Fatal(err)
        }
    }
    // Note: LoadFile tries the specified file, then env vars; Parse handles flags/env if file fails

    // Demonstrate Resurrect by accessing an undefined key
    undefined := figs.String("undefined")
    log.Printf("Resurrected undefined key: %s", *undefined)
    // Note: Resurrect creates a new string entry if undefined, checking env and files first

    // Print initial configuration using Usage
    log.Println("Initial configuration:")
    log.Println(figs.Usage())
    // Note: Usage displays all registered flags in a human-readable format

    // Simulate periodic access in a goroutine to check for mutations
    go func() {
        ticker := time.NewTicker(5 * time.Second)
        defer ticker.Stop()
        for {
            select {
            case <-ctx.Done():
                log.Println("Worker shutting down due to context cancellation")
                return
            case <-ticker.C:
                // Access all config values, triggering mutation checks
                log.Printf("Workers: %d, MaxRetries: %d, Threshold: %.2f, Endpoint: %s, Debug: %t, Timeout: %s, Interval: %s, Servers: %v, Metadata: %v",
                    *figs.Int("workers"),
                    *figs.Int64("maxRetries"),
                    *figs.Float64("threshold"),
                    *figs.String("endpoint"),
                    *figs.Bool("debug"),
                    *figs.Duration("timeout"),
                    *figs.UnitDuration("interval"),
                    *figs.List("servers"),
                    *figs.Map("metadata"),
                )
                // Note: Getters check env against withered values, sending mutations if tracking is on
            }
        }
    }()

    // Demonstrate Curse and Recall by toggling tracking
    log.Println("Cursing the tree (disabling tracking)...")
    figs.Curse()
    time.Sleep(2 * time.Second) // Let some ticks pass
    log.Println("Recalling the tree (re-enabling tracking)...")
    figs.Recall()
    // Note: Curse locks the tree and closes mutationsCh; Recall unlocks and reopens it

    // Main loop to listen for signals and mutations
    for {
        select {
        case <-ctx.Done():
            log.Println("Context canceled, shutting down")
            return
        case sig := <-sigCh:
            log.Printf("Received signal: %v, initiating shutdown", sig)
            cancel() // Cancel context to stop goroutines
            // Note: SIGINT/SIGTERM triggers shutdown by canceling the context
        case mutation, ok := <-figs.Mutations():
            if !ok {
                log.Println("Mutations channel closed, shutting down")
                return
            }
            log.Printf("Mutation detected: %s changed from %v to %v at %s",
                mutation.Property, mutation.Old, mutation.New, mutation.When)
            // Note: This logs a mutation (e.g., change "workers" to 20 in env)
        }
    }
}

// Example config.yaml (create in the same directory):
/*
workers: 15
maxRetries: 3
threshold: 0.9
endpoint: "https://api.example.com"
debug: true
timeout: 45s
interval: 2
servers: "server3,server4"
metadata: "env=dev,version=2.0"
*/
  1. Create config.yaml
workers: 15
maxRetries: 3
threshold: 0.9
endpoint: "https://api.example.com"
debug: true
timeout: 45s
interval: 2
servers: "server3,server4"
metadata: "env=dev,version=2.0"
  1. Compile and run
go run main.go
  1. Output (example...)
2025/03/27 00:50:41 Initial configuration:
2025/03/27 00:50:41 Usage of ./main:
  -debug: Enable debug mode (default: false)
  -endpoint: API endpoint (default: "https://api.example.com")
  -interval: Polling interval in minutes (default: 2m0s)
  -maxRetries: Maximum retry attempts (default: 3)
  -metadata: Metadata key-value pairs (default: "env=dev,version=2.0")
  -servers: List of servers (default: "server3,server4")
  -threshold: Threshold value (default: 0.9)
  -timeout: Request timeout (default: 45s)
  -workers: Number of workers (default: 15)
2025/03/27 00:50:41 Resurrected undefined key: 
2025/03/27 00:50:46 Workers: 15, MaxRetries: 3, Threshold: 0.90, Endpoint: https://api.example.com, Debug: true, Timeout: 45s, Interval: 2m0s, Servers: [server3 server4], Metadata: map[env:dev version:2.0]
2025/03/27 00:50:46 Cursing the tree (disabling tracking)...
2025/03/27 00:50:48 Recalling the tree (re-enabling tracking)...
[after export workers=20]
2025/03/27 00:50:51 Mutation detected: workers changed from 15 to 20 at 2025-03-27 00:50:51
2025/03/27 00:50:51 Workers: 20, MaxRetries: 3, Threshold: 0.90, Endpoint: https://api.example.com, Debug: true, Timeout: 45s, Interval: 2m0s, Servers: [server3 server4], Metadata: map[env:dev version:2.0]
[after Ctrl+C]
2025/03/27 00:50:56 Received signal: interrupt, initiating shutdown
2025/03/27 00:50:56 Context canceled, shutting down
Custom Config File Path
figs := figtree.Grow()
figs.ConfigFilePath = filepath.Join("/","etc","myapp","myapp.production.yaml")
figs.Load()
Defining Configuration Variables

The Configurable package provides several methods to define different types of configuration variables. Each method takes a name, default value, and usage description as parameters and returns a pointer to the respective variable:

const (
   kPort string = "port"
   kTimeout string = "timeout"
   kDebug string = "debug"
)
figs.NewInt(kPort, 8080, "The port number to listen on")
figs.NewUnitDuration(kTimeout, time.Second * 5, time.Second, "The timeout duration for requests")
figs.NewBool(kDebug, false, "Enable debug mode")
Loading Configuration from Files

You can load configuration data from JSON, YAML, and INI files using the LoadFile() method:

err := figtree.Grow().ParseFile("config.json")
if err != nil {
    // Handle error
}

The package automatically parses the file based on its extension. Make sure to place the file in the correct format in the specified location.

Parsing Command-Line Arguments

The Configurable package also allows you to parse command-line arguments. Call the Parse() method to parse the arguments after defining your configuration variables:

figs := figtree.New()
figs.Parse()

or

---
workers: 45
seconds: 47
const kWorkers string = "workers"
const kSeconds string = "seconds"
figs := figtree.With(figtree.Options{Tracking: true})
figs.NewInt(kWorkers, 17, "number of workers")
figs.NewUnitDuration(kSeconds, 76, time.Second, "number of seconds")
go func(){
  for mutation := range figs.Mutations() {
    log.Printf("Fig Changed! %s went from '%v' to '%v'", mutation.Property, mutation.Old, mutation.New)
  }
}()
err := figs.ParseFile(filepath.Join(".","config.yaml"))
if err != nil {
   log.Fatal(err)
}
workers := *figs.Int(kWorkers)
seconds := *figs.UnitDuration(kSeconds, time.Second)
minutes := *figs.UnitDuration(kSeconds, time.Minute) // use time.Minute instead as the unit
fmt.Printf("There are %d workers and %v minutes %v seconds", workers, minutes, seconds)
WORKERS=333 SECONDS=666 CONFIG_FILE=config.yaml go run . -workers=3 -seconds 6 # ENV overrides yaml and args
There are 333 workers and (666*time.Minute) minutes and (666*time.Second) seconds. # runtime calculates minutes and seconds

or

figs := figtree.Grow() // allows you to use for mutation := range figs.Mutations() {} to get notified of changes to configs
figs.Load() // will attempt to use ./config.yaml or ./config.json or ./config.ini automatically if CONFIG_FILE is not defined

Passing an empty string to Parse() means it will only parse the command-line arguments and not load any file.

Accessing Configuration Values

You can access the values of your configuration variables using the respective getter methods:

fmt.Println("Port:", *cfigs.Int(kPort))
fmt.Println("Timeout:", *cfigs.UnitDuration(kTimeout, time.Second))
fmt.Println("Debug mode:", *cfigs.String(kDebug))

UnitDuration and Duration are interchangeable as they both rely on *time.Duration.

Environment Variables

The Configurable package supports setting configuration values through environment variables. If an environment variable with the same name as a configuration variable exists, the package will automatically assign its value to the respective variable. Ensure that the environment variables are in uppercase and match the configuration variable names.

Displaying Usage Information

To generate a usage string with information about your configuration variables, use the Usage() method:

fmt.Println(figtree.New().Usage())

On any runtime with figs.Parse() or subsequently activated figtree, you can run on your command line -h or -help and print the Usage() func's output.

The generated usage string includes information about each configuration variable, including its name, default value, description, and the source from which it was set (flag, environment, JSON, YAML, or INI).

License

This package is distributed under the MIT License. See the LICENSE file for more information.

Contributing

Contributions to this package are welcome. If you find any issues or have suggestions for improvements, please open an issue or submit a pull request.

Enjoy using the Figtree package in your projects!

Documentation

Index

Constants

View Source
const (
	DefaultYAMLFile string = "config.yml"  // Default filename for a YAML configuration file
	DefaultJSONFile string = "config.json" // Default filename for a JSON configuration file
	DefaultINIFile  string = "config.ini"  // Default filename for a INI configuration file

	VERSION = "v1.0.1"
)

Variables

View Source
var AssureBoolFalse = func(value interface{}) error {
	if v, ok := value.(bool); ok {
		if v {
			return fmt.Errorf("value must be false, got true")
		}
		return nil
	}
	return fmt.Errorf("invalid type, expected bool, got %T", value)
}

AssureBoolFalse ensures a boolean value is false. Returns an error if the value is true or not a bool.

View Source
var AssureBoolTrue = func(value interface{}) error {
	if v, ok := value.(bool); ok {
		if !v {
			return fmt.Errorf("value must be true, got false")
		}
		return nil
	}
	return fmt.Errorf("invalid type, expected bool, got %T", value)
}

AssureBoolTrue ensures a boolean value is true. Returns an error if the value is false or not a bool.

View Source
var AssureDurationGreaterThan = func(above time.Duration) ValidatorFunc {
	return func(value interface{}) error {
		var t time.Duration
		if v, ok := value.(time.Duration); ok {
			t = v
		}
		if v, ok := value.(*time.Duration); ok {
			t = *v
		}
		if t < above {
			return fmt.Errorf("value must be above %v, got = %v", above, t)
		}
		return nil
	}
}

AssureDurationGreaterThan ensures a time.Duration is greater than (but not including) a time.Duration. Returns an error if the value is below, or not an int.

View Source
var AssureDurationLessThan = func(below time.Duration) ValidatorFunc {
	return func(value interface{}) error {
		var t time.Duration
		if v, ok := value.(time.Duration); ok {
			t = v
		}
		if v, ok := value.(*time.Duration); ok {
			t = *v
		}
		if t > below {
			return fmt.Errorf("value must be below %v, got = %v", below, t)
		}
		return nil
	}
}

AssureDurationLessThan ensures a time.Duration is less than (but not including) a time.Duration. Returns an error if the value is below, or not an int.

View Source
var AssureDurationMax = func(max time.Duration) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(time.Duration); ok {
			if v > max {
				return fmt.Errorf("duration must not exceed %s, got %s", max, v)
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected time.Duration, got %T", value)
	}
}

AssureDurationMax ensures a time.Duration does not exceed a maximum value. Returns an error if the value exceeds the max or is not a time.Duration.

View Source
var AssureDurationMin = func(min time.Duration) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(time.Duration); ok {
			if v < min {
				return fmt.Errorf("duration must be at least %s, got %s", min, v)
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected time.Duration, got %T", value)
	}
}

AssureDurationMin ensures a time.Duration is at least a minimum value. Returns a ValidatorFunc that checks the duration against the minimum.

View Source
var AssureDurationPositive = func(value interface{}) error {
	if v, ok := value.(time.Duration); ok {
		if v <= 0 {
			return fmt.Errorf("duration must be positive, got %s", v)
		}
		return nil
	}
	return fmt.Errorf("invalid type, expected time.Duration, got %T", value)
}

AssureDurationPositive ensures a time.Duration is positive. Returns an error if the value is zero or negative, or not a time.Duration.

View Source
var AssureFloat64GreaterThan = func(above float64) ValidatorFunc {
	return func(value interface{}) error {
		if v, err := toFloat64(value); err == nil {
			if v < above {
				return fmt.Errorf("value must be below %f", v)
			}
			return nil
		} else {
			return err
		}
	}
}

AssureFloat64GreaterThan ensures an integer is greater than (but not including) an int. Returns an error if the value is below, or not an int.

View Source
var AssureFloat64InRange = func(min, max float64) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(float64); ok {
			if v < min || v > max {
				return fmt.Errorf("value must be between %f and %f, got %f", min, max, v)
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected float64, got %T", value)
	}
}

AssureFloat64InRange ensures a float64 is within a specified range (inclusive). Returns an error if the value is outside the range or not a float64.

View Source
var AssureFloat64LessThan = func(below float64) ValidatorFunc {
	return func(value interface{}) error {
		if v, err := toFloat64(value); err == nil {
			if v > below {
				return fmt.Errorf("value must be below %f", v)
			}
			return nil
		} else {
			return err
		}
	}
}

AssureFloat64LessThan ensures an integer is less than (but not including) an int. Returns an error if the value is above, or not an int.

View Source
var AssureFloat64NotNaN = func(value interface{}) error {
	if v, ok := value.(float64); ok {
		if math.IsNaN(v) {
			return fmt.Errorf("value must not be NaN, got %f", v)
		}
		return nil
	}
	return fmt.Errorf("invalid type, expected float64, got %T", value)
}

AssureFloat64NotNaN ensures a float64 is not NaN. Returns an error if the value is NaN or not a float64.

View Source
var AssureFloat64Positive = func(value interface{}) error {
	if v, ok := value.(float64); ok {
		if v <= 0 {
			return fmt.Errorf("value must be positive, got %f", v)
		}
		return nil
	}
	return fmt.Errorf("invalid type, expected float64, got %T", value)
}

AssureFloat64Positive ensures a float64 is positive. Returns an error if the value is zero or negative, or not a float64.

View Source
var AssureInt64GreaterThan = func(above int64) ValidatorFunc {
	return func(value interface{}) error {
		if v, err := toInt64(value); err == nil {
			if v < above {
				return fmt.Errorf("value must be below %d", v)
			}
			return nil
		} else {
			return err
		}
	}
}

AssureInt64GreaterThan ensures an integer is greater than (but not including) an int. Returns an error if the value is below, or not an int.

View Source
var AssureInt64InRange = func(min, max int64) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(int64); ok {
			if v < min || v > max {
				return fmt.Errorf("value must be between %d and %d, got %d", min, max, v)
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected int64, got %T", value)
	}
}

AssureInt64InRange ensures an int64 is within a specified range (inclusive). Returns a ValidatorFunc that checks the value against min and max.

View Source
var AssureInt64LessThan = func(below int64) ValidatorFunc {
	return func(value interface{}) error {
		if v, err := toInt64(value); err == nil {
			if v > below {
				return fmt.Errorf("value must be below %d", v)
			}
			return nil
		} else {
			return err
		}
	}
}

AssureInt64LessThan ensures an integer is less than (but not including) an int. Returns an error if the value is above, or not an int.

View Source
var AssureInt64Positive = func(value interface{}) error {
	if v, ok := value.(int64); ok {
		if v <= 0 {
			return fmt.Errorf("value must be positive, got %d", v)
		}
		return nil
	}
	return fmt.Errorf("invalid type, expected int64, got %T", value)
}

AssureInt64Positive ensures an int64 is positive. Returns an error if the value is zero or negative, or not an int64.

View Source
var AssureIntGreaterThan = func(above int) ValidatorFunc {
	return func(value interface{}) error {
		if v, err := toInt(value); err == nil {
			if v < above {
				return fmt.Errorf("value must be below %d", v)
			}
			return nil
		} else {
			return err
		}
	}
}

AssureIntGreaterThan ensures an integer is greater than (but not including) an int. Returns an error if the value is below, or not an int.

View Source
var AssureIntInRange = func(min, max int) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(int); ok {
			if v < min || v > max {
				return fmt.Errorf("value must be between %d and %d, got %d", min, max, v)
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected int, got %T", value)
	}
}

AssureIntInRange ensures an integer is within a specified range (inclusive). Returns an error if the value is outside the range or not an int.

View Source
var AssureIntLessThan = func(below int) ValidatorFunc {
	return func(value interface{}) error {
		if v, err := toInt(value); err == nil {
			if v > below {
				return fmt.Errorf("value must be below %d", v)
			}
			return nil
		} else {
			return err
		}
	}
}

AssureIntLessThan ensures an integer is less than (but not including) an int. Returns an error if the value is above, or not an int.

View Source
var AssureListContains = func(value string) ValidatorFunc {
	return func(v interface{}) error {
		if list, ok := v.(*ListFlag); ok && list != nil {
			for _, item := range *list.values {
				if item == value {
					return nil
				}
			}
		}
		if list, ok := v.(*[]string); ok && list != nil {
			for _, item := range *list {
				if item == value {
					return nil
				}
			}
		}
		if list, ok := v.([]string); ok && list != nil {
			for _, item := range list {
				if item == value {
					return nil
				}
			}
			return fmt.Errorf("list must contain %q, got %v", value, list)
		}
		return fmt.Errorf("invalid type, expected *ListFlag, []string, or *[]string, got %T", v)
	}
}

AssureListContains ensures a list contains a specific string value. Returns a ValidatorFunc that checks for the presence of the value.

View Source
var AssureListContainsKey = func(key string) ValidatorFunc {
	return func(value interface{}) error {
		switch list := value.(type) {
		case *ListFlag:
			if list == nil {
				return fmt.Errorf("list is nil")
			}
			for _, item := range *list.values {
				if item == key {
					return nil
				}
			}
			return fmt.Errorf("list must contain %q, got %v", key, *list.values)
		case *[]string:
			if list == nil {
				return fmt.Errorf("list is nil")
			}
			for _, item := range *list {
				if item == key {
					return nil
				}
			}
			return fmt.Errorf("list must contain %q, got %v", key, *list)
		case []string:
			for _, item := range list {
				if item == key {
					return nil
				}
			}
			return fmt.Errorf("list must contain %q, got %v", key, list)
		default:
			return fmt.Errorf("invalid type, expected *ListFlag or []string, got %T", value)
		}
	}
}

AssureListContainsKey ensures a list contains a specific string. It accepts *ListFlag, *[]string, or []string and returns an error if the key string is not found or the type is invalid.

View Source
var AssureListLength = func(length int) ValidatorFunc {
	return func(value interface{}) error {
		switch list := value.(type) {
		case *ListFlag:
			if list == nil {
				return fmt.Errorf("list is nil")
			}
			if len(*list.values) != length {
				return fmt.Errorf("list must have length %d, got %d", length, len(*list.values))
			}
			return nil
		case *[]string:
			if list == nil {
				return fmt.Errorf("list is nil")
			}
			if len(*list) != length {
				return fmt.Errorf("list must have length %d, got %d", length, len(*list))
			}
			return nil
		case []string:
			if len(list) != length {
				return fmt.Errorf("list must have length %d, got %d", length, len(list))
			}
			return nil
		default:
			return fmt.Errorf("invalid type, expected *ListFlag or []string, got %T", value)
		}
	}
}

AssureListLength ensures a list has exactly the specified length. It accepts *ListFlag, *[]string, or []string and returns an error if the length differs or the type is invalid.

View Source
var AssureListMinLength = func(min int) ValidatorFunc {
	return func(value interface{}) error {
		switch v := value.(type) {
		case *ListFlag:
			if len(*v.values) < min {
				return fmt.Errorf("list must have at least %d elements, got %d", min, len(*v.values))
			}
			return nil
		case *[]string:
			if len(*v) < min {
				return fmt.Errorf("list is empty")
			}
			return nil
		case []string:
			if len(v) < min {
				return fmt.Errorf("list is empty")
			}
			return nil
		default:
			return fmt.Errorf("invalid type, expected *ListFlag or []string, got %T", v)
		}
	}
}

AssureListMinLength ensures a list has at least a minimum number of elements. Returns an error if the list is too short or not a ListFlag.

View Source
var AssureListNotEmpty = func(value interface{}) error {
	switch v := value.(type) {
	case *ListFlag:
		if v == nil || len(*v.values) == 0 {
			return fmt.Errorf("list is empty")
		}
		return nil
	case *[]string:
		if len(*v) == 0 {
			return fmt.Errorf("list is empty")
		}
		return nil
	case []string:
		if len(v) == 0 {
			return fmt.Errorf("list is empty")
		}
		return nil
	default:
		return fmt.Errorf("invalid type, expected *ListFlag or []string, got %T", v)
	}
}

AssureListNotEmpty ensures a list is not empty. Returns an error if the list has no elements or is not a ListFlag.

View Source
var AssureMapHasKey = func(key string) ValidatorFunc {
	return func(value interface{}) error {
		switch v := value.(type) {
		case *MapFlag:
			if _, exists := (*v.values)[key]; !exists {
				return fmt.Errorf("map must contain key %q", key)
			}
			return nil
		case *map[string]string:
			if _, exists := (*v)[key]; !exists {
				return fmt.Errorf("map must contain key %q", key)
			}
			return nil
		case map[string]string:
			if _, exists := v[key]; !exists {
				return fmt.Errorf("map must contain key %q", key)
			}
			return nil
		default:
			return fmt.Errorf("invalid type, got %T", value)
		}
	}
}

AssureMapHasKey ensures a map contains a specific key. Returns an error if the key is missing or the value is not a MapFlag.

View Source
var AssureMapHasKeys = func(keys []string) ValidatorFunc {
	return func(value interface{}) error {
		missing := []string{}
		switch m := value.(type) {
		case *MapFlag:
			if m == nil {
				return fmt.Errorf("map is nil")
			}
			for _, key := range keys {
				if _, exists := (*m.values)[key]; !exists {
					missing = append(missing, key)
				}
			}
		case *map[string]string:
			if m == nil {
				return fmt.Errorf("map is nil")
			}
			for _, key := range keys {
				if _, exists := (*m)[key]; !exists {
					missing = append(missing, key)
				}
			}
		case map[string]string:
			for _, key := range keys {
				if _, exists := m[key]; !exists {
					missing = append(missing, key)
				}
			}
		default:
			return fmt.Errorf("invalid type, expected *MapFlag or map[string]string, got %T", value)
		}
		if len(missing) > 0 {
			return fmt.Errorf("map must contain keys %v, missing %v", keys, missing)
		}
		return nil
	}
}

AssureMapHasKeys ensures a map contains all specified keys. Returns an error if any key is missing or the value is not a *MapFlag.

View Source
var AssureMapLength = func(length int) ValidatorFunc {
	return func(value interface{}) error {
		switch m := value.(type) {
		case *MapFlag:
			if m == nil {
				return fmt.Errorf("map is nil")
			}
			if len(*m.values) != length {
				return fmt.Errorf("map must have length %d, got %d", length, len(*m.values))
			}
			return nil
		case *map[string]string:
			if m == nil {
				return fmt.Errorf("map is nil")
			}
			if len(*m) != length {
				return fmt.Errorf("map must have length %d, got %d", length, len(*m))
			}
			return nil
		case map[string]string:
			if len(m) != length {
				return fmt.Errorf("map must have length %d, got %d", length, len(m))
			}
			return nil
		default:
			return fmt.Errorf("invalid type, expected *MapFlag or map[string]string, got %T", value)
		}
	}
}

AssureMapLength ensures a map has exactly the specified length. It accepts *MapFlag, *map[string]string, or map[string]string and returns an error if the length differs or the type is invalid.

View Source
var AssureMapNotEmpty = func(value interface{}) error {
	switch v := value.(type) {
	case *MapFlag:
		if len(*v.values) == 0 {
			return fmt.Errorf("map is empty")
		}
		return nil
	case *map[string]string:
		if len(*v) == 0 {
			return fmt.Errorf("list is empty")
		}
		return nil
	case map[string]string:
		if len(v) == 0 {
			return fmt.Errorf("list is empty")
		}
		return nil
	default:
		return fmt.Errorf("invalid type, expected *ListFlag or []string, got %T", v)
	}
}

AssureMapNotEmpty ensures a map is not empty. Returns an error if the map has no entries or is not a MapFlag.

View Source
var AssureMapValueMatches = func(key, value string) ValidatorFunc {
	return func(v interface{}) error {
		switch m := v.(type) {
		case *MapFlag:
			if val, exists := (*m.values)[key]; exists {
				if val != value {
					return fmt.Errorf("map key %q must have value %q, got %q", key, value, val)
				}
				return nil
			}
			return fmt.Errorf("map key %q does not exist", key)
		case *map[string]string:
			if val, exists := (*m)[key]; exists {
				if val != value {
					return fmt.Errorf("map value %q must have value %q, got %q", key, value, val)
				}
				return nil
			}
			return fmt.Errorf("map key %q does not exist", key)
		case map[string]string:
			if val, exists := m[key]; exists {
				if val != value {
					return fmt.Errorf("map value %q must have value %q, got %q", key, value, val)
				}
				return nil
			}
			return fmt.Errorf("map key %q does not exist", key)
		default:
			return fmt.Errorf("invalid type, expected map[string]string, got %T", v)
		}
	}
}

AssureMapValueMatches ensures a map has a specific key with a matching value. Returns a ValidatorFunc that checks for the key-value pair.

View Source
var AssureNegativeInt = func(value interface{}) error {
	if v, ok := value.(int); ok {
		if v >= 0 {
			return fmt.Errorf("value must be negative, got %d", v)
		}
		return nil
	}
	return fmt.Errorf("invalid type, expected int, got %T", value)
}

AssureNegativeInt ensures an integer is negative. Returns an error if the value is zero or positive, or not an int.

View Source
var AssurePositiveInt = func(value interface{}) error {
	if v, ok := value.(int); ok {
		if v <= 0 {
			return fmt.Errorf("value must be positive, got %d", v)
		}
		return nil
	}
	return fmt.Errorf("invalid type, expected int, got %T", value)
}

AssurePositiveInt ensures an integer is positive. Returns an error if the value is zero or negative, or not an int.

View Source
var AssureStringContains = func(substring string) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(string); ok {
			if !strings.Contains(v, substring) {
				return fmt.Errorf("string must contain %q, got %q", substring, v)
			}
			return nil
		}
		return fmt.Errorf("invalid type, got %T", value)
	}
}

AssureStringContains ensures a string contains a specific substring. Returns an error if the substring is not found or if the value is not a string.

View Source
var AssureStringHasPrefix = func(prefix string) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(string); ok {
			if !strings.HasPrefix(v, prefix) {
				return fmt.Errorf("string must have prefix substring %q, got %q", prefix, v)
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected string, got %T", value)
	}
}

AssureStringHasPrefix ensures a string begins with a prefix Returns a ValidatorFunc that checks for the substring (case-sensitive).

View Source
var AssureStringHasSuffix = func(suffix string) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(string); ok {
			if !strings.HasSuffix(v, suffix) {
				return fmt.Errorf("string must have suffix substring %q, got %q", suffix, v)
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected string, got %T", value)
	}
}

AssureStringHasSuffix ensures a string ends with a suffix Returns a ValidatorFunc that checks for the substring (case-sensitive).

View Source
var AssureStringLength = func(length int) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(string); ok {
			if len(v) < length {
				return fmt.Errorf("string must be at least %d chars, got %q", length, len(v))
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected string, got %T", value)
	}
}

AssureStringLength ensures a string contains a specific substring. Returns a ValidatorFunc that checks for the substring (case-sensitive).

View Source
var AssureStringLengthGreaterThan = func(length int) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(string); ok {
			if len(v) < length {
				return fmt.Errorf("string must be greater than %d chars, got %d", length, len(v))
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected string, got %T", value)
	}
}

AssureStringLengthGreaterThan ensures the string is greater than an int Returns a ValidatorFunc that checks for the substring (case-sensitive).

View Source
var AssureStringLengthLessThan = func(length int) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(string); ok {
			if len(v) > length {
				return fmt.Errorf("string must be less than %d chars, got %d", length, len(v))
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected string, got %T", value)
	}
}

AssureStringLengthLessThan ensures the string is less than an int Returns a ValidatorFunc that checks for the substring (case-sensitive).

View Source
var AssureStringNotEmpty = func(value interface{}) error {
	if v, ok := value.(string); ok {
		if len(v) == 0 {
			return fmt.Errorf("empty string")
		}
		return nil
	}
	return fmt.Errorf("invalid type, got %T", value)
}

AssureStringNotEmpty ensures a string is not empty. Returns an error if the value is an empty string or not a string.

View Source
var AssureStringSubstring = func(sub string) ValidatorFunc {
	return func(value interface{}) error {
		if v, ok := value.(string); ok {
			if !strings.Contains(v, sub) {
				return fmt.Errorf("string must contain substring %q, got %q", sub, v)
			}
			return nil
		}
		return fmt.Errorf("invalid type, expected string, got %T", value)
	}
}

AssureStringSubstring ensures a string contains a specific substring. Returns a ValidatorFunc that checks for the substring (case-sensitive).

View Source
var ConfigFilePath string = filepath.Join(".", DefaultYAMLFile)

ConfigFilePath stores the path to the configuration file of choice

View Source
var EnvironmentKey string = "CONFIG_FILE"

EnvironmentKey stores the preferred ENV that contains the path to your configuration file (.ini, .json or .yaml)

View Source
var Mutageneses = []Mutagenesis{tString, tBool, tInt, tInt64, tFloat64, tDuration, tUnitDuration, tList, tMap}

Mutageneses is the plural form of Mutagenesis and this is a slice of Mutagenesis

Functions

This section is empty.

Types

type Fig

type Fig struct {
	Flesh       interface{}
	Mutagenesis Mutagenesis
	Validator   ValidatorFunc
	Error       error
	Mutations   []Mutation
}

type Fruit

type Fruit interface {
	// WithValidator binds a ValidatorFunc to a Fig that returns Fruit
	WithValidator(name string, validator func(interface{}) error) Fruit
	// Parse can panic but interprets command line arguments defined with single dashes -example value -another sample
	Parse() error
	// ParseFile can panic but also can throw an error because it will attempt to load either JSON, YAML or INI file passed into it
	ParseFile(filename string) error

	// ErrorFor returns an error attached to a named Fig
	ErrorFor(name string) error

	// Recall allows you to unlock the Tree from changes and resume tracking
	Recall()
	// Curse allows you to lock the Tree from changes and stop tracking
	Curse()
	// Mutations receives Mutation data on a receiver channel
	Mutations() <-chan Mutation
	// Resurrect takes a nil Fig in the Tree.figs map and reloads it from ENV or the config file if available
	Resurrect(name string)

	// Load can panic but also can throw an error but will use the Environment Variable values if they are "EXAMPLE=value" or "ANOTHER=sample"
	Load() error
	// LoadFile accepts a path to a JSON, YAML or INI file to set values
	LoadFile(path string) error
	// Reload will refresh stored values of properties with their new Environment Variable values
	Reload() error

	// Usage displays the helpful menu of figs registered using -h or -help
	Usage() string

	// Int returns a pointer to a registered int32 by name as -name=1 a pointer to 1 is returned
	Int(name string) *int
	// NewInt registers a new int32 flag by name and returns a pointer to the int32 storing the initial value
	NewInt(name string, value int, usage string) *int

	// Int64 returns a pointer to a registered int64 by name as -name=1 a pointer to 1 is returned
	Int64(name string) *int64
	// NewInt64 registers a new int32 flag by name and returns a pointer to the int64 storing the initial value
	NewInt64(name string, value int64, usage string) *int64

	// Float64 returns a pointer to a registered float64 by name as -name=1.0 a pointer to 1.0 is returned
	Float64(name string) *float64
	// NewFloat64 registers a new float64 flag by name and returns a pointer to the float64 storing the initial value
	NewFloat64(name string, value float64, usage string) *float64

	// String returns a pointer to stored string by -name=value
	String(name string) *string
	// NewString registers a new string flag by name and returns a pointer to the string storing the initial value
	NewString(name, value, usage string) *string

	// Bool returns a pointer to stored bool by -name=true
	Bool(name string) *bool
	// NewBool registers a new bool flag by name and returns a pointer to the bool storing the initial value
	NewBool(name string, value bool, usage string) *bool

	// Duration returns a pointer to stored time.Duration (unitless) by name like -minutes=10 (requires multiplication of * time.Minute to match memetics of "minutes" flag name and human interpretation of this)
	Duration(name string) *time.Duration
	// NewDuration registers a new time.Duration by name and returns a pointer to it storing the initial value
	NewDuration(name string, value time.Duration, usage string) *time.Duration

	// UnitDuration returns a pointer to stored time.Duration (-name=10 w/ units as time.Minute == 10 minutes time.Duration)
	UnitDuration(name string) *time.Duration
	// NewUnitDuration registers a new time.Duration by name and returns a pointer to it storing the initial value
	NewUnitDuration(name string, value, units time.Duration, usage string) *time.Duration

	// List returns a pointer to a []string containing strings
	List(name string) *[]string
	// NewList registers a new []string that can be assigned -name="ONE,TWO,THREE,FOUR"
	NewList(name string, value []string, usage string) *[]string

	// Map returns a pointer to a map[string]string containing strings
	Map(name string) *map[string]string
	// NewMap registers a new map[string]string that can be assigned -name="PROPERTY=VALUE,ANOTHER=VALUE"
	NewMap(name string, value map[string]string, usage string) *map[string]string

	// StoreInt replaces name with value and can issue a Mutation when receiving on Mutations()
	StoreInt(name string, value int) Fruit
	// StoreInt64 replaces name with value and can issue a Mutation when receiving on Mutations()
	StoreInt64(name string, value int64) Fruit
	// StoreFloat64 replaces name with value and can issue a Mutation when receiving on Mutations()
	StoreFloat64(name string, value float64) Fruit
	// StoreString replaces name with value and can issue a Mutation when receiving on Mutations()
	StoreString(name, value string) Fruit
	// StoreBool replaces name with value and can issue a Mutation when receiving on Mutations()
	StoreBool(name string, value bool) Fruit
	// StoreDuration replaces name with value and can issue a Mutation when receiving on Mutations()
	StoreDuration(name string, value time.Duration) Fruit
	// StoreUnitDuration replaces name with value and can issue a Mutation when receiving on Mutations()
	StoreUnitDuration(name string, value, units time.Duration) Fruit
	// StoreList replaces name with value and can issue a Mutation when receiving on Mutations()
	StoreList(name string, value []string) Fruit
	// StoreMap replaces name with value and can issue a Mutation when receiving on Mutations()
	StoreMap(name string, value map[string]string) Fruit
}

Fruit defines the interface for configuration management.

func Grow

func Grow() Fruit

Grow is a memetic alias of New Example:

 ctx, cancel := context.WithCancel(context.Background())
 defer cancel()
	figs := figtree.Grow()
 go func() {
   for {
     select {
       case <-ctx.Done():
         return
       case mutation, ok := <-figs.Mutations():
         if ok {
           log.Println(mutation)
         }
     }
   }
 }()

// figs implements figtree.Fruit interface

func New

func New() Fruit

New will initialize the Tree package Usage:

			When defining:
			    figs := figtree.New()
		     figs.NewInt("workers", 10, "number of workers")
		     figs.Parse()
	      OR err := figs.Load()
	      OR err := figs.ParseFile("path/to/file.json")
       THEN workers := *figs.Int("workers") // workers is a regular int

func With

func With(opts Options) Fruit

type ListFlag

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

ListFlag stores values in a list type configurable

func (*ListFlag) Set

func (l *ListFlag) Set(value string) error

Set unpacks a comma separated value argument and appends items to the list of []string

func (*ListFlag) String

func (l *ListFlag) String() string

String returns the slice of strings using strings.Join

type MapFlag

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

MapFlag stores values in a map type configurable

func (*MapFlag) Set

func (m *MapFlag) Set(value string) error

Set accepts a value like KEY=VALUE,KEY=VALUE,KEY=VALUE to override map values

func (*MapFlag) String

func (m *MapFlag) String() string

String returns the map[string]string as string=string,string=string,...

type Mutagenesis

type Mutagenesis string

Mutagenesis stores the type as a string like String, Bool, Float, etc to represent a supported Type

type Mutation

type Mutation struct {
	Property string
	Kind     string
	Way      string
	Old      interface{}
	New      interface{}
	When     time.Time
}

type Options

type Options struct {
	ConfigFile string
	// Tracking creates a buffered channel that allows you to select { case mutation, ok := <-figs.Mutations(): }
	Tracking bool

	// Germinate enables the option to filter os.Args that begin with -test. prefix
	Germinate bool

	// Harvest allows you to set the buffer size of the Mutations channel
	Harvest int

	// Pollinate will enable Getters to lookup the environment for changes on every read
	Pollinate bool
}

Options allow you enable mutation tracking on your figs.Grow

type Tree

type Tree struct {
	ConfigFilePath string
	// contains filtered or unexported fields
}

Tree stores figs that are defined by their name and Fig as well as a mutations channel and tracking bool for Options.Tracking

func (*Tree) Bool

func (fig *Tree) Bool(name string) *bool

Bool with mutation tracking

func (*Tree) Curse

func (fig *Tree) Curse()

Curse is when you lock the fig *Tree from further changes, stop tracking and close the channel

func (*Tree) Duration

func (fig *Tree) Duration(name string) *time.Duration

Duration with mutation tracking

func (*Tree) ErrorFor

func (fig *Tree) ErrorFor(name string) error

ErrorFor returns an error on a given name if one exists

func (*Tree) Float64

func (fig *Tree) Float64(name string) *float64

Float64 with mutation tracking

func (*Tree) Int

func (fig *Tree) Int(name string) *int

Int with mutation tracking

func (*Tree) Int64

func (fig *Tree) Int64(name string) *int64

Int64 with mutation tracking

func (*Tree) List

func (fig *Tree) List(name string) *[]string

List with mutation tracking

func (*Tree) Load

func (fig *Tree) Load() (err error)

Load uses the EnvironmentKey and the DefaultJSONFile, DefaultYAMLFile, and DefaultINIFile to run ParseFile if it exists

func (*Tree) LoadFile

func (fig *Tree) LoadFile(path string) (err error)

LoadFile accepts a path and uses it to populate the Tree

func (*Tree) Map

func (fig *Tree) Map(name string) *map[string]string

Map with mutation tracking

func (*Tree) MutagensisOf

func (fig *Tree) MutagensisOf(what interface{}) Mutagenesis

MutagensisOf accepts anything and allows you to determine the Mutagensis of the type of from what

func (*Tree) MutagensisOfFig

func (fig *Tree) MutagensisOfFig(name string) Mutagenesis

MutagensisOfFig returns the Mutagensis of the name

func (*Tree) Mutations

func (fig *Tree) Mutations() <-chan Mutation

Mutations returns a receiver channel of Mutation data

func (*Tree) NewBool

func (fig *Tree) NewBool(name string, value bool, usage string) *bool

NewBool with validator and withered support

func (*Tree) NewDuration

func (fig *Tree) NewDuration(name string, value time.Duration, usage string) *time.Duration

NewDuration with validator and withered support

func (*Tree) NewFloat64

func (fig *Tree) NewFloat64(name string, value float64, usage string) *float64

NewFloat64 with validator and withered support

func (*Tree) NewInt

func (fig *Tree) NewInt(name string, value int, usage string) *int

NewInt with validator and withered support

func (*Tree) NewInt64

func (fig *Tree) NewInt64(name string, value int64, usage string) *int64

NewInt64 with validator and withered support

func (*Tree) NewList

func (fig *Tree) NewList(name string, value []string, usage string) *[]string

NewList with validator and withered support

func (*Tree) NewMap

func (fig *Tree) NewMap(name string, value map[string]string, usage string) *map[string]string

NewMap with validator and withered support

func (*Tree) NewString

func (fig *Tree) NewString(name string, value string, usage string) *string

NewString with validator and withered support

func (*Tree) NewUnitDuration

func (fig *Tree) NewUnitDuration(name string, value, units time.Duration, usage string) *time.Duration

NewUnitDuration registers a new time.Duration with a unit time.Duration against a name

func (*Tree) Parse

func (fig *Tree) Parse() (err error)

Parse uses Tree.flagSet to run flag.Parse() on the registered figs and returns nil for validated results

func (*Tree) ParseFile

func (fig *Tree) ParseFile(filename string) (err error)

ParseFile will check if filename is set and run loadFile on it.

func (*Tree) Recall

func (fig *Tree) Recall()

Recall is when you bring the mutations channel back to life and you unlock making further changes to the fig *Tree

func (*Tree) Reload

func (fig *Tree) Reload() error

Reload will readEnv on each flag in the configurable package

func (*Tree) Resurrect

func (fig *Tree) Resurrect(name string)

Resurrect revives a missing or nil definition, checking env and config files first

func (*Tree) Store

func (fig *Tree) Store(mut Mutagenesis, name string, value interface{}) Fruit

func (*Tree) StoreBool

func (fig *Tree) StoreBool(name string, value bool) Fruit

StoreBool replaces the name with the new value while issuing a Mutation if Tree.tracking is true

func (*Tree) StoreDuration

func (fig *Tree) StoreDuration(name string, value time.Duration) Fruit

StoreDuration replaces the name with the new value while issuing a Mutation if Tree.tracking is true

func (*Tree) StoreFloat64

func (fig *Tree) StoreFloat64(name string, value float64) Fruit

StoreFloat64 replaces the name with the new value while issuing a Mutation if Tree.tracking is true

func (*Tree) StoreInt

func (fig *Tree) StoreInt(name string, value int) Fruit

StoreInt replaces the name with the new value while issuing a Mutation if Tree.tracking is true

func (*Tree) StoreInt64

func (fig *Tree) StoreInt64(name string, value int64) Fruit

StoreInt64 replaces the name with the new value while issuing a Mutation if Tree.tracking is true

func (*Tree) StoreList

func (fig *Tree) StoreList(name string, value []string) Fruit

StoreList replaces the name with the new value while issuing a Mutation if Tree.tracking is true

func (*Tree) StoreMap

func (fig *Tree) StoreMap(name string, value map[string]string) Fruit

StoreMap replaces the name with the new value while issuing a Mutation if Tree.tracking is true

func (*Tree) StoreString

func (fig *Tree) StoreString(name, value string) Fruit

StoreString replaces the name with the new value while issuing a Mutation if Tree.tracking is true

func (*Tree) StoreUnitDuration

func (fig *Tree) StoreUnitDuration(name string, value, units time.Duration) Fruit

StoreUnitDuration replaces the name with the new value while issuing a Mutation if Tree.tracking is true

func (*Tree) String

func (fig *Tree) String(name string) *string

String with mutation tracking

func (*Tree) UnitDuration

func (fig *Tree) UnitDuration(name string) *time.Duration

UnitDuration with mutation tracking

func (*Tree) Usage

func (fig *Tree) Usage() string

Usage prints a helpful table of figs in a human-readable format

func (*Tree) WithValidator

func (fig *Tree) WithValidator(name string, validator func(interface{}) error) Fruit

WithValidator adds a validator to an int flag

type ValidatorFunc

type ValidatorFunc func(interface{}) error

Jump to

Keyboard shortcuts

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