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: use os.Args[0] instead of "go" in the go command output #67775

Open
michalderkacz opened this issue Jun 2, 2024 · 5 comments
Open

cmd/go: use os.Args[0] instead of "go" in the go command output #67775

michalderkacz opened this issue Jun 2, 2024 · 5 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@michalderkacz
Copy link
Contributor

michalderkacz commented Jun 2, 2024

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.

@gopherbot gopherbot added this to the Proposal milestone Jun 2, 2024
@ianlancetaylor ianlancetaylor changed the title proposal: use os.Args[0] instead of "go" in the go command output cmd/go: use os.Args[0] instead of "go" in the go command output Jun 3, 2024
@ianlancetaylor
Copy link
Contributor

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.

@ianlancetaylor ianlancetaylor added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. and removed Proposal labels Jun 3, 2024
@ianlancetaylor ianlancetaylor modified the milestones: Proposal, Unplanned Jun 3, 2024
@michalderkacz
Copy link
Contributor Author

michalderkacz commented Jun 3, 2024

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.

@seankhliao
Copy link
Member

if emgo calls go through os/exec, then go will always see go in os.Args[0]

@michalderkacz
Copy link
Contributor Author

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].

@mauri870
Copy link
Member

mauri870 commented Jun 3, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants