Skip to content
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: run should provide a way to find the file being run. #5157

Closed
gopherbot opened this issue Mar 29, 2013 · 9 comments
Closed

cmd/go: run should provide a way to find the file being run. #5157

gopherbot opened this issue Mar 29, 2013 · 9 comments

Comments

@gopherbot
Copy link

by brady@apcera.com:

Right now it is impossible to find the initial command line, or file being executed when
I use "go run foo.go", ideally the command line should be exposed via an
environment variable, or some other mechanism so I can find out the user provided
command line.

Our current use case is this: There is a config file placed next to our binary. If I cd
into that directory and use "go run foo.go then I can open the file using
'os.Open("configfile")'. If I build the program, then run the built file I can
make an assumption that the command should be near the binary, as such getting the
absolute directory for os.Args[0] works perfectly enough to find out where the config
might exist. However if the user uses go run somedir/foo.go its impossible to find out
either the path to the go file, or the command line used without jank like opening the
compiled program being run (os.Args[0]) and looking for string paths.

Ideally the initial command could be set in an environment variable such as
"GO_RUN_COMMANDLINE" or some such so that the invoked application can find out
what program was actually run.
@bradfitz
Copy link
Contributor

Comment 1:

"go run" is intended for playing and learning more than anything.  I wouldn't be
surprised if this is closed "Working As Intended".  There is a general resistance to
adding complexity with new options or environment variables.

@philpennock
Copy link

Comment 2:

For clarity: to get around this, it's opening _go_.6 (found via glob to be architecture
independent) in the filepath.Dir(os.Args[0]) and then looking with a regexp to find the
source file used to define package main, which works when main is one file, rather than
the result of everything in the directory.
As Brady puts it, "jank".  I can write it, I'd rather not maintain it.  :)
While "go run" may be intended for playing, it's also the easiest way to run a tool
written as a single Go file, so people will end up using it anyway.  I like Go for its
pragmatism, instead of telling folks they're doing it wrong by using the way set up to
be easiest.  I can document "build first, or run from same directory", but in practice,
that just results in pain and stalls when developers are trying to focus on something
else.  Rather than interrupt their mental flow, I added jank.
If we can just get the list of original gofiles in an environment variable, while
running under "go run", it looks much more like existing concepts such as
$SSH_ORIGINAL_COMMAND, $SUDO_COMMAND and is _reducing_ complexity by restoring the
information that would normally be available via os.Args[0] but has otherwise been
removed by the "go run" intermediation.
Thanks.

@gopherbot
Copy link
Author

Comment 3 by brady@apcera.com:

Another completely reasonable approach would be to make a constant in the binary that I
can get too. runtime.OrigionalCommandLine or some such.. It need not be an environment
variable, though I think thats the more typical approach...

@davecheney
Copy link
Contributor

Comment 4:

This sounds the underlying use case is not related to go run, but for the executable
being run to be able to discover the absolute path to itself. 
If so, this is issue, https://golang.org/issue/4057

@gopherbot
Copy link
Author

Comment 5 by brady@apcera.com:

I just thought of a much easier and cleaner way to do this for our use case, though the
command line would still be nice.. but for anybody following along at home the following
code in main() will return the file name containing main() =)
brady@viper tmp$ cat /tmp/a.go 
package main
import(
    "fmt"
    "runtime"
)
func main() {
    _, file, _, _ := runtime.Caller(0)
    fmt.Println(file)
}
brady@viper tmp$ go run a.go
/tmp/a.go
This is a much cleaner and cheaper way of opening the file and is far, far less janky.
I still like the idea of an environment variable, but this can reduce our immediate
nasty jank factor. =)

@philpennock
Copy link

Comment 6:

The problem is that the absolute path to the executable, in the `go run` case, is in the
temporary work dir, not the location where the source is.
Comment #6 on 4057 is accurate: "finding asset files accompanying the executable", but
also in the "from the source dir" case.

@davecheney
Copy link
Contributor

Comment 7:

I intend to close this issue as "working as intended" in the next 24 hours. Please speak
up if you wish to add any new information.

Status changed to WaitingForReply.

@gopherbot
Copy link
Author

Comment 8 by brady@apcera.com:

It may work as intended but I still argue that the intention is messy. Having some
mechanism to find out what the command line used to run the go program is very useful if
for nothing other than help messages. There is some jank to make this slightly easier,
but this is something that I feel should be in either a variable, or accessible in some
way to the program since its something that every other language provides.

@davecheney
Copy link
Contributor

Comment 9:

Yes, it is messy but I think you're expecting too much of go run. As Brad said, go run
is just for experimentation, please don't expect it to move mountains. 
For the more general requirement of figuring out the path of the binary that is
executing this program, not os.Args[0], please refer to issue #4057.

Status changed to WorkingAsIntended.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants