-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
cmd/go: no easy way to use modules fully privately outside of GOPATH #37554
Comments
Not a comment on the proposal -- even though I agree 100% and am disappointed that they've I just wanted to recommend the use of As you've seen, using |
Hi again, sorry, but this is an addendum to the above. I was under the impression that having a local module and doing a "go install" would build and install that module into the local module-cache, but it apparently does not: is that expected? It seems that I'm possibly supposed to use a "replace" directive in my go.mod so that the main module can find the util module. If this is how it's supposed to work, it's not very scalable at all for my use-case, and would be a maintenance nightmare! (Maybe I'm just missing something here?) (Would it not be a good idea for "go install" to simply install the module into my local module cache so that it can be easily found by any other local modules that use the utils? Is this a bug?) |
Thanks DisposaBoy, I'm not sure, but I thought that top-level domains had to be a minimum of 3-chars in length, so I chose "x" assuming that it could never be resolved to a real server (also to avoid import-namespace cruft), but it seems that the name still tries to get resolved anyway (apparently even when it's listed in GOPRIVATE which I find very strange) :( |
A module's path only has to have a dot in the first component if you want to be able to fetch it automatically (such as using You can, today, Note that we still reserve those names in general for the standard library (#32819), but you can use them at your own risk. |
You can't tell people that it's fine to use names without a dot, and then immediately take it back by claiming them as reserved... |
@DisposaBoy, we don't want to limit the names available to the standard library, but it seems reasonable to reserve a specific path prefix (or set of path prefixes) for local, user-defined modules. Want to draft a proposal? |
@marystern, (Unlike GOPATH, the module cache is a cache: given a complete See also #28835. |
Could you explain more about your use-case? (Why would 'replace' directives — or a single dotless root module — not scale, and why would issuing a request against a domain that you own, or an invalid domain, be a security concern?) |
@bcmills Also individual team members should be free to clone the 3 repos anywhere they like on their local filesystems, and work on any or all projects. So, user Alice checks out
but Bob likes to use this arrangement:
So, from the above you can see that both Alice and Bob might need to edit the go.mod replace directives to accommodate their individual workspace preferences. This is what I was referring to as "un-scalable", i.e. across disparate team members or other users of the code (i.e. without mandating a scheme such as "put all your code in ~/go/src so that all relative go.mod replace directives don't need to be edited", i.e. they all have to be under a shared parent dir much like the old GOPATH approach). re: and why would issuing a request against a domain that you own, or an invalid domain, be a security concern?) |
@marystern, if Alice and Bob were using GOPATH mode, they would presumably both have to check out the repositories into exactly:
In that case, you could use |
What about one that you, or in this case your company, owns? It is possible that you will leak information about your own domain to your own DNS server on the local network — but is there a reason you can't trust your own DNS server? Also note that you can set |
Agreed, but the point of this experiment was to check: "Can we successfully use MODULE-MODE locally and ignore GOPATH mode totally?". If the answer is don't even try, then I agree, GOPATH-Mode is the only sensible option (and was the conclusion that I ended up with myself). However, my understanding (which may well be incorrect: please feel free to clarify) was that everyone should be moving to Module Mode: maybe this is not the intention? Note however, that using Module Mode would indeed be preferable to GOPATH Mode for this use case (because 2 projects require 2 different versions of a shared module), and with a couple of tweaks (eg as per my proposal) would be very nice indeed for private, local development as I've outlined in the Use Case. My feeling is that this particular use-case is one that has slipped through the net and has not been given full consideration during the addition of Module support (again, I might well be wrong, and I am indeed aware of the amount and complexity that's been involved in properly supporting dependencies/modules, so please don't take this the wrong way). Hence, you may be fully justified as seeing this as a request for a further enhancement to Module support. |
Yes, but we usually want some external code (eg from github). (Yes, we could use vendoring, but again, I thought this was one of the things that Module support was designed to avoid!) |
If you want to selectively filter dependencies, you can already do that using a local Or, you can set Or, you can set |
Yes: at this point we believe that module mode is ready for general use. We're continuing to improve the user experience, but at this point all of the known use-cases have at least some available option. In this case, you have at least three existing options:
We should investigate those options fully before we consider adding yet another one. |
The downside of this is that we would be forced to setup a proxy for this very simple use-case which seems like overkill.
The downside is that, in this case, there is no domain under our control that we want to (or can) use for this purpose.
Can you explain what you mean by "dotless" import paths please (otherwise I think have explained the problems above)?
|
(A privacy-enforcing local proxy is admittedly less simple, but we're examining all of the options here.)
I hear that there are companies that will sell you a domain for $12/yr. or less. Also note that you can use an IANA-reserved IP address as an import-path prefix — for free! — if you so desire:
Pick a name that you are confident will never be part of the Go standard library, and use that as your import prefix: |
@marystern If you don't mind, I want to ask for more information about this, in order to understand your situation better. That can help with finding a better solution to this issue. Is the problem that you don't have a domain available for this, or that you don't want to maintain a domain for this purpose? You mentioned earlier that:
If it's something you can talk about, can you say if a domain is used for cloning the repositories? If so, would it be viable to reuse that domain for your module paths? Or are there concerns with doing so? I agree it's unfortunate to have to purchase and maintain a new domain for the sole purpose of having a shorter import path and making it so the go command doesn't send requests to a domain that you don't control. That's why I want to learn if there is perhaps a domain you can reuse for this purpose that you haven't considered yet. |
It's both: we don't have a domain and we don't want to have to maintain a domain purely to do private, local builds! Isn't that a reasonable thing?
No, it's very simple: think of it as all code on one machine (ie fully network disconnected). Simply try to build 2 main products, each using different versions of a shared module (I'm reducing the reality here for the sake of example so that you can see the issue clearly: consider the case of a file-system-local repo; a single developer). This is almost the simplest scenario for using GOPATH, but if I want to build both products, I have to somehow switch the versions of the shared module each time I build (and make sure it's correct each time). Modules should be able to fix this Use Case (I had hoped! :) as they deal with the versioning and dependency issues quite nicely. However, this Issue is trying to highlight the complexity of implementing the solution: ie stick to manually switching code all the time; or use vendoring; or introduce a local, private proxy (even though the local module cache looks like it should be sufficient to me, maybe somehow integrated with the local build cache, but that's not detail that I'm fully clear about. Also there are the issues of naming etc as mentioned above.). |
@bcmills I agree that it's possible to do things today in a way that can work, it's just that I find the options very un Go-like (ie very complex for a pretty simple requirement)! (Dare I say it reminds me of python3...... ;) |
Thanks for the answers @marystern.
Before answering that, I think it's helpful to think about the reason using a domain, even if a fake one like Go packages are identified by import paths, which are string values. Two distinct packages made by different groups need to find a way to create unique import paths. If two different packages have the same import path, using those packages together becomes difficult and confusing. The Go project has made use of an existing system, the URL (and as part of that, DNS), as a mechanism for ensuring all import paths can be unique. If everyone picks an import path that has a domain name they own, import path collisions can be avoided. Given the existing solution has good properties and is very simple (an import path is a URL), I think we should be careful not to attempt to build something on top of it. The Go standard library does not have a domain prefix, which itself is a unique namespace reserved by the Go standard library. If the Go standard library used the "golang.org" domain for all packages, then an import like "fmt" would be "golang.org/fmt", "net/http" would be "golang.org/net/http". Doing that would allow users to use no-domain paths for their projects, but that would still be risky in case you want to combine two such codebases in the future. As a result, I think it is reasonable to suggest using a localhost domain like There may still be room for improvement here, but I just wanted to share my understanding of the trade-offs in the current design of import paths. |
@marystern, the most basic development model in module mode is to have everyone work in the same module in the same repository. Then you don't need to worry about versioning at all; that is, IMO, the most “Go-like” option. And I don't think the comparison to python3 is apt at all: this issue has absolutely nothing to do with syntactic compatibility or Unicode strings. (In fact, the vast majority of packages that worked with |
If you really need the complexity of multiple modules, then the cost of that is the complexity of telling the That protocol is described in https://golang.org/cmd/go/#hdr-Remote_import_paths, and it identifies the server hosting a given module by using an HTTP or HTTPS connection to a server at a readily-identifiable domain. The response from that HTTP server tells the So one option is to run a local HTTP server, and either use the path prefix |
Another option (as described earlier) is to run a local A |
Hi all, Thanks for the discussion and feedback. I'd like to conclude with my own thoughts (and remember I'm looking at this as a simple coder with a simple use-case who doesn't really need all the bells and whistles of the "enterprise" module features): 1. Local "publishing" of modulesI would like to be able to simply work locally using modules so that I can manage dependencies in my private, local codebase. The part that seems to be missing is a mechanism to simply build and install a version of one module (with a specific module version number) locally so that it can be picked up by other local modules. When looking at 1.14, I had expected that there be some way to do this without installing a module-proxy. I think I expected to be able to something like:
to build a dev-version (or perhaps check locally to see if the current code was tagged and hence at a specific VCS version), or possibly something like
to build and install as a specific named version (ie not rely on any VCS naming, or to override it if required). So, this would build my module and install it into the local module cache, ready to be picked up by other local modules (without any need to consult anything outside my network/machine). Question: is there any technical reason that this would not be possible (eg as an enhancement to go install)? 2. Naming of domain for local modulesI had expected to be able to use something simple (or indeed nothing, ie GOPATH-compatible import paths) to name my module so that it clearly would never be accessible remotely. My top 2 favorites are I still like option b) as it looks clean and clear and seems to be consistent with the other uses of "_" to mean something that isn't really there. Question: is there any reason that "_" could not be used like this (I realize it might be a lot of work and special cases, etc, but as a user it seems to be a nice, clear solution). If the above 2 things were already possible, I wouldn't have had to stop my progress with using modules locally, and I believe that this would enhance the user experience and ease the transition to using modules when they are required, and would mean that all new code could live in the new "module world", and GOPATH could fade away into history. |
Nope. In fact, I proposed something very similar in #28835 (which is still open for consideration, but not a top priority at the moment). |
That appears to already work today: https://play.golang.org/p/hl_tG2_ndkb I can't see us ever using (CC @jayconrod @matloob) |
So, to close off things from my end: I looked into running a private proxy, but the issue I had is how to build/publish the package (zip) for the proxy to use (probably not too hard, but I've spent too much time on this already, so didn't look into it). Decided instead to use: "_" as a domain name (looks nice and clean and clear to me: please don't make this invalid in the future! From my perspective, it would even be nice if this was highlighted in intro docs as an alternative to a valid domain for anyone else who wants to work privately.) ..together with.. replace directives in my go.mod files. eg a go.mod for main1 would include:
and in the main1, main2 code I use these import paths:
This works as long as all the modules are placed next to each other (ie because I'm replacing with "../"). I can live with this for now, but it's not as flexible as I might wish (I seem to desire a "go put" opposite to "go get" which could be spelled as "go install" or "go mod pack" or whatever). You can close this if you like (sounds like #28835 covers the missing "go put" feature which is something I would like to have!), thanks for all the help and guidance! :) |
Thanks! Closing out this issue, and we'll keep this feedback in mind when considering future improvements. |
What version of Go are you using (
go version
)?What did you do?
I'm trying out the new finalized modules feature in 1.14 and doing everything outside of GOPATH.
I want all my code to never be publicly visible (i.e. it's a fully private codebase and always will be).
I had an existing codebase with a main package and a separate "utility" package.
Under ~/go/src, everything works fine. But, to try out modules locally, I'm putting my code elsewhere (eg ~/src for the sake of example).
However, to migrate to using modules I'm now having to add a compulsory preceding domain to use the utility package from the main package, so eg, before I had this in my main program:
which has to change to:
"x.x" was the minimum domain name that I could think of that:
a) Would not accidentally resolve to a real domain
b) satisfies the "dot required" restriction in the tools.
My Issues:
Proposals
Two thoughts comes to mind (apologies for using this issue also for a prooposal):
It might be fairly easy to just say "if the first part of an import does not have a dot in it, assume it's local and private and hence do none of the public module stuff at all". This has the advantage of being simple; not having to remember to set GOPRIVATE and keeping the code GOPATH-compatible.
Another idea might be to use "_" as a fully private, local, never-publicly used domain name to indicate such usage in a Module World. So in this case, I could use
Maybe there would be problems with these two ideas, but I'm throwing them out there, not as fully formed proposals, but rather to see if you can see the problem and come up with a good solution.
Anyway, I've been a golang user for many years, but Modules seem to be making my life 100 times harder for zero gain (in this particular case; of course I realize it's all brilliant for public code and dependency/version management, etc, so thanks, and keep up the good work :) )!
The text was updated successfully, but these errors were encountered: