API to get the module name
Asked Answered
S

4

7

Is there an API to get the module name of a project which uses go 1.11 module system?

so I need to get abc.com/a/m from the module definition module abc.com/a/m in go.mod file.

Standish answered 7/11, 2018 at 3:55 Comment(3)
No. The nearest is reflect.Type.PkgPathDespot
go list -m good enough?Flotation
@Flotation 'go list -m' is what I was looking for. Thanks.Mainmast
H
6

As of this writing, I am not aware of any exposed APIs for that. However, looking at go mod sources, there is a function that can be quite useful in Go mod source file

// ModulePath returns the module path from the gomod file text.
// If it cannot find a module path, it returns an empty string.
// It is tolerant of unrelated problems in the go.mod file.
func ModulePath(mod []byte) string {
    //...
}

func main() {

    src := `
module github.com/you/hello

require rsc.io/quote v1.5.2
`

    mod := ModulePath([]byte(src))
    fmt.Println(mod)

}

Which outputs github.com/you/hello

Hugues answered 7/11, 2018 at 4:58 Comment(1)
For others finding this question online, note that this answer is no longer true. Go 1.12 added pkg.go.dev/runtime/debug#BuildInfoCorelative
H
3

Try this?

package main

import (
    "fmt"
    "io/ioutil"
    "os"

    modfile "golang.org/x/mod/modfile"
)

const (
    RED   = "\033[91m"
    RESET = "\033[0m"
)

func main() {
    modName := GetModuleName()
    fmt.Fprintf(os.Stdout, "modName=%+v\n", modName)
}

func exitf(beforeExitFunc func(), code int, format string, args ...interface{}) {
    beforeExitFunc()
    fmt.Fprintf(os.Stderr, RED+format+RESET, args...)
    os.Exit(code)
}

func GetModuleName() string {
    goModBytes, err := ioutil.ReadFile("go.mod")
    if err != nil {
        exitf(func() {}, 1, "%+v\n", err)
    }

    modName := modfile.ModulePath(goModBytes)
    fmt.Fprintf(os.Stdout, "modName=%+v\n", modName)

    return modName
}
Hemingway answered 13/8, 2020 at 11:0 Comment(0)
P
2

If your starting point is a go.mod file and you are asking how to parse it, I would suggest starting with go mod edit -json, which outputs a particular go.mod file in JSON format. Here is the documentation:

https://golang.org/cmd/go/#hdr-Edit_go_mod_from_tools_or_scripts

Alternatively, you could use rogpeppe/go-internal/modfile, which is a go package that can parse a go.mod file, and which is used by rogpeppe/gohack and some other tools from the broader community.

Issue #28101 I think tracks adding a new API to the Go standard library to parse go.mod files.

Here is a snippet of the documentation for go mod edit -json:

The -json flag prints the final go.mod file in JSON format instead of writing it back to go.mod. The JSON output corresponds to these Go types:

type Module struct {
    Path string
    Version string
}

type GoMod struct {
    Module  Module
    Go      string
    Require []Require
    Exclude []Module
    Replace []Replace
}

type Require struct {
    Path string
    Version string
    Indirect bool
}

Here is an example snippet of JSON output from go mod edit -json that shows the actual module path (aka module name), which was your original question:

{
        "Module": {
                "Path": "rsc.io/quote"
        },

In this case, the module name is rsc.io/quote.

Phenetole answered 15/3, 2019 at 21:4 Comment(0)
C
1

As of Go 1.12 (for those finding this via a search who are using modules but not necessarily the older version the OP mentioned), the runtime/debug package includes functionality for getting information about the build, including the module name. For example:

import (
    "fmt"
    "runtime/debug"
)

func main() {
    info, _ := debug.ReadBuildInfo()
    fmt.Printf("info: %+v", info.Main.Path)
}

You can run this example on the playground: https://go.dev/play/p/5oGbCRxSnjM

For more information, see the documentation for "runtime/debug".BuildInfo

Corelative answered 7/4, 2022 at 16:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.