Skip to content

go/printer: output differs to "go fmt" for consts and structs #69843

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

Closed
ceving opened this issue Oct 11, 2024 · 2 comments
Closed

go/printer: output differs to "go fmt" for consts and structs #69843

ceving opened this issue Oct 11, 2024 · 2 comments

Comments

@ceving
Copy link

ceving commented Oct 11, 2024

Go version

go version go1.23.2 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/szi/.cache/go-build'
GOENV='/home/szi/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/szi/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/szi/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/go1.23.2.linux-amd64'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/go1.23.2.linux-amd64/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.23.2'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/szi/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build736226514=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Source

package main

import (
	"fmt"
	"go/parser"
	"go/printer"
	"go/token"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
)

const (
	FirstConst = iota
	SecondConst
)

type FirstStruct struct {
	FirstProperty  string
	SecondProperty string
}

func main() {
	// Get source filename
	var err error
	_, InputName, _, ok := runtime.Caller(0)
	if !ok {
		log.Fatalf("Can not read source.")
	}

	// Parse source file
	Fileset := token.NewFileSet()
	Source, err := parser.ParseFile(Fileset, InputName, nil, parser.ParseComments)
	if err != nil {
		log.Fatal(err)
	}

	// Write source
	OutputName := fmt.Sprintf("printer-%s", filepath.Base(InputName))
	Output, err := os.Create(OutputName)
	if err != nil {
		log.Fatal(err)
	}
	err = printer.Fprint(Output, Fileset, Source)
	if err != nil {
		log.Fatal(err)
	}
	Output.Close()

	// Compare
	cmp := exec.Command("cmp", InputName, OutputName)
	err = cmp.Run()
	if err != nil {
		log.Fatal(err)
	}
}

What did you see happen?

$ go fmt inconsistency.go
$ go run inconsistency.go
2024/10/11 09:58:41 exit status 1
exit status 1
$ diff inconsistency.go printer-inconsistency.go 
16c16
<       FirstConst = iota
---
>       FirstConst      = iota
21,22c21,22
<       FirstProperty  string
<       SecondProperty string
---
>       FirstProperty   string
>       SecondProperty  string

The command go fmt and the package go/print do something different for consts and structs.

What did you expect to see?

No difference

@mateusz834
Copy link
Member

mateusz834 commented Oct 11, 2024

This is working as intended, go fmt uses a different configuration for the printer:

tabWidth = 8
printerMode = printer.UseSpaces | printer.TabIndent | printerNormalizeNumbers

res, err := format(fileSet, file, sourceAdj, indentAdj, src, printer.Config{Mode: printerMode, Tabwidth: tabWidth})

than the go/printer defaults:

return (&Config{Tabwidth: 8}).Fprint(output, fset, node)

You should probably use the go/format package instead, it has the same defaults as go fmt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants