I am writing a utility function for my unit tests which is used by unit tests in multiple packages. This utility function must read a particular file (always the same file). Her
Building on the answer by Oleksiy you can create a sub-package in your project called ./internal/projectpath/projectpath.go
and paste in the following:
package projectpath
import (
"path/filepath"
"runtime"
)
var (
_, b, _, _ = runtime.Caller(0)
// Root folder of this project
Root = filepath.Join(filepath.Dir(b), "../..")
)
Then you can use projectpath.Root
in any other package to have the root folder of your project.
You can also use my method without C:
package mypackage
import (
"path/filepath"
"runtime"
"fmt"
)
var (
_, b, _, _ = runtime.Caller(0)
basepath = filepath.Dir(b)
)
func PrintMyPath() {
fmt.Println(basepath)
}
https://play.golang.org/p/ifVRIq7Tx0
Go directories:
// from Executable Directory
ex, _ := os.Executable()
fmt.Println("Executable DIR:", filepath.Dir(ex))
// Current working directory
dir, _ := os.Getwd()
fmt.Println("CWD:", dir)
// Relative on runtime DIR:
_, b, _, _ := runtime.Caller(0)
d1 := path.Join(path.Dir(b))
fmt.Println("Relative", d1)
Yes, Finding package path is possible:
pathfind.go:
package main
/*
const char* GetMyPathFILE = __FILE__;
*/
import "C"
import "path/filepath"
var basepath = ""
//GetMyPath Returns the absolute directory of this(pathfind.go) file
func GetMyPath() string {
if basepath == "" {
g := C.GoString(C.GetMyPathFILE)
basepath = filepath.Dir(g)
}
return basepath
}
All you have to do is copy this file to your project. Keep in mind this comes up with the path for the file, not the caller so you have to copy the function/file to every project you need the function in. Additionally if you put this in a file with other code be sure to respect CGO
's import rules.
Returns the root of the application:
import (
"path"
"path/filepath"
"runtime"
)
func RootDir() string {
_, b, _, _ := runtime.Caller(0)
d := path.Join(path.Dir(b))
return filepath.Dir(d)
}