【问题标题】:API to get the module name获取模块名称的 API
【发布时间】:2022-04-08 00:34:44
【问题描述】:

是否有 API 可以获取使用 go 1.11 模块系统的项目的模块名称?

所以我需要从go.mod 文件中的模块定义module abc.com/a/m 中获取abc.com/a/m

【问题讨论】:

  • 没有。最接近的是 reflect.Type.PkgPath
  • go list -m 够好吗?
  • @wdscxsj 'go list -m' 是我想要的。谢谢。

标签: go go-modules


【解决方案1】:

在撰写本文时,我不知道有任何公开的 API。但是,查看go mod 的来源,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)

}

哪个输出github.com/you/hello

【讨论】:

【解决方案2】:

如果您的起点是一个go.mod 文件并且您询问如何解析它,我建议您从go mod edit -json 开始,它以JSON 格式输出一个特定的go.mod 文件。这是文档:

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

或者,您可以使用rogpeppe/go-internal/modfile,这是一个可以解析go.mod 文件的go 包,rogpeppe/gohack 和更广泛社区的一些其他工具都在使用它。

Issue #28101 我认为跟踪向 Go 标准库添加新 API 以解析 go.mod 文件。

这是go mod edit -json 的文档的sn-p:

-json 标志以 JSON 格式打印最终的 go.mod 文件,而不是 将其写回 go.mod。 JSON 输出对应于这些 Go 类型:

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
}

这是来自go mod edit -json 的 JSON 输出示例 sn-p,它显示了实际的模块路径(又名模块名称),这是您最初的问题:

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

在这种情况下,模块名称是rsc.io/quote

【讨论】:

    【解决方案3】:

    试试这个?

    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
    }
    

    【讨论】:

      【解决方案4】:

      从 Go 1.12 开始,runtime/debug 包包含获取有关构建信息的功能,包括模块名称。例如:

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

      你可以在操场上运行这个例子:https://go.dev/play/p/5oGbCRxSnjM

      有关详细信息,请参阅"runtime/debug".BuildInfo 的文档

      【讨论】:

        猜你喜欢
        • 2013-11-06
        • 1970-01-01
        • 2012-07-27
        • 2016-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-26
        • 2021-06-10
        相关资源
        最近更新 更多