This comment has been minimized.

Is there a good reason for it other than explanatory docs? We've always written cd $GOPATH before without worrying about this. Most people don't know it's a list or don't care. There's also very few times I can think of when you definitively want the first GOPATH entry. Usually you want the source for a particular package, which is

This comment has been minimized.

edited

I often seen docs where people include $GOPATH in bash scripts exactly in ways where it would fail if my GOPATH actually were a list, encouraging people to not make it a list.

I'd like there to be some official answer people could use in docs instead.

$(go list -f '{{.Dir}}' my/pkg/import/path) doesn't work if the directory doesn't yet exist, and it's often mkdir -p $GOPATH/src/github.com/org/private-repo I see in docs, before a git clone into that location.

This comment has been minimized.

This comment has been minimized.

In general it would be good to express the question we want answered instead of the mechanism. In this case we want to know where a particular package will be installed, without really caring about the fact that GOPATH is how we get there.

Maybe go get -dir import/path prints the directory where go get would put import/path after downloading it (even if it doesn't exist, no network activity, and so on). But "get -dir" is probably suggestive of an operation that's not actually happening as just defined. Better names?

edited

This comment has been minimized.

Another possibility is accept a format string. Then this feature could also be used to learn the VCS system that go get would use, the remote url, the destination on disk, the clone command, whether it is a custom import path, etc.

This comment has been minimized.

edited

OK, so -printdir never does anything but only prints the absolute path of the directory where 'go get' would check out the named package, or where one is already checked out that 'go get -u' would update.

If there are no arguments (packages on command line), then that's an error. There must be at least one. If there are multiple arguments, it prints one line for each.

This comment has been minimized.

@bradfitz in your example, go get github.com/org-may-not-exist would fail, not check out a named package, because go get for github requires both an org/user and a repo name. And it can't just using the first arg verbatim (attached to $GOPATH) because that would disagree with 'go get' on custom import paths. At which point you're going through cmd/go's repoRootForImportPath anyway, so we may as well also provide access to the other things it returns--clone url, vcs, isCustom, probably by way of a format string. (Pretty please?)

This comment has been minimized.

I guess? In the case of github.com/foo, 'go get' will always fail, it would never attempt anything. But I guess its something like that. Here are more questions. (None of which are to say this is a bad idea. Just probing edge cases.)

What would go get -printdir rsc.io/pdf/... print? The ... reproduced verbatim? Would go get -printdir context print something in $GOROOT or something in the first $GOPATH?

To handle the the "would update" case, does -printdir check to see whether any GOPATH dir contains code, or does it always just return the subdir of the first $GOPATH dir?

This comment has been minimized.

As an aside, for the specific mkdir -p && cd && git clone sequence above, you don't need the intermediate dirs to exist. git clone url dest will do a mkdir -p dest for you and put the code in the right place. If that's the primary use case, maybe we don't need github.com/does-not-exist to work?

This comment has been minimized.

No, that's the wrong implementation. The whole point of going down this 'go get -printdir' path was because the answer varies by import path. If the target already exists in a later entry in GOPATH, go get will use that one. Josh is right that you really need to give it the actual package you care about. The script is wrong. It should be:

This comment has been minimized.

What about a separate command, go dir. (The suggested semantics below apply to a -printdir flag as well but it being on go get seems weird to me, since it never gets anything)

Given no arguments it prints the elements of $GOPATH, one per line (or the default if not set).

Given arguments it assumes they're packages and prints their absolute paths (including /src/), one per line. Failing if any do not exist. This also would allow it work with /... or any of the special names.

If you only care about the first pipe through head -n 1 or sed 1q. You can redirect to /dev/null if you just want to check the exit code. If it's a separate command these could be flags on the command, though there's no need for them on unixy systems, at least.

That seems like it would cover all the cases for shell scripting. The only problem would be something like go dir $EMPTY_VAR, but if it's a separate command no args could be an error and go dir -gopath could print $GOPATH.

This comment has been minimized.

Honestly, I think this is a non-issue and we should do nothing at all. But I would argue strongly against any command that exposes what GOPATH is directly. Obviously code that cares can find out. But that's almost always the wrong question to be asking. The appropriate question is "where is the code for this particular import path?"

The reason this is on 'go get' is that if you've already got the code you can use 'go list -f whatever-you-need'. The one case that doesn't handle is where the code is yet to be downloaded, and 'go get -printdir' will tell you where it would put the code after the download.

This comment has been minimized.

The one question I often find myself trying to reliably answer with multiple entries in my GOPATH is where go install github.com/my/pkg will install to, so that I can then definitely run the binary (in this case pkg) that is (re-)built, irrespective of the user's PATH. Seems somewhat related (unless I'm missing an obvious solution of course?)

This comment has been minimized.

If possible I'd like to hold off introducing this flag. I understand the desire but package management may potentially invalidate things like this. At this point I'd rather wait on any new features until we're sure that they will make sense in the new world.