Reputation: 646
I'm totally new to golang, and am wondering, why many golang projects write in their source code like this way:
import "github.com/stretchr/testify/assert"
What if this testify
moved to bitbucket?
Why not download testify and import testify
, like other languages?
Upvotes: 12
Views: 9365
Reputation: 845
The question raises a good concern regarding the design of import paths in go. As @xpare mentioned, go brings the dependencies to your local $GOPATH. But the OP's question has not been addressed fully.
Yes, if the authors/maintainers of github.com/stretchr/testify
moved the package to bitbucket, then this will cause a problem. This might not cause a problem on you machine, since you have the dependencies on your machine, but it will cause a problem to anyone who wants to contribute to the app. Not only that, but it will also cause problems to the build server if the build server has to pull the dependencies every time.
Even though people don't move from github to bitbucket often, this proved to be still a concern. When microsoft bought github, many packages moved to other providers. There is no guarantee that any provider, github or others, will keep the same prices, the same quality of service, the same features, etc. It is inevitable that things will move.
Not only that, but also that authors sometimes move packages to a different location within github under a different user. This happens too.
So is that a problem? Yes, though the design of import urls in go allows to the ability to clearly specify the dependencies, the downside is that when the package moves, the code has to change. Vendoring tends to help to make the application resistant to these changes, but vendoring doesn't help if you want to update the package.
The design of go wanted a decentralized package management. This design is immune to problems such as the break of many npm apps due to npm controversially deleting kirk package. So if people disagree with npm philosophy, that will be a big problem. But if people don't like github, they typically move to other providers and the packages will always be there (in go, that will cause change in source code). Because of this, golang does not guarantee that all package names will be unique, and hence the full import path is necessary.
Every approach has its pro and cons. And unfortunately for go, that means that the full import path is needed.
Upvotes: 4
Reputation: 11532
Before I answer your question, you need to understand about the way golang manages it's packages and dependencies.
To download packages, use the go get
command. Usage example:
$ go get github.com/stretchr/testify
Above command will downloads the testify package then store it locally under work space with structure following it's url (TL;DR work space path is registered as $GOPATH
env variable).
$GOPATH/src/github.com/stretchr/testify
An explanation from the doc why the downloaded package name will follow it's url:
Get downloads the packages named by the import paths, along with their dependencies.
Now about your question:
Why does many golang project directly import from GitHub?
The statement import "github.com/stretchr/testify/assert"
doesn't mean that the package is directly imported from github website (through http). It's imported from your local, from github.com/stretchr/testify
path under $GOPATH/src
. The package was downloaded and stored there before, so it can be imported into any project.
Below is an explanation from the documentation about the import statements:
The Go path (
$GOPATH
) is used to resolve import statements.
Also take a look at some code below (taken from my local).
$ echo $GOPATH
/Users/novalagung/Documents/go
$ go get -u github.com/stretchr/testify
# package will be downloaded into $GOPATH/src folder using the same structure as the github url
$ tree -L 1 $GOPATH/src/github.com/stretchr/testify
/Users/novalagung/Documents/go/src/github.com/stretchr/testify
├── Gopkg.lock
├── Gopkg.toml
├── LICENSE
├── README.md
├── _codegen
├── assert
├── doc.go
├── http
├── mock
├── package_test.go
├── require
├── suite
└── vendor
So if you want to import any packages, it must be under $GOPATH/src
folder.
what if this testify moved to bitbucket?
It has no effect on your local project, because the required package already downloaded before. However, if you want to update it, you might need to change the package path to follows it's new url, maybe like bitbucket.org/stretchr/testify/assert
? depends on what the new bitbucket url looks like.
But I don't think the owner of the testify will do that, since it'll break lot people of codes.
Upvotes: 13
Reputation: 191874
why not download testify and import testify, like other languages ?
Some libraries will do this (downloading, I mean), as Go didn't have proper package management and the way around it was to use a technique called vendoring, which basically meant to clone/snapshot the code from wherever it may exist, and use that package structure in your import statements
The downside of that approach is that you will clearly lose out on latest updates until repeating that process, and you're not always guaranteed the code you checkout is a stable release
Upvotes: 0