Skip to content

Commit

Permalink
Merge pull request #111 from meian/96-apply-linter-on-ci
Browse files Browse the repository at this point in the history
#96 Apply linter on CI
  • Loading branch information
meian authored Sep 8, 2022
2 parents 68ed162 + 9c2eb36 commit 248a3de
Show file tree
Hide file tree
Showing 21 changed files with 149 additions and 88 deletions.
42 changes: 42 additions & 0 deletions .github/config/.golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
run:
timeout: 1m
issue-exit-code: 1
tests: true
skip-dirs-use-default: true
allow-parallel-runners: true
go: "1.18"
linters:
enable-all: true
disable:
# deprecated
- deadcode
- exhaustivestruct
- golint
- ifshort
- interfacer
- maligned
- nosnakecase
- scopelint
- structcheck
- varcheck
# ignore for generics
- rowserrcheck
- sqlclosecheck
- wastedassign
# unused rules
- gofumpt
- gomnd
- ireturn
- nlreturn
- paralleltest
- wsl
fast: false
issues:
exclude-rules:
- path: _test.go
linters:
- cyclop
- dupl
- funlen
- gocognit
- varnamelen
28 changes: 28 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: reviewdog

on:
pull_request:
paths:
- "**.go"
- ".github/config/.golangci.yml"
- ".github/workflows/lint.yml"

jobs:
# NOTE: golangci-lint doesn't report multiple errors on the same line from
# different linters and just report one of the errors?

golangci:
name: golangci
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v3
- name: golangci
uses: reviewdog/action-golangci-lint@v2
with:
# optionally use a specific version of Go rather than the latest one
go_version: "1.18"
fail_on_error: true

# Can pass --config flag to change golangci-lint behavior and target directory.
golangci_lint_flags: "--config=.github/config/.golangci.yml"
1 change: 1 addition & 0 deletions common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func testBeforeAndAfter[T any](t *testing.T, itb gcf.Iterable[T]) {
//
// - emptyIterable chaining
// - test any func chaining result from emptyIterable is emptyIterable or not.
//
// - no panic from empty
// - test that panic does not occurred when any func chaining from empty elements that are not emptyIterable.
func testEmpties(t *testing.T, f func(itb gcf.Iterable[int]) gcf.Iterable[int]) {
Expand Down
6 changes: 3 additions & 3 deletions concat.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ type concatIterator[T any] struct {

// Concat makes Iterable elements concatenated of itb1 and itb2.
//
// itb1 := gcf.FromSlice([]int{1, 2, 3})
// itb2 := gcf.FromSlice([]int{4, 5, 6})
// itbc := gcf.Concat(itb1, itb2)
// itb1 := gcf.FromSlice([]int{1, 2, 3})
// itb2 := gcf.FromSlice([]int{4, 5, 6})
// itbc := gcf.Concat(itb1, itb2)
func Concat[T any](itb1 Iterable[T], itb2 Iterable[T]) Iterable[T] {
if isEmpty(itb1) && isEmpty(itb2) {
return orEmpty(itb1)
Expand Down
4 changes: 2 additions & 2 deletions distinct.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ type distinctIterator[T comparable] struct {
// Distinct makes Iterable contains unique elements.
// Inner elements is restrict by comparable constraint.
//
// itb := gcf.FromSlice([]int{1, 2, 3, 3, 4, 2, 5})
// itb = gcf.Distinct(itb)
// itb := gcf.FromSlice([]int{1, 2, 3, 3, 4, 2, 5})
// itb = gcf.Distinct(itb)
//
// Currently, result order is determined, but on spec, is undefined.
func Distinct[T comparable](itb Iterable[T]) Iterable[T] {
Expand Down
4 changes: 1 addition & 3 deletions distinct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ func TestDistinct(t *testing.T) {
itb = gcf.Distinct(itb)
testBeforeAndAfter(t, itb)

testEmpties(t, func(itb gcf.Iterable[int]) gcf.Iterable[int] {
return gcf.Distinct(itb)
})
testEmpties(t, gcf.Distinct[int])
}

func ExampleDistinct() {
Expand Down
2 changes: 1 addition & 1 deletion error.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ package gcf
import "errors"

var (
errStep0 = errors.New("Arg step must not be zero.")
errStep0 = errors.New("arg step must not be zero")
)
4 changes: 2 additions & 2 deletions filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ type filterIterator[T any] struct {

// Filter makes Iterable with elements which filterFunc is true.
//
// itb := gcf.FromSlice([]int{1, 2, 3})
// itb = gcf.Filter(itb, func(v int) bool { return v%2 > 0 })
// itb := gcf.FromSlice([]int{1, 2, 3})
// itb = gcf.Filter(itb, func(v int) bool { return v%2 > 0 })
//
// If filterFunc is nil, returns original Iteratable.
func Filter[T any](itb Iterable[T], filterFunc func(v T) bool) Iterable[T] {
Expand Down
18 changes: 9 additions & 9 deletions map.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ type mapIterator[T any, R any] struct {

// Map makes Iterable in elements convert by mapFunc.
//
// itbs := gcf.Func([]string{"a", "ab", "abc"})
// itbi := gcf.Map(itbs, func(v string) int { return len(v) })
// itbs := gcf.Func([]string{"a", "ab", "abc"})
// itbi := gcf.Map(itbs, func(v string) int { return len(v) })
//
// If mapFunc is nil, return Iterable in zero value elements.
func Map[T any, R any](itb Iterable[T], mapFunc func(v T) R) Iterable[R] {
Expand Down Expand Up @@ -65,13 +65,13 @@ type flatMapIterator[T any, R any] struct {

// FlatMap makes Iterable in elements in slice converted by mapFunc.
//
// itbs := gcf.Func([]string{"a", "ab", "abc"})
// itbi := gcf.Map(itbs, func(v string) int[] {
// var r := make([]int, 0)
// for _, c := range []rune(v) {
// r = append(r, int(c))
// }
// })
// itbs := gcf.Func([]string{"a", "ab", "abc"})
// itbi := gcf.Map(itbs, func(v string) int[] {
// var r := make([]int, 0)
// for _, c := range []rune(v) {
// r = append(r, int(c))
// }
// })
//
// If mapFunc is nil, return empty Iterable.
func FlatMap[T any, R any](itb Iterable[T], mapFunc func(v T) []R) Iterable[R] {
Expand Down
2 changes: 1 addition & 1 deletion map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func ExampleFlatMap() {
itb := gcf.FromSlice(s)
itbs := gcf.FlatMap(itb, func(v string) []string {
r := make([]string, 0, len(v))
for _, c := range []rune(v) {
for _, c := range v {
r = append(r, fmt.Sprintf("%c", c))
}
return r
Expand Down
4 changes: 2 additions & 2 deletions range_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ func TestRange(t *testing.T) {
itb, _ = gcf.Range(3, 1, -1)
testBeforeAndAfter(t, itb)

testEmpties(t, func(itb gcf.Iterable[int]) gcf.Iterable[int] {
testEmpties(t, func(_ gcf.Iterable[int]) gcf.Iterable[int] {
itb, _ = gcf.Range(1, 0, 1)
return itb
})
testEmpties(t, func(itb gcf.Iterable[int]) gcf.Iterable[int] {
testEmpties(t, func(_ gcf.Iterable[int]) gcf.Iterable[int] {
itb, _ = gcf.Range(1, 2, -1)
return itb
})
Expand Down
16 changes: 8 additions & 8 deletions repeat.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@ type repeatIterator[T any] struct {
iteratorItem[T]
}

// Repeat makes Iterable that repeat v a count times.
// Repeat makes Iterable that repeat value a count times.
//
// itb = gcf.Repeat(1, 3)
// itb = gcf.Repeat(1, 3)
//
// If count is 0, returns empty Iterable.
// If count is negative, raises panic.
func Repeat[T any](v T, count int) Iterable[T] {
func Repeat[T any](value T, count int) Iterable[T] {
if count < 0 {
panic("count for Repeat must not be negative.")
}
if count == 0 {
return empty[T]()
}
if count == 1 {
return FromSlice([]T{v})
return FromSlice([]T{value})
}
return &repeatIterable[T]{v, count}
return &repeatIterable[T]{value, count}
}

func (itb *repeatIterable[T]) Iterator() Iterator[T] {
Expand Down Expand Up @@ -70,9 +70,9 @@ type repeatIterableIterator[T any] struct {

// RepeatIterable makes Iterable that repeat elements in itb a count times.
//
// s := []int{1, 2, 3}
// itb := gcf.FromSlice(s)
// itb = gcf.RepeatIterable(itb, 3)
// s := []int{1, 2, 3}
// itb := gcf.FromSlice(s)
// itb = gcf.RepeatIterable(itb, 3)
//
// If count is 0, returns empty Iterable.
// If count is negative, raises panic.
Expand Down
10 changes: 5 additions & 5 deletions reverse.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ type reverseIterator[T any] struct {

// Reverse makes Iterable with reverse order elements.
//
// itb := gcf.FromSlice([]int{1, 2, 3})
// itb = gcf.Reverse(itb)
// itb := gcf.FromSlice([]int{1, 2, 3})
// itb = gcf.Reverse(itb)
func Reverse[T any](itb Iterable[T]) Iterable[T] {
if isEmpty(itb) {
return orEmpty(itb)
Expand Down Expand Up @@ -52,9 +52,9 @@ func (it *reverseIterator[T]) Current() T {

func (it *reverseIterator[T]) build() {
s := iteratorToSlice(it.it)
len := len(s)
for i := 0; i < len/2; i++ {
s[i], s[len-i-1] = s[len-i-1], s[i]
slen := len(s)
for i := 0; i < slen/2; i++ {
s[i], s[slen-i-1] = s[slen-i-1], s[i]
}
it.it = makeSliceIterator(s)
it.built = true
Expand Down
4 changes: 1 addition & 3 deletions reverse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ func TestReverse(t *testing.T) {
itb = gcf.Reverse(itb)
testBeforeAndAfter(t, itb)

testEmpties(t, func(itb gcf.Iterable[int]) gcf.Iterable[int] {
return gcf.Reverse(itb)
})
testEmpties(t, gcf.Reverse[int])
}

func ExampleReverse() {
Expand Down
8 changes: 4 additions & 4 deletions skip.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ type skipIterator[T any] struct {

// Skip makes Iterable with elements excepting counted elements from ahead.
//
// itb := gcf.FromSlice([]{1, 2, 3})
// itb = gcf.Skip(itb, 2)
// itb := gcf.FromSlice([]{1, 2, 3})
// itb = gcf.Skip(itb, 2)
//
// If count is 0, returns original Iterable.
// If count is negative, raises panic.
Expand Down Expand Up @@ -72,8 +72,8 @@ type skipWhileIterator[T any] struct {

// SkipWhile makes Iterable with elements excepting elements that whileFunc is true from ahead.
//
// itb := gcf.FromSlice([]{1, 2, 3})
// itb = gcf.SkipWhile(itb, func(v int) bool { return v <= 2 })
// itb := gcf.FromSlice([]{1, 2, 3})
// itb = gcf.SkipWhile(itb, func(v int) bool { return v <= 2 })
//
// If whileFunc is nil, returns original Iterable.
func SkipWhile[T any](itb Iterable[T], whileFunc func(v T) bool) Iterable[T] {
Expand Down
29 changes: 14 additions & 15 deletions skip_last.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ type skipLastIterable[T any] struct {
type skipLastIterator[T any] struct {
it Iterator[T]
count int
i int
built bool
iteratorItem[T]
}

// SkipLast makes Iterable with elements excepting counted elements from end.
//
// itb := gcf.FromSlice([]{1, 2, 3})
// itb = gcf.SkipLast(itb, 2)
// itb := gcf.FromSlice([]{1, 2, 3})
// itb = gcf.SkipLast(itb, 2)
//
// If count is 0, returns original Iterable.
// If count is negative, raises panic.
Expand Down Expand Up @@ -86,8 +85,8 @@ type skipLastWhileIterator[T any] struct {

// SkipLastWhile makes Iterable with elements excepting elements that whileFunc is true from end.
//
// itb := gcf.FromSlice([]{1, 2, 3})
// itb = gcf.SkipLastWhile(itb, func(v int) bool { return v <= 2 })
// itb := gcf.FromSlice([]{1, 2, 3})
// itb = gcf.SkipLastWhile(itb, func(v int) bool { return v <= 2 })
//
// If whileFunc is nil, returns original Iterable.
func SkipLastWhile[T any](itb Iterable[T], whileFunc func(v T) bool) Iterable[T] {
Expand Down Expand Up @@ -130,28 +129,28 @@ func (it *skipLastWhileIterator[T]) Current() T {
}

func (it *skipLastWhileIterator[T]) build() {
s := iteratorToSlice(it.it)
if len(s) == 0 {
slice := iteratorToSlice(it.it)
if len(slice) == 0 {
it.it = emptyIter[T]()
it.built = true
return
}
if !it.whileFunc(s[len(s)-1]) {
it.it = makeSliceIterator(s)
if !it.whileFunc(slice[len(slice)-1]) {
it.it = makeSliceIterator(slice)
it.built = true
return
}
sLen := len(s)
for i := len(s) - 2; i >= 0; i-- {
if !it.whileFunc(s[i]) {
s = s[:i+1]
sLen := len(slice)
for i := sLen - 2; i >= 0; i-- {
if !it.whileFunc(slice[i]) {
slice = slice[:i+1]
break
}
}
if len(s) == sLen {
if len(slice) == sLen {
it.it = emptyIter[T]()
} else {
it.it = makeSliceIterator(s)
it.it = makeSliceIterator(slice)
}
it.built = true
}
12 changes: 6 additions & 6 deletions slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ type sliceIterator[T any] struct {

// FromSlice makes Iterable from slice.
//
// s := []int{1, 2, 3}
// itb := gcf.FromSlice(s)
// s := []int{1, 2, 3}
// itb := gcf.FromSlice(s)
//
// By change elements in base slice afrer this called, change is affected to Iterator.
// If you want no affects by change, you can use FromSliceImmutable.
Expand All @@ -26,8 +26,8 @@ func FromSlice[T any](s []T) Iterable[T] {

// FromSliceImmutable makes Iterable from slice with immutable.
//
// s := []int{1, 2, 3}
// itb := gcf.FromSliceImmutable(s)
// s := []int{1, 2, 3}
// itb := gcf.FromSliceImmutable(s)
//
// Input slice is duplicated to make immutable, so have some performance bottleneck.
func FromSliceImmutable[T any](s []T) Iterable[T] {
Expand Down Expand Up @@ -63,8 +63,8 @@ func (it *sliceIterator[T]) Current() T {

// ToSlice makes slice of elements listed in Iterable.
//
// itb := gcf.FromSlice([]int{1, 2, 3})
// s := gcf.ToSlice(itb)
// itb := gcf.FromSlice([]int{1, 2, 3})
// s := gcf.ToSlice(itb)
func ToSlice[T any](itb Iterable[T]) []T {
// shortcut for emptyIterable
if _, ok := itb.(emptyIterable[T]); ok {
Expand Down
Loading

0 comments on commit 248a3de

Please sign in to comment.