【问题标题】:how to handle go import absolute paths and github forks?如何处理 go import 绝对路径和 github 分叉?
【发布时间】:2015-08-23 12:27:57
【问题描述】:

有很多关于这个的问题,包括为什么你不应该使用import "./my/path" 以及为什么它只工作因为一些遗留的 go 代码需要它。

如果这是正确的,您如何处理项目的封装以及扩展 github 分叉?在所有其他语言中,我可以做一个项目的 github fork 或 git clone,所有东西都封装在那里。如何从 go 项目中获得相同的行为?

使用 go "hello world" 示例的简单示例。

你好.go

package main

import ("fmt"
    "github.com/golang/examples/stringutil")

func main() {
    fmt.Printf(stringutil.Reverse("hello, world")+"\n")
}

上面的效果很好。但是,如果我想使用我自己的 stringutil,它位于子目录中并将编译为单个二进制文件,我 仍然 需要完整路径:

package main

import ("fmt"
    "github.com/myrepo/examples/util/stringutil")

func main() {
    fmt.Printf(stringutil.Reverse("hello, world")+"\n")
}

现在,如果有人复制或分叉我的 repo,它直接依赖于“github.com/myrepo/”,即使这完全在内部使用!

如果有 20 个不同的文件导入 utils/ 怎么办?每次有人分叉时我都需要更换吗?这是很多无关的更改和无意义的 git 提交。

我在这里缺少什么?为什么相对路径如此糟糕?如何在不更改数十个文件的情况下分叉一个引用其自己的子目录(及其包)的项目?

【问题讨论】:

  • 刚接触 golang 的新人发现了同样的发现。知道 2018 年有什么变化吗?
  • 一些已经改变。如果您不在 GOPATH 或设置 env var GO111MODULE=on,现在支持 Go 模块(从 1.11 开始)。它仍然没有解决根本问题,并且是我对 Go 的主要抱怨之一。忽略语言,我一直强烈认为节点打包是正确的:包中文件内的任意名称,以及映射到绝对位置的“映射文件”(package.json 或其他)。哦,好吧。
  • 我看了看 Go 模块,直到看到“实验”这个词。解决方案似乎是克隆到与上游存储库命名相同的存储库中,同时推送到源(分叉)以进行私有更改。这一切都很蹩脚。
  • Golang 的模块结构相当蹩脚。尽管存在弱点,但它的采用仍然存在。 :-(

标签: go


【解决方案1】:

至于不允许相对导入背后的原因,您可以阅读此讨论以获取一些观点:https://groups.google.com/forum/#!msg/golang-nuts/n9d8RzVnadk/07f9RDlwLsYJ

出于您所描述的原因,我个人更愿意启用它们,至少对于内部导入而言。

现在,如何处理这种情况?

    1234563如果您使用的是像 godep 这样的供应商解决方案,它会顺利运行,因为保存它只会供应您的分叉代码,而 go get 永远不会直接使用。
  1. 如果您的 fork 发生了很大变化并且您打算保持 fork,请重写所有导入路径。您可以使用sed 将其自动化,也可以使用支持重写正在格式化的代码的gofmt -r

[编辑] 我还发现了这个旨在帮助解决这种情况的工具:https://github.com/rogpeppe/govers

我已经完成了 1 和 2 - 当我刚刚对某个库进行了小错误修复时,我只是更改了遥控器并对其进行了更新。当我实际上 fork 一个库而不打算合并我的更改时,我更改了所有导入路径并继续仅使用我的 repo。

我还可以考虑在销售工具之外添加一个允许这些东西自动化的工具,但我认为它们目前都不支持它。

【讨论】:

  • 所以 go 对包的想法是绝对的。时期。您可以将目录放在彼此上方/下方,但如果一件事需要另一件事,并且不在同一个包中,则它是绝对导入。这意味着要么不要构建由一起构建且不是绝对的软件包组成的软件,要么接受大量浪费的重写。我不明白。他们在设计包命名空间时没有考虑到这一点吗?
  • Google 在这方面的理念是,他们将所有内容都提供到一个源代码树中,仅此而已。所以这有点让分叉依赖的整个想法变得多余了,因为每个依赖在某种意义上都已经分叉了。
  • “他们将所有东西都供应到一个源代码树中……每个依赖项都已经分叉了。”所以世界其他地方编写软件的方式——更大的包、子文件和文件夹,允许我们将事物组织和构建到一个单一的版本中,并进行自我封装,并让诸如 github 分叉和颠覆之类的东西检出,等等. 工作 - 谷歌,因此 go 只是不那样工作?
  • @deitch 我不是谷歌用户,这只是基于我从 go 作者那里读到的内容,但本质上 - 是的。 Go 并没有规定你应该如何工作,并且这个关于 forks 的问题不是源于包的组织方式,而是源于(错误的)假设 go get 是一个足够好的依赖管理器,并且导入路径 == git 网址。
  • 换句话说,对于内部企业项目管理来说,这是一种很好的哲学,对于协作式开源管理来说不是一个很好的哲学。这真遗憾。我真的很喜欢 go 所做的许多事情。这不是其中之一
猜你喜欢
  • 2012-09-23
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-27
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
相关资源
最近更新 更多