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: 'go fmt ./...' does not see files with tags in subpackages #39442

Open
starius opened this issue Jun 6, 2020 · 4 comments
Open

cmd/go: 'go fmt ./...' does not see files with tags in subpackages #39442

starius opened this issue Jun 6, 2020 · 4 comments
Labels
NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@starius
Copy link

starius commented Jun 6, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14.4 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOENV="/home/user/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/user"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/user/.goroot"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/user/.goroot/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build876391637=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I have a subpackage in my repo in which all files have a tag. I run go fmt ./... in the top directory of my repo.

What did you expect to see?

I expect all Go files in my repo to be formatted including those with a tag.

What did you see instead?

Files in the subpackage were not formatted!

Here I proveded an example repo where everyone can reproduce the bug:

$ git clone https://github.com/starius/gofmt-bug
$ cd gofmt-bug
$ go fmt ./...
$ go fmt ./bar
bar/bar.go

If there are files without tag in the same package (./bar in my case), go fmt ./... sees all the files and works as expected.

@tpaschalis
Copy link
Contributor

tpaschalis commented Jun 6, 2020

I can confirm that I'm getting the same.
I also noticed that running gofmt instead of go fmt it seems to be working as you expected.

$ go fmt ./...
$ go fmt ./bar
bar/bar.go 
$ gofmt .
// +build integration

package bar

func Bar() {
}
package main

func main() {
}

I'm not the most qualified person to ask, but I think that the behavior might be intended; gofmt just traverses the directory tree and formats the files, while go fmt works as the go command (same as go build or go run), in that it respects the build tags, and ignores packages that have some build constraints.

On the other hand, I'm not sure whether the tags functionality is currently implemented for go fmt, so we might want to include it, in the same way that go build does.

@starius
Copy link
Author

starius commented Jun 6, 2020

go fmt works as the go command (same as go build or go run), in that it respects the build tags, and ignores packages that have some build constraints.

Tags apply per-file, not per-package.

I think that current behavior is not consistent.

First, go fmt ./bar formats bar/bar.go while go fmt ./... does not. ./... should include ./bar.

Second, if I put a file without tags into bar/ then go fmt ./... formats bar/bar.go, so it is not the case that go fmt just ignores files with tags. It ignores them in a very specific case. In normal circumstances go fmt ./... formats all the files. So it looks more like a bug, than an intended behavior.

Also people rely on go fmt ./... to format everything. I found this issue when I run go fmt ./... and found unformatted files in some directory.

@mvdan
Copy link
Member

mvdan commented Jun 6, 2020

For what it's worth, I format with gofmt and not go fmt, one of the reasons being that I want to format all Go files in a directory tree and not bother with packages. Though it does sound like there might be a bug here - see #22183 for a similar one that we fixed a while ago.

@jayconrod
Copy link
Contributor

This does seem like a bug.

go fmt expands command line arguments into a list of packages the same way go list does. It then formats all files in each package.

When expanding patterns like ./..., the package loading infrastructure ignores directories were all files are excluded by build constraints, so that ignores bar in this example. Those packages will be returned with an error when they're named specifically (./bar). go fmt specifically ignores that error and formats all .go files including excluded files.

@jayconrod jayconrod added the NeedsFix The path to resolution is known, but the work has not been done. label Jun 8, 2020
@jayconrod jayconrod added this to the Backlog milestone Jun 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

4 participants