-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: Go 2: cmd/go: allow relative imports #20883
Comments
This is not really about internal at all, since you could have the same situation with non-internal subdirectories you want to import. For better or worse we've decided that having fully-qualified paths is useful for being able to understand imports when you see them. It's not clear we want to break that now. |
Can this be reopened as a proposal for Go 2 or should I create another proposal? I'm especially asking for something similar to this:
It doesn't make sense to hard-code the platform / domain I'm going to host my code on inside the code itself. |
I'll reopen for Go 2. |
While I'm not a fan of Hard-coding the platform / domain one intends to host code under should not be part of the code itself, moving code between different hosting providers (or even renaming the project) should be easier and should not require a.) changes to the source code itself ( This proposal basically is a requirement for proposal: incrementally modify the Go toolchain to work without GOPATH |
I would discourage relative imports to begin with. They can lead to unexpected results. The current model of paths being GOPATH dependent works really well and can be adapted towards a package oriented workflow rather easily.
I would disagree about that. |
For example?
Why? How else would the Go compiler toolchain know if an import should be retrieved from |
I'd share another example where this could be useful. Let's assume there is a project with the following structure: github.com/janeRoe/myapp
import (
"github.com/janeRoe/myapp/handlers"
"github.com/janeRoe/myapp/models"
"github.com/janeRoe/myapp/routes"
)
I want to fork the project and make a few changes to, say,
|
Because currently Go packages are distinguished by import paths, support for relative import paths would mean that very early on in the build process the relative imports would have to be converted to full paths. As far as I can see the only time it is useful to have a relative import path is when you are going to move a set of packages around. That seems to happen relatively rarely, and it would be straightforward to write a tool to move a set of packages while rewriting the import paths. I'm not aware of any such tool today, but if we had one would there still be a need for relative import paths? |
@ianlancetaylor , if I fork other people's project on github, and want to contribute back to this project.It seems there is still no way to keep the forked project go gettable and the import paths inside this forked project to be same with the original's. If I want to use it as my own, I have to rewrite the import path, and if I want to contribute, I have to rewrite the import path again. So I think it's not quite friendly to the current github workflow.(but if you can provide a rewriting tool, this annoying procedure can be more convenient than now. |
@cch123 Seems like you may be assuming that the other person's project is already using relative imports, which it most likely is not. |
@ianlancetaylor ,for example,I forked etcd project,this file https://github.com/coreos/etcd/blob/master/discovery/discovery.go contains imports of the same project's paths:
After forked to my own repo, the import path should be:
If I don't change the import paths and then execute
Then the project will appear at But the import paths inside this project are not correct. I'm not assuming other people is using relative imports, but I mean if we could support some way(eg.relative import? or some way of internal usage) to unbind the import path with the host address, then I will not be forced to change the import paths back and forth. The original issue is that I want to make use of internal feature to bind dependencies together with my library. Because dependencies on site like github cannot avoid risks to be deleted by original author(like the sad story of leftpad in npm community). So I think feature of this could make my library more safe in such situation. But if I make these dependencies as my library internals , it will also meet the import path problem. I have to change all the import paths of these dependencies if they use the import path like the above case. |
@cch123 I recommend you read http://blog.sgmansfield.com/2016/06/working-with-forks-in-go/ on how to work with forks if you want to contribute changes to a project. If you want to use your fork instead of the original place, Relative import paths is something I would love to see gone in Go2 as they are a constant source of pain. |
I agree with @cch123 forking packages with subpackages in them is a huge pain. You can actually abuse the vendor system to solve this problem. Just put your subpackages into vendor, and you've got project-relative imports, you can fork the package easily without having to rewrite everything. Obviously that's an ugly hack, but I'd like to see something like that as a solution to this problem, maybe not full relative imports. |
@nkovacs this is not a band-aid, nor would relative import paths solve anything in this case. dep allows something that's considered basic functionality for package managers. There is nothing new or different for Go compared to other languages.
This is not why we have the vendor directory. We have it for reproducible builds. It allows guaranteed that, if committed, everyone gets the same identical source code regardless of environment.
I don't understand how relative imports solve any problem that you have. |
If I fork a php package, I can publish it on packagist without first having to change a bunch of imports inside it. Both composer and npm allow you to specify a temporary fork instead of the canonical package. But in both ecosystems you can just publish your forked package without having to rewrite a bunch of imports inside it, because they're all relative. You can't do that in go.
Of course not. I said you can abuse it to fix the problem.
I wouldn't have to do this: nkovacs/ifacemaker@c327e8d |
Which, compared to the effort of forking, modifying and maintaining a project, takes absolutely zero effort. |
To give you the counter-point for the PHP example. You would have to override the autoload process to tell it that your project provides now the reference for the namespace you want to use, rather than the original package, see https://github.com/Seldaek/monolog/blob/master/composer.json#L46-L48 Now Go being different than PHP is is allowed to behave in a different way. If you ask me, instructing dep to fetch the source from a different place is a lot more cleaner and obvious than digging in the package.json and figuring out where the autoloader will perform the operation for loading certain package. And even in PHP or in Go world, allowing relative import paths suffer greatly when introducing symlinks into play (which at least for me in the PHP world have been a source of needlessly spent hours of debugging why something doesn't work in a particular setup of a developer / environment or in bug reports that I had to handle). As far as I can tell, the whole argument is: please allow relative import paths so we don't have to run a search & replace operation for forks we want to use as main source but we don't want to use |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I, too, ran into the issues pointed out by @johnDoe2018 and @cch123 recently. I tried the proposed solution involving dep ensure, but I could not get it to work for internal packages. I tend to agree with @cch123 that this dep functionality is a bit of a band-aid. From the documentation:
I am convinced that there are good reasons to completely remove relative paths from Go and so I'll leave that discussion to people more familiar with Go. On the other hand I think that forking repositories, creating pull requests and validating them on CI systems are part of daily developer life. The current need to adress packages inside my own project by their full repository path seems to conflict with that workflow. |
The underlying problem seems to be solved by go modules and their support for "github-forking etcd", with a |
How about treating import paths that start with
With module relative import
Since the module name is present from |
I'm not sure what are the implications but it seems required. Link: golang/go#20883 Signed-off-by: Robin Jarry <[email protected]>
I would say relative paths are extremely important whenever developing an application. If my understanding is correct from this conversation any "module" I create needs to be moved to the go PATH rather than simply referencing it from "./myModule" or "./myModule.go". This seems extremely inconvenient and while not being able to auto-fork or pull down from a github repository as my goal, but rather just use modules I make locally - it seems relative pathing would make life so much easier. (IE: Look at JS) |
With our current module ecosystem, our use of |
It feels to me as though the proposal to use import paths starting with slash as same-module imports would be amenable to Go 1, at the very least by providing a suitable directive in One would then have 3 styles of import:
The module fork-then-PR use-case (or even fork without PRs) is the most persuading of the need for such functionality. Renaming or relocating a module may be unusual in some patterns of use but overall, not sufficiently unusual that the pain need not be alleviated. |
I think this is a useful feature for library writers, sometimes dependency can not be avoided for a lib.
eg. a proxy lib may use a sql parser written by third party.
The library package layout may look like follows:
If I want to make the dependency invisible to lib endusers, currently I have to move the dependencies to internal package, and manually change the import path to, maybe:
It's quite ugly and inconvenient.
If internal can be imported easily, then import path will be,
quite clear
I noticed that some libs also have inner package, and they currently layout their project like the following:
If someone wants to fork this mqtool lib to fix bugs or maintain it as his own, then he will meet a lot problems (to modify endless import paths).
Someone may say that he can git clone this project to the correct path, but
go get
can not support such case, which is really weird (becausego get
will put this project to the forked path, not the original path).If internal package can be found in relative path, I think things can go much better :-)
Then the above project may become like this:
The text was updated successfully, but these errors were encountered: