Repository: daixiang0/gci
Pull request #151 (2023-03-13 08:05:18)

Revert: keep standard package list
If no `go` in the PATH, `packages` will raise error:
`err: go command required, not found: exec: "go": executable file not found in $PATH: stderr: `


Patch:
diff --git a/Makefile b/Makefile
index 8c5f33e..4e75d57 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
-.PHONY: clean test build
+.PHONY: clean generate test build
 
 BIN_OUTPUT := $(if $(filter $(shell go env GOOS), windows), dist/gci.exe, dist/gci)
 
-default: clean test build
+default: clean generate test build
 
 clean:
 	@echo BIN_OUTPUT: ${BIN_OUTPUT}
@@ -13,3 +13,6 @@ build: clean
 
 test: clean
 	@go test -v -count=1 -cover ./...
+
+generate:
+	@go generate ./...
diff --git a/go.mod b/go.mod
index 06092eb..68161f1 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/daixiang0/gci
 
-go 1.20
+go 1.18
 
 require (
 	github.com/hexops/gotextdiff v1.0.3
diff --git a/internal/generate.go b/internal/generate.go
new file mode 100644
index 0000000..f106be2
--- /dev/null
+++ b/internal/generate.go
@@ -0,0 +1,87 @@
+package main
+
+import (
+	"bytes"
+	"go/format"
+	"os"
+	"runtime"
+	"strings"
+	"text/template"
+
+	"golang.org/x/tools/go/packages"
+)
+
+//go:generate go run .
+
+const outputFile = "../pkg/section/standard_list.go"
+
+const stdTemplate = `
+package section
+
+// Code generated based on {{ .Version }}. DO NOT EDIT.
+
+var standardPackages = map[string]struct{}{
+{{- range $pkg := .Packages }}
+		"{{ $pkg }}":  {},
+{{- end}}
+}
+
+`
+
+func main() {
+	err := generate()
+	if err != nil {
+		panic(err)
+	}
+}
+
+func generate() error {
+	all, err := packages.Load(nil, "std")
+	if err != nil {
+		return err
+	}
+
+	var pkgs []string
+
+	// go list std | grep -v vendor | grep -v internal
+	for _, pkg := range all {
+		if !strings.Contains(pkg.PkgPath, "internal") && !strings.Contains(pkg.PkgPath, "vendor") {
+			pkgs = append(pkgs, pkg.PkgPath)
+		}
+	}
+
+	file, err := os.Create(outputFile)
+	if err != nil {
+		return err
+	}
+
+	models := map[string]interface{}{
+		"Packages": pkgs,
+		"Version":  runtime.Version(),
+	}
+
+	tlt, err := template.New("std-packages").Parse(stdTemplate)
+	if err != nil {
+		return err
+	}
+
+	b := &bytes.Buffer{}
+
+	err = tlt.Execute(b, models)
+	if err != nil {
+		return err
+	}
+
+	// gofmt
+	source, err := format.Source(b.Bytes())
+	if err != nil {
+		return err
+	}
+
+	_, err = file.Write(source)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
diff --git a/pkg/section/parser.go b/pkg/section/parser.go
index 57e5a35..9834dcd 100644
--- a/pkg/section/parser.go
+++ b/pkg/section/parser.go
@@ -22,7 +22,7 @@ func Parse(data []string) (SectionList, error) {
 		if s == "default" {
 			list = append(list, Default{})
 		} else if s == "standard" {
-			list = append(list, NewStandard())
+			list = append(list, Standard{})
 		} else if s == "newline" {
 			list = append(list, NewLine{})
 		} else if strings.HasPrefix(s, "prefix(") && len(d) > 8 {
diff --git a/pkg/section/section.go b/pkg/section/section.go
index b84ba2c..cc0a43f 100644
--- a/pkg/section/section.go
+++ b/pkg/section/section.go
@@ -28,7 +28,7 @@ func (list SectionList) String() []string {
 }
 
 func DefaultSections() SectionList {
-	return SectionList{NewStandard(), Default{}}
+	return SectionList{Standard{}, Default{}}
 }
 
 func DefaultSectionSeparators() SectionList {
diff --git a/pkg/section/standard.go b/pkg/section/standard.go
index 223c6b5..26c7e9d 100644
--- a/pkg/section/standard.go
+++ b/pkg/section/standard.go
@@ -1,33 +1,16 @@
 package section
 
 import (
-	"golang.org/x/tools/go/packages"
-
 	"github.com/daixiang0/gci/pkg/parse"
 	"github.com/daixiang0/gci/pkg/specificity"
 )
 
 const StandardType = "standard"
 
-type Standard struct {
-	standardPackages map[string]struct{}
-}
-
-func NewStandard() Standard {
-	pkgs, err := packages.Load(nil, "std")
-	if err != nil {
-		panic(err)
-	}
-
-	standardPackages := make(map[string]struct{})
-	for _, p := range pkgs {
-		standardPackages[p.PkgPath] = struct{}{}
-	}
-	return Standard{standardPackages: standardPackages}
-}
+type Standard struct{}
 
 func (s Standard) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity {
-	if _, ok := s.standardPackages[spec.Path]; ok {
+	if isStandard(spec.Path) {
 		return specificity.StandardMatch{}
 	}
 	return specificity.MisMatch{}
@@ -40,3 +23,8 @@ func (s Standard) String() string {
 func (s Standard) Type() string {
 	return StandardType
 }
+
+func isStandard(pkg string) bool {
+	_, ok := standardPackages[pkg]
+	return ok
+}
diff --git a/pkg/section/standard_list.go b/pkg/section/standard_list.go
new file mode 100644
index 0000000..f0e904d
--- /dev/null
+++ b/pkg/section/standard_list.go
@@ -0,0 +1,162 @@
+package section
+
+// Code generated based on go1.20.1. DO NOT EDIT.
+
+var standardPackages = map[string]struct{}{
+	"archive/tar":          {},
+	"archive/zip":          {},
+	"bufio":                {},
+	"bytes":                {},
+	"compress/bzip2":       {},
+	"compress/flate":       {},
+	"compress/gzip":        {},
+	"compress/lzw":         {},
+	"compress/zlib":        {},
+	"container/heap":       {},
+	"container/list":       {},
+	"container/ring":       {},
+	"context":              {},
+	"crypto":               {},
+	"crypto/aes":           {},
+	"crypto/cipher":        {},
+	"crypto/des":           {},
+	"crypto/dsa":           {},
+	"crypto/ecdh":          {},
+	"crypto/ecdsa":         {},
+	"crypto/ed25519":       {},
+	"crypto/elliptic":      {},
+	"crypto/hmac":          {},
+	"crypto/md5":           {},
+	"crypto/rand":          {},
+	"crypto/rc4":           {},
+	"crypto/rsa":           {},
+	"crypto/sha1":          {},
+	"crypto/sha256":        {},
+	"crypto/sha512":        {},
+	"crypto/subtle":        {},
+	"crypto/tls":           {},
+	"crypto/x509":          {},
+	"crypto/x509/pkix":     {},
+	"database/sql":         {},
+	"database/sql/driver":  {},
+	"debug/buildinfo":      {},
+	"debug/dwarf":          {},
+	"debug/elf":            {},
+	"debug/gosym":          {},
+	"debug/macho":          {},
+	"debug/pe":             {},
+	"debug/plan9obj":       {},
+	"embed":                {},
+	"encoding":             {},
+	"encoding/ascii85":     {},
+	"encoding/asn1":        {},
+	"encoding/base32":      {},
+	"encoding/base64":      {},
+	"encoding/binary":      {},
+	"encoding/csv":         {},
+	"encoding/gob":         {},
+	"encoding/hex":         {},
+	"encoding/json":        {},
+	"encoding/pem":         {},
+	"encoding/xml":         {},
+	"errors":               {},
+	"expvar":               {},
+	"flag":                 {},
+	"fmt":                  {},
+	"go/ast":               {},
+	"go/build":             {},
+	"go/build/constraint":  {},
+	"go/constant":          {},
+	"go/doc":               {},
+	"go/doc/comment":       {},
+	"go/format":            {},
+	"go/importer":          {},
+	"go/parser":            {},
+	"go/printer":           {},
+	"go/scanner":           {},
+	"go/token":             {},
+	"go/types":             {},
+	"hash":                 {},
+	"hash/adler32":         {},
+	"hash/crc32":           {},
+	"hash/crc64":           {},
+	"hash/fnv":             {},
+	"hash/maphash":         {},
+	"html":                 {},
+	"html/template":        {},
+	"image":                {},
+	"image/color":          {},
+	"image/color/palette":  {},
+	"image/draw":           {},
+	"image/gif":            {},
+	"image/jpeg":           {},
+	"image/png":            {},
+	"index/suffixarray":    {},
+	"io":                   {},
+	"io/fs":                {},
+	"io/ioutil":            {},
+	"log":                  {},
+	"log/syslog":           {},
+	"math":                 {},
+	"math/big":             {},
+	"math/bits":            {},
+	"math/cmplx":           {},
+	"math/rand":            {},
+	"mime":                 {},
+	"mime/multipart":       {},
+	"mime/quotedprintable": {},
+	"net":                  {},
+	"net/http":             {},
+	"net/http/cgi":         {},
+	"net/http/cookiejar":   {},
+	"net/http/fcgi":        {},
+	"net/http/httptest":    {},
+	"net/http/httptrace":   {},
+	"net/http/httputil":    {},
+	"net/http/pprof":       {},
+	"net/mail":             {},
+	"net/netip":            {},
+	"net/rpc":              {},
+	"net/rpc/jsonrpc":      {},
+	"net/smtp":             {},
+	"net/textproto":        {},
+	"net/url":              {},
+	"os":                   {},
+	"os/exec":              {},
+	"os/signal":            {},
+	"os/user":              {},
+	"path":                 {},
+	"path/filepath":        {},
+	"plugin":               {},
+	"reflect":              {},
+	"regexp":               {},
+	"regexp/syntax":        {},
+	"runtime":              {},
+	"runtime/cgo":          {},
+	"runtime/coverage":     {},
+	"runtime/debug":        {},
+	"runtime/metrics":      {},
+	"runtime/pprof":        {},
+	"runtime/race":         {},
+	"runtime/trace":        {},
+	"sort":                 {},
+	"strconv":              {},
+	"strings":              {},
+	"sync":                 {},
+	"sync/atomic":          {},
+	"syscall":              {},
+	"testing":              {},
+	"testing/fstest":       {},
+	"testing/iotest":       {},
+	"testing/quick":        {},
+	"text/scanner":         {},
+	"text/tabwriter":       {},
+	"text/template":        {},
+	"text/template/parse":  {},
+	"time":                 {},
+	"time/tzdata":          {},
+	"unicode":              {},
+	"unicode/utf16":        {},
+	"unicode/utf8":         {},
+	"unsafe":               {},
+}


Test patch:
diff --git a/pkg/section/standard_test.go b/pkg/section/standard_test.go
index aba4a13..2209402 100644
--- a/pkg/section/standard_test.go
+++ b/pkg/section/standard_test.go
@@ -7,15 +7,14 @@ import (
 )
 
 func TestStandardPackageSpecificity(t *testing.T) {
-	standard := NewStandard()
 	testCases := []specificityTestData{
-		{"context", standard, specificity.StandardMatch{}},
-		{"contexts", standard, specificity.MisMatch{}},
-		{"crypto", standard, specificity.StandardMatch{}},
-		{"crypto1", standard, specificity.MisMatch{}},
-		{"crypto/ae", standard, specificity.MisMatch{}},
-		{"crypto/aes", standard, specificity.StandardMatch{}},
-		{"crypto/aes2", standard, specificity.MisMatch{}},
+		{"context", Standard{}, specificity.StandardMatch{}},
+		{"contexts", Standard{}, specificity.MisMatch{}},
+		{"crypto", Standard{}, specificity.StandardMatch{}},
+		{"crypto1", Standard{}, specificity.MisMatch{}},
+		{"crypto/ae", Standard{}, specificity.MisMatch{}},
+		{"crypto/aes", Standard{}, specificity.StandardMatch{}},
+		{"crypto/aes2", Standard{}, specificity.MisMatch{}},
 	}
 	testSpecificity(t, testCases)
 }