As of today, it is required to hardcode the full import path of dependencies in each go file, this proposal is to define an alias for the dependencies directly in the go.mod file and to use it throughout the code.
For example, this is a typical go.mod file:
module github.com/ufoscout/myModule
require (
github.com/gin-gonic/gin v1.1.4
github.com/ufoscout/go-up v0.5.0
)
Currently, the dependencies in a go file are imported this way:
import (
ginweb "github.com/gin-gonic/gin" // using "ginweb" alias
"github.com/ufoscout/go-up"
"github.com/ufoscout/myModule/subpackage" // import a subpackage
)
With this proposal, the aliases could be specified directly in the go.mod file. For example, introducing the aliases in the previous go.mod file:
module myModule github.com/ufoscout/myModule
require (
ginweb github.com/gin-gonic/gin v1.1.4
go-up github.com/ufoscout/go-up v0.5.0
)
the go code becomes:
import (
"ginweb"
"go-up"
"myModule/subpackage" // import a subpackage
)
This permits to decouple the source code from the physical location of a dependency and to, for example, easily switch to a fork with a single change in the go.mod file.
One goal of vgo is to not make the source go files dependent on the module file. If the vgo file is removed, the worset result is a fresh build gets the latest in major version series.
This proposal appears to break that principal.
@kardianos
I agree that this proposal breaks the principle you mentioned; nevertheless, using the aliases is not mandatory and, if used, a warning message at build time can inform that the code will not work without vgo.
Right now, the library maintainers decide the minimal Go version supported, precisely in the same way each library can choose whether to use the feature or not.
I think this is an acceptable compromise for a feature that could free the developers from the annoying problem of the hardcoded repository paths in the code.
Besides, the aliases can be used with no drawbacks in every application that is not supposed to be imported as a third party dependency. For example, in my company, we would definitely use this approach for all our web applications.
The build tools do not issue any warnings. It should stay that way.
Also, import paths are not repository paths. Vgo doesn't change that. Maybe you can use vgo's existing replace directive to achieve what you want?
I also do not like the way that the paths are hardcoded. For example in Angular 2+, I can move any module to a new location or to a new application without any changes. And in Golang I have to do a search and replace all the files to replace all the paths.
Doing textual search-and-replace is not particularly burdensome for programmers. It's something we already do in all sorts of contexts every day.
@frou
We know the workaround; we would like to have a solution instead. Also, It's a matter of personal taste, but from my point of view, the search-and-replace workaround is indeed quite burdensome and risky too.
Coincidentally, @rsc brought up exactly this point in blog post part 9:
As another example, Go import paths are URLs. If code said
import "uuid", you鈥檇 have to ask whichuuidpackage. Searching foruuidon godoc.org turns up dozens of packages. If instead the code saysimport "github.com/pborman/uuid", now it鈥檚 clear which package we mean. Using URLs avoids ambiguity and also reuses an existing mechanism for giving out names, making it simpler and easier to coordinate with other programmers.
Per text @bcmills quoted, vgo is working as intended. While it may be true that you can solve everything in computer science with another level of indirection, new levels of indirection also add new complexity in understanding the system. We're explicitly avoiding an indirection here, by design.
Most helpful comment
One goal of vgo is to not make the source go files dependent on the module file. If the vgo file is removed, the worset result is a fresh build gets the latest in major version series.
This proposal appears to break that principal.