Want viper to read configuration from different directory

Hello, first timer here and very new to go (almost 0 previous experience)

I am trying to write a subcommand with viper. It is a very simple command which will basically manipulate the key value in a configuration file. Now the issue, the problem here is that the configuration file is in /root-of-project/server/configurations/environment.yaml and the path for the command i’m writing is in /root-of-project/cli/cmd/cmd.go. Initially, I hardcoded the path by adding viper.AddConfigPath(the_path_to_environment.yaml), but that did not work because when I compiled the binary and moved the binary to $PATH, it couldn’t basically find /server/configurations/ if I execute from any other random directory.

I read a previous thread here which says that this type of call is not possible. But, I still want to know if you had to tackle this problem, then what approach would you follow and how would you proceed with solving the problem here ?

Ref: the cmd.go file

viper.AddConfigPath("../server/configurations/") ?
try

pwd, _ := os.Getwd()
viper.AddConfigPath(path.Join(pwd, "../server/configurations/"))

If this doesn’t work, you should check the environment to see if it is inaccessible.

Thats what I’ve done currently, but the problem with using this is that when I compile the binary, move it to some random directory in my /home/user, it won’t work because it won’t be able to find ../systems/configurations at the first place.

Same problem will be there with os.Getwd().

Can you share some more details of what you meant by “check the environment to see if it is accessible” ?

First you should check whether the target file exists and can be accessed normally by your program.
If you cannot confirm, you should print out path.Join(pwd, “…/server/configurations/”) and confirm whether there is a path problem.
If you have eliminated the above problems, you should be able to confirm that you can actually access the path through os.Open.
It’s not clear to me how you execute the binary. However, some launchers will isolate the binary path. For example, systemd will isolate the / path, so that the program cannot correctly access files in the / path.

Ohh okay, I will try doing that. I had that in my mind already, but I did not spend time on it was because that I felt it would be a a lot of unnecessary code.

This is how I execute the binary:

go build // to compile the binary
mv cli ~ // moving to a random location
./cli command arg[0]

And then it would end up saying file not found in [/home/user/project /home/user/server/configurations/] or similar.

Have you made sure the path actually exists?

yes, obviously it exists.

The path does exist or else it wouldn’t have worked when I execute the binary without moving it to random location on my system.

Have you tried os.Open and the path will not report an error?

Nah, nope. I am going to do, also will implement using os.Executable with os.Getwd() and then maybe join the paths to server/configurations like you and chatGPT suggested.

I don’t know what your troubleshooting thinking is, but I think it’s important to make sure the path is correct, and your problem sounds like a path error that makes it inaccessible.
os. Open makes sure that the program gets into that path, and that’s it. It’s the unitary approach that matters, and that’s what I think.

I think, you misunderstood.

let me try to explain you with a bit more of examples. Do not worry about the path they are absolutely right .But, the reason that fails when I execute the binary from some other directory is the path being not right for that particular directory.

For example, if I execute the config in home directory and the path for the file.yaml is in dev/server/configurations/file.yaml then the cli will try finding it in home ../server/configurations/file which won’t work.

I couldn’t get back to this problem yesterday because of some problem, but today i’ll do and make sure I don’t have to sit in front of this later.

Hope you understand.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.