Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with formats other than YAML #967

Open
prarit opened this issue Sep 2, 2020 · 10 comments
Open

Issues with formats other than YAML #967

prarit opened this issue Sep 2, 2020 · 10 comments

Comments

@prarit
Copy link

prarit commented Sep 2, 2020

I've been trying a few different config formats to see how they differ. For example,

package main 
import (
    "fmt"
    "log"

    "github.com/spf13/viper"
)     

func main() {
    viper.SetConfigType("hcl")

    viper.AddConfigPath(".")
    viper.SetConfigName("example.hcl")

    err := viper.ReadInConfig()
    if err != nil {
            log.Fatal(err)
    }

    fmt.Println("host.address =", viper.GetString("host.address"))
    fmt.Println("host.port =", viper.GetString("host.port"))
    viper.Reset()
}

with config file ./example.hcl as


"host" = {
 "address" = "localhost"
 "port" = "5799" 
}   

The output is empty:


host.address = 
host.port =

If I try this with ./example.yaml (and make the two hcl to yaml changes in the code) everything works:


{
"host": {
    "address": "localhost",
    "port": 5799
  }
}

Is this a bug or is there some nature of using HCL/TOML/etc. that I'm missing? FWIW only YAML appears to work properly when embedded this way. If I use a simple HCL file of (and, again, make appropriate code changes)


 "address" = "localhost"
 "port" = "5799" 

then the address and port values are output correctly.

@prarit
Copy link
Author

prarit commented Sep 2, 2020

FWIW. A TOML file also fails:


[host]
   address = localhost
   port = 5799

@sagikazarmark
Copy link
Collaborator

First things first: viper.SetConfigName("example.hcl") is not entirely correct. It should be viper.SetConfigName("example"). If you want to set a file path directly, use SetConfigFile.

To be honest, I'm not really familiar with HCL (other than using it in terraform), but looking at your example, it seems your snippet is translated into this:

map[string]interface{}{
    "host":[]map[string]interface{}{
        map[string]interface{}{
            "address": "localhost",
            "port": 5799,
        },
    },
}

Notice that the value of host is actually a slice (as also pointed out in the linked issue). This seems to be HCL specific. I'm not entirely sure how to fix this. The test cases are also not very good for HCL. :\

You can get the original value using log.Print(viper.Get("host").([]map[string]interface{})[0]["address"]), but that's just awful.

I'd recommend choosing another format, until it's sorted out.

As for TOML: your example is invalid: you need to quote strings:

[host]
address = "localhost"
port = 5799

Also, make sure to properly set the config name and type. TOML works just fine for me with the above example.

Let me know if it helps.

@prarit prarit closed this as completed Sep 2, 2020
@prarit prarit reopened this Sep 2, 2020
@AutomationD
Copy link

@spf13 hey, I wanted to check-in and see if this is simply a lower-priority item, or there is some fundamental issue that prevents this to get fixed?

Thanks!

@sagikazarmark
Copy link
Collaborator

@AutomationD please see my answer above.

TL;DR HCL (or at least the implementation) is fundamentally broken and will be removed from Viper 2.

@AutomationD
Copy link

AutomationD commented Nov 30, 2021

@sagikazarmark Hey, thanks for your response. So I'm curious what is stopping us to ensure the traversal is done considering the extra slice in-between maps?

@sagikazarmark
Copy link
Collaborator

I wouldn't want to add that kind of behavior to the config lookup, just to handle the quirks of HCL when it's not actually a popular option.

Once encoding/decoding is properly factored out from the Viper core, I don't mind doing any additional steps to make up for HCL's weird behavior. See #1167.

@AutomationD
Copy link

Good point. Thanks! What would be the top preferred formats to use with viper right now?

@sagikazarmark
Copy link
Collaborator

Yaml or json both work quite well.

@AutomationD
Copy link

Where do you see TOML in this list? would it be kept as a first-class citizen?

@sagikazarmark
Copy link
Collaborator

I think so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants