Skip to content

x/tools/cmd/goimports: Report package name != base src directory #23184

@Dominik-K

Description

@Dominik-K

go version go1.9.2 darwin/amd64
golang.org/x/tools/cmd/goimports @ 64890f4

Using imported package surprise (in path a/packg) as packg, not surprise. goimports silently removes this import, so does Visual Studio Code (perhaps other IDEs as well).

File a/main.go:

package main

import "a/packg"

func main() {
	packg.SomeFunc()
}

and package file a/packg/lib.go:

package surprise

import "fmt"

func SomeFunc() {
	fmt.Println("Hello from surprise.")
}

This silent removing confuses a lot (again a new colleague/Go newbie stumbled upon this). That's why go build explicitly shows the package name difference to the base of the import path since Go 1.2 (see #5957):

# command-line-arguments
./main.go:3:8: imported and not used: "a/packg" as surprise
./main.go:6:2: undefined: packg

What did you expect to see?

An error on stderr like this:

./main.go:3:8: used as "packg" but package name is "surprise". Skipped removing (flag "--no-rm-pkg-name-differ" set)

and a flag --no-rm-pkg-name-differ (working title) to skip removing this import that IDEs can opt-in to show this error at this line instead.

I think it should be a part of goimports because IDEs will first run goimports before go build to add maybe needed imports (neat feature 👍, btw) which will otherwise fail on build.

Not using flags at all for goimports (see recent #23004 (comment)) and sticking to Go convention

Another convention is that the package name is the base name of its source directory; the package in src/encoding/base64 is imported as "encoding/base64" but has name base64[...]

would mean that goimports should fail in this scenario (also go build?!). This would make goimports backwards-incompatible and IDEs need to handle this. I think this is not the preferred way, so that's why I'm suggesting the flag and logging to stderr instead.

What did you see instead?

goimports -v main.go output:

2017/12/19 20:15:40.420475 fixImports(filename="main.go"), abs="/Users/dominik/go/src/a/main.go", srcDir="/Users/dominik/go/src/a" ...
2017/12/19 20:15:40.420845 importPathToNameGoPathParse("a/packg", srcDir="/Users/dominik/go/src/a") = "surprise", <nil>
2017/12/19 20:15:40.420991 open /Users/dominik/go/src/.goimportsignore: no such file or directory
2017/12/19 20:15:40.421005 scanning $GOPATH
2017/12/19 20:15:40.421117 scanning $GOROOT
2017/12/19 20:15:40.434210 scanned $GOROOT
2017/12/19 20:15:40.711721 goimports: scanning directory /Users/dominik/go/src: permission denied
2017/12/19 20:15:40.711735 scanned $GOPATH
package main

func main() {
	packg.SomeFunc()
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeWaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions