4

I have a project with next structure:

|_main.go
|_config
  |_config.go
  |_config_test.go
  |_config.json

I'm having next code line in config.go:

file, _ := os.Open("config/config.json")

When I'm executing method contained this code line from main.go all is working. But when I'm trying to execute this method from config_test.go it produces error:

open config/config.json: no such file or directory

As I understood it is a working directory issue because I'm launching same code with relative path from different directories. How can I fix this problem without using full path in config.go?

Cortwave
  • 4,747
  • 2
  • 25
  • 42
  • Possible duplicate of [how to reference a relative file from code and tests](http://stackoverflow.com/questions/31059023/how-to-reference-a-relative-file-from-code-and-tests) – icza Apr 05 '16 at 08:28
  • You should not rely on the fact that the final compiled executable will be at the same location as its source code. There are several ways to specify which configuration file to use at runtime, the most obvious one being to pass it as a command line option. In this specific case, the path to the config file should be known by main.go and config_test.go, and vary accordingly. – SirDarius Apr 05 '16 at 09:21

1 Answers1

5

Relative paths are always resolved basis your current directory. Hence it's better to avoid relative paths.

Use command line flags or a configuration management tool (better approach) like Viper

Also according to The Twelve-Factor App your config files should be outside your project.

Eg usage with Viper:

import "github.com/spf13/viper"

func init() {

    viper.SetConfigName("config")

    // Config files are stored here; multiple locations can be added
    viper.AddConfigPath("$HOME/configs")
    errViper := viper.ReadInConfig()

    if errViper != nil {
        panic(errViper)
    }
    // Get values from config.json
    val := viper.GetString("some_key")

    // Use the value
}
Monodeep
  • 1,392
  • 1
  • 17
  • 39