<p>I'm new to go (and to reddit). I am learning go to use it on some pet projects, loving the language and the philosophy around it.</p>
<p>One thing I'm trying to understand is how to sanely manage my projects dependencies. Before posting this question, I read as much as I could on the subject, including posts from this subreddit, the documentation for <code>go get</code> and vendoring, and other blog articles.</p>
<p>I understand I need to make a change in my mental paradigm in regards to dependencies (been using Ruby, Python, and Java fat work) so here I ask how you guys sanely handle dependencies. Here are somethings I've tried:</p>
<p><strong>Context:</strong> My project is a website and I want to use <a href="https://github.com/gin-gonic/gin" rel="nofollow">gin</a></p>
<ul>
<li><p>Tried vendoring gin, so I <code>git clone</code>d it into my project's vendor/ directory. Then realized I'd have to pull all of its dependencies too and flatten them. This is a lot of work and therefore seems impractical. I'd automate that part, but that feels like the start of a package manager</p></li>
<li><p>Looked into vendoring/package manager tools out there: glide, gb, godeps, and govendor. But from what I understand about good practice in the go community, using projects that sanely keep their master branches stable so I can rely on <code>go get</code> is/could be best practice</p></li>
<li><p>So last I thought about having various <em>GOPATH</em>s, one per project, where each has only the dependencies I need for the particular project that I can get and update with <code>go get</code>. I'd be passing GOPATH to the <code>go</code> tool for each project (that seems error prone as heck). I'd also keep a GOPATH on my <em>.bashrc</em> where go tools such as gocode, guru, and golint would be installed (for Text Editor usage). This way I avoid having a huge monorepo of go code and confused about what to update with <code>go get -u</code>. Would this practice void the usability of <em>vendor/</em> support?</p></li>
</ul>
<p>Each option seems valid to me, and I think extra work to manage dependencies can be good because I should be mindful of them anyways. However, I'd like to know from people with more experience what they are doing to tackle this before I commit to one way and regret it down the line.</p>
<p>And if I'm overthinking this, let me know too... anything helps. Thanks.</p>
<p><em>Edit:</em> I guess what I didn't try yet was to just rely on the standard library and only vendor libraries that aren't frameworks (or that don't depend in a crap-ton of libraries themselves). This is valid too...</p>
<hr/>**评论:**<br/><br/>sonneiko: <pre><p>Glide. works with other tools like gb, uses vendor folder. Works perfect for me to make reproducible builds on jenkins.
I've made a golang container with glide binary in and I just build my projects inside it. </p></pre>interactiv_: <pre><blockquote>
<p>using projects that sanely keep their master branches stable so I can rely on go get is/could be best practice</p>
</blockquote>
<p>That's just insane. Go is not Linux Kernel C where libraries are absolutely stable and don't break. You want reproducible builds in a professional environment? either you never use 3rd party libraries , or you use a package manager. </p>
<p>Anybody who tell beginners "just use go get" is not a serious developer.</p>
<p>I'm a bit sick of a these "you don't need that with Go". </p>
<p>Go is not a special snowflake language where good programming practices don't apply. A modern language with no official package manager is doomed to fail into community fragmentation, because on the long people will have to use a package manager anyway. Any alternative technique doesn't scale. Most shops are not google, most shops don't use mono-repos, most shops don't limit themselves to their own libraries ...</p>
<p>So the more the go team stay silent on this, because they just don't give a fuck about these issues, "at google, we don't have this problem", the more the community will become fragmented. I wrote my own package manager for go by the way, but I'm not going to publish it because of the toxic attitude of the community regarding open source projects they don't like or they do not deem "idiomatic".</p></pre>andradei: <pre><p>The very need of me having to ask what's the best way to handle vendoring and dependencies is proof of the fragmentation you mention.</p>
<p>Rust is the only language that I saw being shipped with a package manager, cargo.</p>
<p>Besides Rust, I think this fragmentation is only natural given how relatively young go is.</p>
<p>But after reading your comment, something that I now find very, very curious is that go is opinionated enough to have shipped gofmt with the language tooling, which got rid of silly debates and made people more productive, yet it didn't do the same for vendoring (and I leave library dependencies out of question here) on 1.6 (when it stopped being an experiment). Wouldn't having a vendoring tool to fetch and flatten the dependency tree coming from the go team have the same benefit as gofmt? 1.7 could be a great opportunity to think about this. But if it is too late now, maybe a 1.8 goal.</p>
<p>Anyways, I'll pick a vendoring tool and move on with my project.</p></pre>interactiv_: <pre><p>You know what I don't know why things are like that. go get is half of a package manager because it can fetch dependencies, but it just doesn't support versioning. </p>
<p>Why ? I don't know, the justification is "you don't need that in go " or "at google we don't need that" .</p>
<p>So it's not like it's not opinionated, they just don't give a damn about the issue so they deem it irrelevant. </p>
<p>Sure nobody owes us anything, it's just a frustrating fact that hurts Go's adoption and growth , along with the toxic extremely community.</p></pre>andradei: <pre><p>As far as the community goes, I find it to be good. Most people are succinct in their answers, only a few are rude. The IRC channel is fun to "watch" sometimes.</p>
<p>Sure the community isn't amazingly helpful 100% of the time like, say, Rust's, but it might be because of the nature of the languages... </p>
<p>Rust most often than not seems to be happy to add more and more and more features via their RFC system. Naturally, more people are going to be happy I guess... While Go's features are locked, period. That drives some people crazy. This itself is a feature, and I quite like it to be honest. The only thing not locked in Go is its official tooling, and from what I'm learning that's where I'd like to see vendoring getting better support :)</p></pre>skelterjohn: <pre><p>try out github.com/skelterjohn/wgo. it helps ease the pressure of some vendoring issues. Using it, if you 'go get (whatever the url for gin is)', it will fetch all the deps into the project's vendor dir, and let you pin (or vendor) deps there.</p></pre>andradei: <pre><blockquote>
<p>github.com/skelterjohn/wgo</p>
</blockquote>
<p>Looks very interesting, I'll try it out.</p></pre>ChristophBerger: <pre><blockquote>
<p>But from what I understand about good practice in the go community, using projects that sanely keep their master branches stable so I can rely on go get is/could be best practice</p>
</blockquote>
<p>This is true for library projects. If your project produces an executable you are free to use vendoring tools for transitively flattening the library dependencies into <code>/vendor</code>. </p>
<p>At least this is what I understand from discussions like <a href="https://www.reddit.com/r/golang/comments/4cptba/best_practice_for_vendoring_in_libraries/" rel="nofollow">this one</a>, but it seems a sane approach to me.</p></pre>shovelpost: <pre><p>Till now, vendoring is the community's accepted way to manage dependencies. That said you should approach it like this:</p>
<ul>
<li>Vendor things by hand first to see how the whole thing works.</li>
<li>Get tired of vendoring by hand.</li>
<li>Do the job easier with one of the <a href="https://github.com/golang/go/wiki/PackageManagementTools" rel="nofollow">tools</a>. </li>
<li>Profit.</li>
</ul></pre>andradei: <pre><p>I think I'm on step 3 now. There is also a hidden step somewhere around 3:</p>
<ul>
<li>Write a vendoring tool that suits your needs/matches your interpretation of the problem :D</li>
</ul></pre>shovelpost: <pre><p>Personal opinion/recommendation:</p>
<p>Use the simplest tool possible for the job. The ones I've tried and liked are <a href="https://github.com/kardianos/govendor" rel="nofollow">govendor</a> and <a href="https://github.com/FiloSottile/gvt" rel="nofollow">gvt</a> with gvt being the one I am using. Avoid glide.</p></pre>nilstgmd: <pre><p>I'm using /vendor with govendor as well, which does what it should. I was wondering what is the recommended way to handle /vendor in git repos? Is it just checking in everything (like I do) and have the pain of large PullRequests/Diffs or is there a better way?</p></pre>itsmontoya: <pre><p>I rarely have dependency issues. Though, we do write a lot of our libraries in house..</p></pre>Duncan3: <pre><p>In short you swear a lot and wish they would just make up their minds already and pick a solution, any of the proposed solutions, because they all work. But no...</p>
<p>In the meantime, pick a hack <a href="https://github.com/golang/go/wiki/PackageManagementTools" rel="nofollow">https://github.com/golang/go/wiki/PackageManagementTools</a> - we are using Trash, after some issues with Glide.</p>
<p>Just don't break your master branch is probably the only useful advice, and cross your fingers all your dependencies can do the same.</p></pre>Bake_Jailey: <pre><p>I just found trash last night. Really great, albeit pretty slow to update dependencies when compared to what I've used in the past. Getting told when I don't need a dep anymore is a nice touch.</p>
<p>Unfortunately most other managers do silly things like downloading the entire docker repo when I get go-dockerclient. Only trash and govendor seem to know better (gvt used to, and it was supposed to be fixed in glide).</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传