feat: squash multiple modules to one

This commit is contained in:
2024-05-08 19:09:33 +03:00
parent 55719b4399
commit fef404f1a7
37 changed files with 37 additions and 491 deletions

View File

@ -1,50 +0,0 @@
.DEFAULT_GOAL := help
# ==================================================================================== #
# HELPERS
# ==================================================================================== #
## help: print this help message
.PHONY: help
help:
@echo 'Usage:'
@sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /'
## all: tidy + audit + test/cover
all: tidy audit test/cover
# ==================================================================================== #
# QUALITY CONTROL
# ==================================================================================== #
## tidy: format code and tidy modfile
.PHONY: tidy
tidy:
go fmt ./...
go mod tidy -v
## audit: run quality control checks
.PHONY: audit
audit:
go mod verify
go vet ./...
go run honnef.co/go/tools/cmd/staticcheck@latest -checks=all,-ST1000,-U1000 ./...
go run golang.org/x/vuln/cmd/govulncheck@latest ./...
go test -race -buildvcs -vet=off ./...
go run github.com/golangci/golangci-lint/cmd/golangci-lint@latest run -v ./...
# ==================================================================================== #
# DEVELOPMENT
# ==================================================================================== #
## test: run all tests
.PHONY: test
test:
go test -v -race -buildvcs ./...
## test/cover: run all tests and display coverage
.PHONY: test/cover
test/cover:
go test -v -race -buildvcs -coverprofile=/tmp/coverage.out ./...
go tool cover -html=/tmp/coverage.out

View File

@ -1,28 +0,0 @@
package main
import "flag"
const stdin = "-"
type Config struct {
Key int
Numeric bool
Reverse bool
Unique bool
Sources []string
}
func (c *Config) ParseFlags() {
flag.IntVar(&c.Key, "k", 0, "sort via column")
flag.BoolVar(&c.Numeric, "n", false, "compare according to string numerical value")
flag.BoolVar(&c.Reverse, "r", false, "reverse the result of comparisons")
flag.BoolVar(&c.Unique, "u", false, "output only the first of an equal run")
flag.Parse()
c.Sources = flag.Args()
if len(c.Sources) == 0 {
c.Sources = []string{stdin}
}
}

View File

@ -1,4 +1,4 @@
package main
package sortcli
import (
"bufio"
@ -13,9 +13,9 @@ import (
// NL New line constant
const NL = "\n"
type content [][]byte
type Content [][]byte
func (c *content) Sort(reverse bool) {
func (c *Content) Sort(reverse bool) {
slices.SortFunc(*c, func(a, b []byte) int {
if reverse {
a, b = b, a
@ -25,10 +25,10 @@ func (c *content) Sort(reverse bool) {
})
}
func (c *content) Uniques() {
func (c *Content) Uniques() {
m := make(map[string]struct{}, len(*c))
*c = slices.DeleteFunc[content, []byte](*c, func(line []byte) bool {
*c = slices.DeleteFunc[Content, []byte](*c, func(line []byte) bool {
if _, ok := m[string(line)]; !ok {
m[string(line)] = struct{}{}
@ -39,7 +39,7 @@ func (c *content) Uniques() {
})
}
func (c *content) String() string {
func (c *Content) String() string {
lines := *c
var n int
@ -64,7 +64,7 @@ func (c *content) String() string {
return sb.String()
}
func (c *content) Load(r io.Reader) {
func (c *Content) Load(r io.Reader) {
br := bufio.NewReader(r)
for {

View File

@ -1,4 +1,4 @@
package main
package sortcli
import (
"strings"
@ -16,7 +16,7 @@ Africa
`
func TestLoad(t *testing.T) {
c := &content{}
c := &Content{}
c.Load(strings.NewReader(input))
assert.Equal(t, input, c.String())
@ -42,7 +42,7 @@ America`,
tc := tc
t.Run(tc.Name, func(t *testing.T) {
c := &content{}
c := &Content{}
c.Load(strings.NewReader(tc.Content))
c.Uniques()

View File

@ -1,14 +0,0 @@
module sort-cli
go 1.21.6
require (
github.com/stretchr/testify v1.8.4
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View File

@ -1,12 +0,0 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,4 +1,4 @@
package main
package sortcli
import (
"io"
@ -6,13 +6,13 @@ import (
"os"
)
func open(sources []string) io.Reader {
func Open(sources []string) io.Reader {
rs := make([]io.Reader, 0, len(sources))
for _, source := range sources {
var r io.Reader
if source == stdin {
if source == "-" {
r = os.Stdin
} else {
if _, err := os.Stat(source); err != nil {

View File

@ -1,31 +0,0 @@
package main
import (
"os"
)
func main() {
result := run()
if _, err := os.Stdout.WriteString(result); err != nil {
panic(err)
}
os.Exit(0)
}
func run() string {
cfg := &Config{}
cfg.ParseFlags()
lines := content{}
lines.Load(open(cfg.Sources))
if cfg.Unique {
lines.Uniques()
}
lines.Sort(cfg.Reverse)
return lines.String()
}

View File

@ -1,71 +0,0 @@
package main
import (
"flag"
"os"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestFlags(t *testing.T) {
// We manipulate the Args to set them up for the testcases
// after this test we restore the initial args
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
cases := []struct {
Name string
Args []string
ExpectedExit int
ExpectedOutput string
}{
{
"No flags",
[]string{"testdata/first"},
0,
"alabama barcelona\nbarcelona california\ncalifornia denver\ncalifornia denver\nамур брянск\nбелгород волгоград\nволгоград геленджик",
},
{
"Reverse",
[]string{"-r", "testdata/first"},
0,
"волгоград геленджик\nбелгород волгоград\nамур брянск\ncalifornia denver\ncalifornia denver\nbarcelona california\nalabama barcelona",
},
{
"Unique",
[]string{"-u", "testdata/first"},
0,
"alabama barcelona\nbarcelona california\ncalifornia denver\nамур брянск\nбелгород волгоград\nволгоград геленджик",
},
{
"Column 2",
[]string{"-k=2", "testdata/first"},
0,
"alabama barcelona\nbarcelona california\ncalifornia denver\ncalifornia denver\nамур брянск\nбелгород волгоград\nволгоград геленджик",
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.Name, func(t *testing.T) {
// this call is required because otherwise flags panics, if args are set between flag.Parse calls
flag.CommandLine = flag.NewFlagSet(tc.Name, flag.ExitOnError)
// we need a value to set Args[0] to, cause flag begins parsing at Args[1]
os.Args = append([]string{tc.Name}, tc.Args...)
assert.Equal(t, tc.ExpectedOutput, strings.Trim(run(), "\n"))
})
}
}
func BenchmarkRun(b *testing.B) {
for i := 0; i < b.N; i++ {
flag.CommandLine = flag.NewFlagSet("Bench", flag.ExitOnError)
os.Args = append([]string{"Bench"}, "testdata/first")
_ = run()
}
}

View File

@ -1,7 +0,0 @@
волгоград геленджик
амур брянск
alabama barcelona
california denver
california denver
barcelona california
белгород волгоград