简体   繁体   English

如何获取 Go 模块依赖项的路径?

[英]How to get the path to a Go module dependency?

I have two Go modules, let's name them example.com/a and example.com/b .我有两个 Go 模块,我们将它们命名为example.com/aexample.com/b

Let this be example.com/a 's go.mod :让它成为example.com/ago.mod

module example.com/a

go 1.12

require (
  example.com/b v0.4.2
)

In example.com/b 's root directory, there is a file named data.yaml .example.com/b的根目录下,有一个名为data.yaml的文件。 example.com/a needs to autogenerate some code as part of its build process. example.com/a需要在构建过程中自动生成一些代码。 This autogeneration needs to read data.yaml .这种自动生成需要读取data.yaml

How can I in the directory of example.com/a query for the path of example.com/b to read that file?如何在example.com/b的目录中查询example.com/a的路径来读取该文件? I know that after downloading, the module will be somewhere in (go env GOPATH)/pkg/mod but I don't know how the path will be constructed from there as it contains some !我知道下载后,该模块将位于(go env GOPATH)/pkg/mod中的某个位置,但我不知道如何从那里构建路径,因为它包含一些! characters that are not part of the import path.不属于导入路径的字符。 I hoped that there is some subcommand of go mod or go list that will output the path, but I haven't found it in the documentation.我希望go modgo list中有一些子命令将 output 路径,但我没有在文档中找到它。

I have thought about including data.yaml in Go code via go-bindata (yes I'm aware of //go:embed but I don't want to require Go 1.16 for now) but then I would only have access at run-time when I need it at compile-time.我已经考虑过包括data.yaml in z5f075ae3e3e1f9d0382bbbbbbbb8c4632991f96f96f96f96f96fz indy in go-bindata (是的,我不需要emby //go:embed reply go:reply go:reply go:reply go:reply go:reply go:reply go:impy go:im ob go:imp o ny3555ffz1555ffz1555ffz ins of /rec.55ffz ins of /rec.55ffz in。我在编译时需要它的时间。

You can use go list with the -m flag and the -f flag like so:您可以使用带有-m标志和-f标志的go list ,如下所示:

go list -m -f '{{.Dir}}' example.com/b

The -m flag: -m标志:

causes go list to list modules instead of packages.导致 go list 列出模块而不是包。 In this mode, the arguments to go list may be modules, module patterns (containing the... wildcard), version queries, or the special pattern all, which matches all modules in the build list.在此模式下,arguments 到 go 列表可以是模块、模块模式(包含...通配符)、版本查询或特殊模式 all,它匹配构建列表中的所有模块。 If no arguments are specified, the main module is listed.如果未指定 arguments,则列出主模块。

( reference ) 参考

The -f flag: -f标志:

specifies an alternate format for the output, using the syntax of package template.使用 package 模板的语法为 output 指定替代格式。 The struct being passed to the template, when using the -m flag, is:当使用-m标志时,传递给模板的结构是:

 type Module struct { Path string // module path Version string // module version Versions []string // available module versions (with -versions) Replace *Module // replaced by this module Time *time.Time // time version was created Update *Module // available update, if any (with -u) Main bool // is this the main module? Indirect bool // is this module only an indirect dependency of main module? Dir string // directory holding files for this module, if any GoMod string // path to go.mod file for this module, if any GoVersion string // go version used in module Error *ModuleError // error loading module } type ModuleError struct { Err string // the error itself }

[the above quote was altered for context] [以上引用已根据上下文进行了更改]

( reference ) 参考

You can figure out the module path like this:您可以像这样找出模块路径:

package main

import (
    "fmt"
    "os"
    "path"

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

func GetModulePath(name, version string) (string, error) {
    // first we need GOMODCACHE
    cache, ok := os.LookupEnv("GOMODCACHE")
    if !ok {
        cache = path.Join(os.Getenv("GOPATH"), "pkg", "mod")
    }

    // then we need to escape path
    escapedPath, err := module.EscapePath(name)
    if err != nil {
        return "", err
    }

    // version also
    escapedVersion, err := module.EscapeVersion(version)
    if err != nil {
        return "", err
    }

    return path.Join(cache, escapedPath+"@"+escapedVersion), nil
}

func main() {
    var path, err = GetModulePath("github.com/jakubDoka/mlok", "v0.4.7")
    if err != nil {
        panic(err)
    }

    if _, err := os.Stat(path); os.IsNotExist(err) {
        fmt.Println("you don't have this module/version installed")
    }
    fmt.Println("module found in", path)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM