Repository: daixiang0/gci
Pull request #72 (2022-07-11 06:47:10)

revert section order
Signed-off-by: Loong Dai <loong.dai@intel.com>

daixiang0: Fix https://github.com/daixiang0/gci/issues/71

Patch:
diff --git a/README.md b/README.md
index 5f1ee7b..0df5866 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ GCI splits all import blocks into different sections, now support three section
 - custom: Custom section, use full and the longest match(match full string first, if multiple matches, use the longest one)
 - default: All rest import blocks
 
-The priority is standard>custom>default, all sections sort alphabetically inside.
+The priority is standard > default > custom, all sections sort alphabetically inside.
 
 All import blocks use one TAB(`\t`) as Indent.
 
@@ -49,13 +49,12 @@ Aliases:
 
 Flags:
   -d, --debug             Enables debug output from the formatter
-  -h, --help              help for print
-  -s, --section strings   Sections define how inputs will be processed. Section names are case-insensitive and may contain parameters in (). A section can contain a Prefix and a Suffix section which is delimited by ":". These sections can be used for formatting and will only be rendered if the main section contains an entry. The Section order is the same as below, default value is [Standard,Default].
-                          Std | Standard - Captures all standard packages if they do not match another section
-                          Prefix(github.com/daixiang0) | pkgPrefix(github.com/daixiang0) - Groups all imports with the specified Prefix. Imports will be matched to the longest Prefix.
-                          Def | Default - Contains all imports that could not be matched to another section type
-                          [DEPRECATED] Comment(your text here) | CommentLine(your text here) - Prints the specified indented comment
-                          [DEPRECATED] NL | NewLine - Prints an empty line
+  -h, --help              help for write
+  -s, --section strings   Sections define how inputs will be processed. Section names are case-insensitive and may contain parameters in (). The section order is standard > default > custom. The default value is [standard,default].
+                          standard - standard section that Golang provides officially, like "fmt"
+                          Prefix(github.com/daixiang0) - custom section, groups all imports with the specified Prefix. Imports will be matched to the longest Prefix.
+                          default - default section, contains all rest imports (default [standard,default])
+      --skip-generated    Skip generated files
 ```
 
 ```shell
@@ -71,12 +70,11 @@ Aliases:
 Flags:
   -d, --debug             Enables debug output from the formatter
   -h, --help              help for write
-  -s, --section strings   Sections define how inputs will be processed. Section names are case-insensitive and may contain parameters in (). A section can contain a Prefix and a Suffix section which is delimited by ":". These sections can be used for formatting and will only be rendered if the main section contains an entry. The Section order is the same as below, default value is [Standard,Default].
-                          Std | Standard - Captures all standard packages if they do not match another section
-                          Prefix(github.com/daixiang0) | pkgPrefix(github.com/daixiang0) - Groups all imports with the specified Prefix. Imports will be matched to the longest Prefix.
-                          Def | Default - Contains all imports that could not be matched to another section type
-                          [DEPRECATED] Comment(your text here) | CommentLine(your text here) - Prints the specified indented comment
-                          [DEPRECATED] NL | NewLine - Prints an empty line
+  -s, --section strings   Sections define how inputs will be processed. Section names are case-insensitive and may contain parameters in (). The section order is standard > default > custom. The default value is [standard,default].
+                          standard - standard section thatolang provides officially, like "fmt"
+                          Prefix(github.com/daixiang0) - custom section, groups all imports with the specified Prefix. Imports will be matched to the longest Prefix.
+                          default - default section, contains all rest imports (default [standard,default])
+      --skip-generated    Skip generated files
 ```
 
 ```shell
@@ -88,13 +86,13 @@ Usage:
 
 Flags:
   -d, --debug             Enables debug output from the formatter
-  -h, --help              help for diff
-  -s, --section strings   Sections define how inputs will be processed. Section names are case-insensitive and may contain parameters in (). A section can contain a Prefix and a Suffix section which is delimited by ":". These sections can be used for formatting and will only be rendered if the main section contains an entry. The Section order is the same as below, default value is [Standard,Default].
-                          Std | Standard - Captures all standard packages if they do not match another section
-                          Prefix(github.com/daixiang0) | pkgPrefix(github.com/daixiang0) - Groups all imports with the specified Prefix. Imports will be matched to the full and longest Prefix. All groups are in alphabetical order.
-                          Def | Default - Contains all imports that could not be matched to another section type
-                          [DEPRECATED] Comment(your text here) | CommentLine(your text here) - Prints the specified indented comment
-                          [DEPRECATED] NL | NewLine - Prints an empty line
+  -h, --help              help for write
+  -s, --section strings   Sections define how inputs will be processed. Section names are case-insensitive and may contain parameters in (). The section order is standard > default > custom. The default value is [standard,default].
+                          standard - standard section thatolang provides officially, like "fmt"
+                          Prefix(github.com/daixiang0) - custom section, groups all imports with the specified Prefix. Imports will be matched to the longest Prefix.
+                          default - default section, contains all rest imports (default [standard,default])
+      --skip-generated    Skip generated files
+
 ```
 
 ### Old style
@@ -140,9 +138,9 @@ package main
 import (
     "fmt"
 
-    "github.com/daixiang0/gci"
-
     "golang.org/x/tools"
+
+    "github.com/daixiang0/gci"
 )
 ```
 
@@ -164,9 +162,9 @@ package main
 import (
   "fmt"
 
-  "github.com/daixiang0/gci"
-
   go "github.com/golang"
+
+  "github.com/daixiang0/gci"
 )
 ```
 
diff --git a/cmd/gci/gcicommand.go b/cmd/gci/gcicommand.go
index 7f77066..9d0034c 100644
--- a/cmd/gci/gcicommand.go
+++ b/cmd/gci/gcicommand.go
@@ -46,16 +46,14 @@ func (e *Executor) newGciCommand(use, short, long string, aliases []string, stdI
 
 	debug = cmd.Flags().BoolP("debug", "d", false, "Enables debug output from the formatter")
 
-	sectionHelp := `Sections define how inputs will be processed. Section names are case-insensitive and may contain parameters in (). A section can contain a Prefix and a Suffix section which is delimited by ":". These sections can be used for formatting and will only be rendered if the main section contains an entry. The Section order is the same as below, default value is [Standard,Default].
-Std | Standard - Captures all standard packages if they do not match another section
-Prefix(github.com/daixiang0) | pkgPrefix(github.com/daixiang0) - Groups all imports with the specified Prefix. Imports will be matched to the longest Prefix.
-Def | Default - Contains all imports that could not be matched to another section type
-[DEPRECATED] Comment(your text here) | CommentLine(your text here) - Prints the specified indented comment
-[DEPRECATED] NL | NewLine - Prints an empty line`
+	sectionHelp := `Sections define how inputs will be processed. Section names are case-insensitive and may contain parameters in (). The section order is standard > default > custom. The default value is [standard,default].
+standard - standard section that Golang provides officially, like "fmt"
+Prefix(github.com/daixiang0) - custom section, groups all imports with the specified Prefix. Imports will be matched to the longest Prefix.
+default - default section, contains all rest imports`
 
 	skipGenerated = cmd.Flags().Bool("skip-generated", false, "Skip generated files")
 
-	sectionStrings = cmd.Flags().StringSliceP("section", "s", nil, sectionHelp)
+	sectionStrings = cmd.Flags().StringSliceP("section", "s", section.DefaultSections().String(), sectionHelp)
 
 	// deprecated
 	noInlineComments = cmd.Flags().Bool("NoInlineComments", false, "Drops inline comments while formatting")
diff --git a/pkg/gci/gci.go b/pkg/gci/gci.go
index 22fc89a..170c03f 100644
--- a/pkg/gci/gci.go
+++ b/pkg/gci/gci.go
@@ -151,7 +151,7 @@ func LoadFormatGoFile(file io.FileObj, cfg config.Config) (src, dist []byte, err
 	firstWithIndex := true
 
 	var body []byte
-	// order: standard > custom > rest
+	// order: standard > default > custom
 	if len(result["standard"]) > 0 {
 		for _, d := range result["standard"] {
 			AddIndent(&body, &firstWithIndex)
@@ -162,6 +162,17 @@ func LoadFormatGoFile(file io.FileObj, cfg config.Config) (src, dist []byte, err
 		}
 	}
 
+	if len(result["default"]) > 0 {
+		for _, d := range result["default"] {
+			AddIndent(&body, &firstWithIndex)
+			body = append(body, src[d.Start:d.End]...)
+		}
+
+		if len(customKeys) > 0 {
+			body = append(body, utils.Linebreak)
+		}
+	}
+
 	if len(customKeys) > 0 {
 		sort.Sort(sort.Reverse(sort.StringSlice(customKeys)))
 		for _, k := range customKeys {
@@ -172,17 +183,8 @@ func LoadFormatGoFile(file io.FileObj, cfg config.Config) (src, dist []byte, err
 			body = append(body, utils.Linebreak)
 		}
 
-		// no default section, remove breakline in the end
-		if len(result["default"]) == 0 {
-			body = body[:len(body)-1]
-		}
-	}
-
-	if len(result["default"]) > 0 {
-		for _, d := range result["default"] {
-			AddIndent(&body, &firstWithIndex)
-			body = append(body, src[d.Start:d.End]...)
-		}
+		// remove breakline in the end
+		body = body[:len(body)-1]
 	}
 
 	var totalLen int
diff --git a/pkg/gci/specificity/default.go b/pkg/gci/specificity/default.go
deleted file mode 100644
index f7ae4b8..0000000
--- a/pkg/gci/specificity/default.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package specificity
-
-type Default struct{}
-
-func (d Default) IsMoreSpecific(than MatchSpecificity) bool {
-	return isMoreSpecific(d, than)
-}
-
-func (d Default) Equal(to MatchSpecificity) bool {
-	return equalSpecificity(d, to)
-}
-
-func (d Default) class() specificityClass {
-	return DefaultClass
-}
-
-func (d Default) String() string {
-	return "Default"
-}
diff --git a/pkg/gci/specificity/match.go b/pkg/gci/specificity/match.go
deleted file mode 100644
index f08d2b6..0000000
--- a/pkg/gci/specificity/match.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package specificity
-
-import "fmt"
-
-type Match struct {
-	Length int
-}
-
-func (m Match) IsMoreSpecific(than MatchSpecificity) bool {
-	otherMatch, isMatch := than.(Match)
-	return isMoreSpecific(m, than) || (isMatch && m.Length > otherMatch.Length)
-}
-
-func (m Match) Equal(to MatchSpecificity) bool {
-	return equalSpecificity(m, to)
-}
-
-func (m Match) class() specificityClass {
-	return MatchClass
-}
-
-func (m Match) String() string {
-	return fmt.Sprintf("Match(length: %d)", m.Length)
-}
diff --git a/pkg/gci/specificity/mismatch.go b/pkg/gci/specificity/mismatch.go
deleted file mode 100644
index 8e87111..0000000
--- a/pkg/gci/specificity/mismatch.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package specificity
-
-type MisMatch struct{}
-
-func (m MisMatch) IsMoreSpecific(than MatchSpecificity) bool {
-	return isMoreSpecific(m, than)
-}
-
-func (m MisMatch) Equal(to MatchSpecificity) bool {
-	return equalSpecificity(m, to)
-}
-
-func (m MisMatch) class() specificityClass {
-	return MisMatchClass
-}
-
-func (m MisMatch) String() string {
-	return "Mismatch"
-}
diff --git a/pkg/gci/specificity/specificity.go b/pkg/gci/specificity/specificity.go
deleted file mode 100644
index 0a7c9f8..0000000
--- a/pkg/gci/specificity/specificity.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package specificity
-
-type specificityClass int
-
-const (
-	MisMatchClass        = 0
-	DefaultClass         = 10
-	StandardPackageClass = 20
-	MatchClass           = 30
-)
-
-// MatchSpecificity is used to determine which section matches an import best
-type MatchSpecificity interface {
-	IsMoreSpecific(than MatchSpecificity) bool
-	Equal(to MatchSpecificity) bool
-	class() specificityClass
-}
-
-func isMoreSpecific(this, than MatchSpecificity) bool {
-	return this.class() > than.class()
-}
-
-func equalSpecificity(base, to MatchSpecificity) bool {
-	// m.class() == to.class() would not work for Match
-	return !base.IsMoreSpecific(to) && !to.IsMoreSpecific(base)
-}
diff --git a/pkg/gci/specificity/standard.go b/pkg/gci/specificity/standard.go
deleted file mode 100644
index 8b11d04..0000000
--- a/pkg/gci/specificity/standard.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package specificity
-
-type StandardPackageMatch struct{}
-
-func (s StandardPackageMatch) IsMoreSpecific(than MatchSpecificity) bool {
-	return isMoreSpecific(s, than)
-}
-
-func (s StandardPackageMatch) Equal(to MatchSpecificity) bool {
-	return equalSpecificity(s, to)
-}
-
-func (s StandardPackageMatch) class() specificityClass {
-	return StandardPackageClass
-}
-
-func (s StandardPackageMatch) String() string {
-	return "Standard"
-}


Test patch:
diff --git a/pkg/gci/internal/testdata/already-good.out.go b/pkg/gci/internal/testdata/already-good.out.go
index f82e05d..89de7a0 100644
--- a/pkg/gci/internal/testdata/already-good.out.go
+++ b/pkg/gci/internal/testdata/already-good.out.go
@@ -2,7 +2,7 @@ package main
 import (
 	"fmt"
 
-	"github.com/daixiang0/gci"
-
 	g "github.com/golang"
+
+	"github.com/daixiang0/gci"
 )
diff --git a/pkg/gci/internal/testdata/drop-prefix-comments.out.go b/pkg/gci/internal/testdata/drop-prefix-comments.out.go
index 54e8151..223f546 100644
--- a/pkg/gci/internal/testdata/drop-prefix-comments.out.go
+++ b/pkg/gci/internal/testdata/drop-prefix-comments.out.go
@@ -6,9 +6,9 @@ import (
 	// Std imports
 	"os"
 
-	"github.com/daixiang0/gci"
-
 	// Github
 	"github.com/local/dlib/dexec"
+
+	"github.com/daixiang0/gci"
 	// Github
 )
diff --git a/pkg/gci/internal/testdata/nolint.out.go b/pkg/gci/internal/testdata/nolint.out.go
index 272e671..96c3dec 100644
--- a/pkg/gci/internal/testdata/nolint.out.go
+++ b/pkg/gci/internal/testdata/nolint.out.go
@@ -3,7 +3,7 @@ package main
 import (
 	"fmt"
 
-	_ "github.com/daixiang0/gci" //nolint:depguard
-
 	"github.com/forbidden/pkg" //nolint:depguard
+
+	_ "github.com/daixiang0/gci" //nolint:depguard
 )
diff --git a/pkg/gci/internal/testdata/number-in-alias.out.go b/pkg/gci/internal/testdata/number-in-alias.out.go
index 1491cc5..91026c4 100644
--- a/pkg/gci/internal/testdata/number-in-alias.out.go
+++ b/pkg/gci/internal/testdata/number-in-alias.out.go
@@ -2,7 +2,7 @@ package main
 import (
 	"fmt"
 
-	"github.com/daixiang0/gci"
-
 	go_V1 "github.com/golang"
+
+	"github.com/daixiang0/gci"
 )
diff --git a/pkg/gci/internal/testdata/simple-case.out.go b/pkg/gci/internal/testdata/simple-case.out.go
index fe0d758..1c0e49f 100644
--- a/pkg/gci/internal/testdata/simple-case.out.go
+++ b/pkg/gci/internal/testdata/simple-case.out.go
@@ -2,7 +2,7 @@ package main
 import (
 	"fmt"
 
-	"github.com/daixiang0/gci"
-
 	"golang.org/x/tools"
+
+	"github.com/daixiang0/gci"
 )
diff --git a/pkg/gci/internal/testdata/whitespace-test.out.go b/pkg/gci/internal/testdata/whitespace-test.out.go
index 7e60bb0..0347b51 100644
--- a/pkg/gci/internal/testdata/whitespace-test.out.go
+++ b/pkg/gci/internal/testdata/whitespace-test.out.go
@@ -3,7 +3,7 @@ package main
 import (
 	"fmt"
 
-	alias "github.com/daixiang0/gci"
-
 	"github.com/golang" // golang
+
+	alias "github.com/daixiang0/gci"
 )
diff --git a/pkg/gci/internal/testdata/with-above-comment-and-alias.out.go b/pkg/gci/internal/testdata/with-above-comment-and-alias.out.go
index 1432109..13c89f9 100644
--- a/pkg/gci/internal/testdata/with-above-comment-and-alias.out.go
+++ b/pkg/gci/internal/testdata/with-above-comment-and-alias.out.go
@@ -2,8 +2,8 @@ package main
 import (
 	"fmt"
 
-	"github.com/daixiang0/gci"
-
 	// golang
 	_ "github.com/golang"
+
+	"github.com/daixiang0/gci"
 )
diff --git a/pkg/gci/internal/testdata/with-comment-and-alias.out.go b/pkg/gci/internal/testdata/with-comment-and-alias.out.go
index c9ca1b3..6b2c628 100644
--- a/pkg/gci/internal/testdata/with-comment-and-alias.out.go
+++ b/pkg/gci/internal/testdata/with-comment-and-alias.out.go
@@ -2,7 +2,7 @@ package main
 import (
 	"fmt"
 
-	"github.com/daixiang0/gci"
-
 	_ "github.com/golang" // golang
+
+	"github.com/daixiang0/gci"
 )
diff --git a/pkg/gci/specificity/specificity_test.go b/pkg/gci/specificity/specificity_test.go
deleted file mode 100644
index f6a1cb2..0000000
--- a/pkg/gci/specificity/specificity_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package specificity
-
-import (
-	"fmt"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-)
-
-func TestSpecificityOrder(t *testing.T) {
-	testCases := testCasesInSpecificityOrder()
-	for i := 1; i < len(testCases); i++ {
-		t.Run(fmt.Sprintf("Specificity(%v)>Specificity(%v)", testCases[i], testCases[i-1]), func(t *testing.T) {
-			assert.True(t, testCases[i].IsMoreSpecific(testCases[i-1]))
-		})
-	}
-}
-
-func TestSpecificityEquality(t *testing.T) {
-	for _, testCase := range testCasesInSpecificityOrder() {
-		t.Run(fmt.Sprintf("Specificity(%v)==Specificity(%v)", testCase, testCase), func(t *testing.T) {
-			assert.True(t, testCase.Equal(testCase))
-		})
-	}
-}
-
-func testCasesInSpecificityOrder() []MatchSpecificity {
-	return []MatchSpecificity{MisMatch{}, Default{}, StandardPackageMatch{}, Match{0}, Match{1}}
-}