Skip to content

Commit

Permalink
[ISSUE-104] Separated groups for "_" and "." imports
Browse files Browse the repository at this point in the history
  • Loading branch information
incu6us committed Oct 13, 2023
1 parent 607f2e6 commit 7cff1fd
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 87 deletions.
117 changes: 50 additions & 67 deletions reviser/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type SourceFile struct {
shouldUseAliasForVersionSuffix bool
shouldFormatCode bool
shouldSkipAutoGenerated bool
hasSeparateSideEffectGroup bool
companyPackagePrefixes []string
importsOrders ImportsOrders

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

stdImports, generalImports, projectLocalPkgs, projectImports := groupImports(
groups := f.groupImports(
f.projectName,
f.companyPackagePrefixes,
importsWithMetadata,
Expand All @@ -96,7 +97,7 @@ func (f *SourceFile) Fix(options ...SourceFileOption) ([]byte, bool, error) {
pf.Decls = decls
}

f.fixImports(pf, stdImports, generalImports, projectLocalPkgs, projectImports, importsWithMetadata)
f.fixImports(pf, groups, importsWithMetadata)

f.formatDecls(pf)

Expand Down Expand Up @@ -157,21 +158,32 @@ func fixCommentGroup(commentGroup *ast.CommentGroup) *ast.CommentGroup {
return formattedDoc
}

func groupImports(
func (f *SourceFile) groupImports(
projectName string,
localPkgPrefixes []string,
importsWithMetadata map[string]*commentsMetadata,
) ([]string, []string, []string, []string) {
) *groupsImports {
var (
stdImports []string
projectImports []string
projectLocalPkgs []string
generalImports []string
blankedImports []string
dottedImports []string
)

for imprt := range importsWithMetadata {
pkgWithoutAlias := skipPackageAlias(imprt)
if f.importsOrders.hasBlankedImportOrder() && strings.HasPrefix(imprt, "_") {
blankedImports = append(blankedImports, imprt)
continue
}

if f.importsOrders.hasDottedImportOrder() && strings.HasPrefix(imprt, ".") {
dottedImports = append(dottedImports, imprt)
continue
}

pkgWithoutAlias := skipPackageAlias(imprt)
if _, ok := std.StdPackages[pkgWithoutAlias]; ok {
stdImports = append(stdImports, imprt)
continue
Expand Down Expand Up @@ -202,8 +214,20 @@ func groupImports(
sort.Strings(generalImports)
sort.Strings(projectLocalPkgs)
sort.Strings(projectImports)

return stdImports, generalImports, projectLocalPkgs, projectImports
sort.Strings(blankedImports)
sort.Strings(dottedImports)

result := &groupsImports{
common: &common{
std: stdImports,
general: generalImports,
company: projectLocalPkgs,
project: projectImports,
},
blanked: blankedImports,
dotted: dottedImports,
}
return result
}

func skipPackageAlias(pkg string) string {
Expand Down Expand Up @@ -237,7 +261,7 @@ func isSingleCgoImport(dd *ast.GenDecl) bool {

func (f *SourceFile) fixImports(
file *ast.File,
stdImports, generalImports, projectLocalPkgs, projectImports []string,
groups *groupsImports,
commentsMetadata map[string]*commentsMetadata,
) {
var importsPositions []*importPosition
Expand All @@ -258,8 +282,8 @@ func (f *SourceFile) fixImports(
},
)

one, two, three, four := f.importsOrders.sortImportsByOrder(stdImports, generalImports, projectLocalPkgs, projectImports)
dd.Specs = rebuildImports(dd.Tok, commentsMetadata, one, two, three, four)
imports := f.importsOrders.sortImportsByOrder(groups)
dd.Specs = rebuildImports(dd.Tok, commentsMetadata, imports)
}

clearImportDocs(file, importsPositions)
Expand All @@ -275,8 +299,10 @@ func (f *SourceFile) fixImports(
// to
// -----
// import (
// "fmt"
//
// "fmt"
// "io"
//
// )
func hasMultipleImportDecls(f *ast.File) ([]ast.Decl, bool) {
importSpecs := make([]ast.Spec, 0, len(f.Imports))
Expand Down Expand Up @@ -349,71 +375,24 @@ func removeEmptyImportNode(f *ast.File) {
}
}

func rebuildImports(
tok token.Token,
commentsMetadata map[string]*commentsMetadata,
firstImportGroup []string,
secondImportsGroup []string,
thirdImportsGroup []string,
fourthImportGroup []string,
) []ast.Spec {
func rebuildImports(tok token.Token, commentsMetadata map[string]*commentsMetadata, imports [][]string) []ast.Spec {
var specs []ast.Spec

linesCounter := len(firstImportGroup)
for _, imprt := range firstImportGroup {
spec := &ast.ImportSpec{
Path: &ast.BasicLit{Value: importWithComment(imprt, commentsMetadata), Kind: tok},
}
specs = append(specs, spec)

linesCounter--

if linesCounter == 0 && (len(secondImportsGroup) > 0 || len(thirdImportsGroup) > 0 || len(fourthImportGroup) > 0) {
spec = &ast.ImportSpec{Path: &ast.BasicLit{Value: "", Kind: token.STRING}}

specs = append(specs, spec)
}
}

linesCounter = len(secondImportsGroup)
for _, imprt := range secondImportsGroup {
spec := &ast.ImportSpec{
Path: &ast.BasicLit{Value: importWithComment(imprt, commentsMetadata), Kind: tok},
}
specs = append(specs, spec)

linesCounter--

if linesCounter == 0 && (len(thirdImportsGroup) > 0 || len(fourthImportGroup) > 0) {
spec = &ast.ImportSpec{Path: &ast.BasicLit{Value: "", Kind: token.STRING}}

amountOfGroups := len(imports)
for i, group := range imports {
for _, imprt := range group {
spec := &ast.ImportSpec{
Path: &ast.BasicLit{Value: importWithComment(imprt, commentsMetadata), Kind: tok},
}
specs = append(specs, spec)
}
}

linesCounter = len(thirdImportsGroup)
for _, imprt := range thirdImportsGroup {
spec := &ast.ImportSpec{
Path: &ast.BasicLit{Value: importWithComment(imprt, commentsMetadata), Kind: tok},
}
specs = append(specs, spec)

linesCounter--

if linesCounter == 0 && len(fourthImportGroup) > 0 {
spec = &ast.ImportSpec{Path: &ast.BasicLit{Value: "", Kind: token.STRING}}
if len(group) != 0 && i != amountOfGroups-1 {
spec := &ast.ImportSpec{Path: &ast.BasicLit{Value: "", Kind: token.STRING}}

specs = append(specs, spec)
}
}

for _, imprt := range fourthImportGroup {
spec := &ast.ImportSpec{
Path: &ast.BasicLit{Value: importWithComment(imprt, commentsMetadata), Kind: tok},
}
specs = append(specs, spec)
}

return specs
}

Expand Down Expand Up @@ -520,6 +499,10 @@ func setAliasForVersionedImportSpec(importSpec *ast.ImportSpec, packageImports m
return importSpecStr
}

func isDottedOrDashedImport(importSpec *ast.ImportSpec) bool {
return importSpec.Name.String() == "_" || importSpec.Name.String() == "."

Check warning on line 503 in reviser/file.go

View check run for this annotation

Codecov / codecov/patch

reviser/file.go#L502-L503

Added lines #L502 - L503 were not covered by tests
}

type commentsMetadata struct {
Doc *ast.CommentGroup
Comment *ast.CommentGroup
Expand Down
80 changes: 79 additions & 1 deletion reviser/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,51 @@ import (
"log"
)
// nolint:gomnd
`,
wantChange: true,
wantErr: false,
},
{
name: "success project,company,general,std,blanked,dotted",
args: args{
projectName: "github.com/incu6us/goimports-reviser",
filePath: "./testdata/example.go",
importsOrder: "project,company,general,std,blanked,dotted",
fileContent: `package testdata
import (
"log"
"github.com/incu6us/goimports-reviser/testdata/innderpkg"
"bytes"
. "io"
"golang.org/x/exp/slices"
_ "fmt"
)
// nolint:gomnd
`,
},
want: `package testdata
import (
"github.com/incu6us/goimports-reviser/testdata/innderpkg"
"golang.org/x/exp/slices"
"bytes"
"log"
_ "fmt"
. "io"
)
// nolint:gomnd
`,
wantChange: true,
Expand Down Expand Up @@ -960,6 +1005,39 @@ func main() {
wantChange: true,
wantErr: false,
},
{
name: "skip blanked and dotted import names",
args: args{
projectName: "github.com/incu6us/goimports-reviser",
filePath: "./testdata/example.go",
fileContent: `// Some comments are here
package testdata
import (
_ "fmt"
. "io"
)
// nolint:gomnd
func main() {
}
`,
},
want: `// Some comments are here
package testdata
import (
_ "fmt"
. "io"
)
// nolint:gomnd
func main() {
}
`,
wantChange: false,
wantErr: false,
},
{
name: `success with "C"`,
args: args{
Expand Down Expand Up @@ -1020,8 +1098,8 @@ func main() {
}

assert.NoError(t, err)
assert.Equal(t, tt.wantChange, hasChange)
assert.Equal(t, tt.want, string(got))
assert.Equal(t, tt.wantChange, hasChange)
})
}
}
Expand Down
Loading

0 comments on commit 7cff1fd

Please sign in to comment.