Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to reference a relative file from code and tests

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?

like image 750
Pablo Fernandez Avatar asked Jun 25 '15 19:06

Pablo Fernandez


People also ask

What is a relative file path?

File paths are a common stumbling block for novice programmers. First, what’s the difference between a relative file path and an absolute file path? A relative path describes the location of a file relative to the current (working) directory*. An absolute path describes the location from the root directory.

How do I add a file to a test without copying?

One of the choices is 'Add As Link'. This will add the file to your project without copying it. On the file properties you can choose 'Copy if newer' for 'Copy to Output Directory'. You can then consume the file in your test without maintaining two copies.

Why can't I load an application from a relative path?

You have mixed up Resources in Applications, which are usually embedded in an assembly, with loose files your application can load at runtime using a relative path. I think I understood how you get here, hence another post. Let me try to summarize these two issues one last time for you:

What is the difference between relative and absolute path?

A relative path describes the location of a file relative to the current (working) directory*. An absolute path describes the location from the root directory. When learning to access data files through programming, we regularly use relative file paths. In these Java examples, we define a path to the EQs_last_last_week_of_2021.csv file.


2 Answers

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"
like image 71
icza Avatar answered Oct 20 '22 07:10

icza


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
like image 28
alediaferia Avatar answered Oct 20 '22 07:10

alediaferia