Proposal Details
I'm maintaining a thin wrapper over go command called emgo. It adds to the go build command some useful features for embedded programming. In the context of this proposal, the main feature is to allow users to have to two toolchains (the original Go and the Embedded Go) and select the correct one by using go or emgo command.
It would be nice that the go command would print os.Args[0]
instead of "go"
, especially in the strings that are intended to be copy-pasted. See the example below:
$ emgo build
main.go:7:2: missing go.sum entry for module providing package
github.com/embeddedgo/espat (imported by teensyApp); to add:
go get teensyApp
It would be nice to see emgo get teensyApp
instead of go get teensyApp
if the emgo wrapper was used.
Comment From: ianlancetaylor
I don't think this needs to be a proposal, taking it out of the proposal process.
That said, I don't think I understand this issue. Are you linking additional code into the go command? The go command doesn't support that. You are free to do it if you like, but we aren't going to modify the go command for that kind of unsupported use. And if you aren't linking additional code into the go command, then I don't understand why os.Args[0]
matters.
Comment From: michalderkacz
Are you linking additional code into the go command?
No. I have an external command called emgo
that searches for the specific Go toolchain (user of emgo almost always have at least two Go toolchains installed). Next it arranges the environment variables for it and passes some specific tags and other options like -o
, -tags
, -ldflags
:
cmd := &exec.Cmd{
Path: goCmd,
Args: append(
[]string{"emgo", "build", "-tags", tags, "-ldflags", ldflags, "-o", elf},
flag.Args()...,
),
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
After that it simply calls go command from the selected toolchain but with emgo instead of go in arg0. So the emgo is a wrapper that behaves like go, but with some extensions added.
Think of it this way. If user wants use the standard go toolchain he/she uses go
command. If she/he wants the other specific/extended toolchain it uses a wrapper, in my case called emgo
that calls go
internally. Then go prints some output intended to be copy/pasted:
go get teensyApp
and the user executes it not paying attention to the fact that he/she used the standard toolchain and not the specific/extended one.
I don't propose to replace any go
string with filepath.Base(os.Args[0])
in the source code but it will be helpful to use os.Args[0]
in the printed commands that user may copy/paste.
I know the go command doesn't promise to collaborate with the other commands this way but I think it's worth considering, hence I think of it as a proposal instead of an issue.
Using basename(arg0)
by a command to tell about itself is a well-established practice at last in the Unix word.
Thank you for your work, and the years of patient handling such annoying issues like this one.
Comment From: seankhliao
if emgo calls go
through os/exec
, then go
will always see go
in os.Args[0]
Comment From: michalderkacz
Let's say this is a printargs
program:
func main() {
fmt.Println(os.Args)
}
If you run it as ./printargs a b c
its output is like this:
[./printargs a b c]
Let's write a program called wrapper
:
func main() {
cmd := &exec.Cmd{
Path: "printargs",
Args: []string{"wrapper", "a", "b", "c"},
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
if err := cmd.Run(); err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
and run it in the same directory the printargs
is. It's output is like this:
[wrapper a b c]
so the printargs
sees "wrapper"
in its os.Args[0]
.
Comment From: mauri870
This may also apply to specific go toolchains you may have installed. You may invoke gotip
or go1.22.3
and they will report os.Args[0] as go as well.
# gotip, go1.22.3, etc
$ gotip run main.go
main.go:4:2: no required module provides package rsc.io/quote; to add it:
go get rsc.io/quote
-- main.go --
package main
import (
_ "rsc.io/quote"
)
func main() {}
-- go.mod --
module test
go 1.21
Comment From: matloob
Hi, this seems pretty harmless, but I'd like to see more uses for it before making a change like this.
The main issue is that it's hard to get right: we print commands for the user to run all over in the go command and we'd have to be careful to use os.Args[0] in every place even though it's "go" almost all the time.
Comment From: gopherbot
Timed out in state WaitingForInfo. Closing.
(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)