How to get the name of the current package in go?

Is there a way to get the name of the current package at runtime?

package main import "fmt" func main() { pkgName := {some magic here:)} fmt.Println(pkgName) } 

... and the result should be "main"

Now I use a constant like:

 package main import "fmt" const ( pkgName = "main" ) func main() { fmt.Println(pkgName) } 

but I wonder if you can avoid this

+15
go
source share
4 answers

There is no runtime or reflect method that provides the functionality you are looking for.

The closest I could find is:

 package main import ( "azul3d.org/lmath.v1" "fmt" "reflect" ) type Empty struct{} func main() { fmt.Println(reflect.TypeOf(Empty{}).PkgPath()) fmt.Println(reflect.TypeOf(lmath.Vec3{0, 0, 0}).PkgPath()) } 

This will lead to the conclusion:

 main azul3d.org/lmath.v1 

You can also read the first line of the file and remove the substring "package". (Not sure if this is the best idea)

 package main import ( "bufio" "bytes" "fmt" "os" ) func main() { file, err := os.Open("so.go") if err != nil { panic(err) } r := bufio.NewReader(file) line, _, err := r.ReadLine() if err != nil { panic(err) } packageName := bytes.TrimPrefix(line, []byte("package ")) fmt.Println(string(packageName)) } 
+21
source share

Here is part of my registration package. It retrieves the caller information of the logging function to display later on the output.

 func retrieveCallInfo() *callInfo { pc, file, line, _ := runtime.Caller(2) _, fileName := path.Split(file) parts := strings.Split(runtime.FuncForPC(pc).Name(), ".") pl := len(parts) packageName := "" funcName := parts[pl-1] if parts[pl-2][0] == '(' { funcName = parts[pl-2] + "." + funcName packageName = strings.Join(parts[0:pl-2], ".") } else { packageName = strings.Join(parts[0:pl-1], ".") } return &callInfo{ packageName: packageName, fileName: fileName, funcName: funcName, line: line, } } 

As you can see, it also returns the name of the package.

+21
source share

To reliably get the package name, you can use the go parser to parse only the package sentence.

 import ( "fmt" "go/ast" "go/parser" "go/token" ) func packageName(file string) (string, error) { fset := token.NewFileSet() // parse the go soure file, but only the package clause astFile, err := parser.ParseFile(fset, l.path, nil, parser.PackageClauseOnly) if err != nil { return "", err } if astFile.Name == nil { return "", fmt.Errorf("no package name found") } return astFile.Name.Name, nil } 
+6
source share

This can help:

 import ( "runtime" "strings" ) func Package() string { pc, _, _, _ := runtime.Caller(1) parts := strings.Split(runtime.FuncForPC(pc).Name(), ".") pl := len(parts) pkage := "" funcName := parts[pl-1] if parts[pl-2][0] == '(' { funcName = parts[pl-2] + "." + funcName pkage = strings.Join(parts[0:pl-2], ".") } else { pkage = strings.Join(parts[0:pl-1], ".") } return pkage } 
0
source share

All Articles