dqvrlgi3247 2016-10-21 03:50
浏览 50
已采纳

供应商Golang共享存储库

Trying to move to the officially supported Golang vendoring solution from legacy Godeps workflow.

Scenario:

Repo A===
         \
           ========> Repo C (shared library code)
         /  
Repo B===

What is the best workflow I can choose for a mid-size (roughly 5-10 member) team of engineers to vendor Repo C for both Repo A and Repo B? Engineers of varying abilities, most of which probably shouldn't need to know the details of this at all?

I'm currently using govendor for this. I'd prefer not to switch but would if there is a tool that provides a better workflow.

This needs to integrate with a CI server running the builds. I can think of 3 scenarios:

Vendor Repo C into A & B:

  • Pros:

    • Reproducible Builds
    • Easy integration with CI
  • Cons:

    • Manual and Error Prone - Can easily vendor incorrect code
    • Engineers need decent knowledge of vendor tool and methodology

Symlink Repo C trunk branch into vendor folders of A & B:

  • Pros:

    • Engineers need no knowledge of vendor tool
    • Low Developer Maintenance
  • Cons:

    • Builds not (easily) reproducible
    • Possibility of including code in build that shouldn't be released
    • Less Flexible (Repo A and Repo B can't have differing versions of C)

Include Repo C as a git submodule or subtree in Repo A and Repo B (either utilizing vendor or not):

  • Pros:

    • Engineers need no knowledge of vendor tool
    • Easy Setup
    • Less Maintenance
    • Reproducible Builds
  • Cons:

    • Having to use git submodule or subtree

Finding surprisingly little about this question on the internet. Is there some idiomatic way of doing this? I'm sure there are other ways of doing this; what am I missing?

  • 写回答

1条回答 默认 最新

  • duanbu9345 2016-10-21 07:52
    关注

    i suggest to use a manifest based approach with version constraint.

    Project A == Manifest
                 |- Repo A@~1.0.1
                 |- Repo B@~1.0.1
    
    Repo A == Manifest
                 |- Repo C@~1.0.1
    
    Repo B == Manifest
                 |- Repo C@~1.0.5
    
    Repo C == Manifest empty
    

    Which will resolve into

    Project A == Resolved Manifest
                 |- Repo A@1.0.1
                 |- Repo B@1.0.1
                 |- Repo C@1.0.5
    

    where ~1.0.1 means >=1.0.1 <1.1.0.

    As you see B and A dependency to C are independent, yet within project they are resolved correctly.

    In the event A and B would define incompatible dependency to C, an error should occur as the project should not be build-able.

    You may prefer to use caret ^ rather than tilde ~, ^1.0.1 -> >=1.0.1 < 2.0.0.

    Note that you are not forced to use those 'helpers' such tilde and caret, you may define explicit version range.

    You shall decide which constraint to apply given the level of confidence you give to the remote author to correctly upgrade its version number.

    Finally,you can use glide to solve that for you.

    Starting with Repo C, assuming you already tagged the repos, run glide init, git commit -am 'glide init', git push

    Repo A, glide init, glide get git@repo.com/repoc, git commit -am 'glide init', git push

    Repo B, glide init, glide get git@repo.com/repoc, git commit -am 'glide init', git push

    Finally, Project A, glide init, glide get git@repo.com/repoa, glide get git@repo.com/repob, git commit -am 'glide init', git push

    To re install the project, glide install, go build.

    Nothing prevent you to tarball ProjectA with its vendor folder, in order to skip the glide install command when you execute the remote installation.

    But you normally don t want to commit the vendor folder for a development environment. You d usually add vendor/ to your .gitignore file and run glide install or glide update.

    Expect some difficulties in the begin, passed that step, things will work.

    Once you jumped to that workflow, note that you ll have to bump every changes on your repos.

    That is bloatware when you work both project A and repo B to reach a viable change, so in that case, rather than vendoring repoB into project A (you can leave the manifest definition, but get ride of the repoB folder into vendor/), install repoB as a go module with the go get command. Doing so the changes are taken in effect immediately on re-build. Once the change set is completed, browse into each repos and bump them appropriately.

    Finally you may want to use a version bumper to help you to get it done quick and fast, it happens i did one for my personal usage.

    hope this helps.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突