4 ms·
I've created a couple of projects in Go so far (a map server, similar to TileStache etc.) - Sure, the lack of generics is annoying, but I think the real elephan
by kitsune_ 12y ago
I've created a couple of projects in Go so far (a map server, similar to TileStache etc.) - Sure, the lack of generics is annoying, but I think the real elephant in the room is dependency and package management. The way Go expects you to organize your source code (the workspace concept, GOPATH, go get and github-repos as import paths) is a huge road block here. To this day the Go community hasn't settled on any kind of solution. If you bring any of this up on the mailing list you'll be crucified by the Go zealots who think Go's way of doing things is a thing of immaculate perfection.
If you want to be safe you will have to version your dependencies with your project. So one way to achieve this is to put your entire GOPATH src folder into your project repository. Of course this defeats the purpose of resolving "github.com/myname/myproject" with "go get". Or, more annoying still, you'll put them into a /vendor/ folder inside your package folder and rewrite all the import paths. So "github.com/myname/myproject/vendor/somepackage".
Of course, if you simply rely on "go get" then dependency hell is just around the corner when it comes to transient dependencies. A -> C-v1 and A -> B -> C-v1.1. In fact if the entire Go eco-system relied on "go get" there would be no guarantee that a library worked - upstream dependencies could change at any moment.
- matthewmacleod 12y agoThe way Go expects you to organize your source code (the workspace concept, GOPATH, go get and github-repos as import paths) is a huge road block here. To this day the Go community hasn't settled on any kind of solution. This has been a major roadblock for me. I've worked with a whole bunch of different languages, and this drives me completely nuts.
- NateDad 12y agoI actually love it. Here's what you do: don't use "workspaces". Keep all your code in one GOPATH, preferably $GOPATH=$HOME. That's it. 99% of the time that'll work great.
- jamra 12y agoHave you looked at http://labix.org/gopkg.in http://labix.org/gopkg.in It is an attempt to make things still go gettable and maintain versioning so that API breaking changes don't ruin your go get. I think it's a good start.
- blablabla123 12y agoI have used Go 2-3 years fulltime and I didn't find it a problem. Right now I'm using node.js and I wonder why there are more than a dozen packages with that exist in multiple versions in my npm. This is absolutely confusing.
- Shish2k 12y agoToday I'm working on a project A which depends on B, which depends on C, which depends on D. In order to fix a bug in D, it seems that I need to make a personal copy of B and C in order to rewrite their import statements, and then I'm responsible for keeping all those packages up to date :/ (Unless I'm missing something, I am pretty new to Go. I really hope I am missing something...)
- NateDad 12y agoSo, assuming that upstream will accept your changes, the easiest thing to do is create a branch of D in the same on-disk location as the original code (so, $GOPATH/src/github.com/D-team/D for example). You then make your modifications there... the import statements still work because they still refer to the same place on disk. Read this: http://blog.natefinch.com/2014/03/go-and-github.html http://blog.natefinch.com/2014/03/go-and-github.html
- mavoapp 12y ago> Of course, if you simply rely on "go get" then dependency hell is just around the corner when it comes to transient dependencies. A -> C-v1 and A -> B -> C-v1.1. In fact if the entire Go eco-system relied on "go get" there would be no guarantee that a library worked - upstream dependencies could change at any moment. And that's a reason, why go projects should (at least) tag or branch properly. Other projects in other languages do releases, so that you can rest assured that your project works properly with version X of a third party dependency. If a go dependency properly tags or versions its code upstream, you can use that specific tag, which should give you some safety (at least as much as with the traditional release package mechanism in other languages). I do not see a big deal here within the go approach itself. The problem is that many just do not do this properly yet but instead push every change to their main branch, without thinking about the possible impact for consumers of their go packages.
- NateDad 12y agoA -> C-v1 and A -> B -> C-v1.1 is a problem in any language. As for the rest, you can have your cake and eat it too. Go get is useful for getting trunk, so let it get trunk. You can use Keith Rarick's godeps to pin branch revisions on release branches to have repeatable builds there. Then go get can still get trunk, which is what most devs will want to do to start hacking on it (and honestly, no one but devs are going to use go get, right?) Yes, this means that if one of the repos you depend on goes offline, you have a problem.... but this is DVCS, you almost certainly have N backups of that repo, where N equals the number of developers on your team. So it's not like you're hosed for forever. If you want to be really paranoid you can use godeps or third_party, or one of the many other vendoring tools to keep all the code in your repo. This is a lot like keeping libraries in your repo in other languages. It's not really a problem, in fact, you have many different ways to solve dependency management in Go. That's not a bad thing. You just need to choose one, (or not, and choose your upstreams wisely).
- espadrine 12y ago> A -> C-v1 and A -> B -> C-v1.1 is a problem in any language. That is inaccurate in two ways. First, it isn't a problem in node.js. Second, it isn't a language problem, it is an algorithm problem. dpkg has the same issue, but nix is immune to it. I'd also like to point out how bad those things were in C (and C-style languages). Go is definitely an improvement, but it isn't the end of the road.
- NateDad 12y agoHow is this not a problem in node.js? Keep in mind, I don't know node. However, in general, there's going to be several common problems in any language: Values from v1 and v1.1 won't interoperate perfectly. If you get a v1 object and pass it to B which uses v1.1 to operate on it, stuff may blow up / not work correctly, which may only be obvious in rare runtime situations. Any external resources used by both v1 and v1.1 will now be in contention. If both of them try to open port 12345, or write to the same config file, for example. And that assumes that there's no ambiguity based on just importing almost the same code twice, like if you say C.Foo... which C? Can be gotten around by always namespacing the code via the version number, I suppose. There's no magic fix for these problems. Some human has to go through all the dependencies and make sure that there won't be conflicts. Maybe v1 and v1.1 can coincide just fine, maybe they'll instantly explode. Computers can't figure that stuff out.
- MetaCosm 12y agohttp://labix.org/gopkg.in http://labix.org/gopkg.in is a rather good solution for distributing libraries with transitive dependencies. It requires critical mass for it to really take off, but the level of effort is extremely low for implementation (make a branch on github, don't break it... done!). I think this low level of effort is really important, as I have been able to simply poke authors of my favorite packages for support, and had it in a day or so. As for an internal project (non-distributed) I think vendoring is the solution everyone who is sane has always been using, why would you risk you project on a random guy deciding he wants to delete his github account.