【问题标题】:Is there an easier way to keep local Go packages updated有没有更简单的方法来更新本地 Go 包
【发布时间】:2019-12-16 08:23:20
【问题描述】:

我正在使用导入到不同项目中的多个包,这些包包括用于我的业务逻辑的自定义适配器,这些适配器由 lambda 和谷歌云功能以及其他公共包共享。我现在这样做的方式是提供它们并将它们包含在云功能中。对于可以在 VM 上编译和部署的应用程序,我将它们分别编译。这对我来说很好,但是,开发这些模块很痛苦。

如果我更新包中的方法签名和名称,我必须将我的更改推送到 github/gitlab(我的包路径类似于 gitlab.com/groupName/projectName/pkg/packageName)然后执行@987654321 @更新包。

这也并没有真正更新它,有时我被旧版本卡住了,不知道如何更新它。我想知道有没有更简单的方法来处理这个问题。


为了清楚起见:

导出的包 1 路径:gitlab.com/some/name/group/pkg/clients/psql

psql-client
    |
    |_ pkg
        |
        |_psql.go

应用程序 1 使用 psql-client 路径:gitlab.com/some/name/app1

应用程序 2 使用 psql-client 路径:gitlab.com/some/name/app2

【问题讨论】:

  • 执行 go get -u 时遇到什么错误?使用 go get 时没有版本的概念,那么卡在旧版本上是什么意思?

标签: go go-modules go-packages


【解决方案1】:

go get 是可传递的,因此您可以将其添加到您的构建过程中。一个典型的 Go 项目构建基本上是:

go get -u ./... && go test ./... && go build ./cmd/myapp

获取和更新依赖项,运行所有项目测试,然后构建二进制文件。

【讨论】:

    【解决方案2】:

    我的理解是(a)您使用的是new Go modules system,而(b)问题的一部分是您不希望在执行本地操作时跨不同的存储库将更改推送到 github 或 gitlab发展。

    换句话说,如果您在本地进行更改,听起来您不想通过 github/gitlab 往返这些更改,以便这些更改在您正在本地处理的相关存储库中可见.

    最重要的建议

    在单个存储库中拥有 > 1 个模块会使您的工作流程变得非常复杂。

    如您的示例所示,通常在单个存储库中拥有 > 1 个模块几乎总是需要更多的工作。也很难做到正确。对于大多数人来说,成本几乎总是不值得的。此外,收益通常不是人们所期望的,或者在某些情况下,在 repo 中拥有 > 1 个模块并没有实际的好处。

    我绝对建议您遵循普遍遵循的“1 个 repo == 1 个模块”的规则,至少现在是这样。 This answer 有更多关于原因的详细信息。

    使用多个存储库

    如果您正在使用 Go 模块,一种方法是您可以将 replace 指令添加到模块的 go.mod 文件中,以告知该 Go 模块其他 Go 模块在磁盘上的位置。

    示例结构

    例如,如果您有三个 repos repo1、repo2、repo3,您可以克隆它们,使它们在您的本地磁盘上彼此相邻:

    myproject/
    ├── repo1
    ├── repo2
    └── repo3
    

    然后,如果repo1 依赖于repo2 和repo3,您可以为repo1 设置go.mod 文件以了解其他两个模块的相对磁盘位置:

    repo1 go.mod:

    replace github.com/me/repo2 => ../repo2
    replace github.com/me/repo3 => ../repo3
    

    当您位于repo1 目录或其任何子目录中时,go 命令(如go build 或go test ./....)将使用repo2 和repo3 的磁盘版本。

    repo2 go.mod:

    如果repo2依赖repo3,你也可以设置:

    replace github.com/me/repo3 => ../repo3
    

    repo3 go.mod:

    例如,如果repo3 不依赖于repo1 或repo2,那么您不需要将replace 添加到其go.mod。

    其他详情

    模块 wiki 上的 replace FAQ 中更详细地介绍了 replace 指令。

    最后,这取决于您的具体用例,但此时的常见解决方案是使用gohack,它可以自动执行此过程中的一些。特别是,它创建了一个依赖项的可变副本(默认情况下在$HOME/gohack 中,但位置由$GOHACK 变量控制)。 gohack还将您当前的go.mod 文件设置为具有指向该可变副本的replace 指令。

    【讨论】:

    • 我已经使用替换并使用磁盘位置,但是,这就是我的 go.mod 文件的外观 ``` 替换 github.com/me/parent-repo v0.0.0-20190808145620-8465703829e1 => ../../ ``` 我想我没有使用替换作为子包,而是使用替换作为父包,这在当时对我来说是有意义的
    • 我将此标记为已接受的答案,因为它以某种方式回答了查询。我仍然有问题,因为我有很多内部依赖项,我想我需要通过更好地构建我的包来解决这些问题
    • 一个问题是你有多少个仓库,你有多少个模块?每个存储库有一个模块,还是有一些存储库包含多个模块/go.mod 文件?
    • 我问你在一个仓库中有多少个模块的原因是有时人们会在一个仓库中放置 > 1 个模块,这通常会使工作流程变得非常复杂。遵循“1 repo == 1 module”的一般规则几乎总是更容易。
    • 在单个存储库中拥有 > 1 个模块几乎总是需要更多的工作。也很难做到正确。对于大多数人来说,成本几乎总是不值得的。此外,收益通常不是人们所期望的,或者在某些情况下,在 repo 中拥有 > 1 个模块并没有实际的好处。我绝对会推荐你遵循“1 repo == 1 module”这一普遍遵循的规则,至少现在是这样。 This answer 有更多关于原因的详细信息。
    猜你喜欢
    • 1970-01-01
    • 2019-07-05
    • 1970-01-01
    • 2012-01-11
    • 2021-11-08
    • 2011-10-26
    • 1970-01-01
    • 2011-04-22
    • 1970-01-01
    相关资源
    最近更新 更多