0

几个组织分发同一个项目的变体,我们定期相互拉取更改。如果我们最终能够合并代码存储库,并且也许有一个由联盟管理的公共源代码树,那就太好了。但是,每个成员可能都希望选择分发他们自己的变体,而不会给客户带来太多痛苦,以防在上游处理更新产品所需的更改时遇到麻烦。

该项目由三个包组成:

  1. 图书馆
  2. 输出需要导入库的go代码的编译器可执行文件
  3. 使用#2 生成的代码并与#1 链接的实用程序可执行文件

当来回拉动更改时,一个很大的烦恼是导入路径的无故差异。我们基本上必须编辑 to 的每个import "github.com/companyA/whatever"版本import "companyB.com/whatever"。当然,这些问题会随着(喘气)相对导入路径而消失。如果我们诉诸这种异端,我们的编译器可以在生成的代码中硬编码绝对导入路径,以将最终用户与库的导入路径隔离开来。它还只需要源代码树(编译器中输出导入语句的行)中的一个无偿差异,而不是一堆。

但无论如何,我知道相对导入路径不好 - 这是一个棘手的情况。我知道这与诸如thisthis之类的问题类似,因为出于实际和政治原因,仅要求最终用户创建一个名为companyB.com并从中克隆某些内容的目录的答案companyA是行不通的。

我已经知道 go 并不能很好地适应这种情况,所以我也不是要一个灵丹妙药来让 go 处理它不能处理的事情。不幸的是,另一件事是要求客户这样做curl whatever | sh,因为这被视为过多的责任(被认为是“培训客户做危险的事情”)。也许我们可以放弃go get,让每个人都克隆到 . 下的某个中性非 DNS 名称$GOPATH/src,但我们需要在没有“标志日”的情况下执行此操作,如果代码在错误的位置,代码会突然中断。

我的问题是,是否有人成功地将 SDK 类型的项目与现有的最终用户合并,如果是,您是如何做到的,哪些有效,哪些无效?您实际上是否避免了相对导入路径或粗糙的GOPATH黑客攻击,如果是的话,是否值得?您采用了哪些机制(环境变量、配置文件、.project-config当前工作目录中的文件、滥用vendor目录、在编译时确定其绝对导入路径的代码生成包)来使这项工作顺利进行?您是否只是应付大量sed或可能gofmt -r?是否有涉及巧妙使用.gitattributesgo generate重写结帐/签入时的导入路径的技巧?

4

1 回答 1

1

合并它们非常容易 - 交叉合并以使它们都匹配,选择一个(或创建一个新的)作为规范的事实来源,然后将所有引用迁移到规范导入并在那里进行所有未来的更新。

问题出现在这里:

每个成员可能都希望选择分发他们自己的变体,而不会给客户带来太多痛苦,以防在上游处理新产品所需的更改时遇到麻烦

如果不使用您已经排除的任何已知解决方案,没有特别好的方法可以做到这一点,也没有办法做到这一点,具体取决于您对“太多痛苦”的阈值。

在不了解情况的情况下很难提出选择,但如果有任何方法可以让每家公司将他们的部分抽象到一个单独的库中,他们可以按照自己的节奏维护和更新,同时使用一个具有共同责任的较小的共享库,那很可能是最好的选择——类似于Terraform为其提供者使用的模型?基本上,您将共享维护共享“核心”,然后独立维护“供应商特定”包。

于 2018-06-28T18:01:23.467 回答