<p>Hello everyone !</p>
<p>I'm new to golang and I have some questions about the workspace and the dependencies management.</p>
<p>I'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't have one yet, just asking for my knowledge).</p>
<p>Let's say I want to develop a script which will be deployed as a binary. I can't understand where I should put this code and the dependencies I could have</p></pre>neoasterisk: <pre><blockquote>
<p>Let's say I want to develop a script which will be deployed as a binary</p>
</blockquote>
<p>Go'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'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'd argue that you shouldn'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'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'm more comfortable about having all of my Go projects into the same workspace since in "emergency case" I can vendor the dependencies I want.</p>
<p>And since a 'go get' 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 'go get' command find the list of all the dependencies I'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'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'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 'go get' 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
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传