Skip to content

Commit

Permalink
Skip imports ordering and formatting for generated files(by default).…
Browse files Browse the repository at this point in the history
… Option for the feature is added (#90)

closes #81
  • Loading branch information
incu6us authored Nov 10, 2022
1 parent 820d875 commit 2b9c240
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 15 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ goimports-reviser -rm-unused -set-alias -format ./...
### Options:
```text
Usage of goimports-reviser:
-apply-to-generated-files
Apply imports sorting and formatting(if the option is set) to generated files. Generated file is a file with first comment which starts with comment '// Code generated'. Optional parameter.
-company-prefixes string
Company package prefixes which will be placed after 3rd-party group by default(if defined). Values should be comma-separated. Optional parameters.
-format
Option will perform additional formatting. Optional parameter.
-imports-order string
Expand All @@ -62,9 +66,7 @@ Usage of goimports-reviser:
project - your local project dependencies.
Optional parameter. (default "std,general,company,project")
-list-diff
Option will list-diff files whose formatting differs from goimports-reviser. Optional parameter.
-company-prefixes string
Company package prefixes which will be placed after 3rd-party group(if defined). Values should be comma-separated. Optional parameters.
Option will list files whose formatting differs from goimports-reviser. Optional parameter.
-output string
Can be "file", "write" or "stdout". Whether to write the formatted content back to the file or to stdout. When "write" together with "-list-diff" will list the file name and write back to the file. Optional parameter. (default "file")
-project-name string
Expand All @@ -76,7 +78,7 @@ Usage of goimports-reviser:
-set-alias
Set alias for versioned package names, like 'github.com/go-pg/pg/v9'. In this case import will be set as 'pg "github.com/go-pg/pg/v9"'. Optional parameter.
-set-exit-status
set the exit status to 1 if a change is needed/made. Optional parameter.
set the exit status to 1 if a change is needed/made. Optional parameter.
-use-cache
Use cache to improve performance. Optional parameter.
```
Expand Down
34 changes: 23 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"path/filepath"
"strings"

"github.com/mitchellh/go-homedir"
homedir "github.com/mitchellh/go-homedir"
"github.com/pkg/errors"

"github.com/incu6us/goimports-reviser/v3/helper"
Expand All @@ -32,6 +32,7 @@ const (
setExitStatusArg = "set-exit-status"
recursiveArg = "recursive"
useCacheArg = "use-cache"
applyToGeneratedFiles = "apply-to-generated-files"

// Deprecated options
localArg = "local"
Expand All @@ -45,14 +46,15 @@ var (
SourceURL string
GoVersion string

shouldShowVersion *bool
shouldRemoveUnusedImports *bool
shouldSetAlias *bool
shouldFormat *bool
listFileName *bool
setExitStatus *bool
isRecursive *bool
isUseCache *bool
shouldShowVersion *bool
shouldRemoveUnusedImports *bool
shouldSetAlias *bool
shouldFormat *bool
shouldApplyToGeneratedFiles *bool
listFileName *bool
setExitStatus *bool
isRecursive *bool
isUseCache *bool
)

var (
Expand Down Expand Up @@ -95,7 +97,7 @@ func init() {
&output,
outputArg,
"file",
`Can be "file", "write" or "stdout". Whether to write the formatted content back to the file or to stdout. When "write" together with "-list" will list the file name and write back to the file. Optional parameter.`,
`Can be "file", "write" or "stdout". Whether to write the formatted content back to the file or to stdout. When "write" together with "-list-diff" will list the file name and write back to the file. Optional parameter.`,
)

flag.StringVar(
Expand All @@ -105,7 +107,7 @@ func init() {
`Your imports groups can be sorted in your way.
std - std import group;
general - libs for general purpose;
company - inter-org libs(if you set '-local'-option, then 4th group will be split separately. In other case, it will be the part of general purpose libs);
company - inter-org or your company libs(if you set '-company-prefixes'-option, then 4th group will be split separately. In other case, it will be the part of general purpose libs);
project - your local project dependencies.
Optional parameter.`,
)
Expand Down Expand Up @@ -153,6 +155,12 @@ Optional parameter.`,
"Use cache to improve performance. Optional parameter.",
)

shouldApplyToGeneratedFiles = flag.Bool(
applyToGeneratedFiles,
false,
"Apply imports sorting and formatting(if the option is set) to generated files. Generated file is a file with first comment which starts with comment '// Code generated'. Optional parameter.",
)

if Tag != "" {
shouldShowVersion = flag.Bool(
versionArg,
Expand Down Expand Up @@ -219,6 +227,10 @@ func main() {
options = append(options, reviser.WithCodeFormatting)
}

if shouldApplyToGeneratedFiles != nil && !*shouldApplyToGeneratedFiles {
options = append(options, reviser.WithSkipGeneratedFile)
}

if localPkgPrefixes != "" {
if companyPkgPrefixes != "" {
companyPkgPrefixes = localPkgPrefixes
Expand Down
19 changes: 19 additions & 0 deletions reviser/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type SourceFile struct {
shouldRemoveUnusedImports bool
shouldUseAliasForVersionSuffix bool
shouldFormatCode bool
shouldSkipAutoGenerated bool
companyPackagePrefixes []string
importsOrders ImportsOrders

Expand Down Expand Up @@ -70,6 +71,10 @@ func (f *SourceFile) Fix(options ...SourceFileOption) ([]byte, bool, error) {
return nil, false, err
}

if f.shouldSkipAutoGenerated && isFileAutoGenerate(pf) {
return originalContent, false, nil
}

importsWithMetadata, err := f.parseImports(pf)
if err != nil {
return nil, false, err
Expand Down Expand Up @@ -103,6 +108,20 @@ func (f *SourceFile) Fix(options ...SourceFileOption) ([]byte, bool, error) {
return formattedContent, !bytes.Equal(originalContent, formattedContent), nil
}

func isFileAutoGenerate(pf *ast.File) bool {
for _, comment := range pf.Comments {
for _, c := range comment.List {
if c.Slash == 1 && strings.HasPrefix(c.Text, "// Code generated") {

This comment has been minimized.

Copy link
@devenami

devenami Nov 26, 2022

Contributor

first line may be copyright, not // Code generated.
so
we must remove c.Slash==1 condition.
We should think that only the // Code generated by <util-name>. DO NOT EDIT. rule exists, the formatting operation should be ignored.

return true
}
if c.Slash > 1 {
return false
}
}
}
return false
}

func (f *SourceFile) formatDecls(file *ast.File) {
if !f.shouldFormatCode {
return
Expand Down
7 changes: 7 additions & 0 deletions reviser/file_option.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ func WithImportsOrder(orders []ImportsOrder) SourceFileOption {
return nil
}
}

// WithSkipGeneratedFile will skip formatting and imports sorting for auto-generated file which starts with
// comment on first line: `// Code generated`
func WithSkipGeneratedFile(f *SourceFile) error {
f.shouldSkipAutoGenerated = true
return nil
}
113 changes: 113 additions & 0 deletions reviser/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,45 @@ import (
"github.com/incu6us/goimports-reviser/testdata/innderpkg"
)
// nolint:gomnd
`,
wantChange: true,
wantErr: false,
},

{
name: "success with auto-generated",
args: args{
projectName: "github.com/incu6us/goimports-reviser",
filePath: "./testdata/example.go",
fileContent: `// Code generated by some tool
package testdata
import (
"log"
"github.com/incu6us/goimports-reviser/testdata/innderpkg"
"bytes"
"github.com/pkg/errors"
)
// nolint:gomnd
`,
},
want: `// Code generated by some tool
package testdata
import (
"bytes"
"log"
"github.com/pkg/errors"
"github.com/incu6us/goimports-reviser/testdata/innderpkg"
)
// nolint:gomnd
`,
wantChange: true,
Expand Down Expand Up @@ -1404,3 +1443,77 @@ func test1() {}
})
}
}

func TestSourceFile_Fix_WithSkipGeneratedFile(t *testing.T) {
type args struct {
projectName string
filePath string
fileContent string
}

tests := []struct {
name string
args args
want string
wantChange bool
wantErr bool
}{
{
name: "success with generated file",
args: args{
projectName: "github.com/incu6us/goimports-reviser",
filePath: "./testdata/example.go",
fileContent: `// Code generated by some tool
package testdata
import (
"log"
"github.com/incu6us/goimports-reviser/testdata/innderpkg"
"bytes"
"github.com/pkg/errors"
)
// nolint:gomnd
`,
},
want: `// Code generated by some tool
package testdata
import (
"log"
"github.com/incu6us/goimports-reviser/testdata/innderpkg"
"bytes"
"github.com/pkg/errors"
)
// nolint:gomnd
`,
wantChange: false,
wantErr: false,
},
}
for _, tt := range tests {
if tt.args.filePath != StandardInput && !strings.Contains(tt.args.filePath, "does-not-exist") {
if err := ioutil.WriteFile(tt.args.filePath, []byte(tt.args.fileContent), 0644); err != nil {
t.Errorf("write test file failed: %s", err)
}
}

t.Run(tt.name, func(t *testing.T) {
got, hasChange, err := NewSourceFile(tt.args.projectName, tt.args.filePath).Fix(WithSkipGeneratedFile)
if (err != nil) != tt.wantErr {
t.Errorf("Fix() error = %v, wantErr %v", err, tt.wantErr)
return
}

assert.Equal(t, tt.wantChange, hasChange)
assert.Equal(t, tt.want, string(got))
})
}
}

0 comments on commit 2b9c240

Please sign in to comment.