By Pablo Fernandez


2015-06-25 19:21:55 8 Comments

I need to reference patients.json from patients.go, here's the folder structure:

enter image description here

If I do:

filepath.Abs("../../conf/patients.json")

it works for go test ./... but fails for revel run

If I do:

filepath.Abs("conf/patients.json")

the exact opposite happens (revel is fine but tests fail).

Is there a way to correctly reference the file so that it works both for tests and normal program run?

3 comments

@Billy Yuan 2019-01-16 09:58:25

This is not the problem with path, but the problem with your design.

You should design your code more careful.

As far as I can tell, you share same path in your test file and reveal run. I guess that maybe you hard code your json path in your model package which is not suggested.

Better way is

  • model package get json path from global config, or init model with json path like model := NewModel(config_path). so reveal run can init model with any json you want.
  • hard code "../../conf/patients.json" in your xxxx_testing.go

@icza 2015-06-25 19:27:15

Relative paths are always interpreted / resolved to a base path: the current or working directory - therefore it will always have its limitations.

If you can live with always taking care of the proper working directory, you may keep using relative paths.

What I would suggest is to not rely on the working directory, but an explicitly specified base path. This may have a default value hard-coded in your application (which may be the working directory as well), and you should provide several ways to override its value.

Recommended ways to override the base path to which your "relative" paths are resolved against:

  1. Command line flag (see flag package)
  2. Environment variable (see os.Getenv())
  3. (Fix named) Config file in user's home directory (see os/user/User and os/user/Current())

Once you have the base path, you can get the full path by joining the base path and the relative path. You may use path.Join() or filepath.Join(), e.g.:

// Get base path, from any or from the combination of the above mentioned solutions
base := "/var/myapp"

// Relative path, resource to read/write from:
relf := "conf/patients.json"

// Full path that identifies the resource:
full := filepath.Join(base, relf) // full will be "/var/myapp/conf/patients.json"

@Pablo Fernandez 2015-06-25 20:03:08

is there a way to know the path of the .go file?

@icza 2015-06-25 20:30:55

@PabloFernandez If it is compiled into an executable binary, there isn't even a .go file...

@kostix 2016-04-25 16:44:36

On Linux, if /proc is mounted, it's possible to know the location of the program being executed by calling os.Readlink() on the symlink named "/proc/self/exe". In either case, it's a) not portable; b) may have little sense anyway as a properly packaged software package for a GNU/Linux-based system should have its binaries and "assets" separated anyway.

@kostix 2016-04-25 16:50:00

I'd mention another possibility as well: 1) have a global variable defining the base directory prefix for the assets, say, main.AssetsDir; 2) allow downstream packagers override it at build time using the linker's ability to override string-typed values, like with: go build -ldflags="-X main.AssetsDir=/usr/share/cool_app/assets". The OP could get more background on this by studying the outputs of go help build and go tool link -h.

@icza 2016-04-25 17:06:07

@kostix Good idea, but that limits the configurability to developers. Users without programming knowledge would find command line flags much friendlier and easier to use than build flags.

@alediaferia 2015-06-25 19:28:26

I've never used Revel myself but the following looks helpful to me:

http://revel.github.io/docs/godoc/revel.html

  • revel.BasePath
  • revel.AppPath

@Pablo Fernandez 2015-06-25 20:02:01

Not sure why but both BasePath and AppPath return the empty string :/

@alediaferia 2015-06-25 20:02:50

@PabloFernandez did you revel.Init()?

@Matt3o12 2017-07-05 09:51:19

The link is dead. The new one seems to be https://revel.github.io/

Related Questions

Sponsored Content

13 Answered Questions

[SOLVED] How to get an absolute file path in Python

3 Answered Questions

Revel Framework - Go Lang - Not able to find controller

  • 2016-08-17 05:25:55
  • user27111987
  • 391 View
  • 0 Score
  • 3 Answer
  • Tags:   go revel

23 Answered Questions

[SOLVED] Import a module from a relative path

0 Answered Questions

Using revel with dep for dependency management

  • 2018-06-29 10:28:51
  • Shaumux
  • 159 View
  • 0 Score
  • 0 Answer
  • Tags:   go revel godeps

1 Answered Questions

Organizing revel tests into sub packages

  • 2017-05-17 15:40:49
  • Camway
  • 201 View
  • 1 Score
  • 1 Answer
  • Tags:   testing go revel

1 Answered Questions

[SOLVED] Python nose test with relative pandas file path

1 Answered Questions

[SOLVED] how to get the location of the current file in revel

  • 2016-03-26 17:05:53
  • GIRISH RAMNANI
  • 257 View
  • 0 Score
  • 1 Answer
  • Tags:   go revel

1 Answered Questions

[SOLVED] Read "public" file content in a Revel app

  • 2014-04-11 18:19:41
  • Jérémy
  • 466 View
  • 1 Score
  • 1 Answer
  • Tags:   go revel

2 Answered Questions

[SOLVED] Relative Path for reference files

2 Answered Questions

[SOLVED] Go Revel framework with a non-localhost, live site

Sponsored Content