I know there is godep, but I am curious why go doesn't natively support versions via git url stub. Something along these lines
import (
"os"
"github.com/uname/myrepo1"
"github.com/uname/myrepo2@dev"
"github.com/uname/myrepo2@c8ufj1"
)
That seems to fit go idioms fairly well. Is there a place that the language accepts feature requests? I wouldn't mind implementing this given a good direction to go in.
评论:
tv64738:
flydonkey:This horse has been beaten to death on the mailing list.
What would happen if I import
database/sql@1
and you importdatabase/sql@2
?
agentargo:Throw a compiler error?
danredux:That seems totally reasonable to me
calebdoxsey:I feel like I'm missing something, but why would it be an issue if people imported, hell, BOTH of those in the same package?
Sure, you'd have to rename one on import.. but that's all.
danredux:Libraries often have state or initialization with side effects. For example if you imported two MySQL libraries the latter would probably overwrite the former.
You also wouldn't be able to transfer data between the two different versions because the types would be different. For example suppose you were using a redis library and passed around a redis connection everywhere in your own code. If you had two versions of redis included which redis connection would you define for you functions? (And how would you convert one type of redis connection to another?)
Yojihito:I can't think of a situation where importing two versions of the same package would cause problems with overwriting initalization/state, excepting I suppose if some third package has some option that is changed between sql versions, and the value that sql@2 sets is incompatible with the value that sql@1 sets.
However the solution to this is quite simply- reset the "import" cache when importing a new version. IE, sql@1 and sql@1 get two entirely separate compilations of each package they import.
However, there's almost no state in packages at the top-level and this might not even be a problem. The packages could simply be aware that, to support versioning, they may not rely on third-party package state.
Edit: In fact, this is already an issue! Two parts of your program (or two packages) can both import and configure a third-party package's state. Nothing changes from versioning this way.
danredux:Why not just use sql@1.doSomething() and sql@2.doAnotherThing()?
agentargo:Because you want to simplify the common case, always.
Importing a version should, by default, go to a simple namespace.
If you wanted to import both versions, you could import them with a name like "sqlV1" and "sqlV2".
gdey:I'd love to read those chains if you have links to them.
The case where you have two branchs and each import a different version. I'd argue it's even more clear at merge time if you have to explicitly resolve the conflict to make sure you match the correct API.
The other case being you literally have two import in the same file with two different versions. That seems like it should be a compiler error unless you explicitly rename the imports
So this is a compiler error
import ( "database/sql@1" "database/sql@2" )
and this being OK
import ( sql_1 "database/sql@1" sql_2 "database/sql@2" )
Again maybe I'm missing something here that is covered in the mailing list, but that behavior seems totally reasonable to me.
Other languages handle the versioning outside of the code and pip requirements would throw an error if you tried to import a lib twice. Having the git path linked creates a bit of a misnomer to me if you can only reference head. I'd say that the import should be just the name and the external version management tool should define the location.
EDIT:
Found this thread https://groups.google.com/forum/#!topic/golang-dev/nMWoEAG55v8%5B1-25%5D
agentargo:It's because the import paths are opaque to the go compiler. There are projects that provide you with versioning. gopkg.in is a service that allows you to have stable versioned packages.
For example the YAML package is released this way. gopkg.in/yaml.v1 — get's you version one of the yaml package. And because of the way imports work, the package name is yaml.
Isn't the definition of an opaque pointer to hide implementation details? So if the name is opaque, the library loader could choose to interpret the path with the @ symbol to point to branch/tag/commit. I could be misinterpreting that though.
This seems like such a hack to create a URL with an implicit version that points to the correct commit.
