Workspace and dependencies

polaris · 2017-03-27 16:00:05 · 1197 次点击    
这是一个分享于 2017-03-27 16:00:05 的资源,其中的信息可能已经有所发展或是发生改变。

Hello everyone !

I'm new to golang and I have some questions about the workspace and the dependencies management.

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).

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 ?

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).

Thanks for your answers !


评论:

neoasterisk:

Is the project a library/package or a binary?

rafoufoun:

It could be both (don't have one yet, just asking for my knowledge).

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

neoasterisk:

Let's say I want to develop a script which will be deployed as a binary

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 src, pkg and bin. All source code for any Go project lives under the src folder. So your project will be under ~/go/src/github.com/rafoufoun/projectname and maybe it includes a dependency which lives under ~/go/src/github.com/boltdb/bolt. If someone does go get github.com/rafoufoun/projectname that will also fetch the dependency.

The case of binary, it is the easiest case because when you compile github.com/rafoufoun/projectname it will also include the boltdb dependency in the binary. So all you have to do is distribute that binary and you are done.

You should treat the src folder as a huge monorepo. If many projects share the boltdb dependency then all of them will find the dependency in the exact same path ~/go/src/github.com/boltdb/bolt. 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.

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 go get. 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 ~/go/src/github.com/rafoufoun/projectname/vendor/github.com/shady/project. That will allow you to do import github.com/shady/project in your code and guarantee that it will always use the version under the vendor folder.

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 ?

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.

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 ?

If the other developer does go get github.com/rafoufoun/projectname 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.

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).

Vendor the different version of the library under each project that needs it.

I hope that helps.

rafoufoun:

That helps me A LOT !

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.

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.

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.

Your answer is perfect thanks again ;).

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 ?

neoasterisk:

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.

It is made like this because Go is designed by Google to help solve Google's problems and Google is using a monorepo.

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.

One more thing, where can the 'go get' command find the list of all the dependencies

Go get treats the source code as the only source of truth. If go get sees in your code import github.com/boltdb/bolt then it will try to fetch that dependency. So from your perspective all you ever have to do is type go get.

If you really need to know the names of the dependencies of an unknown/large project then you can use some tools like go list or use something like the web interface of go doc with the ?imports parameter: https://godoc.org/github.com/boltdb/bolt?imports

rafoufoun:

Thanks ! I assume that if a library is in the GOPATH and vendored, the vendor one take the priority in the dependency resolution ?

You helped me a lot here to get started

neoasterisk:

I assume that if a library is in the GOPATH and vendored, the vendor one take the priority in the dependency resolution ?

Yes the go toolchain looks first in the vendor folder for imports before looking under GOPATH/src.


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

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