heetch/confita

Can't load config into struct with json tags

slon opened this issue · 1 comments

slon commented

I noticed a regression in behaviour. Here is code for reproducing the issue.

package confitajson

import (
	"context"
	"log"
	"testing"

	"github.com/heetch/confita"
	"github.com/heetch/confita/backend/file"
)

func TestLoad(t *testing.T) {
	b := file.NewBackend("config.json")

	var c struct {
		Field string `json:"field"`
	}

	if err := confita.NewLoader(b).Load(context.Background(), &c); err != nil {
		log.Fatalf("failed to load config: %v", err)
	}

	if c.Field != "value" {
		log.Fatal("field value is not updated")
	}
}

Content of config.json file is following:

{
    "field": "value"
}

When running this test on the latest confita release, struct field is not updated. But on version v0.7.0 code works fine.

prime@bee ~/C/confitajson> go get github.com/heetch/confita@v0.7.0
go: downloading github.com/heetch/confita v0.7.0
prime@bee ~/C/confitajson> go test .
ok  	github.com/slon/confitajson	0.002s
prime@bee ~/C/confitajson> go get github.com/heetch/confita
go: github.com/heetch/confita upgrade => v0.9.1
prime@bee ~/C/confitajson> go test .
2020/05/27 20:02:34 field value is not updated
FAIL	github.com/slon/confitajson	0.002s
FAIL

I also noticed, that removing these 3 lines, seems to fix this issue for me. https://github.com/heetch/confita/blob/master/config.go#L183-L185

Is that change in behaviour intentional, or is it indeed a regression?

I noticed that in the current version if I use the config tag and json tags I get very different behaviors:

package main

import (
	"context"
	"github.com/heetch/confita"
	"github.com/heetch/confita/backend/file"
	"github.com/heetch/confita/backend/flags"
	log "github.com/sirupsen/logrus"
	"time"
)

type Config struct {
	Host        string        `config:"host"`
	Port        uint32        `config:"port"`
	Timeout     time.Duration `config:"timeout"`
	Password    string        `config:"password"`
	Name string `config:"name,required"`
	OrderValue float64 `config:"order_value"`
	itemNumber int `config:"item_number"`
}

func main() {
	loader := confita.NewLoader(
		file.NewBackend("cmd/confita/config.json"),
		flags.NewBackend(),
		)

	// default values
	cfg := Config{
		Host: "127.0.0.1",
		Port: 5656,
		Timeout: 5 * time.Second,
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5 * time.Second)
	defer cancel()

	// loading configuration
	if err := loader.Load(ctx, &cfg); err != nil {
		log.WithError(err).Fatal("loading config")
	}


	// check the config
	log.WithField("config", cfg).Info("config loaded")
}

Using the config tag, strings seem to load fine however floats and ints don't. If I then use the json tag, strings and floats load fine but not ints.

example JSON FIle:
{ "name" : "red shoes", "item_number" : 2, "order_value": 23.45 }

output with config tags:
time="2021-02-15T20:31:04Z" level=info msg="config loaded" config="{127.0.0.1 5656 5s red shoes 0 0}"

output with json tags:
time="2021-02-15T20:38:12Z" level=info msg="config loaded" config="{127.0.0.1 5656 5s red shoes 23.45 0}"