Skip to content

asciimoth/configer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

configer

configer is a small Go abstraction for querying and patching JSON-like configuration trees without tying callers to one storage format.

The core module provides the configer.Config interface and an in-memory implementation. The hujson module adapts Tailscale HuJSON, preserving comments and formatting where the backing AST supports it.

Install

go get github.com/asciimoth/configer/configer
go get github.com/asciimoth/configer/hujson

In-Memory Usage

package main

import (
	"fmt"

	"github.com/asciimoth/configer/configer"
)

func main() {
	cfg := configer.NewMemory(map[string]any{
		"server": map[string]any{
			"listen": ":8080",
			"tls": map[string]any{
				"enabled": false,
			},
		},
	})

	_ = cfg.Set(configer.Path{"server", "tls", "enabled"}, true)

	tls := cfg.View(configer.Path{"server", "tls"})
	enabled, _ := tls.Get(configer.Path{"enabled"})

	fmt.Println(enabled)
}

HuJSON Usage

package main

import (
	"fmt"

	"github.com/asciimoth/configer/configer"
	confighujson "github.com/asciimoth/configer/hujson"
)

func main() {
	cfg, err := confighujson.Parse([]byte(`{
  // deployment target
  "deploy": {
    "region": "iad",
    "replicas": 2,
  },
}`))
	if err != nil {
		panic(err)
	}

	_ = cfg.Set(configer.Path{"deploy", "replicas"}, 3)
	_ = cfg.SetComment(configer.Path{"deploy", "replicas"}, "number of replicas")

	fmt.Println(string(cfg.Pack()))
}

Struct Marshal and Unmarshal

configer.Marshal uses standard json tags and merges object fields into an existing config. Fields omitted by omitempty leave existing values untouched. If the config also supports comments, comment tags are written to matching paths.

type Service struct {
	Enabled bool   `json:"enabled" comment:"turn service on or off"`
	Mode    string `json:"mode,omitempty" comment:"deployment strategy"`
}

cfg, _ := confighujson.Parse([]byte(`{
  "service": {
    "enabled": false,
    "token": "kept"
  }
}`))

_ = configer.Marshal(cfg.View(configer.Path{"service"}), Service{
	Enabled: true,
	Mode:    "rolling",
})

var service Service
_ = configer.Unmarshal(cfg.View(configer.Path{"service"}), &service)

Views and Read-Only Access

Views are backed by the same storage and lock as the original config.

service := cfg.View(configer.Path{"service"})
readonly := service.ReadOnly()

_, _ = readonly.Get(configer.Path{"enabled"})
err := readonly.Set(configer.Path{"enabled"}, false) // configer.ErrReadOnly
_ = err

License

Files in this repository are distributed under the CC0 license.

CC0
To the extent possible under law, ASCIIMoth has waived all copyright and related or neighboring rights to configer.

About

Config formats abstraction lib for go

Topics

Resources

License

Stars

Watchers

Forks

Contributors