Workspace and dependencies

polaris · · 765 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hello everyone !</p> <p>I&#39;m new to golang and I have some questions about the workspace and the dependencies management.</p> <p>I&#39;ve read that GOPATH is the location of my workspace, where all of my go code belongs (personal project and dependencies of all of these projects).</p> <p>If I want to push one of my project on github, will I push only my project source code or will I also push the dependencies ? If I must push only my code, how another developer who wants to clone my repo can find the list of my dependencies and use the rights versions ?</p> <p>Can I have two projects using two different version of the same library ? (It seems to be impossible if all of my project and dependencies are in the same folder).</p> <p>Thanks for your answers !</p> <hr/>**评论:**<br/><br/>neoasterisk: <pre><p>Is the project a library/package or a binary?</p></pre>rafoufoun: <pre><p>It could be both (don&#39;t have one yet, just asking for my knowledge).</p> <p>Let&#39;s say I want to develop a script which will be deployed as a binary. I can&#39;t understand where I should put this code and the dependencies I could have</p></pre>neoasterisk: <pre><blockquote> <p>Let&#39;s say I want to develop a script which will be deployed as a binary</p> </blockquote> <p>Go&#39;s default source code organization is based around the concept of a monorepo. That means that you have a folder (by default ~/go) and under that folder you have <code>src</code>, <code>pkg</code> and <code>bin</code>. All source code for any Go project lives under the <code>src</code> folder. So your project will be under <code>~/go/src/github.com/rafoufoun/projectname</code> and maybe it includes a dependency which lives under <code>~/go/src/github.com/boltdb/bolt</code>. If someone does <code>go get github.com/rafoufoun/projectname</code> that will also fetch the dependency.</p> <p>The case of binary, it is the easiest case because when you compile <code>github.com/rafoufoun/projectname</code> it will also include the boltdb dependency in the binary. So all you have to do is distribute that binary and you are done.</p> <p>You should treat the <code>src</code> folder as a huge monorepo. If many projects share the <code>boltdb</code> dependency then all of them will find the dependency in the exact same path <code>~/go/src/github.com/boltdb/bolt</code>. When working with a monorepo, ideally all projects should use the same exact version. Go&#39;s version 1 compatibility guarantee and general philosophy of minimizing dependencies and focus on backwards compatibility make this easier.</p> <p>Obviously in practice, things are not perfect. You might end up having to use a shady or unfinished project that keeps having breaking changes every time you do <code>go get</code>. I&#39;d argue that you shouldn&#39;t even be using such a project as a dependency but if you really should then you should vendor that dependency. That means that you are gonna have a vendor folder under your project folder and under that folder it will be the pinned dependency. So it will look like <code>~/go/src/github.com/rafoufoun/projectname/vendor/github.com/shady/project</code>. That will allow you to do <code>import github.com/shady/project</code> in your code and guarantee that it will always use the version under the vendor folder.</p> <blockquote> <p>If I want to push one of my project on github, will I push only my project source code or will I also push the dependencies ?</p> </blockquote> <p>It depends on your style. Personally when I vendor dependencies I like to commit the vendor folder. That makes it much easier to have the whole code in the repo.</p> <blockquote> <p>If I must push only my code, how another developer who wants to clone my repo can find the list of my dependencies and use the rights versions ?</p> </blockquote> <p>If the other developer does <code>go get github.com/rafoufoun/projectname</code> that will also fetch all the dependencies. If you worry about the dependencies having breaking changes then you should vendor them as I described above.</p> <blockquote> <p>Can I have two projects using two different version of the same library ? (It seems to be impossible if all of my project and dependencies are in the same folder).</p> </blockquote> <p>Vendor the different version of the library under each project that needs it.</p> <p>I hope that helps.</p></pre>rafoufoun: <pre><p>That helps me A LOT ! </p> <p>The way Go handle dependencies is quite confusing at first. What I understand is that it&#39;s made like this according to the philosophy of minimizing dependencies, and made possible with the backward compatibility of Go 1.</p> <p>Now I&#39;m more comfortable about having all of my Go projects into the same workspace since in &#34;emergency case&#34; I can vendor the dependencies I want.</p> <p>And since a &#39;go get&#39; on my cloned project will fetch all the dependency and install them in the GOPATH, no worries about that neither.</p> <p>Your answer is perfect thanks again ;).</p> <p>One more thing, where can the &#39;go get&#39; command find the list of all the dependencies I&#39;m using to get them back if they are not in the GOPATH ?</p></pre>neoasterisk: <pre><blockquote> <p>What I understand is that it&#39;s made like this according to the philosophy of minimizing dependencies, and made possible with the backward compatibility of Go 1.</p> </blockquote> <p>It is made like this because <a href="https://talks.golang.org/2012/splash.article" rel="nofollow">Go is designed by Google to help solve Google&#39;s problems</a> and Google is using a monorepo.</p> <p>Simplicity, minimizing dependencies, focus on backwards compatibility and stability are indeed included in the Go philosophy but it has nothing to do with why Go uses the monorepo method.</p> <blockquote> <p>One more thing, where can the &#39;go get&#39; command find the list of all the dependencies</p> </blockquote> <p>Go get treats the source code as the only source of truth. If go get sees in your code <code>import github.com/boltdb/bolt</code> then it will try to fetch that dependency. So from your perspective all you ever have to do is type <code>go get</code>.</p> <p>If you really need to know the names of the dependencies of an unknown/large project then you can use some tools like <a href="https://dave.cheney.net/2014/09/14/go-list-your-swiss-army-knife" rel="nofollow">go list</a> or use something like the web interface of go doc with the <code>?imports</code> parameter: <a href="https://godoc.org/github.com/boltdb/bolt?imports" rel="nofollow">https://godoc.org/github.com/boltdb/bolt?imports</a></p></pre>rafoufoun: <pre><p>Thanks ! I assume that if a library is in the GOPATH and vendored, the vendor one take the priority in the dependency resolution ? </p> <p>You helped me a lot here to get started</p></pre>neoasterisk: <pre><blockquote> <p>I assume that if a library is in the GOPATH and vendored, the vendor one take the priority in the dependency resolution ?</p> </blockquote> <p>Yes the go toolchain looks first in the vendor folder for imports before looking under GOPATH/src.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

765 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传