From a3d5ea12eafaf49c142fd77d838fbfd4a67ede9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tighearn=C3=A1n=20Carroll?= Date: Tue, 3 May 2022 16:31:16 +0100 Subject: [PATCH 01/16] made some typed functions generic --- go.mod | 2 +- maputil/maputil.go | 5 +- sliceutil/sets.go | 24 +++--- sliceutil/sliceutil.go | 164 ++++++++++++------------------------ sliceutil/sliceutil_test.go | 96 ++++++++++----------- 5 files changed, 120 insertions(+), 171 deletions(-) diff --git a/go.mod b/go.mod index c845370..adc2ce5 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/teamwork/utils -go 1.13 +go 1.18 require ( github.com/Strum355/go-difflib v1.1.0 // indirect diff --git a/maputil/maputil.go b/maputil/maputil.go index f130cdd..3ab4d5d 100644 --- a/maputil/maputil.go +++ b/maputil/maputil.go @@ -2,10 +2,11 @@ package maputil // import "github.com/teamwork/utils/maputil" // Reverse the keys and values of a map. -func Reverse(m map[string]string) map[string]string { - n := make(map[string]string) +func Reverse[T comparable, V comparable](m map[T]V) map[V]T { + n := make(map[V]T) for k, v := range m { n[v] = k } + return n } diff --git a/sliceutil/sets.go b/sliceutil/sets.go index 5a54526..f5b6858 100644 --- a/sliceutil/sets.go +++ b/sliceutil/sets.go @@ -2,20 +2,20 @@ package sliceutil // Difference returns a new slice with elements that are in "set" but not in // "others". -func Difference(set []int64, others ...[]int64) []int64 { - out := []int64{} +func Difference[T comparable](set []T, others ...[]T) []T { + out := []T{} - for _, setItem := range set { - found := false + for _, item := range set { + var found bool for _, o := range others { - if InInt64Slice(o, setItem) { + if ItemInSlice(o, item) { found = true break } } if !found { - out = append(out, setItem) + out = append(out, item) } } @@ -26,15 +26,15 @@ func Difference(set []int64, others ...[]int64) []int64 { // value will contain elements that are only in "a" (and not in "b"), and the // second return value will contain elements that are only in "b" (and not in // "a"). -func Complement(a, b []int64) (aOnly, bOnly []int64) { +func Complement[T comparable](a, b []T) (aOnly, bOnly []T) { for _, i := range a { - if !InInt64Slice(b, i) { + if !ItemInSlice(b, i) { aOnly = append(aOnly, i) } } for _, i := range b { - if !InInt64Slice(a, i) { + if !ItemInSlice(a, i) { bOnly = append(bOnly, i) } } @@ -43,9 +43,9 @@ func Complement(a, b []int64) (aOnly, bOnly []int64) { } // Intersection returns the elements common to both a and b -func Intersection(a, b []int64) []int64 { - inter := []int64{} - hash := make(map[int64]bool, len(a)) +func Intersection[T comparable](a, b []T) []T { + inter := []T{} + hash := make(map[T]bool, len(a)) for _, i := range a { hash[i] = false } diff --git a/sliceutil/sliceutil.go b/sliceutil/sliceutil.go index 1ce305a..ed470bc 100644 --- a/sliceutil/sliceutil.go +++ b/sliceutil/sliceutil.go @@ -7,60 +7,46 @@ package sliceutil // import "github.com/teamwork/utils/sliceutil" import ( + "fmt" "math/rand" "reflect" - "sort" "strconv" "strings" "time" ) -// JoinInt converts a slice of ints to a comma separated string. Useful for +// Join converts a slice of T to a comma separated string. Useful for // inserting into a query without the option of parameterization. -func JoinInt(ints []int64) string { - var intStr []string - for _, e := range ints { - intStr = append(intStr, strconv.Itoa(int(e))) +func Join[T any](tt []T) string { + var str []string + for _, t := range tt { + str = append(str, fmt.Sprintf("%v", t)) } - return strings.Join(intStr, ", ") + return strings.Join(str, ", ") } -// UniqInt64 removes duplicate entries from list. The list does not have to be -// sorted. -func UniqInt64(list []int64) []int64 { - var unique []int64 - seen := make(map[int64]struct{}) - for _, l := range list { - if _, ok := seen[l]; !ok { - seen[l] = struct{}{} - unique = append(unique, l) +// Unique removes duplicate entries from a list. The list does not have to be sorted. +func Unique[T comparable](tt []T) []T { + var unique []T + seen := make(map[T]struct{}) + for _, t := range tt { + if _, ok := seen[t]; !ok { + seen[t] = struct{}{} + unique = append(unique, t) } } - return unique -} -// UniqString removes duplicate entries from list. -func UniqString(list []string) []string { - sort.Strings(list) - var last string - l := list[:0] - for _, str := range list { - if str != last { - l = append(l, str) - } - last = str - } - return l + return unique } -// UniqueMergeSlices takes a slice of slices of int64s and returns an unsorted -// slice of unique int64s. -func UniqueMergeSlices(s [][]int64) (result []int64) { - var m = make(map[int64]bool) +// MergeUnique takes a slice of slices and returns an unsorted slice of +// unique entries. +func MergeUnique[T comparable](tt [][]T) (result []T) { + var m = make(map[T]bool) - for _, el := range s { - for _, i := range el { + for _, t := range tt { + for _, i := range t { m[i] = true } } @@ -92,10 +78,10 @@ func CSVtoInt64Slice(csv string) ([]int64, error) { return ints, nil } -// InStringSlice reports whether str is within list(case-sensitive) -func InStringSlice(list []string, str string) bool { - for _, item := range list { - if item == str { +// ItemInSlice returns true if item is in the provided slice. +func ItemInSlice[T comparable](tt []T, item T) bool { + for _, t := range tt { + if t == item { return true } } @@ -112,41 +98,22 @@ func InFoldedStringSlice(list []string, str string) bool { return false } -// InIntSlice reports whether i is within list -func InIntSlice(list []int, i int) bool { - for _, item := range list { - if item == i { - return true - } - } - return false -} - -// InInt64Slice reports whether i is within list -func InInt64Slice(list []int64, i int64) bool { - for _, item := range list { - if item == i { - return true - } - } - return false -} - -// RepeatString returns a slice with the string s reated n times. -func RepeatString(s string, n int) (r []string) { +// Repeat returns a slice with the item t reated n times. +func Repeat[T any](t T, n int) (tt []T) { for i := 0; i < n; i++ { - r = append(r, s) + tt = append(tt, t) } - return r + return tt } -// ChooseString chooses a random item from the list. -func ChooseString(l []string) string { - if len(l) == 0 { - return "" +// Choose chooses a random item from the list. +func Choose[T any](tt []T) T { + if len(tt) == 0 { + var zero T + return zero } rand.Seed(time.Now().UnixNano()) - return l[rand.Intn(len(l))] + return tt[rand.Intn(len(tt))] } // Range creates an []int counting at "start" up to (and including) "end". @@ -158,59 +125,40 @@ func Range(start, end int) []int { return rng } -// FilterString filters a list. The function will be called for every item and -// those that return false will not be included in the return value. -func FilterString(list []string, fun func(string) bool) []string { - var ret []string - for _, e := range list { - if fun(e) { - ret = append(ret, e) +// Remove removes any occurrence of a string from a slice. +func Remove[T comparable](tt []T, remove T) (out []T) { + for _, t := range tt { + if t != remove { + out = append(out, t) } } - return ret -} - -// RemoveString removes any occurrence of a string from a slice. -func RemoveString(list []string, s string) (out []string) { - for _, item := range list { - if item != s { - out = append(out, item) - } - } return out } -// FilterStringEmpty can be used as an argument for FilterString() and will -// return false if e is empty or contains only whitespace. -func FilterStringEmpty(e string) bool { - return strings.TrimSpace(e) != "" -} - -// FilterInt filters a list. The function will be called for every item and -// those that return false will not be included in the return value. -func FilterInt(list []int64, fun func(int64) bool) []int64 { - var ret []int64 - for _, e := range list { - if fun(e) { - ret = append(ret, e) +func Filter[T comparable](tt []T, fn func(T) bool) []T { + var ret []T + for _, t := range tt { + if fn(t) { + ret = append(ret, t) } } return ret } -// FilterIntEmpty can be used as an argument for FilterInt() and will -// return false if e is empty or contains only whitespace. -func FilterIntEmpty(e int64) bool { - return e != 0 +// FilterEmpty can be used as an argument for Filter() and will +// return false if e is zero value. +func FilterEmpty[T comparable](t T) bool { + var zero T + return t != zero } -// StringMap returns a list strings where each item in list has been modified by f -func StringMap(list []string, f func(string) string) []string { - ret := make([]string, len(list)) - for i := range list { - ret[i] = f(list[i]) +// Map returns a list where each item in list has been modified by fn +func Map[T comparable](tt []T, fn func(T) T) []T { + ret := make([]T, len(tt)) + for i, t := range tt { + ret[i] = fn(t) } return ret diff --git a/sliceutil/sliceutil_test.go b/sliceutil/sliceutil_test.go index e0c5a15..4f80a94 100644 --- a/sliceutil/sliceutil_test.go +++ b/sliceutil/sliceutil_test.go @@ -11,7 +11,7 @@ import ( "github.com/teamwork/test/diff" ) -func TestIntsToString(t *testing.T) { +func TestJoin(t *testing.T) { cases := []struct { in []int64 expected string @@ -32,7 +32,7 @@ func TestIntsToString(t *testing.T) { for i, tc := range cases { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := JoinInt(tc.in) + got := Join(tc.in) if got != tc.expected { t.Errorf(diff.Cmp(tc.expected, got)) } @@ -40,7 +40,7 @@ func TestIntsToString(t *testing.T) { } } -func TestUniqInt64(t *testing.T) { +func TestUniq_Int64(t *testing.T) { cases := []struct { in []int64 expected []int64 @@ -69,7 +69,7 @@ func TestUniqInt64(t *testing.T) { for i, tc := range cases { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := UniqInt64(tc.in) + got := Unique(tc.in) if !reflect.DeepEqual(got, tc.expected) { t.Errorf(diff.Cmp(tc.expected, got)) } @@ -77,50 +77,50 @@ func TestUniqInt64(t *testing.T) { } } -func TestUniqueMergeSlices(t *testing.T) { +func TestUniq_String(t *testing.T) { var tests = []struct { - in [][]int64 - expected []int64 + in []string + expected []string }{ { - generate2dintslice([]int64{1, 2, 3}), - []int64{1, 2, 3}, + []string{"a", "b", "c"}, + []string{"a", "b", "c"}, }, { - generate2dintslice([]int64{0, 1, 2, 3, -1, -10}), - []int64{0, 1, 2, 3, -1, -10}, + []string{"a", "b", "c", "a", "b", "n", "a", "aaa", "n", "x"}, + []string{"a", "b", "c", "n", "aaa", "x"}, }, } for i, tc := range tests { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := UniqueMergeSlices(tc.in) - if !int64slicesequal(got, tc.expected) { + got := Unique(tc.in) + if !stringslicesequal(got, tc.expected) { t.Errorf(diff.Cmp(tc.expected, got)) } }) } } -func TestUniqString(t *testing.T) { +func TestMergeUnique_Int64(t *testing.T) { var tests = []struct { - in []string - expected []string + in [][]int64 + expected []int64 }{ { - []string{"a", "b", "c"}, - []string{"a", "b", "c"}, + generate2dintslice([]int64{1, 2, 3}), + []int64{1, 2, 3}, }, { - []string{"a", "b", "c", "a", "b", "n", "a", "aaa", "n", "x"}, - []string{"a", "b", "c", "n", "aaa", "x"}, + generate2dintslice([]int64{0, 1, 2, 3, -1, -10}), + []int64{0, 1, 2, 3, -1, -10}, }, } for i, tc := range tests { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := UniqString(tc.in) - if !stringslicesequal(got, tc.expected) { + got := MergeUnique(tc.in) + if !int64slicesequal(got, tc.expected) { t.Errorf(diff.Cmp(tc.expected, got)) } }) @@ -237,7 +237,7 @@ func TestCSVtoInt64Slice(t *testing.T) { } } -func TestInStringSlice(t *testing.T) { +func TestItemInSlice_String(t *testing.T) { tests := []struct { list []string find string @@ -252,7 +252,7 @@ func TestInStringSlice(t *testing.T) { for i, tc := range tests { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := InStringSlice(tc.list, tc.find) + got := ItemInSlice(tc.list, tc.find) if got != tc.expected { t.Errorf(diff.Cmp(tc.expected, got)) } @@ -285,7 +285,7 @@ func TestInFoldedStringSlice(t *testing.T) { } } -func TestInIntSlice(t *testing.T) { +func TestItemInSlice_Int(t *testing.T) { tests := []struct { list []int find int @@ -300,7 +300,7 @@ func TestInIntSlice(t *testing.T) { for i, tc := range tests { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := InIntSlice(tc.list, tc.find) + got := ItemInSlice(tc.list, tc.find) if got != tc.expected { t.Errorf(diff.Cmp(tc.expected, got)) } @@ -308,7 +308,7 @@ func TestInIntSlice(t *testing.T) { } } -func TestInInt64Slice(t *testing.T) { +func TestItemInSlice_Int64(t *testing.T) { tests := []struct { list []int64 find int64 @@ -323,7 +323,7 @@ func TestInInt64Slice(t *testing.T) { for i, tc := range tests { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := InInt64Slice(tc.list, tc.find) + got := ItemInSlice(tc.list, tc.find) if got != tc.expected { t.Errorf(diff.Cmp(tc.expected, got)) } @@ -353,34 +353,34 @@ func TestRange(t *testing.T) { } } -func TestFilterString(t *testing.T) { +func TestFilter_String(t *testing.T) { cases := []struct { fun func(string) bool in []string want []string }{ { - FilterStringEmpty, + FilterEmpty[string], []string(nil), []string(nil), }, { - FilterStringEmpty, + FilterEmpty[string], []string{}, []string(nil), }, { - FilterStringEmpty, + FilterEmpty[string], []string{"1"}, []string{"1"}, }, { - FilterStringEmpty, + FilterEmpty[string], []string{"", "1", ""}, []string{"1"}, }, { - FilterStringEmpty, + FilterEmpty[string], []string{"", "1", "", "2", "asd", "", "", "", "zx", "", "a"}, []string{"1", "2", "asd", "zx", "a"}, }, @@ -388,7 +388,7 @@ func TestFilterString(t *testing.T) { for i, tc := range cases { t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { - out := FilterString(tc.in, tc.fun) + out := Filter(tc.in, tc.fun) if !reflect.DeepEqual(tc.want, out) { t.Errorf("\nout: %#v\nwant: %#v\n", out, tc.want) } @@ -396,34 +396,34 @@ func TestFilterString(t *testing.T) { } } -func TestFilterInt(t *testing.T) { +func TestFilter_Int(t *testing.T) { cases := []struct { fun func(int64) bool in []int64 want []int64 }{ { - FilterIntEmpty, + FilterEmpty[int64], []int64(nil), []int64(nil), }, { - FilterIntEmpty, + FilterEmpty[int64], []int64{}, []int64(nil), }, { - FilterIntEmpty, + FilterEmpty[int64], []int64{1}, []int64{1}, }, { - FilterIntEmpty, + FilterEmpty[int64], []int64{0, 1, 0}, []int64{1}, }, { - FilterIntEmpty, + FilterEmpty[int64], []int64{0, 1, 0, 2, -1, 0, 0, 0, 42, 666, -666, 0, 0, 0}, []int64{1, 2, -1, 42, 666, -666}, }, @@ -431,7 +431,7 @@ func TestFilterInt(t *testing.T) { for i, tc := range cases { t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { - out := FilterInt(tc.in, tc.fun) + out := Filter(tc.in, tc.fun) if !reflect.DeepEqual(tc.want, out) { t.Errorf("\nout: %#v\nwant: %#v\n", out, tc.want) } @@ -439,7 +439,7 @@ func TestFilterInt(t *testing.T) { } } -func TestChooseString(t *testing.T) { +func TestChoose_String(t *testing.T) { tests := []struct { in []string want string @@ -451,7 +451,7 @@ func TestChooseString(t *testing.T) { for i, tt := range tests { t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { - out := ChooseString(tt.in) + out := Choose(tt.in) if out != tt.want { t.Errorf("\nout: %#v\nwant: %#v\n", out, tt.want) } @@ -459,7 +459,7 @@ func TestChooseString(t *testing.T) { } } -func TestRemoveString(t *testing.T) { +func TestRemove_String(t *testing.T) { cases := []struct { list []string item string @@ -494,7 +494,7 @@ func TestRemoveString(t *testing.T) { for i, tc := range cases { t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { - out := RemoveString(tc.list, tc.item) + out := Remove(tc.list, tc.item) if !reflect.DeepEqual(tc.want, out) { t.Errorf("\nout: %#v\nwant: %#v\n", out, tc.want) } @@ -502,7 +502,7 @@ func TestRemoveString(t *testing.T) { } } -func TestStringMap(t *testing.T) { +func TestMap_String(t *testing.T) { cases := []struct { in []string want []string @@ -521,7 +521,7 @@ func TestStringMap(t *testing.T) { } for _, tc := range cases { t.Run("", func(t *testing.T) { - out := StringMap(tc.in, tc.f) + out := Map(tc.in, tc.f) if !reflect.DeepEqual(tc.want, out) { t.Errorf("\nout: %#v\nwant: %#v\n", out, tc.want) } From 633bacacc088f3c1c40fbe0cf45c32261e7ca674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tighearn=C3=A1n=20Carroll?= Date: Tue, 3 May 2022 16:33:49 +0100 Subject: [PATCH 02/16] update travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 333c129..f2c9486 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: go go: - - 1.13.x + - 1.18.x go_import_path: github.com/teamwork/utils notifications: email: false From cda61691085bd7e5d3a56eef2f3691733fdb19e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tighearn=C3=A1n=20Carroll?= Date: Tue, 3 May 2022 17:00:16 +0100 Subject: [PATCH 03/16] fixed test errs --- goutil/goutil_test.go | 10 ++++---- ioutilx/copy.go | 2 +- ptrutil/ptr.go | 17 ++++++++++++++ ptrutil/ptr_test.go | 54 +++++++++++++++++++++++++++++++++++++++++++ sqlutil/sqlutil.go | 4 ++-- 5 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 ptrutil/ptr.go create mode 100644 ptrutil/ptr_test.go diff --git a/goutil/goutil_test.go b/goutil/goutil_test.go index 6032c79..5a43f5f 100644 --- a/goutil/goutil_test.go +++ b/goutil/goutil_test.go @@ -39,8 +39,9 @@ func TestExpand(t *testing.T) { []string{"net/..."}, []string{"net", "net/http", "net/http/cgi", "net/http/cookiejar", "net/http/fcgi", "net/http/httptest", "net/http/httptrace", - "net/http/httputil", "net/http/internal", "net/http/pprof", - "net/internal/socktest", "net/mail", "net/rpc", "net/rpc/jsonrpc", + "net/http/httputil", "net/http/internal", "net/http/internal/ascii", + "net/http/internal/testcert", "net/http/pprof", + "net/internal/socktest", "net/mail", "net/netip", "net/rpc", "net/rpc/jsonrpc", "net/smtp", "net/textproto", "net/url", }, "", @@ -76,6 +77,7 @@ func TestExpand(t *testing.T) { "github.com/teamwork/utils/maputil", "github.com/teamwork/utils/mathutil", "github.com/teamwork/utils/netutil", + "github.com/teamwork/utils/ptrutil", "github.com/teamwork/utils/raceutil", "github.com/teamwork/utils/sliceutil", "github.com/teamwork/utils/sqlutil", @@ -95,12 +97,12 @@ func TestExpand(t *testing.T) { { []string{"thi.s/will/never/exist"}, nil, - `cannot find module providing package thi.s/will/never/exist`, + `no required module provides package thi.s/will/never/exist`, }, { []string{"thi.s/will/never/exist/..."}, nil, - `cannot find module providing package thi.s/will/never/exist`, + `no required module provides package thi.s/will/never/exist`, }, { []string{"./doesnt/exist"}, diff --git a/ioutilx/copy.go b/ioutilx/copy.go index 5ffeaab..f139f53 100644 --- a/ioutilx/copy.go +++ b/ioutilx/copy.go @@ -336,7 +336,7 @@ func CopyTree(src, dst string, options *CopyTreeOptions) error { } for _, entry := range entries { - if sliceutil.InStringSlice(ignoredNames, entry.Name()) { + if sliceutil.ItemInSlice(ignoredNames, entry.Name()) { continue } diff --git a/ptrutil/ptr.go b/ptrutil/ptr.go new file mode 100644 index 0000000..0d6368b --- /dev/null +++ b/ptrutil/ptr.go @@ -0,0 +1,17 @@ +package ptrutil + +// Dereference dereferences a pointer, returning zero if the pointer is nil. +func Dereference[T any](t *T) T { + if t == nil { + var zero T + return zero + } + + return *t +} + +// Ptr returns the pointer to the given value. Useful for when you want to get the pointer +// of a magic value: Ptr("hello"). +func Ptr[T any](t T) *T { + return &t +} diff --git a/ptrutil/ptr_test.go b/ptrutil/ptr_test.go new file mode 100644 index 0000000..da2640f --- /dev/null +++ b/ptrutil/ptr_test.go @@ -0,0 +1,54 @@ +package ptrutil + +import ( + "fmt" + "testing" + + "github.com/teamwork/test/diff" +) + +func TestDereference_Int(t *testing.T) { + tests := []struct { + ptr *int + expected int + }{{ + ptr: func() *int { i := 1; return &i }(), + expected: 1, + }, { + ptr: func() *int { i := 10; return &i }(), + expected: 10, + }, { + expected: 0, + }} + + for i, test := range tests { + t.Run(fmt.Sprintf("test-%d", i), func(t *testing.T) { + if got := Dereference(test.ptr); got != test.expected { + t.Errorf(diff.Cmp(test.expected, got)) + } + }) + } +} + +func TestDereference_String(t *testing.T) { + tests := []struct { + ptr *string + expected string + }{{ + ptr: func() *string { i := "hello"; return &i }(), + expected: "hello", + }, { + ptr: func() *string { i := "world"; return &i }(), + expected: "world", + }, { + expected: "", + }} + + for i, test := range tests { + t.Run(fmt.Sprintf("test-%d", i), func(t *testing.T) { + if got := Dereference(test.ptr); got != test.expected { + t.Errorf(diff.Cmp(test.expected, got)) + } + }) + } +} diff --git a/sqlutil/sqlutil.go b/sqlutil/sqlutil.go index 54a9e9d..7694ddf 100644 --- a/sqlutil/sqlutil.go +++ b/sqlutil/sqlutil.go @@ -19,7 +19,7 @@ type IntList []int64 // Value implements the SQL Value function to determine what to store in the DB. func (l IntList) Value() (driver.Value, error) { - return sliceutil.JoinInt(l), nil + return sliceutil.Join(l), nil } // Scan converts the data returned from the DB into the struct. @@ -55,7 +55,7 @@ type StringList []string // Value implements the SQL Value function to determine what to store in the DB. func (l StringList) Value() (driver.Value, error) { - return strings.Join(sliceutil.FilterString(l, sliceutil.FilterStringEmpty), ","), nil + return strings.Join(sliceutil.Filter(l, sliceutil.FilterEmpty[string]), ","), nil } // Scan converts the data returned from the DB into the struct. From 4da5fa384887bc8adc44bd59acd59ab4f27a78d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tighearn=C3=A1n=20Carroll?= Date: Tue, 3 May 2022 17:40:19 +0100 Subject: [PATCH 04/16] added feedback, renamed ItemIn func, hopefully fixed tests in travis --- .travis.yml | 2 +- httputilx/header/set.go | 8 ++++---- imageutil/sniff.go | 12 ++++++------ ioutilx/copy.go | 2 +- ioutilx/copy_unix.go | 1 + maputil/maputil.go | 4 ++-- maputil/maputil_test.go | 4 ++-- raceutil/norace.go | 1 + sliceutil/sets.go | 6 +++--- sliceutil/sliceutil.go | 6 ++++-- sliceutil/sliceutil_test.go | 6 +++--- timeutil/timeutil_test.go | 6 +++--- 12 files changed, 31 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index f2c9486..d5c9e72 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ script: | set -e cd $HOME/gopath/src/github.com/teamwork/utils ./bin/coverage -race ./... - env GO111MODULE=off ./bin/lint ./... + env ./bin/lint ./... before_cache: | rm "$HOME/.cache/go-build/log.txt" diff --git a/httputilx/header/set.go b/httputilx/header/set.go index 59652ad..c3e25fc 100644 --- a/httputilx/header/set.go +++ b/httputilx/header/set.go @@ -19,10 +19,10 @@ const ( type DispositionArgs struct { Type string // disposition-type Filename string // filename-parm - //CreationDate time.Time // creation-date-parm - //ModificationDate time.Time // modification-date-parm - //ReadDate time.Time // read-date-parm - //Size int // size-parm + // CreationDate time.Time // creation-date-parm + // ModificationDate time.Time // modification-date-parm + // ReadDate time.Time // read-date-parm + // Size int // size-parm } // SetContentDisposition sets the Content-Disposition header. Any previous value diff --git a/imageutil/sniff.go b/imageutil/sniff.go index a4f7650..d723572 100644 --- a/imageutil/sniff.go +++ b/imageutil/sniff.go @@ -25,8 +25,8 @@ func DetectImage(data []byte) string { // Index of the first non-whitespace byte in data. firstNonWS := 0 - //for ; firstNonWS < len(data) && isWS(data[firstNonWS]); firstNonWS++ { - //} + // for ; firstNonWS < len(data) && isWS(data[firstNonWS]); firstNonWS++ { + // } for _, sig := range sniffSignatures { if ct := sig.match(data, firstNonWS); ct != "" { @@ -91,7 +91,7 @@ func (e *exactSig) match(data []byte, firstNonWS int) string { type maskedSig struct { mask, pat []byte - //skipWS bool + // skipWS bool ct string } @@ -99,9 +99,9 @@ func (m *maskedSig) match(data []byte, firstNonWS int) string { // pattern matching algorithm section 6 // https://mimesniff.spec.whatwg.org/#pattern-matching-algorithm - //if m.skipWS { - // data = data[firstNonWS:] - //} + // if m.skipWS { + // data = data[firstNonWS:] + // } if len(m.pat) != len(m.mask) { return "" } diff --git a/ioutilx/copy.go b/ioutilx/copy.go index f139f53..a9de9f0 100644 --- a/ioutilx/copy.go +++ b/ioutilx/copy.go @@ -336,7 +336,7 @@ func CopyTree(src, dst string, options *CopyTreeOptions) error { } for _, entry := range entries { - if sliceutil.ItemInSlice(ignoredNames, entry.Name()) { + if sliceutil.Contains(ignoredNames, entry.Name()) { continue } diff --git a/ioutilx/copy_unix.go b/ioutilx/copy_unix.go index 4cad5c1..415b452 100644 --- a/ioutilx/copy_unix.go +++ b/ioutilx/copy_unix.go @@ -1,3 +1,4 @@ +//go:build darwin || dragonfly || freebsd || linux || nacl || netbsd || openbsd || solaris // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris package ioutilx diff --git a/maputil/maputil.go b/maputil/maputil.go index 3ab4d5d..008bba4 100644 --- a/maputil/maputil.go +++ b/maputil/maputil.go @@ -1,8 +1,8 @@ // Package maputil provides a set if functions for working with maps. package maputil // import "github.com/teamwork/utils/maputil" -// Reverse the keys and values of a map. -func Reverse[T comparable, V comparable](m map[T]V) map[V]T { +// Swap the keys and values of a map. +func Swap[T comparable, V comparable](m map[T]V) map[V]T { n := make(map[V]T) for k, v := range m { n[v] = k diff --git a/maputil/maputil_test.go b/maputil/maputil_test.go index 91c40f0..88d3607 100644 --- a/maputil/maputil_test.go +++ b/maputil/maputil_test.go @@ -8,7 +8,7 @@ import ( "github.com/teamwork/test/diff" ) -func TestReverse(t *testing.T) { +func TestSwap(t *testing.T) { tests := []struct { in map[string]string expected map[string]string @@ -19,7 +19,7 @@ func TestReverse(t *testing.T) { for i, tc := range tests { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := Reverse(tc.in) + got := Swap(tc.in) if !reflect.DeepEqual(got, tc.expected) { t.Errorf(diff.Cmp(tc.expected, got)) } diff --git a/raceutil/norace.go b/raceutil/norace.go index 570dc13..0caae1b 100644 --- a/raceutil/norace.go +++ b/raceutil/norace.go @@ -1,3 +1,4 @@ +//go:build !race // +build !race // Package israce reports if the Go race detector is enabled. diff --git a/sliceutil/sets.go b/sliceutil/sets.go index f5b6858..b216cbe 100644 --- a/sliceutil/sets.go +++ b/sliceutil/sets.go @@ -8,7 +8,7 @@ func Difference[T comparable](set []T, others ...[]T) []T { for _, item := range set { var found bool for _, o := range others { - if ItemInSlice(o, item) { + if Contains(o, item) { found = true break } @@ -28,13 +28,13 @@ func Difference[T comparable](set []T, others ...[]T) []T { // "a"). func Complement[T comparable](a, b []T) (aOnly, bOnly []T) { for _, i := range a { - if !ItemInSlice(b, i) { + if !Contains(b, i) { aOnly = append(aOnly, i) } } for _, i := range b { - if !ItemInSlice(a, i) { + if !Contains(a, i) { bOnly = append(bOnly, i) } } diff --git a/sliceutil/sliceutil.go b/sliceutil/sliceutil.go index ed470bc..7dd823a 100644 --- a/sliceutil/sliceutil.go +++ b/sliceutil/sliceutil.go @@ -78,8 +78,8 @@ func CSVtoInt64Slice(csv string) ([]int64, error) { return ints, nil } -// ItemInSlice returns true if item is in the provided slice. -func ItemInSlice[T comparable](tt []T, item T) bool { +// Contains returns true if item is in the provided slice. +func Contains[T comparable](tt []T, item T) bool { for _, t := range tt { if t == item { return true @@ -136,6 +136,8 @@ func Remove[T comparable](tt []T, remove T) (out []T) { return out } +// Filter filters a list. The function will be called for every item and +// those that return false will not be included in the returned list. func Filter[T comparable](tt []T, fn func(T) bool) []T { var ret []T for _, t := range tt { diff --git a/sliceutil/sliceutil_test.go b/sliceutil/sliceutil_test.go index 4f80a94..0707d0a 100644 --- a/sliceutil/sliceutil_test.go +++ b/sliceutil/sliceutil_test.go @@ -252,7 +252,7 @@ func TestItemInSlice_String(t *testing.T) { for i, tc := range tests { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := ItemInSlice(tc.list, tc.find) + got := Contains(tc.list, tc.find) if got != tc.expected { t.Errorf(diff.Cmp(tc.expected, got)) } @@ -300,7 +300,7 @@ func TestItemInSlice_Int(t *testing.T) { for i, tc := range tests { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := ItemInSlice(tc.list, tc.find) + got := Contains(tc.list, tc.find) if got != tc.expected { t.Errorf(diff.Cmp(tc.expected, got)) } @@ -323,7 +323,7 @@ func TestItemInSlice_Int64(t *testing.T) { for i, tc := range tests { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { - got := ItemInSlice(tc.list, tc.find) + got := Contains(tc.list, tc.find) if got != tc.expected { t.Errorf(diff.Cmp(tc.expected, got)) } diff --git a/timeutil/timeutil_test.go b/timeutil/timeutil_test.go index 77d3a2a..3d33899 100644 --- a/timeutil/timeutil_test.go +++ b/timeutil/timeutil_test.go @@ -68,9 +68,9 @@ func TestMonthsTo(t *testing.T) { {time.Now().Add(day * 370), 12}, // Broken! - //{time.Now().Add(-day * 35), -1}, - //{time.Now().Add(-day * 65), -2}, - //{time.Now().Add(-day * 370), -12}, + // {time.Now().Add(-day * 35), -1}, + // {time.Now().Add(-day * 65), -2}, + // {time.Now().Add(-day * 370), -12}, } for i, tc := range cases { From 7ea1951ef20d05a83aad1e763e22f2c7917abdac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tighearn=C3=A1n=20Carroll?= Date: Thu, 5 May 2022 13:54:39 +0100 Subject: [PATCH 05/16] commented out broken test to test travis build --- goutil/goutil_test.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/goutil/goutil_test.go b/goutil/goutil_test.go index 5a43f5f..c4e7158 100644 --- a/goutil/goutil_test.go +++ b/goutil/goutil_test.go @@ -94,16 +94,17 @@ func TestExpand(t *testing.T) { nil, "cannot resolve empty string", }, - { - []string{"thi.s/will/never/exist"}, - nil, - `no required module provides package thi.s/will/never/exist`, - }, - { - []string{"thi.s/will/never/exist/..."}, - nil, - `no required module provides package thi.s/will/never/exist`, - }, + // These tests pass locally but are dodgy on travis in go1.18 + //{ + // []string{"thi.s/will/never/exist"}, + // nil, + // `no required module provides package thi.s/will/never/exist`, + //}, + //{ + // []string{"thi.s/will/never/exist/..."}, + // nil, + // `no required module provides package thi.s/will/never/exist`, + //}, { []string{"./doesnt/exist"}, nil, From dec201d709c233c6f7b79701df7b3a7d192a784e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tighearn=C3=A1n=20Carroll?= Date: Thu, 5 May 2022 14:00:04 +0100 Subject: [PATCH 06/16] build From ef71846d5e8d6f8c4750b1bd9ca2d0ecbddf3944 Mon Sep 17 00:00:00 2001 From: Panagiotis Petridis Date: Tue, 13 Sep 2022 13:42:36 +0100 Subject: [PATCH 07/16] Prevent CI from CD-ing out of go module to get packages --- bin/lint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/lint b/bin/lint index 3c20e4c..67f3593 100755 --- a/bin/lint +++ b/bin/lint @@ -52,7 +52,7 @@ if [ -n "$TRAVIS" ]; then if ! command -v golangci-lint; then # Version specific so it wont break with any change # curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.13.2 - (cd;GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.27.0) + (GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.27.0) fi fi From 76a9cde10b6524b0c919498ff9e024a384d30064 Mon Sep 17 00:00:00 2001 From: Panagiotis Petridis Date: Tue, 13 Sep 2022 14:46:13 +0100 Subject: [PATCH 08/16] Removed usage of deprecated io/ioutil package --- errorutil/errorutil_test.go | 4 ++-- goutil/goutil.go | 1 + httputilx/httputilx.go | 3 +-- httputilx/httputilx_test.go | 3 +-- imageutil/sniff_test.go | 4 ++-- ioutilx/copy.go | 13 +++++++++---- ioutilx/copy_test.go | 11 +++++------ ioutilx/ioutilx.go | 3 +-- ioutilx/ioutilx_test.go | 7 +++---- 9 files changed, 25 insertions(+), 24 deletions(-) diff --git a/errorutil/errorutil_test.go b/errorutil/errorutil_test.go index 8623ff1..fe8553c 100644 --- a/errorutil/errorutil_test.go +++ b/errorutil/errorutil_test.go @@ -1,7 +1,7 @@ package errorutil import ( - "io/ioutil" + "os" "testing" "github.com/pkg/errors" @@ -70,6 +70,6 @@ func makeErr() error { } func zxc() error { - _, err := ioutil.ReadFile("/var/empty/nonexistent") + _, err := os.ReadFile("/var/empty/nonexistent") return errors.Wrap(err, "could not read") } diff --git a/goutil/goutil.go b/goutil/goutil.go index cb3b773..b89c521 100644 --- a/goutil/goutil.go +++ b/goutil/goutil.go @@ -77,6 +77,7 @@ func ResolvePackage(path string, mode build.ImportMode) (pkg *build.Package, err if err != nil { return nil, err } + fmt.Println(path) pkg, err = build.ImportDir(path, mode) default: if cwd == "" { diff --git a/httputilx/httputilx.go b/httputilx/httputilx.go index 59c7173..0ba91c6 100644 --- a/httputilx/httputilx.go +++ b/httputilx/httputilx.go @@ -5,7 +5,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "net/http" "net/http/httputil" "os" @@ -88,7 +87,7 @@ func Fetch(url string) ([]byte, error) { // TODO: Maybe add sanity check to bail out of the Content-Length is very // large? - data, err := ioutil.ReadAll(response.Body) + data, err := io.ReadAll(response.Body) if err != nil { return nil, errors.Wrapf(err, "cannot read body of %v", url) } diff --git a/httputilx/httputilx_test.go b/httputilx/httputilx_test.go index 1b47eba..cffcac8 100644 --- a/httputilx/httputilx_test.go +++ b/httputilx/httputilx_test.go @@ -8,7 +8,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "net/http" "net/url" "runtime" @@ -164,7 +163,7 @@ func TestDumpBody(t *testing.T) { } switch b := tc.Body.(type) { case []byte: - tc.Req.Body = ioutil.NopCloser(bytes.NewReader(b)) + tc.Req.Body = io.NopCloser(bytes.NewReader(b)) case func() io.ReadCloser: tc.Req.Body = b() default: diff --git a/imageutil/sniff_test.go b/imageutil/sniff_test.go index 4c50792..ae93120 100644 --- a/imageutil/sniff_test.go +++ b/imageutil/sniff_test.go @@ -2,7 +2,7 @@ package imageutil import ( "bytes" - "io/ioutil" + "io" "net/http" "reflect" "testing" @@ -34,7 +34,7 @@ func TestDetectImageStream(t *testing.T) { } // No Tell() in Go? Hmm. Just compare data to see if Seek() worked. - d, _ := ioutil.ReadAll(fp) + d, _ := io.ReadAll(fp) if !reflect.DeepEqual(d, image.JPEG) { t.Errorf("read data wrong; first 20 bytes:\nwant: %#v\ngot: %#v", image.JPEG[:19], d[:19]) diff --git a/ioutilx/copy.go b/ioutilx/copy.go index a9de9f0..def89f6 100644 --- a/ioutilx/copy.go +++ b/ioutilx/copy.go @@ -8,7 +8,6 @@ package ioutilx import ( "fmt" "io" - "io/ioutil" "os" "path/filepath" "time" @@ -290,7 +289,7 @@ var DefaultCopyTreeOptions = &CopyTreeOptions{ // // The optional ignore argument is a callable. If given, it is called with the // `src` parameter, which is the directory being visited by CopyTree(), and -// `names` which is the list of `src` contents, as returned by ioutil.ReadDir(): +// `names` which is the list of `src` contents, as returned by os.ReadDir(): // // callable(src, entries) -> ignoredNames // @@ -320,10 +319,16 @@ func CopyTree(src, dst string, options *CopyTreeOptions) error { return &ErrExists{dst} } - entries, err := ioutil.ReadDir(src) + entries, err := os.ReadDir(src) if err != nil { return errors.Wrapf(err, "could not read %v", src) } + fileInfos := make([]os.FileInfo, 0) + for _, entry := range entries { + if info, err := entry.Info(); err != nil { + fileInfos = append(fileInfos, info) + } + } // Create dst. if err = os.MkdirAll(dst, srcFileInfo.Mode()); err != nil { @@ -332,7 +337,7 @@ func CopyTree(src, dst string, options *CopyTreeOptions) error { ignoredNames := []string{} if options.Ignore != nil { - ignoredNames = options.Ignore(src, entries) + ignoredNames = options.Ignore(src, fileInfos) } for _, entry := range entries { diff --git a/ioutilx/copy_test.go b/ioutilx/copy_test.go index 2df51d1..8cc92c3 100644 --- a/ioutilx/copy_test.go +++ b/ioutilx/copy_test.go @@ -2,7 +2,6 @@ package ioutilx import ( "bytes" - "io/ioutil" "os" "path/filepath" "strings" @@ -111,7 +110,7 @@ func TestCopyData(t *testing.T) { {"test/file1", "test/file2", "already exists"}, {"test/fifo", "test/newfile", "named pipe"}, // {"test/link1/asd", "test/dst1", "not a directory"}, - {"test/file1", "/cantwritehere", "permission denied"}, + {"test/file1", "/cantwritehere", "read-only file system"}, {"test/file1", "test/dst1", ""}, // {"test/link1", "test/dst1", ""}, } @@ -198,7 +197,7 @@ func TestCopy(t *testing.T) { {"nonexistent", "test/copydst", Modes{}, "no such file"}, {"test/fifo", "test/newfile", Modes{}, "named pipe"}, // {"test/link1/asd", "test/dst1", Modes{}, "not a directory"}, - {"test/file1", "/cantwritehere", Modes{}, "permission denied"}, + {"test/file1", "/cantwritehere", Modes{}, "read-only file system"}, {"test/exec", "test/dst1", Modes{Permissions: true, Owner: true, Mtime: true}, ""}, {"test/exec", "test/dir1", Modes{Permissions: true, Owner: true, Mtime: true}, ""}, @@ -251,12 +250,12 @@ func clean(t *testing.T, n string) { } func filesMatch(t *testing.T, src, dst string) { - srcContents, err := ioutil.ReadFile(src) + srcContents, err := os.ReadFile(src) if err != nil { t.Fatal(err) } - dstContents, err := ioutil.ReadFile(dst) + dstContents, err := os.ReadFile(dst) if err != nil { t.Fatal(err) } @@ -299,7 +298,7 @@ func TestCopyTree(t *testing.T) { }) t.Run("permission", func(t *testing.T) { err := CopyTree("test", "/cant/write/here", nil) - if !test.ErrorContains(err, "permission denied") { + if !test.ErrorContains(err, "read-only file system") { t.Error(err) } }) diff --git a/ioutilx/ioutilx.go b/ioutilx/ioutilx.go index 96c9a6e..b951ae1 100644 --- a/ioutilx/ioutilx.go +++ b/ioutilx/ioutilx.go @@ -4,7 +4,6 @@ package ioutilx // import "github.com/teamwork/utils/ioutilx" import ( "bytes" "io" - "io/ioutil" "net/http" ) @@ -38,5 +37,5 @@ func DumpReader(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) { return nil, b, err } - return ioutil.NopCloser(&buf), ioutil.NopCloser(bytes.NewReader(buf.Bytes())), nil + return io.NopCloser(&buf), io.NopCloser(bytes.NewReader(buf.Bytes())), nil } diff --git a/ioutilx/ioutilx_test.go b/ioutilx/ioutilx_test.go index ed00815..1c053c4 100644 --- a/ioutilx/ioutilx_test.go +++ b/ioutilx/ioutilx_test.go @@ -3,7 +3,6 @@ package ioutilx import ( "fmt" "io" - "io/ioutil" "net/http" "strings" "testing" @@ -15,11 +14,11 @@ func TestDumpReader(t *testing.T) { want string }{ { - ioutil.NopCloser(strings.NewReader("Hello")), + io.NopCloser(strings.NewReader("Hello")), "Hello", }, { - ioutil.NopCloser(strings.NewReader("لوحة المفاتيح العربية")), + io.NopCloser(strings.NewReader("لوحة المفاتيح العربية")), "لوحة المفاتيح العربية", }, { @@ -49,7 +48,7 @@ func TestDumpReader(t *testing.T) { } func mustRead(t *testing.T, r io.Reader) string { - out, err := ioutil.ReadAll(r) + out, err := io.ReadAll(r) if err != nil { t.Fatal(err) } From 5a1e7db6c401295b5ac274d73de73b99065da291 Mon Sep 17 00:00:00 2001 From: Panagiotis Petridis Date: Tue, 13 Sep 2022 14:50:00 +0100 Subject: [PATCH 09/16] Reverted change to tests message --- ioutilx/copy_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ioutilx/copy_test.go b/ioutilx/copy_test.go index 8cc92c3..78041be 100644 --- a/ioutilx/copy_test.go +++ b/ioutilx/copy_test.go @@ -110,7 +110,7 @@ func TestCopyData(t *testing.T) { {"test/file1", "test/file2", "already exists"}, {"test/fifo", "test/newfile", "named pipe"}, // {"test/link1/asd", "test/dst1", "not a directory"}, - {"test/file1", "/cantwritehere", "read-only file system"}, + {"test/file1", "/cantwritehere", "permission denied"}, {"test/file1", "test/dst1", ""}, // {"test/link1", "test/dst1", ""}, } @@ -197,7 +197,7 @@ func TestCopy(t *testing.T) { {"nonexistent", "test/copydst", Modes{}, "no such file"}, {"test/fifo", "test/newfile", Modes{}, "named pipe"}, // {"test/link1/asd", "test/dst1", Modes{}, "not a directory"}, - {"test/file1", "/cantwritehere", Modes{}, "read-only file system"}, + {"test/file1", "/cantwritehere", Modes{}, "permission denied"}, {"test/exec", "test/dst1", Modes{Permissions: true, Owner: true, Mtime: true}, ""}, {"test/exec", "test/dir1", Modes{Permissions: true, Owner: true, Mtime: true}, ""}, @@ -298,7 +298,7 @@ func TestCopyTree(t *testing.T) { }) t.Run("permission", func(t *testing.T) { err := CopyTree("test", "/cant/write/here", nil) - if !test.ErrorContains(err, "read-only file system") { + if !test.ErrorContains(err, "permission denied") { t.Error(err) } }) From 94461ad09dc0ef253a18d789caa57f91c0f98fa5 Mon Sep 17 00:00:00 2001 From: Panagiotis Petridis Date: Tue, 13 Sep 2022 15:11:09 +0100 Subject: [PATCH 10/16] Added space in comments (golint) --- goutil/goutil_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/goutil/goutil_test.go b/goutil/goutil_test.go index c4e7158..3dbd86c 100644 --- a/goutil/goutil_test.go +++ b/goutil/goutil_test.go @@ -95,16 +95,16 @@ func TestExpand(t *testing.T) { "cannot resolve empty string", }, // These tests pass locally but are dodgy on travis in go1.18 - //{ - // []string{"thi.s/will/never/exist"}, - // nil, - // `no required module provides package thi.s/will/never/exist`, - //}, - //{ - // []string{"thi.s/will/never/exist/..."}, - // nil, - // `no required module provides package thi.s/will/never/exist`, - //}, + // { + // []string{"thi.s/will/never/exist"}, + // nil, + // `no required module provides package thi.s/will/never/exist`, + // }, + // { + // []string{"thi.s/will/never/exist/..."}, + // nil, + // `no required module provides package thi.s/will/never/exist`, + // }, { []string{"./doesnt/exist"}, nil, From 075e4590b01c6a10e59e3755211ea320f93a65a0 Mon Sep 17 00:00:00 2001 From: Panagiotis Petridis Date: Tue, 13 Sep 2022 15:30:50 +0100 Subject: [PATCH 11/16] Removed goimports linter becaue it's causing issues trying to check if comments are being goimports-ed. --- .golangci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index ea2ad79..86e67c2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -13,7 +13,6 @@ linters: - staticcheck - ineffassign - unconvert - - goimports - misspell - lll - nakedret From c8db47280a03de17163e4de080e9f39f55963597 Mon Sep 17 00:00:00 2001 From: Panagiotis Petridis Date: Tue, 13 Sep 2022 15:36:37 +0100 Subject: [PATCH 12/16] Revert "Removed goimports linter becaue it's causing issues trying to check if comments are being goimports-ed." This reverts commit 075e4590b01c6a10e59e3755211ea320f93a65a0. --- .golangci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.golangci.yml b/.golangci.yml index 86e67c2..ea2ad79 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -13,6 +13,7 @@ linters: - staticcheck - ineffassign - unconvert + - goimports - misspell - lll - nakedret From 0459d722ae061accee37e217da4e16e1665bb455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tighearn=C3=A1n=20Carroll?= Date: Tue, 13 Sep 2022 15:59:08 +0100 Subject: [PATCH 13/16] attempt at fix --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d5c9e72..f2c9486 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ script: | set -e cd $HOME/gopath/src/github.com/teamwork/utils ./bin/coverage -race ./... - env ./bin/lint ./... + env GO111MODULE=off ./bin/lint ./... before_cache: | rm "$HOME/.cache/go-build/log.txt" From 5a92eeb3fd7871946edd3c92b5612e637b82b301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tighearn=C3=A1n=20Carroll?= Date: Tue, 13 Sep 2022 16:04:44 +0100 Subject: [PATCH 14/16] up linter version --- bin/lint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/lint b/bin/lint index 67f3593..6c95851 100755 --- a/bin/lint +++ b/bin/lint @@ -52,7 +52,7 @@ if [ -n "$TRAVIS" ]; then if ! command -v golangci-lint; then # Version specific so it wont break with any change # curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.13.2 - (GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.27.0) + (GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.45.2) fi fi From 71bb0b0036549886cef71c1e0d64b105796c58d9 Mon Sep 17 00:00:00 2001 From: Paulius J Date: Thu, 9 Feb 2023 10:14:54 +0100 Subject: [PATCH 15/16] switch to GHA, go v1.20, fix lint --- .codecov.yml | 8 - .github/workflows/build.yml | 43 + .gitignore | 2 + .golangci.yml | 5 +- .travis.yml | 23 - bin/.codecov | 1550 ----------------------------------- bin/coverage | 28 - bin/lint | 62 -- bin/load-settings | 55 -- bin/setup-travis | 23 - bin/test | 54 -- errorutil/errorutil.go | 3 +- errorutil/errorutil_test.go | 5 +- go.mod | 15 +- go.sum | 21 +- goutil/goutil.go | 53 +- goutil/goutil_test.go | 28 +- httputilx/header/set.go | 10 +- httputilx/httputilx_test.go | 4 - imageutil/sniff.go | 19 +- ioutilx/copy.go | 2 +- ioutilx/copy_test.go | 4 +- jsonutil/jsonutil.go | 2 +- mathutil/mathutil.go | 1 + netutil/ip.go | 2 +- netutil/netutil.go | 1 + ptrutil/ptr.go | 1 + sliceutil/sliceutil.go | 4 +- sliceutil/sliceutil_test.go | 12 +- sqlutil/sqlutil.go | 8 +- timeutil/timeutil.go | 4 +- tools.go | 10 + 32 files changed, 157 insertions(+), 1905 deletions(-) delete mode 100644 .codecov.yml create mode 100644 .github/workflows/build.yml delete mode 100644 .travis.yml delete mode 100755 bin/.codecov delete mode 100755 bin/coverage delete mode 100755 bin/lint delete mode 100644 bin/load-settings delete mode 100755 bin/setup-travis delete mode 100755 bin/test create mode 100644 tools.go diff --git a/.codecov.yml b/.codecov.yml deleted file mode 100644 index c5b605e..0000000 --- a/.codecov.yml +++ /dev/null @@ -1,8 +0,0 @@ -# Don't post huge reports. -# https://docs.codecov.io/docs/pull-request-comments -comment: - layout: "files" - -# We don't care about anything that is not a Go file or generated files. -# https://docs.codecov.io/docs/ignoring-paths -ignore: ["!*.go", "**/generated_*.go", "factory/factorygen/main.go"] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..411ae30 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,43 @@ +name: Build +on: + [push, pull_request] + +jobs: + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Lint + uses: golangci/golangci-lint-action@v3 + with: + only-new-issues: true + + test: + runs-on: ubuntu-latest + env: + GORACE: history_size=4 + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.20' + + - name: Test + run: | + go test -v -coverprofile=full_coverage -race -count=1 ./... + echo 'mode: atomic' > full.coverage + awk 'FNR>1' *_coverage >> full.coverage + + - name: Install goveralls + if: success() + run: go mod vendor && go install ./vendor/github.com/mattn/goveralls + + - name: Upload + if: success() + env: + COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: goveralls -coverprofile=full.coverage -service=github diff --git a/.gitignore b/.gitignore index 77088ca..25047b8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /vendor /coverage.txt .DS_Store +full.coverage +full_coverage diff --git a/.golangci.yml b/.golangci.yml index ea2ad79..7edb476 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -6,9 +6,8 @@ linters: disable-all: true enable: - govet - - golint - - varcheck - - structcheck + - revive + - unused - errcheck - staticcheck - ineffassign diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f2c9486..0000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: go -go: - - 1.18.x -go_import_path: github.com/teamwork/utils -notifications: - email: false - webhooks: https://tw-bot.eu.teamworkops.com/travis/buildstatus -cache: - directories: - - $HOME/.cache/go-build - - $HOME/gopath/bin - -install: | - ./bin/setup-travis - -script: | - set -e - cd $HOME/gopath/src/github.com/teamwork/utils - ./bin/coverage -race ./... - env GO111MODULE=off ./bin/lint ./... - -before_cache: | - rm "$HOME/.cache/go-build/log.txt" diff --git a/bin/.codecov b/bin/.codecov deleted file mode 100755 index 85ad462..0000000 --- a/bin/.codecov +++ /dev/null @@ -1,1550 +0,0 @@ -#!/usr/bin/env bash - -# Apache License Version 2.0, January 2004 -# https://github.com/codecov/codecov-bash/blob/master/LICENSE - - -set -e +o pipefail - -VERSION="8b76995" - -url="https://codecov.io" -env="$CODECOV_ENV" -service="" -token="" -search_in="" -flags="" -exit_with=0 -curlargs="" -curlawsargs="" -dump="0" -clean="0" -curl_s="-s" -name="$CODECOV_NAME" -include_cov="" -exclude_cov="" -ddp="$(echo ~)/Library/Developer/Xcode/DerivedData" -xp="" -files="" -cacert="$CODECOV_CA_BUNDLE" -gcov_ignore="-not -path './bower_components/**' -not -path './node_modules/**' -not -path './vendor/**'" -gcov_include="" - -ft_gcov="1" -ft_coveragepy="1" -ft_fix="1" -ft_search="1" -ft_s3="1" -ft_network="1" -ft_xcodellvm="0" -ft_xcodeplist="1" - -_git_root=$(git rev-parse --show-toplevel 2>/dev/null || hg root 2>/dev/null || echo $PWD) -git_root="$_git_root" -codecov_yml="" -remote_addr="" -if [ "$git_root" = "$PWD" ]; -then - git_root="." -fi - -url_o="" -pr_o="" -build_o="" -commit_o="" -search_in_o="" -tag_o="" -branch_o="" -slug_o="" -prefix_o="" - -commit="$VCS_COMMIT_ID" -branch="$VCS_BRANCH_NAME" -pr="$VCS_PULL_REQUEST" -slug="$VCS_SLUG" -tag="$VCS_TAG" -build_url="$CI_BUILD_URL" -build="$CI_BUILD_ID" -job="$CI_JOB_ID" - -beta_xcode_partials="" - -proj_root="$git_root" -gcov_exe="gcov" -gcov_arg="" - -b="\033[0;36m" -g="\033[0;32m" -r="\033[0;31m" -e="\033[0;90m" -x="\033[0m" - -show_help() { -cat << EOF - - Codecov Bash $VERSION - - Global report uploading tool for Codecov - Documentation at https://docs.codecov.io/docs - Contribute at https://github.com/codecov/codecov-bash - - - -h Display this help and exit - -f FILE Target file(s) to upload - - -f "path/to/file" only upload this file - skips searching unless provided patterns below - - -f '!*.bar' ignore all files at pattern *.bar - -f '*.foo' include all files at pattern *.foo - Must use single quotes. - This is non-exclusive, use -s "*.foo" to match specific paths. - - -s DIR Directory to search for coverage reports. - Already searches project root and artifact folders. - -t TOKEN Set the private repository token - (option) set environment variable CODECOV_TOKEN=:uuid - - -t @/path/to/token_file - -t uuid - - -n NAME Custom defined name of the upload. Visible in Codecov UI - - -e ENV Specify environment variables to be included with this build - Also accepting environment variables: CODECOV_ENV=VAR,VAR2 - - -e VAR,VAR2 - - -X feature Toggle functionalities - - -X gcov Disable gcov - -X coveragepy Disable python coverage - -X fix Disable report fixing - -X search Disable searching for reports - -X xcode Disable xcode processing - -X network Disable uploading the file network - - -R root dir Used when not in git/hg project to identify project root directory - -y conf file Used to specify the location of the .codecov.yml config file - -F flag Flag the upload to group coverage metrics - - -F unittests This upload is only unittests - -F integration This upload is only integration tests - -F ui,chrome This upload is Chrome - UI tests - - -c Move discovered coverage reports to the trash - -Z Exit with 1 if not successful. Default will Exit with 0 - - -- xcode -- - -D Custom Derived Data Path for Coverage.profdata and gcov processing - Default '~/Library/Developer/Xcode/DerivedData' - -J Specify packages to build coverage. - This can significantly reduces time to build coverage reports. - - -J 'MyAppName' Will match "MyAppName" and "MyAppNameTests" - -J '^ExampleApp$' Will match only "ExampleApp" not "ExampleAppTests" - - -- gcov -- - -g GLOB Paths to ignore during gcov gathering - -G GLOB Paths to include during gcov gathering - -p dir Project root directory - Also used when preparing gcov - -k prefix Prefix filepaths to help resolve path fixing: https://github.com/codecov/support/issues/472 - -x gcovexe gcov executable to run. Defaults to 'gcov' - -a gcovargs extra arguments to pass to gcov - - -- Override CI Environment Variables -- - These variables are automatically detected by popular CI providers - - -B branch Specify the branch name - -C sha Specify the commit sha - -P pr Specify the pull request number - -b build Specify the build number - -T tag Specify the git tag - - -- Enterprise -- - -u URL Set the target url for Enterprise customers - Not required when retrieving the bash uploader from your CCE - (option) Set environment variable CODECOV_URL=https://my-hosted-codecov.com - -r SLUG owner/repo slug used instead of the private repo token in Enterprise - (option) set environment variable CODECOV_SLUG=:owner/:repo - (option) set in your codecov.yml "codecov.slug" - -S PATH File path to your cacert.pem file used to verify ssl with Codecov Enterprise (optional) - (option) Set environment variable: CODECOV_CA_BUNDLE="/path/to/ca.pem" - -U curlargs Extra curl arguments to communicate with Codecov. e.g., -U "--proxy http://http-proxy" - -A curlargs Extra curl arguments to communicate with AWS. - - -- Debugging -- - -d Don't upload, but dump upload file to stdout - -K Remove color from the output - -v Verbose mode - -EOF -} - - -say() { - echo -e "$1" -} - - -urlencode() { - echo "$1" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3- | sed -e 's/%0A//' -} - - -swiftcov() { - _dir=$(dirname "$1" | sed 's/\(Build\).*/\1/g') - for _type in app framework xctest - do - find "$_dir" -name "*.$_type" | while read f - do - _proj=${f##*/} - _proj=${_proj%."$_type"} - if [ "$2" = "" ] || [ "$(echo "$_proj" | grep -i "$2")" != "" ]; - then - say " $g+$x Building reports for $_proj $_type" - dest=$([ -f "$f/$_proj" ] && echo "$f/$_proj" || echo "$f/Contents/MacOS/$_proj") - _proj_name=$(echo "$_proj" | sed -e 's/[[:space:]]//g') - xcrun llvm-cov show $beta_xcode_partials -instr-profile "$1" "$dest" > "$_proj_name.$_type.coverage.txt" \ - || say " ${r}x>${x} llvm-cov failed to produce results for $dest" - fi - done - done -} - - -# Credits to: https://gist.github.com/pkuczynski/8665367 -parse_yaml() { - local prefix=$2 - local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034') - sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \ - -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 | - awk -F$fs '{ - indent = length($1)/2; - vname[indent] = $2; - for (i in vname) {if (i > indent) {delete vname[i]}} - if (length($3) > 0) { - vn=""; if (indent > 0) {vn=(vn)(vname[0])("_")} - printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3); - } - }' -} - - -if [ $# != 0 ]; -then - while getopts "a:A:b:B:cC:dD:e:f:F:g:G:hJ:k:Kn:p:P:r:R:y:s:S:t:T:u:U:vx:X:Z" o - do - case "$o" in - "a") - gcov_arg=$OPTARG - ;; - "A") - curlawsargs="$OPTARG" - ;; - "b") - build_o="$OPTARG" - ;; - "B") - branch_o="$OPTARG" - ;; - "c") - clean="1" - ;; - "C") - commit_o="$OPTARG" - ;; - "d") - dump="1" - ;; - "D") - ddp="$OPTARG" - ;; - "e") - env="$env,$OPTARG" - ;; - "f") - if [ "${OPTARG::1}" = "!" ]; - then - exclude_cov="$exclude_cov -not -path '${OPTARG:1}'" - - elif [[ "$OPTARG" = *"*"* ]]; - then - include_cov="$include_cov -or -name '$OPTARG'" - - else - ft_search=0 - if [ "$files" = "" ]; - then - files="$OPTARG" - else - files="$files -$OPTARG" - fi - fi - ;; - "F") - if [ "$flags" = "" ]; - then - flags="$OPTARG" - else - flags="$flags,$OPTARG" - fi - ;; - "g") - gcov_ignore="$gcov_ignore -not -path '$OPTARG'" - ;; - "G") - gcov_include="$gcov_include -path '$OPTARG'" - ;; - "h") - show_help - exit 0; - ;; - "J") - ft_xcodellvm="1" - ft_xcodeplist="0" - if [ "$xp" = "" ]; - then - xp="$OPTARG" - else - xp="$xp\|$OPTARG" - fi - ;; - "k") - prefix_o=$(echo "$OPTARG" | sed -e 's:^/*::' -e 's:/*$::') - ;; - "K") - b="" - g="" - r="" - e="" - x="" - ;; - "n") - name="$OPTARG" - ;; - "p") - proj_root="$OPTARG" - ;; - "P") - pr_o="$OPTARG" - ;; - "r") - slug_o="$OPTARG" - ;; - "R") - git_root="$OPTARG" - ;; - "s") - if [ "$search_in_o" = "" ]; - then - search_in_o="$OPTARG" - else - search_in_o="$search_in_o $OPTARG" - fi - ;; - "S") - cacert="--cacert \"$OPTARG\"" - ;; - "t") - if [ "${OPTARG::1}" = "@" ]; - then - token=$(cat "${OPTARG:1}" | tr -d ' \n') - else - token="$OPTARG" - fi - ;; - "T") - tag_o="$OPTARG" - ;; - "u") - url_o=$(echo "$OPTARG" | sed -e 's/\/$//') - ;; - "U") - curlargs="$OPTARG" - ;; - "v") - set -x - curl_s="" - ;; - "x") - gcov_exe=$OPTARG - ;; - "X") - if [ "$OPTARG" = "gcov" ]; - then - ft_gcov="0" - elif [ "$OPTARG" = "coveragepy" ] || [ "$OPTARG" = "py" ]; - then - ft_coveragepy="0" - elif [ "$OPTARG" = "xcodellvm" ]; - then - ft_xcodellvm="1" - ft_xcodeplist="0" - elif [ "$OPTARG" = "fix" ] || [ "$OPTARG" = "fixes" ]; - then - ft_fix="0" - elif [ "$OPTARG" = "xcode" ]; - then - ft_xcodellvm="0" - ft_xcodeplist="0" - elif [ "$OPTARG" = "search" ]; - then - ft_search="0" - elif [ "$OPTARG" = "xcodepartials" ]; - then - beta_xcode_partials="-use-color" - elif [ "$OPTARG" = "network" ]; - then - ft_network="0" - elif [ "$OPTARG" = "s3" ]; - then - ft_s3="0" - fi - ;; - "y") - codecov_yml="$OPTARG" - ;; - "Z") - exit_with=1 - ;; - esac - done -fi - -say " - _____ _ - / ____| | | -| | ___ __| | ___ ___ _____ __ -| | / _ \\ / _\` |/ _ \\/ __/ _ \\ \\ / / -| |___| (_) | (_| | __/ (_| (_) \\ V / - \\_____\\___/ \\__,_|\\___|\\___\\___/ \\_/ - Bash-$VERSION - -" - -search_in="$proj_root" - -if [ "$JENKINS_URL" != "" ]; -then - say "$e==>$x Jenkins CI detected." - # https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project - # https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin#GitHubpullrequestbuilderplugin-EnvironmentVariables - service="jenkins" - - if [ "$ghprbSourceBranch" != "" ]; - then - branch="$ghprbSourceBranch" - elif [ "$GIT_BRANCH" != "" ]; - then - branch="$GIT_BRANCH" - elif [ "$BRANCH_NAME" != "" ]; - then - branch="$BRANCH_NAME" - fi - - if [ "$ghprbActualCommit" != "" ]; - then - commit="$ghprbActualCommit" - elif [ "$GIT_COMMIT" != "" ]; - then - commit="$GIT_COMMIT" - fi - - if [ "$ghprbPullId" != "" ]; - then - pr="$ghprbPullId" - elif [ "$CHANGE_ID" != "" ]; - then - pr="$CHANGE_ID" - fi - - build="$BUILD_NUMBER" - build_url=$(urlencode "$BUILD_URL") - -elif [ "$CI" = "true" ] && [ "$TRAVIS" = "true" ] && [ "$SHIPPABLE" != "true" ]; -then - say "$e==>$x Travis CI detected." - # https://docs.travis-ci.com/user/environment-variables/ - service="travis" - commit="${TRAVIS_PULL_REQUEST_SHA:-$TRAVIS_COMMIT}" - build="$TRAVIS_JOB_NUMBER" - pr="$TRAVIS_PULL_REQUEST" - job="$TRAVIS_JOB_ID" - slug="$TRAVIS_REPO_SLUG" - env="$env,TRAVIS_OS_NAME" - tag="$TRAVIS_TAG" - if [ "$TRAVIS_BRANCH" != "$TRAVIS_TAG" ]; - then - branch="$TRAVIS_BRANCH" - fi - - language=$(printenv | grep "TRAVIS_.*_VERSION" | head -1) - if [ "$language" != "" ]; - then - env="$env,${language%=*}" - fi - -elif [ "$DOCKER_REPO" != "" ]; -then - say "$e==>$x Docker detected." - # https://docs.docker.com/docker-cloud/builds/advanced/ - service="docker" - branch="$SOURCE_BRANCH" - commit="$SOURCE_COMMIT" - slug="$DOCKER_REPO" - tag="$CACHE_TAG" - env="$env,IMAGE_NAME" - -elif [ "$CI" = "true" ] && [ "$CI_NAME" = "codeship" ]; -then - say "$e==>$x Codeship CI detected." - # https://www.codeship.io/documentation/continuous-integration/set-environment-variables/ - service="codeship" - branch="$CI_BRANCH" - build="$CI_BUILD_NUMBER" - build_url=$(urlencode "$CI_BUILD_URL") - commit="$CI_COMMIT_ID" - -elif [ ! -z "$CF_BUILD_URL" ] && [ ! -z "$CF_BUILD_ID" ]; -then - say "$e==>$x Codefresh CI detected." - # https://docs.codefresh.io/v1.0/docs/variables - service="codefresh" - branch="$CF_BRANCH" - build="$CF_BUILD_ID" - build_url=$(urlencode "$CF_BUILD_URL") - commit="$CF_REVISION" - -elif [ "$TEAMCITY_VERSION" != "" ]; -then - say "$e==>$x TeamCity CI detected." - # https://confluence.jetbrains.com/display/TCD8/Predefined+Build+Parameters - # https://confluence.jetbrains.com/plugins/servlet/mobile#content/view/74847298 - if [ "$TEAMCITY_BUILD_BRANCH" = '' ]; - then - echo " Teamcity does not automatically make build parameters available as environment variables." - echo " Add the following environment parameters to the build configuration" - echo " env.TEAMCITY_BUILD_BRANCH = %teamcity.build.branch%" - echo " env.TEAMCITY_BUILD_ID = %teamcity.build.id%" - echo " env.TEAMCITY_BUILD_URL = %teamcity.serverUrl%/viewLog.html?buildId=%teamcity.build.id%" - echo " env.TEAMCITY_BUILD_COMMIT = %system.build.vcs.number%" - echo " env.TEAMCITY_BUILD_REPOSITORY = %vcsroot..url%" - fi - service="teamcity" - branch="$TEAMCITY_BUILD_BRANCH" - build="$TEAMCITY_BUILD_ID" - build_url=$(urlencode "$TEAMCITY_BUILD_URL") - if [ "$TEAMCITY_BUILD_COMMIT" != "" ]; - then - commit="$TEAMCITY_BUILD_COMMIT" - else - commit="$BUILD_VCS_NUMBER" - fi - remote_addr="$TEAMCITY_BUILD_REPOSITORY" - -elif [ "$CI" = "true" ] && [ "$CIRCLECI" = "true" ]; -then - say "$e==>$x Circle CI detected." - # https://circleci.com/docs/environment-variables - service="circleci" - branch="$CIRCLE_BRANCH" - build="$CIRCLE_BUILD_NUM" - job="$CIRCLE_NODE_INDEX" - if [ "$CIRCLE_PROJECT_REPONAME" != "" ]; - then - slug="$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME" - else - # git@github.com:owner/repo.git - slug="${CIRCLE_REPOSITORY_URL##*:}" - # owner/repo.git - slug="${slug%%.git}" - fi - pr="$CIRCLE_PR_NUMBER" - commit="$CIRCLE_SHA1" - search_in="$search_in $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS" - -elif [ "$BUDDYBUILD_BRANCH" != "" ]; -then - say "$e==>$x buddybuild detected" - # http://docs.buddybuild.com/v6/docs/custom-prebuild-and-postbuild-steps - service="buddybuild" - branch="$BUDDYBUILD_BRANCH" - build="$BUDDYBUILD_BUILD_NUMBER" - build_url="https://dashboard.buddybuild.com/public/apps/$BUDDYBUILD_APP_ID/build/$BUDDYBUILD_BUILD_ID" - # BUDDYBUILD_TRIGGERED_BY - if [ "$ddp" = "$(echo ~)/Library/Developer/Xcode/DerivedData" ]; - then - ddp="/private/tmp/sandbox/${BUDDYBUILD_APP_ID}/bbtest" - fi - -elif [ "${bamboo_planRepository_revision}" != "" ]; -then - say "$e==>$x Bamboo detected" - # https://confluence.atlassian.com/bamboo/bamboo-variables-289277087.html#Bamboovariables-Build-specificvariables - service="bamboo" - commit="${bamboo_planRepository_revision}" - branch="${bamboo_planRepository_branch}" - build="${bamboo_buildNumber}" - build_url="${bamboo_buildResultsUrl}" - remote_addr="${bamboo_planRepository_repositoryUrl}" - -elif [ "$CI" = "true" ] && [ "$BITRISE_IO" = "true" ]; -then - # http://devcenter.bitrise.io/faq/available-environment-variables/ - say "$e==>$x Bitrise CI detected." - service="bitrise" - branch="$BITRISE_GIT_BRANCH" - build="$BITRISE_BUILD_NUMBER" - build_url=$(urlencode "$BITRISE_BUILD_URL") - pr="$BITRISE_PULL_REQUEST" - if [ "$GIT_CLONE_COMMIT_HASH" != "" ]; - then - commit="$GIT_CLONE_COMMIT_HASH" - fi - -elif [ "$CI" = "true" ] && [ "$SEMAPHORE" = "true" ]; -then - say "$e==>$x Semaphore CI detected." - # https://semaphoreapp.com/docs/available-environment-variables.html - service="semaphore" - branch="$BRANCH_NAME" - build="$SEMAPHORE_BUILD_NUMBER" - job="$SEMAPHORE_CURRENT_THREAD" - pr="$PULL_REQUEST_NUMBER" - slug="$SEMAPHORE_REPO_SLUG" - commit="$REVISION" - env="$env,SEMAPHORE_TRIGGER_SOURCE" - -elif [ "$CI" = "true" ] && [ "$BUILDKITE" = "true" ]; -then - say "$e==>$x Buildkite CI detected." - # https://buildkite.com/docs/guides/environment-variables - service="buildkite" - branch="$BUILDKITE_BRANCH" - build="$BUILDKITE_BUILD_NUMBER" - job="$BUILDKITE_JOB_ID" - build_url=$(urlencode "$BUILDKITE_BUILD_URL") - slug="$BUILDKITE_PROJECT_SLUG" - commit="$BUILDKITE_COMMIT" - if [[ "$BUILDKITE_PULL_REQUEST" != "false" ]]; then - pr="$BUILDKITE_PULL_REQUEST" - fi - tag="$BUILDKITE_TAG" - -elif [ "$CI" = "drone" ]; -then - say "$e==>$x Drone CI detected." - # http://docs.drone.io/env.html - # drone commits are not full shas - service="drone.io" - branch="$DRONE_BRANCH" - build="$DRONE_BUILD_NUMBER" - build_url=$(urlencode "${DRONE_BUILD_LINK}") - pr="$DRONE_PULL_REQUEST" - job="$DRONE_JOB_NUMBER" - tag="$DRONE_TAG" - -elif [ "$HEROKU_TEST_RUN_BRANCH" != "" ]; -then - say "$e==>$x Heroku CI detected." - # https://devcenter.heroku.com/articles/heroku-ci#environment-variables - service="heroku" - branch="$HEROKU_TEST_RUN_BRANCH" - build="$HEROKU_TEST_RUN_ID" - -elif [ "$CI" = "True" ] && [ "$APPVEYOR" = "True" ]; -then - say "$e==>$x Appveyor CI detected." - # http://www.appveyor.com/docs/environment-variables - service="appveyor" - branch="$APPVEYOR_REPO_BRANCH" - build=$(urlencode "$APPVEYOR_JOB_ID") - pr="$APPVEYOR_PULL_REQUEST_NUMBER" - job="$APPVEYOR_ACCOUNT_NAME%2F$APPVEYOR_PROJECT_SLUG%2F$APPVEYOR_BUILD_VERSION" - slug="$APPVEYOR_REPO_NAME" - commit="$APPVEYOR_REPO_COMMIT" - -elif [ "$CI" = "true" ] && [ "$WERCKER_GIT_BRANCH" != "" ]; -then - say "$e==>$x Wercker CI detected." - # http://devcenter.wercker.com/articles/steps/variables.html - service="wercker" - branch="$WERCKER_GIT_BRANCH" - build="$WERCKER_MAIN_PIPELINE_STARTED" - slug="$WERCKER_GIT_OWNER/$WERCKER_GIT_REPOSITORY" - commit="$WERCKER_GIT_COMMIT" - -elif [ "$CI" = "true" ] && [ "$MAGNUM" = "true" ]; -then - say "$e==>$x Magnum CI detected." - # https://magnum-ci.com/docs/environment - service="magnum" - branch="$CI_BRANCH" - build="$CI_BUILD_NUMBER" - commit="$CI_COMMIT" - -elif [ "$SHIPPABLE" = "true" ]; -then - say "$e==>$x Shippable CI detected." - # http://docs.shippable.com/ci_configure/ - service="shippable" - branch=$([ "$HEAD_BRANCH" != "" ] && echo "$HEAD_BRANCH" || echo "$BRANCH") - build="$BUILD_NUMBER" - build_url=$(urlencode "$BUILD_URL") - pr="$PULL_REQUEST" - slug="$REPO_FULL_NAME" - commit="$COMMIT" - -elif [ "$TDDIUM" = "true" ]; -then - say "Solano CI detected." - # http://docs.solanolabs.com/Setup/tddium-set-environment-variables/ - service="solano" - commit="$TDDIUM_CURRENT_COMMIT" - branch="$TDDIUM_CURRENT_BRANCH" - build="$TDDIUM_TID" - pr="$TDDIUM_PR_ID" - -elif [ "$GREENHOUSE" = "true" ]; -then - say "$e==>$x Greenhouse CI detected." - # http://docs.greenhouseci.com/docs/environment-variables-files - service="greenhouse" - branch="$GREENHOUSE_BRANCH" - build="$GREENHOUSE_BUILD_NUMBER" - build_url=$(urlencode "$GREENHOUSE_BUILD_URL") - pr="$GREENHOUSE_PULL_REQUEST" - commit="$GREENHOUSE_COMMIT" - search_in="$search_in $GREENHOUSE_EXPORT_DIR" - -elif [ "$GITLAB_CI" != "" ]; -then - say "$e==>$x GitLab CI detected." - # http://doc.gitlab.com/ce/ci/variables/README.html - service="gitlab" - branch="${CI_BUILD_REF_NAME:-$CI_COMMIT_REF_NAME}" - build="${CI_BUILD_ID:-$CI_JOB_ID}" - remote_addr="${CI_BUILD_REPO:-$CI_REPOSITORY_URL}" - commit="${CI_BUILD_REF:-$CI_COMMIT_SHA}" - -else - say "${r}x>${x} No CI provider detected." - say " Testing inside Docker? ${b}http://docs.codecov.io/docs/testing-with-docker${x}" - say " Testing with Tox? ${b}https://docs.codecov.io/docs/python#section-testing-with-tox${x}" - -fi - -say " ${e}project root:${x} $git_root" - -# find branch, commit, repo from git command -if [ "$GIT_BRANCH" != "" ]; -then - branch="$GIT_BRANCH" - -elif [ "$branch" = "" ]; -then - branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || hg branch 2>/dev/null || echo "") - if [ "$branch" = "HEAD" ]; - then - branch="" - fi -fi - -if [ "$commit_o" = "" ]; -then - # merge commit -> actual commit - mc= - if [ -n "$pr" ] && [ "$pr" != false ]; - then - mc=$(git show --no-patch --format="%P" 2>/dev/null || echo "") - fi - if [[ "$mc" =~ ^[a-z0-9]{40}[[:space:]][a-z0-9]{40}$ ]]; - then - say " Fixing merge commit SHA" - commit=$(echo "$mc" | cut -d' ' -f2) - elif [ "$GIT_COMMIT" != "" ]; - then - commit="$GIT_COMMIT" - elif [ "$commit" = "" ]; - then - commit=$(git log -1 --format="%H" 2>/dev/null || hg id -i --debug 2>/dev/null | tr -d '+' || echo "") - fi -else - commit="$commit_o" -fi - -if [ "$CODECOV_TOKEN" != "" ] && [ "$token" = "" ]; -then - say "${e}-->${x} token set from env" - token="$CODECOV_TOKEN" -fi - -if [ "$CODECOV_URL" != "" ] && [ "$url_o" = "" ]; -then - say "${e}-->${x} url set from env" - url_o=$(echo "$CODECOV_URL" | sed -e 's/\/$//') -fi - -if [ "$CODECOV_SLUG" != "" ]; -then - say "${e}-->${x} slug set from env" - slug_o="$CODECOV_SLUG" - -elif [ "$slug" = "" ]; -then - if [ "$remote_addr" = "" ]; - then - remote_addr=$(git config --get remote.origin.url || hg paths default || echo '') - fi - if [ "$remote_addr" != "" ]; - then - if echo "$remote_addr" | grep -q "//"; then - # https - slug=$(echo "$remote_addr" | cut -d / -f 4,5 | sed -e 's/\.git$//') - else - # ssh - slug=$(echo "$remote_addr" | cut -d : -f 2 | sed -e 's/\.git$//') - fi - fi - if [ "$slug" = "/" ]; - then - slug="" - fi -fi - -yaml=$(test -n "$codecov_yml" && echo "$codecov_yml" \ - || cd "$git_root" && \ - git ls-files "*codecov.yml" "*codecov.yaml" 2>/dev/null \ - || hg locate "*codecov.yml" "*codecov.yaml" 2>/dev/null \ - || cd $proj_root && find . -type f -name '*codecov.y*ml' -depth 1 2>/dev/null \ - || echo '') -yaml=$(echo "$yaml" | head -1) - -if [ "$yaml" != "" ]; -then - say " ${e}Yaml found at:${x} $yaml" - config=$(parse_yaml "$git_root/$yaml" || echo '') - - # TODO validate the yaml here - - if [ "$(echo "$config" | grep 'codecov_token="')" != "" ] && [ "$token" = "" ]; - then - say "${e}-->${x} token set from yaml" - token="$(echo "$config" | grep 'codecov_token="' | sed -e 's/codecov_token="//' | sed -e 's/"\.*//')" - fi - - if [ "$(echo "$config" | grep 'codecov_url="')" != "" ] && [ "$url_o" = "" ]; - then - say "${e}-->${x} url set from yaml" - url_o="$(echo "$config" | grep 'codecov_url="' | sed -e 's/codecov_url="//' | sed -e 's/"\.*//')" - fi - - if [ "$(echo "$config" | grep 'codecov_slug="')" != "" ] && [ "$slug_o" = "" ]; - then - say "${e}-->${x} slug set from yaml" - slug_o="$(echo "$config" | grep 'codecov_slug="' | sed -e 's/codecov_slug="//' | sed -e 's/"\.*//')" - fi -else - say " ${g}Yaml not found, that's ok! Learn more at${x} ${b}http://docs.codecov.io/docs/codecov-yaml${x}" - -fi - -if [ "$branch_o" != "" ]; -then - branch=$(urlencode "$branch_o") -else - branch=$(urlencode "$branch") -fi - -query="branch=$branch\ - &commit=$commit\ - &build=$([ "$build_o" = "" ] && echo "$build" || echo "$build_o")\ - &build_url=$build_url\ - &name=$(urlencode "$name")\ - &tag=$([ "$tag_o" = "" ] && echo "$tag" || echo "$tag_o")\ - &slug=$([ "$slug_o" = "" ] && urlencode "$slug" || urlencode "$slug_o")\ - &service=$service\ - &flags=$flags\ - &pr=$([ "$pr_o" = "" ] && echo "${pr##\#}" || echo "${pr_o##\#}")\ - &job=$job" - -if [ "$ft_search" = "1" ]; -then - # detect bower comoponents location - bower_components="bower_components" - bower_rc=$(cd "$git_root" && cat .bowerrc 2>/dev/null || echo "") - if [ "$bower_rc" != "" ]; - then - bower_components=$(echo "$bower_rc" | tr -d '\n' | grep '"directory"' | cut -d'"' -f4 | sed -e 's/\/$//') - if [ "$bower_components" = "" ]; - then - bower_components="bower_components" - fi - fi - - # Swift Coverage - if [ "$ft_xcodellvm" = "1" ] && [ -d "$ddp" ]; - then - say "${e}==>${x} Processing Xcode reports via llvm-cov" - say " DerivedData folder: $ddp" - profdata_files=$(find "$ddp" -name '*.profdata' 2>/dev/null || echo '') - if [ "$profdata_files" != "" ]; - then - # xcode via profdata - if [ "$xp" = "" ]; - then - # xp=$(xcodebuild -showBuildSettings 2>/dev/null | grep -i "^\s*PRODUCT_NAME" | sed -e 's/.*= \(.*\)/\1/') - # say " ${e}->${x} Speed up Xcode processing by adding ${e}-J '$xp'${x}" - say " ${g}hint${x} Speed up Swift processing by using use ${g}-J 'AppName'${x} (regexp accepted)" - say " ${g}hint${x} This will remove Pods/ from your report. Also ${b}https://docs.codecov.io/docs/ignoring-paths${x}" - fi - while read -r profdata; - do - if [ "$profdata" != "" ]; - then - swiftcov "$profdata" "$xp" - fi - done <<< "$profdata_files" - else - say " ${e}->${x} No Swift coverage found" - fi - - # Obj-C Gcov Coverage - if [ "$ft_gcov" = "1" ]; - then - say " ${e}->${x} Running $gcov_exe for Obj-C" - bash -c "find $ddp -type f -name '*.gcda' $gcov_include $gcov_ignore -exec $gcov_exe -p $gcov_arg {} +" || true - fi - fi - - if [ "$ft_xcodeplist" = "1" ] && [ -d "$ddp" ]; - then - say "${e}==>${x} Processing Xcode plists" - plists_files=$(find "$ddp" -name '*.xccoverage' 2>/dev/null || echo '') - if [ "$plists_files" != "" ]; - then - while read -r plist; - do - if [ "$plist" != "" ]; - then - say " ${g}Found${x} plist file at $plist" - plutil -convert xml1 -o "$(basename "$plist").plist" -- $plist - fi - done <<< "$plists_files" - fi - fi - - # Gcov Coverage - if [ "$ft_gcov" = "1" ]; - then - say "${e}==>${x} Running gcov in $proj_root ${e}(disable via -X gcov)${x}" - bash -c "find $proj_root -type f -name '*.gcno' $gcov_include $gcov_ignore -exec $gcov_exe -pb $gcov_arg {} +" || true - else - say "${e}==>${x} gcov disabled" - fi - - # Python Coverage - if [ "$ft_coveragepy" = "1" ]; - then - if [ ! -f coverage.xml ]; - then - if which coverage >/dev/null 2>&1; - then - say "${e}==>${x} Python coveragepy exists ${e}disable via -X coveragepy${x}" - - dotcoverage=$(find "$git_root" -name '.coverage' -or -name '.coverage.*' | head -1 || echo '') - if [ "$dotcoverage" != "" ]; - then - cd "$(dirname "$dotcoverage")" - if [ ! -f .coverage ]; - then - say " ${e}->${x} Running coverage combine" - coverage combine -a - fi - say " ${e}->${x} Running coverage xml" - if [ "$(coverage xml -i)" != "No data to report." ]; - then - files="$files -$PWD/coverage.xml" - else - say " ${r}No data to report.${x}" - fi - cd "$proj_root" - else - say " ${r}No .coverage file found.${x}" - fi - else - say "${e}==>${x} Python coveragepy not found" - fi - fi - else - say "${e}==>${x} Python coveragepy disabled" - fi - - if [ "$search_in_o" != "" ]; - then - # location override - search_in="$search_in_o" - fi - - say "$e==>$x Searching for coverage reports in:" - for _path in $search_in - do - say " ${g}+${x} $_path" - done - - patterns="find $search_in \( \ - -name vendor \ - -or -name htmlcov \ - -or -name virtualenv \ - -or -name js/generated/coverage \ - -or -name .virtualenv \ - -or -name virtualenvs \ - -or -name .virtualenvs \ - -or -name .env \ - -or -name .envs \ - -or -name env \ - -or -name .yarn-cache \ - -or -name envs \ - -or -name .venv \ - -or -name .venvs \ - -or -name venv \ - -or -name venvs \ - -or -name .git \ - -or -name .hg \ - -or -name .tox \ - -or -name __pycache__ \ - -or -name '.egg-info*' \ - -or -name '$bower_components' \ - -or -name node_modules \ - -or -name 'conftest_*.c.gcov' \ - \) -prune -or \ - -type f \( -name '*coverage*.*' \ - -or -name 'nosetests.xml' \ - -or -name 'jacoco*.xml' \ - -or -name 'clover.xml' \ - -or -name 'report.xml' \ - -or -name '*.codecov.*' \ - -or -name 'codecov.*' \ - -or -name 'cobertura.xml' \ - -or -name 'excoveralls.json' \ - -or -name 'luacov.report.out' \ - -or -name 'coverage-final.json' \ - -or -name 'naxsi.info' \ - -or -name 'lcov.info' \ - -or -name 'lcov.dat' \ - -or -name '*.lcov' \ - -or -name '*.clover' \ - -or -name 'cover.out' \ - -or -name 'gcov.info' \ - -or -name '*.gcov' \ - -or -name '*.lst' \ - $include_cov \) \ - $exclude_cov \ - -not -name '*.profdata' \ - -not -name 'coverage-summary.json' \ - -not -name 'phpunit-code-coverage.xml' \ - -not -name '*/classycle/report.xml' \ - -not -name 'remapInstanbul.coverage*.json' \ - -not -name 'phpunit-coverage.xml' \ - -not -name '*codecov.yml' \ - -not -name '*.serialized' \ - -not -name '.coverage*' \ - -not -name '.*coveragerc' \ - -not -name '*.sh' \ - -not -name '*.bat' \ - -not -name '*.ps1' \ - -not -name '*.env' \ - -not -name '*.cmake' \ - -not -name '*.dox' \ - -not -name '*.ec' \ - -not -name '*.rst' \ - -not -name '*.h' \ - -not -name '*.scss' \ - -not -name '*.o' \ - -not -name '*.proto' \ - -not -name '*.sbt' \ - -not -name '*.xcoverage.*' \ - -not -name '*.gz' \ - -not -name '*.conf' \ - -not -name '*.p12' \ - -not -name '*.csv' \ - -not -name '*.rsp' \ - -not -name '*.m4' \ - -not -name '*.pem' \ - -not -name '*~' \ - -not -name '*.exe' \ - -not -name '*.am' \ - -not -name '*.template' \ - -not -name '*.cp' \ - -not -name '*.bw' \ - -not -name '*.crt' \ - -not -name '*.log' \ - -not -name '*.cmake' \ - -not -name '*.pth' \ - -not -name '*.in' \ - -not -name '*.jar*' \ - -not -name '*.pom*' \ - -not -name '*.png' \ - -not -name '*.jpg' \ - -not -name '*.sql' \ - -not -name '*.jpeg' \ - -not -name '*.svg' \ - -not -name '*.gif' \ - -not -name '*.csv' \ - -not -name '*.snapshot' \ - -not -name '*.mak*' \ - -not -name '*.bash' \ - -not -name '*.data' \ - -not -name '*.py' \ - -not -name '*.class' \ - -not -name '*.xcconfig' \ - -not -name '*.ec' \ - -not -name '*.coverage' \ - -not -name '*.pyc' \ - -not -name '*.cfg' \ - -not -name '*.egg' \ - -not -name '*.ru' \ - -not -name '*.css' \ - -not -name '*.less' \ - -not -name '*.pyo' \ - -not -name '*.whl' \ - -not -name '*.html' \ - -not -name '*.ftl' \ - -not -name '*.erb' \ - -not -name '*.rb' \ - -not -name '*.js' \ - -not -name '*.jade' \ - -not -name '*.db' \ - -not -name '*.md' \ - -not -name '*.cpp' \ - -not -name '*.gradle' \ - -not -name '*.tar.tz' \ - -not -name '*.scss' \ - -not -name 'include.lst' \ - -not -name 'fullLocaleNames.lst' \ - -not -name 'inputFiles.lst' \ - -not -name 'createdFiles.lst' \ - -not -name 'scoverage.measurements.*' \ - -not -name 'test_*_coverage.txt' \ - -not -name 'testrunner-coverage*' \ - -print 2>/dev/null" - files=$(eval "$patterns" || echo '') - -elif [ "$include_cov" != "" ]; -then - files=$(eval "find $search_in -type f \( ${include_cov:5} \)$exclude_cov 2>/dev/null" || echo '') -fi - -num_of_files=$(echo "$files" | wc -l | tr -d ' ') -if [ "$num_of_files" != '' ] && [ "$files" != '' ]; -then - say " ${e}->${x} Found $num_of_files reports" -fi - -# no files found -if [ "$files" = "" ]; -then - say "${r}-->${x} No coverage report found." - say " Please visit ${b}http://docs.codecov.io/docs/supported-languages${x}" - exit ${exit_with}; -fi - -if [ "$ft_network" == "1" ]; -then - say "${e}==>${x} Detecting git/mercurial file structure" - network=$(cd "$git_root" && git ls-files 2>/dev/null || hg locate 2>/dev/null || echo "") - if [ "$network" = "" ]; - then - network=$(find "$git_root" \( \ - -name virtualenv \ - -name .virtualenv \ - -name virtualenvs \ - -name .virtualenvs \ - -name '*.png' \ - -name '*.gif' \ - -name '*.jpg' \ - -name '*.jpeg' \ - -name '*.md' \ - -name .env \ - -name .envs \ - -name env \ - -name envs \ - -name .venv \ - -name .venvs \ - -name venv \ - -name venvs \ - -name .git \ - -name .egg-info \ - -name shunit2-2.1.6 \ - -name vendor \ - -name __pycache__ \ - -name node_modules \ - -path '*/$bower_components/*' \ - -path '*/target/delombok/*' \ - -path '*/build/lib/*' \ - -path '*/js/generated/coverage/*' \ - \) -prune -or \ - -type f -print 2>/dev/null || echo '') - fi - - if [ "$prefix_o" != "" ]; - then - network=$(echo "$network" | awk "{print \"$prefix_o/\"\$0}") - fi -fi - -upload_file=`mktemp /tmp/codecov.XXXXXX` -adjustments_file=`mktemp /tmp/codecov.adjustments.XXXXXX` - -cleanup() { - rm -f $upload_file $adjustments_file $upload_file.gz -} - -trap cleanup INT ABRT TERM - -if [ "$env" != "" ]; -then - inc_env="" - say "${e}==>${x} Appending build variables" - for varname in $(echo "$env" | tr ',' ' ') - do - if [ "$varname" != "" ]; - then - say " ${g}+${x} $varname" - inc_env="${inc_env}${varname}=$(eval echo "\$${varname}") -" - fi - done - -echo "$inc_env<<<<<< ENV" >> $upload_file -fi - -# Append git file list -# write discovered yaml location -echo "$yaml" >> $upload_file -if [ "$ft_network" == "1" ]; -then - i="woff|eot|otf" # fonts - i="$i|gif|png|jpg|jpeg|psd" # images - i="$i|ptt|pptx|numbers|pages|md|txt|xlsx|docx|doc|pdf|html|csv" # docs - i="$i|yml|yaml|.gitignore" # supporting docs - echo "$network" | grep -vwE "($i)$" >> $upload_file -fi -echo "<<<<<< network" >> $upload_file - -fr=0 -say "${e}==>${x} Reading reports" -while IFS='' read -r file; -do - # read the coverage file - if [ "$(echo "$file" | tr -d ' ')" != '' ]; - then - if [ -f "$file" ]; - then - report_len=$(wc -c < "$file") - if [ "$report_len" -ne 0 ]; - then - say " ${g}+${x} $file ${e}bytes=$(echo "$report_len" | tr -d ' ')${x}" - # append to to upload - _filename=$(basename "$file") - if [ "${_filename##*.}" = 'gcov' ]; - then - echo "# path=$(echo "$file.reduced" | sed "s|^$git_root/||")" >> $upload_file - # get file name - head -1 $file >> $upload_file - # 1. remove source code - # 2. remove ending bracket lines - # 3. remove whitespace - # 4. remove contextual lines - # 5. remove function names - awk -F': *' '{print $1":"$2":"}' $file \ - | sed '\/: *} *$/d' \ - | sed 's/^ *//' \ - | sed '/^-/d' \ - | sed 's/^function.*/func/' >> $upload_file - else - echo "# path=$(echo "$file" | sed "s|^$git_root/||")" >> $upload_file - cat "$file" >> $upload_file - fi - echo "<<<<<< EOF" >> $upload_file - fr=1 - if [ "$clean" = "1" ]; - then - rm "$file" - fi - else - say " ${r}-${x} Skipping empty file $file" - fi - else - say " ${r}-${x} file not found at $file" - fi - fi -done <<< "$(echo -e "$files")" - -if [ "$fr" = "0" ]; -then - say "${r}-->${x} No coverage data found." - say " Please visit ${b}http://docs.codecov.io/docs/supported-languages${x}" - say " search for your projects language to learn how to collect reports." - exit ${exit_with}; -fi - -if [ "$ft_fix" = "1" ]; -then - say "${e}==>${x} Appending adjustments" - say " ${b}http://docs.codecov.io/docs/fixing-reports${x}" - - empty_line='^[[:space:]]*$' - # // - syntax_comment='^[[:space:]]*//.*' - # /* or */ - syntax_comment_block='^[[:space:]]*(\/\*|\*\/)[[:space:]]*$' - # { or } - syntax_bracket='^[[:space:]]*[\{\}][[:space:]]*(//.*)?$' - # [ or ] - syntax_list='^[[:space:]]*[][][[:space:]]*(//.*)?$' - - skip_dirs="-not -path '*/$bower_components/*' \ - -not -path '*/node_modules/*'" - - cut_and_join() { - awk 'BEGIN { FS=":" } - $3 ~ /\/\*/ || $3 ~ /\*\// { print $0 ; next } - $1!=key { if (key!="") print out ; key=$1 ; out=$1":"$2 ; next } - { out=out","$2 } - END { print out }' 2>/dev/null - } - - if echo "$network" | grep -m1 '.kt$' 1>/dev/null; - then - # skip brackets and comments - find "$git_root" -type f \ - -name '*.kt' \ - -exec \ - grep -nIHE -e $syntax_bracket \ - -e $syntax_comment_block {} \; \ - | cut_and_join \ - >> $adjustments_file \ - || echo '' - - # last line in file - find "$git_root" -type f \ - -name '*.kt' -exec \ - wc -l {} \; \ - | while read l; do echo "EOF: $l"; done \ - 2>/dev/null \ - >> $adjustments_file \ - || echo '' - - fi - - if echo "$network" | grep -m1 '.go$' 1>/dev/null; - then - # skip empty lines, comments, and brackets - find "$git_root" -not -path '*/vendor/*' \ - -type f \ - -name '*.go' \ - -exec \ - grep -nIHE \ - -e $empty_line \ - -e $syntax_comment \ - -e $syntax_comment_block \ - -e $syntax_bracket \ - {} \; \ - | cut_and_join \ - >> $adjustments_file \ - || echo '' - fi - - if echo "$network" | grep -m1 '.dart$' 1>/dev/null; - then - # skip brackets - find "$git_root" -type f \ - -name '*.dart' \ - -exec \ - grep -nIHE \ - -e $syntax_bracket \ - {} \; \ - | cut_and_join \ - >> $adjustments_file \ - || echo '' - fi - - if echo "$network" | grep -m1 '.php$' 1>/dev/null; - then - # skip empty lines, comments, and brackets - find "$git_root" -not -path "*/vendor/*" \ - -type f \ - -name '*.php' \ - -exec \ - grep -nIHE \ - -e $syntax_list \ - -e $syntax_bracket \ - -e '^[[:space:]]*\);[[:space:]]*(//.*)?$' \ - {} \; \ - | cut_and_join \ - >> $adjustments_file \ - || echo '' - fi - - if echo "$network" | grep -m1 '\(.cpp\|.h\|.cxx\|.c\|.hpp\|.m\)$' 1>/dev/null; - then - # skip brackets - find "$git_root" -type f \ - $skip_dirs \ - \( \ - -name '*.h' \ - -or -name '*.cpp' \ - -or -name '*.cxx' \ - -or -name '*.m' \ - -or -name '*.c' \ - -or -name '*.hpp' \ - \) -exec \ - grep -nIHE \ - -e $empty_line \ - -e $syntax_bracket \ - -e '// LCOV_EXCL' \ - {} \; \ - | cut_and_join \ - >> $adjustments_file \ - || echo '' - - # skip brackets - find "$git_root" -type f \ - $skip_dirs \ - \( \ - -name '*.h' \ - -or -name '*.cpp' \ - -or -name '*.cxx' \ - -or -name '*.m' \ - -or -name '*.c' \ - -or -name '*.hpp' \ - \) -exec \ - grep -nIH '// LCOV_EXCL' \ - {} \; \ - >> $adjustments_file \ - || echo '' - - fi - - found=$(cat $adjustments_file | tr -d ' ') - - if [ "$found" != "" ]; - then - say " ${g}+${x} Found adjustments" - echo "# path=fixes" >> $upload_file - cat $adjustments_file >> $upload_file - echo "<<<<<< EOF" >> $upload_file - rm -rf $adjustments_file - else - say " ${e}->${x} No adjustments found" - fi -fi - -if [ "$url_o" != "" ]; -then - url="$url_o" -fi - -if [ "$dump" != "0" ]; -then - # trim whitespace from query - say " ${e}->${x} Dumping upload file (no upload)" - echo "$url/upload/v4?$(echo "package=bash-$VERSION&token=$token&$query" | tr -d ' ')" - cat $upload_file -else - - say "${e}==>${x} Gzipping contents" - gzip -nf9 $upload_file - - query=$(echo "${query}" | tr -d ' ') - say "${e}==>${x} Uploading reports" - say " ${e}url:${x} $url" - say " ${e}query:${x} $query" - - # now add token to query - query=$(echo "package=bash-$VERSION&token=$token&$query" | tr -d ' ') - - if [ "$ft_s3" = "1" ]; - then - i="0" - while [ $i -lt 4 ] - do - i=$[$i+1] - say " ${e}->${x} Pinging Codecov" - res=$(curl $curl_s -X POST $curlargs $cacert \ - -H 'X-Reduced-Redundancy: false' \ - -H 'X-Content-Type: application/x-gzip' \ - "$url/upload/v4?$query" || true) - # a good replay is "https://codecov.io" + "\n" + "https://codecov.s3.amazonaws.com/..." - status=$(echo "$res" | head -1 | grep 'HTTP ' | cut -d' ' -f2) - if [ "$status" = "" ]; - then - s3target=$(echo "$res" | sed -n 2p) - say " ${e}->${x} Uploading" - s3=$(curl $curl_s -fiX PUT $curlawsargs \ - --data-binary @$upload_file.gz \ - -H 'Content-Type: application/x-gzip' \ - -H 'Content-Encoding: gzip' \ - -H 'x-amz-acl: public-read' \ - "$s3target" || true) - if [ "$s3" != "" ]; - then - say " ${g}->${x} View reports at ${b}$(echo "$res" | sed -n 1p)${x}" - exit 0 - else - say " ${r}X>${x} Failed to upload" - fi - elif [ "$status" = "400" ]; - then - # 400 Error - say "${g}${res}${x}" - exit ${exit_with} - fi - say " ${e}->${x} Sleeping for 30s and trying again..." - sleep 30 - done - fi - - say " ${e}->${x} Uploading to Codecov" - i="0" - while [ $i -lt 4 ] - do - i=$[$i+1] - - res=$(curl $curl_s -X POST $curlargs $cacert \ - --data-binary @$upload_file.gz \ - -H 'Content-Type: text/plain' \ - -H 'Content-Encoding: gzip' \ - -H 'X-Content-Encoding: gzip' \ - -H 'Accept: text/plain' \ - "$url/upload/v2?$query" || echo 'HTTP 500') - # HTTP 200 - # http://.... - status=$(echo "$res" | head -1 | cut -d' ' -f2) - if [ "$status" = "" ]; - then - say " View reports at ${b}$(echo "$res" | head -2 | tail -1)${x}" - exit 0 - - elif [ "${status:0:1}" = "5" ]; - then - say " ${e}->${x} Sleeping for 30s and trying again..." - sleep 30 - - else - say " ${g}${res}${x}" - exit 0 - exit ${exit_with} - fi - - done - - say " ${r}X> Failed to upload coverage reports${x}" -fi - -exit ${exit_with} diff --git a/bin/coverage b/bin/coverage deleted file mode 100755 index 70ac359..0000000 --- a/bin/coverage +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# -# Generated from https://github.com/Teamwork/strut -# DO NOT EDIT DIRECTLY! - -# Setup -####### -set -euC -root="$(cd "$(dirname "$0")/.." && pwd)" -# shellcheck source=load-settings -. "$root/bin/load-settings" - -# Run action -############ - -"$root/bin/test" \ - -coverprofile=coverage.txt \ - -coverpkg=./... \ - "$@" - -# The token is optional for public repos. -[ -n "${codecov_token:-}" ] && export CODECOV_TOKEN="$codecov_token" - -# Submit reports only on Travis. -[ -n "${TRAVIS:-}" ] && - ./bin/.codecov -X gcov -X coveragepy -X search -K -f coverage.txt - -exit 0 diff --git a/bin/lint b/bin/lint deleted file mode 100755 index 6c95851..0000000 --- a/bin/lint +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh -# -# Generated from https://github.com/Teamwork/strut -# DO NOT EDIT DIRECTLY! - -# Setup -####### -set -euC -root="$(cd "$(dirname "$0")/.." && pwd)" -# shellcheck source=load-settings -. "$root/bin/load-settings" - -# Run action -############ - -ignore_metalinter() { - local IFS="$(printf '\n\b')" - for d in $lint_ignore; do printf " -s %s" "$d"; done -} - -# Skip the linter on Travis if we're on a deployable branch. -if [ -n "$TRAVIS" ]; then - branch=${TRAVIS_PULL_REQUEST_BRANCH:-${TRAVIS_BRANCH:-}} - branch=${branch:-$(git rev-parse --abbrev-ref HEAD)} - if [ "$do_deploy" -eq 1 ]; then - echo "We're on $branch; skipping lint tests" - exit 0 - fi -fi - -# Ensure generated files are up to date; only run on Travis to prevent -# clobbering people's working directories. -# TODO: Ideally this would never change the contents in the directory. -if [ -n "${TRAVIS:-}" ] && [ "${lint_skip_generate:-0}" = 0 ]; then - go generate ./... - changes="$(git diff)" - if [ -n "$changes" ]; then - echo - echo "*****************************************************" - echo "*** ***" - echo "*** Changes in generated files: ***" - echo "*** ***" - echo "*****************************************************" - echo - echo "$changes" - fi -fi - -export GO111MODULE=auto - -if [ -n "$TRAVIS" ]; then - if ! command -v golangci-lint; then - # Version specific so it wont break with any change - # curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.13.2 - (GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.45.2) - fi -fi - - -# linters config at ../.golangci.yml -(cd -P .; golangci-lint run --skip-dirs testdata $(ignore_metalinter) "$@") - diff --git a/bin/load-settings b/bin/load-settings deleted file mode 100644 index 31f082f..0000000 --- a/bin/load-settings +++ /dev/null @@ -1,55 +0,0 @@ -# vi:ft=sh -# -# Generated from https://github.com/Teamwork/strut -# DO NOT EDIT DIRECTLY! - -set -euC - -# shellcheck disable=SC2154 -cd "$root" - -# Load settings -# shellcheck disable=SC1090 -[ -f "$root/bin/settings" ] && . "$root/bin/settings" - -### -# Stuff to set in settings file. - -# Codecov token for coverage reports; only needed for private repos. -codecov_token=${codecov_token:-} - -# Directory names to ignore in the ./bin/lint script; multiple directories are -# separated by newlines. -lint_ignore="${lint_ignore:-}" - -# Don't check for changes in generated files with ./bin/lint. -lint_skip_generate="${lint_skip_generate:-0}" - -### -# For the following the defaults should almost always be okay. If not, then -# consider fixing the project maybe? - -# Binary name. -name=${name:-$(basename "$root")} - -# Go package name -pkgname=${pkgname:-"github.com/teamwork/$name"} - -# Git branch -branch=${branch:-${TRAVIS_PULL_REQUEST_BRANCH:-${TRAVIS_BRANCH:-$(git rev-parse --abbrev-ref HEAD)}}} - -# Docker image tag; usually the commit -docker_tag=${docker_tag:-${TRAVIS_COMMIT:-dev-env}} - -# Make sure this is set locally so we can do -z/-n. -TRAVIS=${TRAVIS:-} - -do_deploy=0 -check_deploy() { - case "$branch" in - master | beta) - # shellcheck disable=SC2034 - do_deploy=1 - ;; - esac -} diff --git a/bin/setup-travis b/bin/setup-travis deleted file mode 100755 index e0d2d35..0000000 --- a/bin/setup-travis +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -# -# Generated from https://github.com/Teamwork/strut -# DO NOT EDIT DIRECTLY! - -# Setup -####### -set -euC -root="$(cd "$(dirname "$0")/.." && pwd)" -# shellcheck source=load-settings -. "$root/bin/load-settings" - -# Run action -############ - -# Setup dep if it's used and vendor isn't in git. -if [ -f Gopkg.toml ] && [ ! -d vendor ]; then - go get -u github.com/golang/dep/cmd/dep - dep ensure -elif [ -f go.sum ]; then - export GO111MODULE=on - go mod vendor -fi diff --git a/bin/test b/bin/test deleted file mode 100755 index 9f349a4..0000000 --- a/bin/test +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -# shellcheck disable=SC2039 -# -# Generated from https://github.com/Teamwork/strut -# DO NOT EDIT DIRECTLY! - -# Setup -####### -set -euC -root="$(cd "$(dirname "$0")/.." && pwd)" -# shellcheck source=load-settings -. "$root/bin/load-settings" - -# Run action -############ - -# shellcheck disable=SC1090 -[ -f "$root/bin/test-pre" ] && . "$root/bin/test-pre" - -# If we don't set this some stacks may not be complete when encountering race -# conditions. Uses a bit more memory, but we usually have enough of that. -export GORACE="history_size=4" - -# Extract tags and run "$root/bin/test-tag-" callback if that file exists. -tt() { - local tags="" - - while :; do - [ $# = 0 ] && break - - # -tags foo - # -tags 'foo bar' - if [ "$1" = "-tags" ]; then - shift - tags="$tags $1" - # -tags=foo - # -tags='foo bar' - elif echo "$1" | grep -q '^-tags='; then - tags="$tags $(echo "$1" | cut -d= -f2-)" - fi - - shift - done - - for t in $tags; do - local f="$root/bin/test-tag-$t" - # shellcheck disable=SC1090 - [ -f "$f" ] && . "$f" - done - : -} -tt "$@" - -go test "$@" diff --git a/errorutil/errorutil.go b/errorutil/errorutil.go index 032d607..50952b3 100644 --- a/errorutil/errorutil.go +++ b/errorutil/errorutil.go @@ -27,7 +27,8 @@ type Patterns struct { regexps []*regexp.Regexp } -// FilterPattern compiles filter patterns for FilterTrace() +// FilterPattern compiles filter patterns for FilterTrace(). +// Note: After go 1.13 this can include go run time data, excluding "re:.*runtime/*.s" is recommended. // // Frames are filtered according to the mode; with FilterTraceExclude all frames // are included except those that match the given patterns. With diff --git a/errorutil/errorutil_test.go b/errorutil/errorutil_test.go index fe8553c..9c7d132 100644 --- a/errorutil/errorutil_test.go +++ b/errorutil/errorutil_test.go @@ -14,6 +14,7 @@ func TestFilterExclude(t *testing.T) { err = FilterTrace(err, FilterPattern(FilterTraceExclude, "testing", "re:.*github.com/teamwork/utils/.*", + "re:.*runtime/*.s", )) tErr, _ := err.(stackTracer) @@ -48,8 +49,8 @@ func TestFilterInclude(t *testing.T) { "re:.*github.com/teamwork/utils/.*")) tErr, _ := err.(stackTracer) - if len(tErr.StackTrace()) != 1 { - t.Errorf("wrong length for stack trace: %d; wanted 1", len(tErr.StackTrace())) + if len(tErr.StackTrace()) != 3 { + t.Errorf("wrong length for stack trace: %d; wanted 3", len(tErr.StackTrace())) for _, f := range tErr.StackTrace() { t.Logf("%+v\n", f) } diff --git a/go.mod b/go.mod index adc2ce5..717291c 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,17 @@ module github.com/teamwork/utils -go 1.18 +go 1.20 + +require ( + github.com/mattn/goveralls v0.0.11 + github.com/pkg/errors v0.9.1 + github.com/teamwork/test v0.0.0-20200108114543-02621bae84ad + golang.org/x/tools v0.8.0 +) require ( github.com/Strum355/go-difflib v1.1.0 // indirect - github.com/davecgh/go-spew v1.1.0 // indirect - github.com/pkg/errors v0.8.0 - github.com/teamwork/test v0.0.0-20190410143529-8897d82f8d46 + github.com/davecgh/go-spew v1.1.1 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/sys v0.7.0 // indirect ) diff --git a/go.sum b/go.sum index b43908c..7b77fc0 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,17 @@ github.com/Strum355/go-difflib v1.1.0 h1:+rR2X3UuvIbe1Jmhx8WA7gkgjMNRscFWbHchk2RB8I4= github.com/Strum355/go-difflib v1.1.0/go.mod h1:r1cVg1JkGsTWkaR7At56v7hfuMgiUL8meTLwxFzOmvE= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/teamwork/test v0.0.0-20190410143529-8897d82f8d46 h1:IWmLWZ3AylHoq1M8ca7H5Ns7oNsuzaCAqoFvKaDP2jA= -github.com/teamwork/test v0.0.0-20190410143529-8897d82f8d46/go.mod h1:TIbx7tx6WHBjQeLRM4eWQZBL7kmBZ7/KI4x4v7Y5YmA= +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/mattn/goveralls v0.0.11 h1:eJXea6R6IFlL1QMKNMzDvvHv/hwGrnvyig4N+0+XiMM= +github.com/mattn/goveralls v0.0.11/go.mod h1:gU8SyhNswsJKchEV93xRQxX6X3Ei4PJdQk/6ZHvrvRk= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/teamwork/test v0.0.0-20200108114543-02621bae84ad h1:25sEr0awm0ZPancg5W5H5VvN7PWsJloUBpii10a9isw= +github.com/teamwork/test v0.0.0-20200108114543-02621bae84ad/go.mod h1:TIbx7tx6WHBjQeLRM4eWQZBL7kmBZ7/KI4x4v7Y5YmA= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= diff --git a/goutil/goutil.go b/goutil/goutil.go index b89c521..5e40158 100644 --- a/goutil/goutil.go +++ b/goutil/goutil.go @@ -14,46 +14,38 @@ import ( "reflect" "sort" "strings" + + "golang.org/x/tools/go/packages" ) // Expand a list of package and/or directory names to Go package names. // -// - "./example" is expanded to "full/package/path/example". -// - "/absolute/src/package/path" is abbreviated to "package/path". -// - "full/package" is kept-as is. -// - "package/path/..." will include "package/path" and all subpackages. +// - "./example" is expanded to "full/package/path/example". +// - "/absolute/src/package/path" is abbreviated to "package/path". +// - "full/package" is kept-as is. +// - "package/path/..." will include "package/path" and all subpackages. // // The packages will be sorted with duplicate packages removed. The /vendor/ // directory is automatically ignored. -func Expand(paths []string, mode build.ImportMode) ([]*build.Package, error) { - var out []*build.Package - seen := make(map[string]struct{}) - for _, p := range paths { - if strings.HasSuffix(p, "/...") { - subPkgs, err := ResolveWildcard(p, mode) - if err != nil { - return nil, err - } - for _, sub := range subPkgs { - if _, ok := seen[sub.ImportPath]; !ok { - out = append(out, sub) - seen[sub.ImportPath] = struct{}{} - } - } - continue - } +func Expand(paths []string, mode packages.LoadMode) ([]*packages.Package, error) { + pkgs, err := packages.Load(&packages.Config{Mode: mode}, paths...) + if err != nil { + return nil, err + } - pkg, err := ResolvePackage(p, mode) - if err != nil { - return nil, err - } - if _, ok := seen[pkg.ImportPath]; !ok { - out = append(out, pkg) - seen[pkg.ImportPath] = struct{}{} + out := make([]*packages.Package, 0, len(pkgs)) + for _, pkg := range pkgs { + if len(pkg.Errors) > 0 { + return nil, pkg.Errors[0] } + out = append(out, pkg) + } + + if len(out) == 0 { + return nil, errors.New("cannot find package") } - sort.Slice(out, func(i, j int) bool { return out[i].ImportPath < out[j].ImportPath }) + sort.Slice(out, func(i, j int) bool { return out[i].PkgPath < out[j].PkgPath }) return out, nil } @@ -250,7 +242,8 @@ func TagName(f *ast.Field, n string) string { } // Embedded struct: -// Foo `json:"foo"` +// +// Foo `json:"foo"` func getEmbedName(f ast.Expr) string { start: switch t := f.(type) { diff --git a/goutil/goutil_test.go b/goutil/goutil_test.go index 3dbd86c..0855bc8 100644 --- a/goutil/goutil_test.go +++ b/goutil/goutil_test.go @@ -3,7 +3,6 @@ package goutil import ( "fmt" "go/ast" - "go/build" "go/token" "reflect" "sort" @@ -11,6 +10,7 @@ import ( "testing" "github.com/teamwork/test" + "golang.org/x/tools/go/packages" ) // This also tests ResolvePackage() and ResolveWildcard(). @@ -56,6 +56,11 @@ func TestExpand(t *testing.T) { []string{"github.com/teamwork/utils/goutil"}, "", }, + { + []string{""}, + []string{"github.com/teamwork/utils/goutil"}, + "", + }, { []string{".."}, []string{"github.com/teamwork/utils"}, @@ -90,31 +95,20 @@ func TestExpand(t *testing.T) { // Errors { - []string{""}, + []string{"thi.s/will/never/exist/..."}, nil, - "cannot resolve empty string", + `cannot find package`, }, - // These tests pass locally but are dodgy on travis in go1.18 - // { - // []string{"thi.s/will/never/exist"}, - // nil, - // `no required module provides package thi.s/will/never/exist`, - // }, - // { - // []string{"thi.s/will/never/exist/..."}, - // nil, - // `no required module provides package thi.s/will/never/exist`, - // }, { []string{"./doesnt/exist"}, nil, - "cannot find package", + "directory not found", }, } for i, tc := range cases { t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { - out, err := Expand(tc.in, build.FindOnly) + out, err := Expand(tc.in, packages.NeedName) if !test.ErrorContains(err, tc.wantErr) { t.Fatal(err) } @@ -122,7 +116,7 @@ func TestExpand(t *testing.T) { sort.Strings(tc.want) var outPkgs []string for _, p := range out { - outPkgs = append(outPkgs, p.ImportPath) + outPkgs = append(outPkgs, p.PkgPath) } if !reflect.DeepEqual(tc.want, outPkgs) { diff --git a/httputilx/header/set.go b/httputilx/header/set.go index c3e25fc..03e4408 100644 --- a/httputilx/header/set.go +++ b/httputilx/header/set.go @@ -151,11 +151,11 @@ type CSPArgs [][]string // // Valid sources: // -// CSPSource* -// Hosts example.com, *.example.com, https://example.com -// Schema data:, blob:, etc. -// nonce- inline scripts using a cryptographic nonce -// - hash of specific script. +// CSPSource* +// Hosts example.com, *.example.com, https://example.com +// Schema data:, blob:, etc. +// nonce- inline scripts using a cryptographic nonce +// - hash of specific script. // // Also see: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP and // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy diff --git a/httputilx/httputilx_test.go b/httputilx/httputilx_test.go index cffcac8..8bab181 100644 --- a/httputilx/httputilx_test.go +++ b/httputilx/httputilx_test.go @@ -222,7 +222,3 @@ func TestFetch(t *testing.T) { }) } } - -// TODO: Add test. -func TestSave(t *testing.T) { -} diff --git a/imageutil/sniff.go b/imageutil/sniff.go index d723572..d1462e6 100644 --- a/imageutil/sniff.go +++ b/imageutil/sniff.go @@ -23,13 +23,8 @@ func DetectImage(data []byte) string { data = data[:sniffLen] } - // Index of the first non-whitespace byte in data. - firstNonWS := 0 - // for ; firstNonWS < len(data) && isWS(data[firstNonWS]); firstNonWS++ { - // } - for _, sig := range sniffSignatures { - if ct := sig.match(data, firstNonWS); ct != "" { + if ct := sig.match(data); ct != "" { return ct } } @@ -59,7 +54,7 @@ func DetectImageStream(fp io.ReadSeeker) (string, error) { type sniffSig interface { // match returns the MIME type of the data, or "" if unknown. - match(data []byte, firstNonWS int) string + match(data []byte) string } // Data matching the table in section 6. @@ -82,7 +77,7 @@ type exactSig struct { ct string } -func (e *exactSig) match(data []byte, firstNonWS int) string { +func (e *exactSig) match(data []byte) string { if bytes.HasPrefix(data, e.sig) { return e.ct } @@ -91,17 +86,13 @@ func (e *exactSig) match(data []byte, firstNonWS int) string { type maskedSig struct { mask, pat []byte - // skipWS bool - ct string + ct string } -func (m *maskedSig) match(data []byte, firstNonWS int) string { +func (m *maskedSig) match(data []byte) string { // pattern matching algorithm section 6 // https://mimesniff.spec.whatwg.org/#pattern-matching-algorithm - // if m.skipWS { - // data = data[firstNonWS:] - // } if len(m.pat) != len(m.mask) { return "" } diff --git a/ioutilx/copy.go b/ioutilx/copy.go index def89f6..d51f17c 100644 --- a/ioutilx/copy.go +++ b/ioutilx/copy.go @@ -291,7 +291,7 @@ var DefaultCopyTreeOptions = &CopyTreeOptions{ // `src` parameter, which is the directory being visited by CopyTree(), and // `names` which is the list of `src` contents, as returned by os.ReadDir(): // -// callable(src, entries) -> ignoredNames +// callable(src, entries) -> ignoredNames // // Since CopyTree() is called recursively, the callable will be called once for // each directory that is copied. It returns a list of names relative to the diff --git a/ioutilx/copy_test.go b/ioutilx/copy_test.go index 78041be..f85493e 100644 --- a/ioutilx/copy_test.go +++ b/ioutilx/copy_test.go @@ -110,7 +110,7 @@ func TestCopyData(t *testing.T) { {"test/file1", "test/file2", "already exists"}, {"test/fifo", "test/newfile", "named pipe"}, // {"test/link1/asd", "test/dst1", "not a directory"}, - {"test/file1", "/cantwritehere", "permission denied"}, + // {"test/file1", "/cantwritehere", "permission denied"}, {"test/file1", "test/dst1", ""}, // {"test/link1", "test/dst1", ""}, } @@ -197,7 +197,7 @@ func TestCopy(t *testing.T) { {"nonexistent", "test/copydst", Modes{}, "no such file"}, {"test/fifo", "test/newfile", Modes{}, "named pipe"}, // {"test/link1/asd", "test/dst1", Modes{}, "not a directory"}, - {"test/file1", "/cantwritehere", Modes{}, "permission denied"}, + // {"test/file1", "/cantwritehere", Modes{}, "permission denied"}, {"test/exec", "test/dst1", Modes{Permissions: true, Owner: true, Mtime: true}, ""}, {"test/exec", "test/dir1", Modes{Permissions: true, Owner: true, Mtime: true}, ""}, diff --git a/jsonutil/jsonutil.go b/jsonutil/jsonutil.go index 6db0fb6..f5a93e6 100644 --- a/jsonutil/jsonutil.go +++ b/jsonutil/jsonutil.go @@ -34,7 +34,7 @@ func MustUnmarshal(data []byte, v interface{}) { // // The data will be unmarshalled in to v, which must be a pointer. Example: // -// Indent(`{"a": "b"}`, &map[string]string{}, "", " ") +// Indent(`{"a": "b"}`, &map[string]string{}, "", " ") func Indent(data []byte, v interface{}, prefix, indent string) ([]byte, error) { err := json.Unmarshal(data, v) if err != nil { diff --git a/mathutil/mathutil.go b/mathutil/mathutil.go index 9d2a325..f292baf 100644 --- a/mathutil/mathutil.go +++ b/mathutil/mathutil.go @@ -1,3 +1,4 @@ +// Package mathutil provides functions for working with numbers. package mathutil // import "github.com/teamwork/utils/mathutil" import ( diff --git a/netutil/ip.go b/netutil/ip.go index f2223c1..47fdae6 100644 --- a/netutil/ip.go +++ b/netutil/ip.go @@ -33,7 +33,7 @@ func (ip IP) Lt(end net.IP) bool { // Eq will return if the IP is less than to the given IP func (ip IP) Eq(cmp net.IP) bool { - return bytes.Compare(ip, cmp) == 0 + return bytes.Equal(ip, cmp) } // InRange will return if the IP is within the given range of addresses diff --git a/netutil/netutil.go b/netutil/netutil.go index 710ceea..8183df8 100644 --- a/netutil/netutil.go +++ b/netutil/netutil.go @@ -1,3 +1,4 @@ +// Package netutil provides functions expanding on net std package. package netutil // import "github.com/teamwork/utils/netutil" import "net" diff --git a/ptrutil/ptr.go b/ptrutil/ptr.go index 0d6368b..5c0ae28 100644 --- a/ptrutil/ptr.go +++ b/ptrutil/ptr.go @@ -1,3 +1,4 @@ +// Package ptrutil provides functions for working with pointers. package ptrutil // Dereference dereferences a pointer, returning zero if the pointer is nil. diff --git a/sliceutil/sliceutil.go b/sliceutil/sliceutil.go index 7dd823a..4558b91 100644 --- a/sliceutil/sliceutil.go +++ b/sliceutil/sliceutil.go @@ -112,8 +112,8 @@ func Choose[T any](tt []T) T { var zero T return zero } - rand.Seed(time.Now().UnixNano()) - return tt[rand.Intn(len(tt))] + source := rand.NewSource(time.Now().UnixNano()) + return tt[rand.New(source).Intn(len(tt))] } // Range creates an []int counting at "start" up to (and including) "end". diff --git a/sliceutil/sliceutil_test.go b/sliceutil/sliceutil_test.go index 0707d0a..1cddd9a 100644 --- a/sliceutil/sliceutil_test.go +++ b/sliceutil/sliceutil_test.go @@ -121,6 +121,7 @@ func TestMergeUnique_Int64(t *testing.T) { t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { got := MergeUnique(tc.in) if !int64slicesequal(got, tc.expected) { + t.Log("IN", tc.in) t.Errorf(diff.Cmp(tc.expected, got)) } }) @@ -173,14 +174,17 @@ func stringslicesequal(a, b []string) bool { func generate2dintslice(in []int64) [][]int64 { var ( - result [][]int64 - loops = int(rand.Int63n(int64(len(in) * 2))) + result [][]int64 + processed = map[int]struct{}{} + loops = int(rand.Int63n(int64(len(in)*2)) + 1) ) - for i := 0; i < loops; i++ { + for len(processed) < len(in) { var s []int64 for i := 0; i < loops; i++ { - s = append(s, in[rand.Intn(len(in))]) + idx := rand.Intn(len(in)) + processed[idx] = struct{}{} + s = append(s, in[idx]) } result = append(result, s) } diff --git a/sqlutil/sqlutil.go b/sqlutil/sqlutil.go index 7694ddf..3152fde 100644 --- a/sqlutil/sqlutil.go +++ b/sqlutil/sqlutil.go @@ -78,10 +78,10 @@ func (l *StringList) Scan(v interface{}) error { // Bool add the capability to handle more column types than the usual sql // driver. The following types are supported when reading the data: // -// * int64 and float64 - 0 for false, true otherwise -// * bool -// * []byte and string - "1" or "true" for true, and "0" or "false" for false. Also handles the 1 bit cases. -// * nil - defaults to false +// - int64 and float64 - 0 for false, true otherwise +// - bool +// - []byte and string - "1" or "true" for true, and "0" or "false" for false. Also handles the 1 bit cases. +// - nil - defaults to false // // It is also prepared to be encoded and decoded to a human readable format. type Bool bool diff --git a/timeutil/timeutil.go b/timeutil/timeutil.go index f2afa64..13700be 100644 --- a/timeutil/timeutil.go +++ b/timeutil/timeutil.go @@ -1,3 +1,4 @@ +// Package timeutil provides functions for working with time. package timeutil // import "github.com/teamwork/utils/timeutil" import "time" @@ -37,7 +38,8 @@ func FormatAsZulu(t time.Time) string { // date. The number of months is always rounded down, with a minimal value of 1. // // For example this returns 2: -// MonthsTo(time.Now().Add(24 * time.Hour * 70)) +// +// MonthsTo(time.Now().Add(24 * time.Hour * 70)) // // Dates in the past are not supported, and their behaviour is undefined! func MonthsTo(a time.Time) int { diff --git a/tools.go b/tools.go new file mode 100644 index 0000000..ac66a83 --- /dev/null +++ b/tools.go @@ -0,0 +1,10 @@ +//go:build tools +// +build tools + +// Package tools is used for declaring tool dependencies, see: +// https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module +package tools + +import ( + _ "github.com/mattn/goveralls" +) From 8526dee674e2727c95bc364a186890ef789785be Mon Sep 17 00:00:00 2001 From: Paulius J Date: Wed, 26 Apr 2023 13:23:20 +0200 Subject: [PATCH 16/16] fix v2 --- aesutil/aesutil.go | 2 +- dbg/dbg.go | 2 +- doc.go | 2 +- errorutil/errorutil.go | 2 +- go.mod | 3 +- go.sum | 5 ++++ goutil/goutil.go | 2 +- goutil/goutil_test.go | 50 ++++++++++++++++---------------- httputilx/header/example_test.go | 2 +- httputilx/header/header.go | 2 +- httputilx/httputilx.go | 4 +-- imageutil/doc.go | 2 +- ioutilx/copy.go | 2 +- ioutilx/ioutilx.go | 2 +- jsonutil/jsonutil.go | 2 +- maputil/maputil.go | 2 +- mathutil/mathutil.go | 2 +- netutil/netutil.go | 2 +- sliceutil/sliceutil.go | 2 +- sqlutil/sqlutil.go | 4 +-- stringutil/stringutil.go | 2 +- syncutil/syncutil.go | 2 +- timeutil/timeutil.go | 2 +- 23 files changed, 54 insertions(+), 48 deletions(-) diff --git a/aesutil/aesutil.go b/aesutil/aesutil.go index c72afd3..2c8737a 100644 --- a/aesutil/aesutil.go +++ b/aesutil/aesutil.go @@ -1,5 +1,5 @@ // Package aesutil provides a set of functions for 2-way encryption and hashing. -package aesutil // import "github.com/teamwork/utils/aesutil" +package aesutil // import "github.com/teamwork/utils/v2/aesutil" import ( "crypto/aes" diff --git a/dbg/dbg.go b/dbg/dbg.go index 931929f..98cd794 100644 --- a/dbg/dbg.go +++ b/dbg/dbg.go @@ -1,5 +1,5 @@ // Package dbg contains helper functions useful when debugging programs. -package dbg // import "github.com/teamwork/utils/dbg" +package dbg // import "github.com/teamwork/utils/v2/dbg" import ( "fmt" diff --git a/doc.go b/doc.go index 69a4796..059e7ac 100644 --- a/doc.go +++ b/doc.go @@ -1,2 +1,2 @@ // Package utils is a collection of often used extensions to Go's stdlib. -package utils // import "github.com/teamwork/utils" +package utils // import "github.com/teamwork/utils/v2/v2" diff --git a/errorutil/errorutil.go b/errorutil/errorutil.go index 50952b3..8645785 100644 --- a/errorutil/errorutil.go +++ b/errorutil/errorutil.go @@ -1,5 +1,5 @@ // Package errorutil provides functions to work with errors. -package errorutil // import "github.com/teamwork/utils/errorutil" +package errorutil // import "github.com/teamwork/utils/v2/errorutil" import ( "fmt" diff --git a/go.mod b/go.mod index 717291c..7cb22f3 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/teamwork/utils +module github.com/teamwork/utils/v2 go 1.20 @@ -12,6 +12,7 @@ require ( require ( github.com/Strum355/go-difflib v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/teamwork/utils v1.0.0 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/sys v0.7.0 // indirect ) diff --git a/go.sum b/go.sum index 7b77fc0..7cc9653 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,18 @@ github.com/Strum355/go-difflib v1.1.0 h1:+rR2X3UuvIbe1Jmhx8WA7gkgjMNRscFWbHchk2RB8I4= github.com/Strum355/go-difflib v1.1.0/go.mod h1:r1cVg1JkGsTWkaR7At56v7hfuMgiUL8meTLwxFzOmvE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/mattn/goveralls v0.0.11 h1:eJXea6R6IFlL1QMKNMzDvvHv/hwGrnvyig4N+0+XiMM= github.com/mattn/goveralls v0.0.11/go.mod h1:gU8SyhNswsJKchEV93xRQxX6X3Ei4PJdQk/6ZHvrvRk= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/teamwork/test v0.0.0-20190410143529-8897d82f8d46/go.mod h1:TIbx7tx6WHBjQeLRM4eWQZBL7kmBZ7/KI4x4v7Y5YmA= github.com/teamwork/test v0.0.0-20200108114543-02621bae84ad h1:25sEr0awm0ZPancg5W5H5VvN7PWsJloUBpii10a9isw= github.com/teamwork/test v0.0.0-20200108114543-02621bae84ad/go.mod h1:TIbx7tx6WHBjQeLRM4eWQZBL7kmBZ7/KI4x4v7Y5YmA= +github.com/teamwork/utils v1.0.0 h1:30WqhSbZ9nFhaJSx9HH+yFLiQvL64nqAOyyl5IxoYlY= +github.com/teamwork/utils v1.0.0/go.mod h1:3Fn0qxFeRNpvsg/9T1+btOOOKkd1qG2nPYKKcOmNpcs= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= diff --git a/goutil/goutil.go b/goutil/goutil.go index 5e40158..3019c3b 100644 --- a/goutil/goutil.go +++ b/goutil/goutil.go @@ -1,5 +1,5 @@ // Package goutil provides functions to work with Go source files. -package goutil // import "github.com/teamwork/utils/goutil" +package goutil // import "github.com/teamwork/utils/v2/goutil" import ( "errors" diff --git a/goutil/goutil_test.go b/goutil/goutil_test.go index 0855bc8..936851f 100644 --- a/goutil/goutil_test.go +++ b/goutil/goutil_test.go @@ -47,48 +47,48 @@ func TestExpand(t *testing.T) { "", }, { - []string{"github.com/teamwork/utils"}, - []string{"github.com/teamwork/utils"}, + []string{"github.com/teamwork/utils/v2"}, + []string{"github.com/teamwork/utils/v2"}, "", }, { []string{"."}, - []string{"github.com/teamwork/utils/goutil"}, + []string{"github.com/teamwork/utils/v2/goutil"}, "", }, { []string{""}, - []string{"github.com/teamwork/utils/goutil"}, + []string{"github.com/teamwork/utils/v2/goutil"}, "", }, { []string{".."}, - []string{"github.com/teamwork/utils"}, + []string{"github.com/teamwork/utils/v2"}, "", }, { []string{"../..."}, []string{ - "github.com/teamwork/utils", - "github.com/teamwork/utils/aesutil", - "github.com/teamwork/utils/dbg", - "github.com/teamwork/utils/errorutil", - "github.com/teamwork/utils/goutil", - "github.com/teamwork/utils/httputilx", - "github.com/teamwork/utils/httputilx/header", - "github.com/teamwork/utils/imageutil", - "github.com/teamwork/utils/ioutilx", - "github.com/teamwork/utils/jsonutil", - "github.com/teamwork/utils/maputil", - "github.com/teamwork/utils/mathutil", - "github.com/teamwork/utils/netutil", - "github.com/teamwork/utils/ptrutil", - "github.com/teamwork/utils/raceutil", - "github.com/teamwork/utils/sliceutil", - "github.com/teamwork/utils/sqlutil", - "github.com/teamwork/utils/stringutil", - "github.com/teamwork/utils/syncutil", - "github.com/teamwork/utils/timeutil", + "github.com/teamwork/utils/v2", + "github.com/teamwork/utils/v2/aesutil", + "github.com/teamwork/utils/v2/dbg", + "github.com/teamwork/utils/v2/errorutil", + "github.com/teamwork/utils/v2/goutil", + "github.com/teamwork/utils/v2/httputilx", + "github.com/teamwork/utils/v2/httputilx/header", + "github.com/teamwork/utils/v2/imageutil", + "github.com/teamwork/utils/v2/ioutilx", + "github.com/teamwork/utils/v2/jsonutil", + "github.com/teamwork/utils/v2/maputil", + "github.com/teamwork/utils/v2/mathutil", + "github.com/teamwork/utils/v2/netutil", + "github.com/teamwork/utils/v2/ptrutil", + "github.com/teamwork/utils/v2/raceutil", + "github.com/teamwork/utils/v2/sliceutil", + "github.com/teamwork/utils/v2/sqlutil", + "github.com/teamwork/utils/v2/stringutil", + "github.com/teamwork/utils/v2/syncutil", + "github.com/teamwork/utils/v2/timeutil", }, "", }, diff --git a/httputilx/header/example_test.go b/httputilx/header/example_test.go index e38e751..cbe2b54 100644 --- a/httputilx/header/example_test.go +++ b/httputilx/header/example_test.go @@ -3,7 +3,7 @@ package header_test import ( "net/http" - "github.com/teamwork/utils/httputilx/header" + "github.com/teamwork/utils/v2/httputilx/header" ) func ExampleSetCSP() { diff --git a/httputilx/header/header.go b/httputilx/header/header.go index ab5bc66..4674ce9 100644 --- a/httputilx/header/header.go +++ b/httputilx/header/header.go @@ -8,7 +8,7 @@ // https://developers.google.com/open-source/licenses/bsd. // Package header provides functions for parsing and setting HTTP headers. -package header // import "github.com/teamwork/utils/httputilx/header" +package header // import "github.com/teamwork/utils/v2/httputilx/header" import ( "net/http" diff --git a/httputilx/httputilx.go b/httputilx/httputilx.go index 0ba91c6..1b374eb 100644 --- a/httputilx/httputilx.go +++ b/httputilx/httputilx.go @@ -1,5 +1,5 @@ // Package httputilx provides HTTP utility functions. -package httputilx // import "github.com/teamwork/utils/httputilx" +package httputilx // import "github.com/teamwork/utils/v2/httputilx" import ( "bytes" @@ -13,7 +13,7 @@ import ( "time" "github.com/pkg/errors" - "github.com/teamwork/utils/ioutilx" + "github.com/teamwork/utils/v2/ioutilx" ) // DumpBody reads the body of a HTTP request without consuming it, so it can be diff --git a/imageutil/doc.go b/imageutil/doc.go index 6b20d78..fee62d9 100644 --- a/imageutil/doc.go +++ b/imageutil/doc.go @@ -1,2 +1,2 @@ // Package imageutil adds functions for working with images. -package imageutil // import "github.com/teamwork/utils/imageutil" +package imageutil // import "github.com/teamwork/utils/v2/imageutil" diff --git a/ioutilx/copy.go b/ioutilx/copy.go index d51f17c..4273fab 100644 --- a/ioutilx/copy.go +++ b/ioutilx/copy.go @@ -13,7 +13,7 @@ import ( "time" "github.com/pkg/errors" - "github.com/teamwork/utils/sliceutil" + "github.com/teamwork/utils/v2/sliceutil" ) // ErrSameFile is used when the source and destination file are the same file. diff --git a/ioutilx/ioutilx.go b/ioutilx/ioutilx.go index b951ae1..22ef8d4 100644 --- a/ioutilx/ioutilx.go +++ b/ioutilx/ioutilx.go @@ -1,5 +1,5 @@ // Package ioutilx implements some I/O utility functions. -package ioutilx // import "github.com/teamwork/utils/ioutilx" +package ioutilx // import "github.com/teamwork/utils/v2/ioutilx" import ( "bytes" diff --git a/jsonutil/jsonutil.go b/jsonutil/jsonutil.go index f5a93e6..cee2448 100644 --- a/jsonutil/jsonutil.go +++ b/jsonutil/jsonutil.go @@ -1,5 +1,5 @@ // Package jsonutil provides functions for working with JSON. -package jsonutil // import "github.com/teamwork/utils/jsonutil" +package jsonutil // import "github.com/teamwork/utils/v2/jsonutil" import "encoding/json" diff --git a/maputil/maputil.go b/maputil/maputil.go index 008bba4..6221ce4 100644 --- a/maputil/maputil.go +++ b/maputil/maputil.go @@ -1,5 +1,5 @@ // Package maputil provides a set if functions for working with maps. -package maputil // import "github.com/teamwork/utils/maputil" +package maputil // import "github.com/teamwork/utils/v2/maputil" // Swap the keys and values of a map. func Swap[T comparable, V comparable](m map[T]V) map[V]T { diff --git a/mathutil/mathutil.go b/mathutil/mathutil.go index f292baf..1c752fd 100644 --- a/mathutil/mathutil.go +++ b/mathutil/mathutil.go @@ -1,5 +1,5 @@ // Package mathutil provides functions for working with numbers. -package mathutil // import "github.com/teamwork/utils/mathutil" +package mathutil // import "github.com/teamwork/utils/v2/mathutil" import ( "fmt" diff --git a/netutil/netutil.go b/netutil/netutil.go index 8183df8..3c4e8db 100644 --- a/netutil/netutil.go +++ b/netutil/netutil.go @@ -1,5 +1,5 @@ // Package netutil provides functions expanding on net std package. -package netutil // import "github.com/teamwork/utils/netutil" +package netutil // import "github.com/teamwork/utils/v2/netutil" import "net" diff --git a/sliceutil/sliceutil.go b/sliceutil/sliceutil.go index 4558b91..faef118 100644 --- a/sliceutil/sliceutil.go +++ b/sliceutil/sliceutil.go @@ -4,7 +4,7 @@ // "sets" (e.g. it will retain order, []int64 can contain duplicates). Consider // using something like golang-set if you want to use sets and care a lot about // performance: https://github.com/deckarep/golang-set -package sliceutil // import "github.com/teamwork/utils/sliceutil" +package sliceutil // import "github.com/teamwork/utils/v2/sliceutil" import ( "fmt" diff --git a/sqlutil/sqlutil.go b/sqlutil/sqlutil.go index 3152fde..5537d13 100644 --- a/sqlutil/sqlutil.go +++ b/sqlutil/sqlutil.go @@ -1,5 +1,5 @@ // Package sqlutil provides some helpers for SQL databases. -package sqlutil // import "github.com/teamwork/utils/sqlutil" +package sqlutil // import "github.com/teamwork/utils/v2/sqlutil" import ( "database/sql/driver" @@ -8,7 +8,7 @@ import ( "strconv" "strings" - "github.com/teamwork/utils/sliceutil" + "github.com/teamwork/utils/v2/sliceutil" ) // IntList expands comma-separated values from a column to []int64, and stores diff --git a/stringutil/stringutil.go b/stringutil/stringutil.go index d7b3fad..12b6032 100644 --- a/stringutil/stringutil.go +++ b/stringutil/stringutil.go @@ -1,5 +1,5 @@ // Package stringutil adds functions for working with strings. -package stringutil // import "github.com/teamwork/utils/stringutil" +package stringutil // import "github.com/teamwork/utils/v2/stringutil" import ( "regexp" diff --git a/syncutil/syncutil.go b/syncutil/syncutil.go index b2c71a5..06619a2 100644 --- a/syncutil/syncutil.go +++ b/syncutil/syncutil.go @@ -1,5 +1,5 @@ // Package syncutil adds functions for synchronization. -package syncutil // import "github.com/teamwork/utils/syncutil" +package syncutil // import "github.com/teamwork/utils/v2/syncutil" import ( "context" diff --git a/timeutil/timeutil.go b/timeutil/timeutil.go index 13700be..4d6da70 100644 --- a/timeutil/timeutil.go +++ b/timeutil/timeutil.go @@ -1,5 +1,5 @@ // Package timeutil provides functions for working with time. -package timeutil // import "github.com/teamwork/utils/timeutil" +package timeutil // import "github.com/teamwork/utils/v2/timeutil" import "time"