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

proposal: cmd/gofmt: Support rare or single-purpose formatting exceptions #65270

Closed
pantsmann opened this issue Jan 24, 2024 · 1 comment
Closed
Labels
Milestone

Comments

@pantsmann
Copy link

Proposal Details

There are times when it would be nice to format code in a custom manner and have gofmt ignore that block of code. I recognize that adding this in a naive way would pretty much defeat the purpose of gofmt. I don't want that so I'm not sure how to do what I want.

Let me try to explain with an example. I'm writing a test function that uses two different but similar structs. They have corresponding fields but due to requirements may not use the same types. Additionally, most of the fields are pointers for one reason or another.

Suppose I have (actual structs are much bigger):

type Input struct{
   AAA *SpecialInt     `db:"AAA" json:"aaa" api-required="true"`
   BB  *SpecialString  `db:"BB" json:"bb"`
   C   *SpecialString2 `db:"C" json:"c" api-required="true"`
}

type Result struct{
   A   *int    `db:"A" json:"a" api-required="true"`
   BB  *string `db:"BB" json:"bb"`
   CCC *string `db:"CCC" json:"ccc" api-required="true"`
}

Suppose in my test I have three objects:

var original Result
var input Input
var want Result

Because the fields a pointers I need to create variables to point to:

iAAA, oA, wA := SpecialInt(100), 200, 100
iBB, oBB, wBB := SpecialString("My mom says I'm special"), "nobody is special", "My mom says I'm special"
iC, oCCC, wCCC := SpecialString2("me too"), "everybody is special here", "me too"

These values are then mixed and matched as pointers in the three test objects for the various test cases. I'd like to format the preceding code block to be a bit easier to read:

iAAA, oA,   wA   := SpecialInt(100),                          200,                         100
iBB,  oBB,  wBB  := SpecialString("My mom says I'm special"), "nobody is special",         "My mom says I'm special"
iC,   oCCC, wCCC := SpecialString2("me too"),                 "everybody is special here", "me too"

It might make sense to update gofmt to format multi-assignment blocks like this or it might not. It occurs to me that there will always be special cases where special-purpose formatting would be really helpful.

Another special-purpose that gofmt doesn't currently support would be to automatically change the struct definitions above to be like this (granted since the tags are a strings, this one can be done by hand and gofmt doesn't cause any problems):

type Input struct{
    AAA *SpecialInt     `db:"AAA" json:"aaa" api-required="true"`
    BB  *SpecialString  `db:"BB"  json:"bb"`
    C   *SpecialString2 `db:"C"   json:"c"   api-required="true"`
}

type Result struct{
    A   *int    `db:"A"   json:"a"   api-required="true"`
    BB  *string `db:"BB"  json:"bb"`
    CCC *string `db:"CCC" json:"ccc" api-required="true"`
}

In the case of my examples, it might be best to implement the rules in gofmt without adding a directive that changes the behavior of gofmt within a particular block. That at least would preserve the purpose of gofmt, but it isn't flexible enough to handle all cases. Valid exceptions to the gofmt rules should be rare, but I think my example shows how supporting exceptions could be really useful. Maybe such a directive could be limited to consecutive single-line statements (no empty lines or lines with just punctuation) or it could be specifically ignored for troublesome snippets like if statements etc. I don't know what would make sense.

@gopherbot gopherbot added this to the Proposal milestone Jan 24, 2024
@ianlancetaylor
Copy link
Contributor

Thanks, but we have consistently rejected requests to customize gofmt. In our opinion the benefits of a single canonical formatting outweigh the fact that the formatting is not ideal in every case.

@ianlancetaylor ianlancetaylor closed this as not planned Won't fix, can't repro, duplicate, stale Feb 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants