3 ms·
A -> 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 le
by NateDad 12y ago
A -> 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.
- espadrine 12y ago> How is this not a problem in node.js? Keep in mind, I don't know node. The automated tool npm relies on a local nested tree. The A -> C-v1 and A -> B -> C-v1.1 problem would look like this: (your code) node_modules/ A/ (code for A) node_modules/ C/ (code for C at v1) B/ (code for B) node_modules/ C/ (code for C at v1.1) The whole tree is created painlessly when you enter `npm install A`. The program figures out the dependencies through JSON files bundled with each module. They include version requirements; npm simply chooses the highest version that respects those requirements. Within each directory, `require('C')` looks for `./node_modules/C/` and finds the module it actually needs. All versions of all modules are kept at all times on a central public server at http://npmjs.org/ http://npmjs.org/. This design is only possible in some languages. Dart, for instance, cannot apply that to its libraries because its types are globally defined and would therefore clash. In Go, types are not global, which means this design can apply in principle, according to the Go Spec. However, the implemented import syntax does not act in a way that would make this possible. Oddly enough, that syntax is not specified in the Go Spec: > The interpretation of the ImportPath is implementation-dependent but it is typically a substring of the full file name of the compiled package and may be relative to a repository of installed packages.
- NateDad 12y agoGetting the modules and making the tree is easy. Making the code work is hard. Yes, sometimes this will work... but if A passes an object from v1 into B and B passes that object into v1.1... that can blow up. If v1 and v1.1 both use any global resources, that can blow up. It doesn't sound like node addresses those problems at all, which are the only ones that are actually difficult.
- kibwen 12y ago> A -> C-v1 and A -> B -> C-v1.1 is a problem in any language. A language that mangles exported symbols with version information can achieve this (with the exception of two versions of a lib trying to contest the same global resource). "A" gets the version of "C" that it expects and "B" gets the version of "C" that it expects, with no name resolution conflicts or method lookup ambiguities. This does require support from the language, though. You need a standard means of mangling symbols, a way to specify version information for each package, a way to qualify package imports with version info, and so on.
- NateDad 12y agoYeah, it's the global resources that are the biggest problem, though. Certainly, if you can namespace everything, then the code itself won't fall over. If you version the URL in Go, you can do that too. Stuff that uses v1 can live along side the stuff that uses 1.1. THey won't be compatible in that you can't pass a v1.Foo into something that wants a v1.1.Foo... but that's not a good idea anyway.