diff --git a/go.mod b/go.mod index 5c7094b8..23e3426b 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,14 @@ go 1.16 require ( github.com/AdguardTeam/dnsproxy v0.39.0 - github.com/AdguardTeam/golibs v0.8.0 + github.com/AdguardTeam/golibs v0.8.4 github.com/AdguardTeam/urlfilter v0.14.6 github.com/NYTimes/gziphandler v1.1.1 github.com/ameshkov/dnscrypt/v2 v2.2.1 github.com/digineo/go-ipset/v2 v2.2.1 github.com/fsnotify/fsnotify v1.4.9 github.com/go-ping/ping v0.0.0-20210506233800-ff8be3320020 - github.com/google/go-cmp v0.5.5 // indirect + github.com/google/go-cmp v0.5.5 github.com/google/renameio v1.0.1 github.com/insomniacslk/dhcp v0.0.0-20210310193751-cfd4d47082c2 github.com/kardianos/service v1.2.0 diff --git a/go.sum b/go.sum index 3551a8db..e7d8d7f0 100644 --- a/go.sum +++ b/go.sum @@ -9,14 +9,13 @@ dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/AdguardTeam/dhcp v0.0.0-20210519141215-51808c73c0bf h1:gc042VRSIRSUzZ+Px6xQCRWNJZTaPkomisDfUZmoFNk= github.com/AdguardTeam/dhcp v0.0.0-20210519141215-51808c73c0bf/go.mod h1:TKl4jN3Voofo4UJIicyNhWGp/nlQqQkFxmwIFTvBkKI= -github.com/AdguardTeam/dnsproxy v0.38.3 h1:DvycTEOn2wuHmY+HE5XL4EnCV2EVbpREpbgZB06IJ0I= -github.com/AdguardTeam/dnsproxy v0.38.3/go.mod h1:aNXKNdTyKfgAG2OS712SYSaGIM9AasZsZxfiY4YiR/0= github.com/AdguardTeam/dnsproxy v0.39.0 h1:5/PN2mpUeCTWtvqXUbSPTMJSOad4lJscPzm+C2f4jB4= github.com/AdguardTeam/dnsproxy v0.39.0/go.mod h1:aNXKNdTyKfgAG2OS712SYSaGIM9AasZsZxfiY4YiR/0= github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= github.com/AdguardTeam/golibs v0.4.2/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= -github.com/AdguardTeam/golibs v0.8.0 h1:rHo+yIgT2fivFG0yW2Cwk/DPc2+t/Aw6QvzPpiIFre0= github.com/AdguardTeam/golibs v0.8.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= +github.com/AdguardTeam/golibs v0.8.4 h1:jd6GwvQQtfSLOKn30qisDVujvas3q7Agjm3BOEqRWpQ= +github.com/AdguardTeam/golibs v0.8.4/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU= github.com/AdguardTeam/urlfilter v0.14.6 h1:emqoKZElooHACYehRBYENeKVN1a/rspxiqTIMYLuoIo= github.com/AdguardTeam/urlfilter v0.14.6/go.mod h1:klx4JbOfc4EaNb5lWLqOwfg+pVcyRukmoJRvO55lL5U= @@ -30,7 +29,6 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmH github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw= github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635/go.mod h1:lmLxL+FV291OopO93Bwf9fQLQeLyt33VJRUg5VJ30us= -github.com/ameshkov/dnscrypt/v2 v2.1.3 h1:DG4Uf7LSDg6XDj9sp3maxh3Ur26jeGQaP5MeYosn6v0= github.com/ameshkov/dnscrypt/v2 v2.1.3/go.mod h1:+8SbPbVXpxxcUsgGi8eodkqWPo1MyNHxKYC8hDpqLSo= github.com/ameshkov/dnscrypt/v2 v2.2.1 h1:+cApRxzeBZqjUNsN26TTz7r5A8U+buON3kJgIYE3QWQ= github.com/ameshkov/dnscrypt/v2 v2.2.1/go.mod h1:+8SbPbVXpxxcUsgGi8eodkqWPo1MyNHxKYC8hDpqLSo= @@ -109,7 +107,6 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8= github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/joomcode/errorx v1.0.1/go.mod h1:kgco15ekB6cs+4Xjzo7SPeXzx38PbJzBwbnu9qfVNHQ= github.com/joomcode/errorx v1.0.3 h1:3e1mi0u7/HTPNdg6d6DYyKGBhA5l9XpsfuVE29NxnWw= diff --git a/internal/aghnet/net.go b/internal/aghnet/net.go index ba3d053a..c063cbea 100644 --- a/internal/aghnet/net.go +++ b/internal/aghnet/net.go @@ -13,9 +13,9 @@ import ( "syscall" "time" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" ) // ErrNoStaticIPInfo is returned by IfaceHasStaticIP when no information about @@ -371,14 +371,14 @@ func ReverseAddr(ip net.IP) (arpa string) { strLen, suffix = arpaV4MaxLen, arpaV4Suffix[1:] ip = ip4 writeByte = func(val byte) { - aghstrings.WriteToBuilder(b, strconv.Itoa(int(val)), dot) + stringutil.WriteToBuilder(b, strconv.Itoa(int(val)), dot) } } else if ip6 := ip.To16(); ip6 != nil { strLen, suffix = arpaV6MaxLen, arpaV6Suffix[1:] ip = ip6 writeByte = func(val byte) { - aghstrings.WriteToBuilder( + stringutil.WriteToBuilder( b, strconv.FormatUint(uint64(val&0xF), 16), dot, @@ -395,7 +395,7 @@ func ReverseAddr(ip net.IP) (arpa string) { for i := len(ip) - 1; i >= 0; i-- { writeByte(ip[i]) } - aghstrings.WriteToBuilder(b, suffix) + stringutil.WriteToBuilder(b, suffix) return b.String() } diff --git a/internal/aghnet/net_linux.go b/internal/aghnet/net_linux.go index bf0c65d0..a646178d 100644 --- a/internal/aghnet/net_linux.go +++ b/internal/aghnet/net_linux.go @@ -14,8 +14,8 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/aghio" "github.com/AdguardTeam/AdGuardHome/internal/aghos" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/golibs/errors" + "github.com/AdguardTeam/golibs/stringutil" "github.com/google/renameio/maybe" "golang.org/x/sys/unix" ) @@ -70,7 +70,7 @@ func (rc *recurrentChecker) checkFile(sourcePath, desired string) ( } // handlePatterns parses the patterns and takes care of duplicates. -func (rc *recurrentChecker) handlePatterns(sourcesSet *aghstrings.Set, patterns []string) ( +func (rc *recurrentChecker) handlePatterns(sourcesSet *stringutil.Set, patterns []string) ( subsources []string, err error, ) { @@ -111,7 +111,7 @@ func (rc *recurrentChecker) check(desired string) (has bool, err error) { var patterns, subsources []string // The slice of sources is separate from the set of sources to keep the // order in which the files are walked. - for sourcesSet := aghstrings.NewSet(rc.initPath); i < len(sources); i++ { + for sourcesSet := stringutil.NewSet(rc.initPath); i < len(sources); i++ { patterns, has, err = rc.checkFile(sources[i], desired) if err != nil { if errors.Is(err, os.ErrNotExist) { @@ -217,7 +217,7 @@ func ifacesStaticConfig(r io.Reader, ifaceName string) (subsources []string, has s := bufio.NewScanner(r) for s.Scan() { line := strings.TrimSpace(s.Text()) - if aghstrings.IsCommentOrEmpty(line) { + if len(line) == 0 || line[0] == '#' { continue } diff --git a/internal/aghnet/systemresolvers_others.go b/internal/aghnet/systemresolvers_others.go index dae8a8dc..32c4ef0f 100644 --- a/internal/aghnet/systemresolvers_others.go +++ b/internal/aghnet/systemresolvers_others.go @@ -11,8 +11,8 @@ import ( "sync" "time" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/golibs/errors" + "github.com/AdguardTeam/golibs/stringutil" ) // defaultHostGen is the default method of generating host for Refresh. @@ -27,7 +27,7 @@ type systemResolvers struct { hostGenFunc HostGenFunc // addrs is the set that contains cached local resolvers' addresses. - addrs *aghstrings.Set + addrs *stringutil.Set addrsLock sync.RWMutex } @@ -64,7 +64,7 @@ func newSystemResolvers(refreshIvl time.Duration, hostGenFunc HostGenFunc) (sr S PreferGo: true, }, hostGenFunc: hostGenFunc, - addrs: aghstrings.NewSet(), + addrs: stringutil.NewSet(), } s.resolver.Dial = s.dialFunc diff --git a/internal/aghstrings/set.go b/internal/aghstrings/set.go deleted file mode 100644 index 4f6081ac..00000000 --- a/internal/aghstrings/set.go +++ /dev/null @@ -1,71 +0,0 @@ -package aghstrings - -// unit is a convenient alias for struct{} -type unit = struct{} - -// Set is a set of strings. -type Set struct { - m map[string]unit -} - -// NewSet returns a new string set containing strs. -func NewSet(strs ...string) (set *Set) { - set = &Set{ - m: make(map[string]unit, len(strs)), - } - - for _, s := range strs { - set.Add(s) - } - - return set -} - -// Add adds s to the set. Add panics if the set is a nil set, just like a nil -// map does. -func (set *Set) Add(s string) { - set.m[s] = unit{} -} - -// Del deletes s from the set. Calling Del on a nil set has no effect, just -// like delete on an empty map doesn't. -func (set *Set) Del(s string) { - if set != nil { - delete(set.m, s) - } -} - -// Has returns true if s is in the set. Calling Has on a nil set returns false, -// just like indexing on an empty map does. -func (set *Set) Has(s string) (ok bool) { - if set != nil { - _, ok = set.m[s] - } - - return ok -} - -// Len returns the length of the set. A nil set has a length of zero, just like -// an empty map. -func (set *Set) Len() (n int) { - if set == nil { - return 0 - } - - return len(set.m) -} - -// Values returns all values in the set. The order of the values is undefined. -// Values returns nil if the set is nil. -func (set *Set) Values() (strs []string) { - if set == nil { - return nil - } - - strs = make([]string, 0, len(set.m)) - for s := range set.m { - strs = append(strs, s) - } - - return strs -} diff --git a/internal/aghstrings/set_test.go b/internal/aghstrings/set_test.go deleted file mode 100644 index a344e8af..00000000 --- a/internal/aghstrings/set_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package aghstrings - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestSet(t *testing.T) { - const s = "a" - - t.Run("nil", func(t *testing.T) { - var set *Set - - assert.NotPanics(t, func() { - set.Del(s) - }) - - assert.NotPanics(t, func() { - assert.False(t, set.Has(s)) - }) - - assert.NotPanics(t, func() { - assert.Equal(t, 0, set.Len()) - }) - - assert.NotPanics(t, func() { - assert.Nil(t, set.Values()) - }) - - assert.Panics(t, func() { - set.Add(s) - }) - }) - - t.Run("non_nil", func(t *testing.T) { - set := NewSet() - assert.Equal(t, 0, set.Len()) - - ok := set.Has(s) - assert.False(t, ok) - - set.Add(s) - ok = set.Has(s) - assert.True(t, ok) - - assert.Equal(t, []string{s}, set.Values()) - - set.Del(s) - ok = set.Has(s) - assert.False(t, ok) - - set = NewSet(s) - assert.Equal(t, 1, set.Len()) - }) -} diff --git a/internal/aghstrings/strings.go b/internal/aghstrings/strings.go deleted file mode 100644 index 58219f9b..00000000 --- a/internal/aghstrings/strings.go +++ /dev/null @@ -1,103 +0,0 @@ -// Package aghstrings contains utilities dealing with strings. -package aghstrings - -import ( - "strings" -) - -// CloneSliceOrEmpty returns the copy of a or empty strings slice if a is nil. -func CloneSliceOrEmpty(a []string) (b []string) { - return append([]string{}, a...) -} - -// CloneSlice returns the exact copy of a. -func CloneSlice(a []string) (b []string) { - if a == nil { - return nil - } - - return CloneSliceOrEmpty(a) -} - -// Coalesce returns the first non-empty string. It is named after the function -// COALESCE in SQL except that since strings in Go are non-nullable, it uses an -// empty string as a NULL value. If strs or all it's elements are empty, it -// returns an empty string. -func Coalesce(strs ...string) (res string) { - for _, s := range strs { - if s != "" { - return s - } - } - - return "" -} - -// FilterOut returns a copy of strs with all strings for which f returned true -// removed. -func FilterOut(strs []string, f func(s string) (ok bool)) (filtered []string) { - for _, s := range strs { - if !f(s) { - filtered = append(filtered, s) - } - } - - return filtered -} - -// InSlice checks if string is in the slice of strings. -func InSlice(strs []string, str string) (ok bool) { - for _, s := range strs { - if s == str { - return true - } - } - - return false -} - -// IsCommentOrEmpty returns true of the string starts with a "#" character or is -// an empty string. -func IsCommentOrEmpty(s string) (ok bool) { - return len(s) == 0 || s[0] == '#' -} - -// SplitNext splits string by a byte and returns the first chunk skipping empty -// ones. Whitespaces are trimmed. -func SplitNext(s *string, sep rune) (chunk string) { - if s == nil { - return chunk - } - - i := strings.IndexByte(*s, byte(sep)) - if i == -1 { - chunk = *s - *s = "" - - return strings.TrimSpace(chunk) - } - - chunk = (*s)[:i] - *s = (*s)[i+1:] - var j int - var r rune - for j, r = range *s { - if r != sep { - break - } - } - - *s = (*s)[j:] - - return strings.TrimSpace(chunk) -} - -// WriteToBuilder is a convenient wrapper for strings.(*Builder).WriteString -// that deals with multiple strings and ignores errors that are guaranteed to be -// nil. -func WriteToBuilder(b *strings.Builder, strs ...string) { - // TODO(e.burkov): Recover from panic? - for _, s := range strs { - _, _ = b.WriteString(s) - } -} diff --git a/internal/aghstrings/strings_test.go b/internal/aghstrings/strings_test.go deleted file mode 100644 index 78cb2923..00000000 --- a/internal/aghstrings/strings_test.go +++ /dev/null @@ -1,137 +0,0 @@ -package aghstrings - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestCloneSlice_family(t *testing.T) { - a := []string{"1", "2", "3"} - - t.Run("cloneslice_simple", func(t *testing.T) { - assert.Equal(t, a, CloneSlice(a)) - }) - - t.Run("cloneslice_nil", func(t *testing.T) { - assert.Nil(t, CloneSlice(nil)) - }) - - t.Run("cloneslice_empty", func(t *testing.T) { - assert.Equal(t, []string{}, CloneSlice([]string{})) - }) - - t.Run("clonesliceorempty_nil", func(t *testing.T) { - assert.Equal(t, []string{}, CloneSliceOrEmpty(nil)) - }) - - t.Run("clonesliceorempty_empty", func(t *testing.T) { - assert.Equal(t, []string{}, CloneSliceOrEmpty([]string{})) - }) - - t.Run("clonesliceorempty_sameness", func(t *testing.T) { - assert.Equal(t, CloneSlice(a), CloneSliceOrEmpty(a)) - }) -} - -func TestCoalesce(t *testing.T) { - assert.Equal(t, "", Coalesce()) - assert.Equal(t, "a", Coalesce("a")) - assert.Equal(t, "a", Coalesce("", "a")) - assert.Equal(t, "a", Coalesce("a", "")) - assert.Equal(t, "a", Coalesce("a", "b")) -} - -func TestFilterOut(t *testing.T) { - strs := []string{ - "1.2.3.4", - "", - "# 5.6.7.8", - } - - want := []string{ - "1.2.3.4", - } - - got := FilterOut(strs, IsCommentOrEmpty) - assert.Equal(t, want, got) -} - -func TestInSlice(t *testing.T) { - simpleStrs := []string{"1", "2", "3"} - - testCases := []struct { - name string - str string - strs []string - want bool - }{{ - name: "yes", - str: "2", - strs: simpleStrs, - want: true, - }, { - name: "no", - str: "4", - strs: simpleStrs, - want: false, - }, { - name: "nil", - str: "any", - strs: nil, - want: false, - }} - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - assert.Equal(t, tc.want, InSlice(tc.strs, tc.str)) - }) - } -} - -func TestSplitNext(t *testing.T) { - t.Run("ordinary", func(t *testing.T) { - s := " a,b , c " - require.Equal(t, "a", SplitNext(&s, ',')) - require.Equal(t, "b", SplitNext(&s, ',')) - require.Equal(t, "c", SplitNext(&s, ',')) - - assert.Empty(t, s) - }) - - t.Run("nil_source", func(t *testing.T) { - assert.Equal(t, "", SplitNext(nil, 's')) - }) -} - -func TestWriteToBuilder(t *testing.T) { - b := &strings.Builder{} - - t.Run("single", func(t *testing.T) { - assert.NotPanics(t, func() { WriteToBuilder(b, t.Name()) }) - assert.Equal(t, t.Name(), b.String()) - }) - - b.Reset() - t.Run("several", func(t *testing.T) { - const ( - _1 = "one" - _2 = "two" - _123 = _1 + _2 - ) - assert.NotPanics(t, func() { WriteToBuilder(b, _1, _2) }) - assert.Equal(t, _123, b.String()) - }) - - b.Reset() - t.Run("nothing", func(t *testing.T) { - assert.NotPanics(t, func() { WriteToBuilder(b) }) - assert.Equal(t, "", b.String()) - }) - - t.Run("nil_builder", func(t *testing.T) { - assert.Panics(t, func() { WriteToBuilder(nil, "a") }) - }) -} diff --git a/internal/dhcpd/v4.go b/internal/dhcpd/v4.go index 9725a05f..654e0c0e 100644 --- a/internal/dhcpd/v4.go +++ b/internal/dhcpd/v4.go @@ -12,9 +12,9 @@ import ( "time" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" "github.com/go-ping/ping" "github.com/insomniacslk/dhcp/dhcpv4" "github.com/insomniacslk/dhcp/dhcpv4/server4" @@ -32,7 +32,7 @@ type v4Server struct { leasedOffsets *bitSet // leaseHosts is the set of all hostnames of all known DHCP clients. - leaseHosts *aghstrings.Set + leaseHosts *stringutil.Set // leases contains all dynamic and static leases. leases []*Lease @@ -105,7 +105,7 @@ func (s *v4Server) ResetLeases(leases []*Lease) (err error) { } s.leasedOffsets = newBitSet() - s.leaseHosts = aghstrings.NewSet() + s.leaseHosts = stringutil.NewSet() s.leases = nil for _, l := range leases { @@ -1017,7 +1017,7 @@ func (s *v4Server) Stop() (err error) { func v4Create(conf V4ServerConf) (srv DHCPServer, err error) { s := &v4Server{} s.conf = conf - s.leaseHosts = aghstrings.NewSet() + s.leaseHosts = stringutil.NewSet() // TODO(a.garipov): Don't use a disabled server in other places or just // use an interface. diff --git a/internal/dnsforward/access.go b/internal/dnsforward/access.go index c53d6e63..bbf899c9 100644 --- a/internal/dnsforward/access.go +++ b/internal/dnsforward/access.go @@ -8,8 +8,8 @@ import ( "strings" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" "github.com/AdguardTeam/urlfilter" "github.com/AdguardTeam/urlfilter/filterlist" ) @@ -20,8 +20,8 @@ type accessCtx struct { allowedIPs *aghnet.IPMap blockedIPs *aghnet.IPMap - allowedClientIDs *aghstrings.Set - blockedClientIDs *aghstrings.Set + allowedClientIDs *stringutil.Set + blockedClientIDs *stringutil.Set blockedHostsEng *urlfilter.DNSEngine @@ -40,7 +40,7 @@ func processAccessClients( clientStrs []string, ips *aghnet.IPMap, nets *[]*net.IPNet, - clientIDs *aghstrings.Set, + clientIDs *stringutil.Set, ) (err error) { for i, s := range clientStrs { if ip := net.ParseIP(s); ip != nil { @@ -71,8 +71,8 @@ func newAccessCtx(allowed, blocked, blockedHosts []string) (a *accessCtx, err er allowedIPs: aghnet.NewIPMap(0), blockedIPs: aghnet.NewIPMap(0), - allowedClientIDs: aghstrings.NewSet(), - blockedClientIDs: aghstrings.NewSet(), + allowedClientIDs: stringutil.NewSet(), + blockedClientIDs: stringutil.NewSet(), } err = processAccessClients(allowed, a.allowedIPs, &a.allowedNets, a.allowedClientIDs) @@ -87,7 +87,7 @@ func newAccessCtx(allowed, blocked, blockedHosts []string) (a *accessCtx, err er b := &strings.Builder{} for _, h := range blockedHosts { - aghstrings.WriteToBuilder(b, strings.ToLower(h), "\n") + stringutil.WriteToBuilder(b, strings.ToLower(h), "\n") } lists := []filterlist.RuleList{ @@ -174,9 +174,9 @@ func (s *Server) accessListJSON() (j accessListJSON) { defer s.serverLock.RUnlock() return accessListJSON{ - AllowedClients: aghstrings.CloneSlice(s.conf.AllowedClients), - DisallowedClients: aghstrings.CloneSlice(s.conf.DisallowedClients), - BlockedHosts: aghstrings.CloneSlice(s.conf.BlockedHosts), + AllowedClients: stringutil.CloneSlice(s.conf.AllowedClients), + DisallowedClients: stringutil.CloneSlice(s.conf.DisallowedClients), + BlockedHosts: stringutil.CloneSlice(s.conf.BlockedHosts), } } diff --git a/internal/dnsforward/config.go b/internal/dnsforward/config.go index 712a26c0..201bcb82 100644 --- a/internal/dnsforward/config.go +++ b/internal/dnsforward/config.go @@ -12,12 +12,12 @@ import ( "time" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/upstream" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" "github.com/ameshkov/dnscrypt/v2" ) @@ -327,17 +327,15 @@ func (s *Server) prepareUpstreamSettings() error { if err != nil { return err } - d := string(data) - for len(d) != 0 { - s := aghstrings.SplitNext(&d, '\n') - upstreams = append(upstreams, s) - } + + upstreams = stringutil.SplitTrimmed(string(data), "\n") + log.Debug("dns: using %d upstream servers from file %s", len(upstreams), s.conf.UpstreamDNSFileName) } else { upstreams = s.conf.UpstreamDNS } - upstreams = aghstrings.FilterOut(upstreams, aghstrings.IsCommentOrEmpty) + upstreams = stringutil.FilterOut(upstreams, IsCommentOrEmpty) upstreamConfig, err := proxy.ParseUpstreamsConfig( upstreams, &upstream.Options{ diff --git a/internal/dnsforward/dns.go b/internal/dnsforward/dns.go index 120c1d64..b11406f6 100644 --- a/internal/dnsforward/dns.go +++ b/internal/dnsforward/dns.go @@ -6,11 +6,11 @@ import ( "time" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/AdGuardHome/internal/dhcpd" "github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" "github.com/miekg/dns" ) @@ -518,7 +518,7 @@ func (s *Server) processUpstream(ctx *dnsContext) (rc resultCode) { if d.Addr != nil && s.conf.GetCustomUpstreamByClient != nil { // Use the clientID first, since it has a higher priority. - id := aghstrings.Coalesce(ctx.clientID, ipStringFromAddr(d.Addr)) + id := stringutil.Coalesce(ctx.clientID, ipStringFromAddr(d.Addr)) upsConf, err := s.conf.GetCustomUpstreamByClient(id) if err != nil { log.Error("dns: getting custom upstreams for client %s: %s", id, err) diff --git a/internal/dnsforward/dnsforward.go b/internal/dnsforward/dnsforward.go index 63bb58f7..3af2e74c 100644 --- a/internal/dnsforward/dnsforward.go +++ b/internal/dnsforward/dnsforward.go @@ -11,7 +11,6 @@ import ( "time" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/AdGuardHome/internal/dhcpd" "github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/AdGuardHome/internal/querylog" @@ -21,6 +20,7 @@ import ( "github.com/AdguardTeam/golibs/cache" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" "github.com/miekg/dns" ) @@ -222,13 +222,13 @@ func (s *Server) WriteDiskConfig(c *FilteringConfig) { sc := s.conf.FilteringConfig *c = sc - c.RatelimitWhitelist = aghstrings.CloneSlice(sc.RatelimitWhitelist) - c.BootstrapDNS = aghstrings.CloneSlice(sc.BootstrapDNS) - c.AllowedClients = aghstrings.CloneSlice(sc.AllowedClients) - c.DisallowedClients = aghstrings.CloneSlice(sc.DisallowedClients) - c.BlockedHosts = aghstrings.CloneSlice(sc.BlockedHosts) - c.TrustedProxies = aghstrings.CloneSlice(sc.TrustedProxies) - c.UpstreamDNS = aghstrings.CloneSlice(sc.UpstreamDNS) + c.RatelimitWhitelist = stringutil.CloneSlice(sc.RatelimitWhitelist) + c.BootstrapDNS = stringutil.CloneSlice(sc.BootstrapDNS) + c.AllowedClients = stringutil.CloneSlice(sc.AllowedClients) + c.DisallowedClients = stringutil.CloneSlice(sc.DisallowedClients) + c.BlockedHosts = stringutil.CloneSlice(sc.BlockedHosts) + c.TrustedProxies = stringutil.CloneSlice(sc.TrustedProxies) + c.UpstreamDNS = stringutil.CloneSlice(sc.UpstreamDNS) } // RDNSSettings returns the copy of actual RDNS configuration. @@ -236,7 +236,7 @@ func (s *Server) RDNSSettings() (localPTRResolvers []string, resolveClients, res s.serverLock.RLock() defer s.serverLock.RUnlock() - return aghstrings.CloneSlice(s.conf.LocalPTRResolvers), + return stringutil.CloneSlice(s.conf.LocalPTRResolvers), s.conf.ResolveClients, s.conf.UsePrivateRDNS } @@ -398,13 +398,13 @@ func (s *Server) filterOurDNSAddrs(addrs []string) (filtered []string, err error return nil, err } - ourAddrsSet := aghstrings.NewSet(ourAddrs...) + ourAddrsSet := stringutil.NewSet(ourAddrs...) // TODO(e.burkov): The approach of subtracting sets of strings is not // really applicable here since in case of listening on all network // interfaces we should check the whole interface's network to cut off // all the loopback addresses as well. - return aghstrings.FilterOut(addrs, ourAddrsSet.Has), nil + return stringutil.FilterOut(addrs, ourAddrsSet.Has), nil } // setupResolvers initializes the resolvers for local addresses. For internal diff --git a/internal/dnsforward/http.go b/internal/dnsforward/http.go index f72af780..ba163691 100644 --- a/internal/dnsforward/http.go +++ b/internal/dnsforward/http.go @@ -10,11 +10,11 @@ import ( "time" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/upstream" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" "github.com/miekg/dns" ) @@ -51,9 +51,9 @@ func (s *Server) getDNSConfig() dnsConfig { s.serverLock.RLock() defer s.serverLock.RUnlock() - upstreams := aghstrings.CloneSliceOrEmpty(s.conf.UpstreamDNS) + upstreams := stringutil.CloneSliceOrEmpty(s.conf.UpstreamDNS) upstreamFile := s.conf.UpstreamDNSFileName - bootstraps := aghstrings.CloneSliceOrEmpty(s.conf.BootstrapDNS) + bootstraps := stringutil.CloneSliceOrEmpty(s.conf.BootstrapDNS) protectionEnabled := s.conf.ProtectionEnabled blockingMode := s.conf.BlockingMode blockingIPv4 := s.conf.BlockingIPv4 @@ -68,7 +68,7 @@ func (s *Server) getDNSConfig() dnsConfig { cacheOptimistic := s.conf.CacheOptimistic resolveClients := s.conf.ResolveClients usePrivateRDNS := s.conf.UsePrivateRDNS - localPTRUpstreams := aghstrings.CloneSliceOrEmpty(s.conf.LocalPTRResolvers) + localPTRUpstreams := stringutil.CloneSliceOrEmpty(s.conf.LocalPTRResolvers) var upstreamMode string if s.conf.FastestAddr { upstreamMode = "fastest_addr" @@ -341,13 +341,20 @@ type upstreamJSON struct { PrivateUpstreams []string `json:"private_upstream"` } +// IsCommentOrEmpty returns true of the string starts with a "#" character or is +// an empty string. This function is useful for filtering out non-upstream +// lines from upstream configs. +func IsCommentOrEmpty(s string) (ok bool) { + return len(s) == 0 || s[0] == '#' +} + // ValidateUpstreams validates each upstream and returns an error if any // upstream is invalid or if there are no default upstreams specified. // // TODO(e.burkov): Move into aghnet or even into dnsproxy. func ValidateUpstreams(upstreams []string) (err error) { // No need to validate comments - upstreams = aghstrings.FilterOut(upstreams, aghstrings.IsCommentOrEmpty) + upstreams = stringutil.FilterOut(upstreams, IsCommentOrEmpty) // Consider this case valid because defaultDNS will be used if len(upstreams) == 0 { @@ -529,7 +536,7 @@ func checkPrivateUpstreamExc(u upstream.Upstream) (err error) { } func checkDNS(input string, bootstrap []string, timeout time.Duration, ef excFunc) (err error) { - if aghstrings.IsCommentOrEmpty(input) { + if IsCommentOrEmpty(input) { return nil } diff --git a/internal/dnsforward/http_test.go b/internal/dnsforward/http_test.go index 582317ec..cb6fa924 100644 --- a/internal/dnsforward/http_test.go +++ b/internal/dnsforward/http_test.go @@ -241,6 +241,12 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) { } } +func TestIsCommentOrEmpty(t *testing.T) { + assert.True(t, IsCommentOrEmpty("")) + assert.True(t, IsCommentOrEmpty("# comment")) + assert.False(t, IsCommentOrEmpty("1.2.3.4")) +} + // TODO(a.garipov): Rewrite to check the actual error messages. func TestValidateUpstream(t *testing.T) { testCases := []struct { diff --git a/internal/filtering/filtering.go b/internal/filtering/filtering.go index 033f950f..acf1c6d2 100644 --- a/internal/filtering/filtering.go +++ b/internal/filtering/filtering.go @@ -14,10 +14,10 @@ import ( "sync/atomic" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/dnsproxy/upstream" "github.com/AdguardTeam/golibs/cache" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" "github.com/AdguardTeam/urlfilter" "github.com/AdguardTeam/urlfilter/filterlist" "github.com/AdguardTeam/urlfilter/rules" @@ -497,7 +497,7 @@ func (d *DNSFilter) processRewrites(host string, qtype uint16) (res Result) { res.Reason = Rewritten } - cnames := aghstrings.NewSet() + cnames := stringutil.NewSet() origHost := host for len(rr) != 0 && rr[0].Type == dns.TypeCNAME { log.Debug("rewrite: CNAME for %s is %s", host, rr[0].Answer) diff --git a/internal/filtering/safebrowsing.go b/internal/filtering/safebrowsing.go index e2c86c5e..d535a39d 100644 --- a/internal/filtering/safebrowsing.go +++ b/internal/filtering/safebrowsing.go @@ -13,10 +13,10 @@ import ( "strings" "time" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/dnsproxy/upstream" "github.com/AdguardTeam/golibs/cache" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" "github.com/miekg/dns" "golang.org/x/net/publicsuffix" ) @@ -186,16 +186,16 @@ func (c *sbCtx) getQuestion() string { for hash := range c.hashToHost { // TODO(e.burkov, a.garipov): Find out and document why exactly // this slice. - aghstrings.WriteToBuilder(b, hex.EncodeToString(hash[0:2]), ".") + stringutil.WriteToBuilder(b, hex.EncodeToString(hash[0:2]), ".") } if c.svc == "SafeBrowsing" { - aghstrings.WriteToBuilder(b, sbTXTSuffix) + stringutil.WriteToBuilder(b, sbTXTSuffix) return b.String() } - aghstrings.WriteToBuilder(b, pcTXTSuffix) + stringutil.WriteToBuilder(b, pcTXTSuffix) return b.String() } diff --git a/internal/home/clients.go b/internal/home/clients.go index c33edbab..5fc81068 100644 --- a/internal/home/clients.go +++ b/internal/home/clients.go @@ -12,7 +12,6 @@ import ( "time" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/AdGuardHome/internal/dhcpd" "github.com/AdguardTeam/AdGuardHome/internal/dnsforward" "github.com/AdguardTeam/AdGuardHome/internal/filtering" @@ -21,6 +20,7 @@ import ( "github.com/AdguardTeam/dnsproxy/upstream" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" ) const clientsUpdatePeriod = 10 * time.Minute @@ -86,7 +86,7 @@ type clientsContainer struct { lock sync.Mutex - allTags *aghstrings.Set + allTags *stringutil.Set // dhcpServer is used for looking up clients IP addresses by MAC addresses dhcpServer *dhcpd.Server @@ -114,7 +114,7 @@ func (clients *clientsContainer) Init( clients.idIndex = make(map[string]*Client) clients.ipToRC = aghnet.NewIPMap(0) - clients.allTags = aghstrings.NewSet(clientTags...) + clients.allTags = stringutil.NewSet(clientTags...) clients.dhcpServer = dhcpServer clients.etcHosts = etcHosts @@ -221,10 +221,10 @@ func (clients *clientsContainer) WriteDiskConfig(objects *[]clientObject) { UseGlobalBlockedServices: !cli.UseOwnBlockedServices, } - cy.Tags = aghstrings.CloneSlice(cli.Tags) - cy.IDs = aghstrings.CloneSlice(cli.IDs) - cy.BlockedServices = aghstrings.CloneSlice(cli.BlockedServices) - cy.Upstreams = aghstrings.CloneSlice(cli.Upstreams) + cy.Tags = stringutil.CloneSlice(cli.Tags) + cy.IDs = stringutil.CloneSlice(cli.IDs) + cy.BlockedServices = stringutil.CloneSlice(cli.BlockedServices) + cy.Upstreams = stringutil.CloneSlice(cli.Upstreams) *objects = append(*objects, cy) } @@ -328,10 +328,10 @@ func (clients *clientsContainer) Find(id string) (c *Client, ok bool) { return nil, false } - c.IDs = aghstrings.CloneSlice(c.IDs) - c.Tags = aghstrings.CloneSlice(c.Tags) - c.BlockedServices = aghstrings.CloneSlice(c.BlockedServices) - c.Upstreams = aghstrings.CloneSlice(c.Upstreams) + c.IDs = stringutil.CloneSlice(c.IDs) + c.Tags = stringutil.CloneSlice(c.Tags) + c.BlockedServices = stringutil.CloneSlice(c.BlockedServices) + c.Upstreams = stringutil.CloneSlice(c.Upstreams) return c, true } @@ -349,7 +349,7 @@ func (clients *clientsContainer) findUpstreams( return nil, nil } - upstreams := aghstrings.FilterOut(c.Upstreams, aghstrings.IsCommentOrEmpty) + upstreams := stringutil.FilterOut(c.Upstreams, dnsforward.IsCommentOrEmpty) if len(upstreams) == 0 { return nil, nil } diff --git a/internal/home/i18n.go b/internal/home/i18n.go index 8df158a5..26b8a3ac 100644 --- a/internal/home/i18n.go +++ b/internal/home/i18n.go @@ -6,12 +6,12 @@ import ( "net/http" "strings" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" ) // TODO(a.garipov): Get rid of a global variable? -var allowedLanguages = aghstrings.NewSet( +var allowedLanguages = stringutil.NewSet( "be", "bg", "cs", diff --git a/internal/home/rdns_test.go b/internal/home/rdns_test.go index a4a37c2c..c125bf5e 100644 --- a/internal/home/rdns_test.go +++ b/internal/home/rdns_test.go @@ -9,12 +9,12 @@ import ( "time" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/AdGuardHome/internal/aghtest" "github.com/AdguardTeam/dnsproxy/upstream" "github.com/AdguardTeam/golibs/cache" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" "github.com/miekg/dns" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -86,7 +86,7 @@ func TestRDNS_Begin(t *testing.T) { list: map[string]*Client{}, idIndex: tc.cliIDIndex, ipToRC: aghnet.NewIPMap(0), - allTags: aghstrings.NewSet(), + allTags: stringutil.NewSet(), }, } ipCache.Clear() @@ -206,7 +206,7 @@ func TestRDNS_WorkerLoop(t *testing.T) { list: map[string]*Client{}, idIndex: map[string]*Client{}, ipToRC: aghnet.NewIPMap(0), - allTags: aghstrings.NewSet(), + allTags: stringutil.NewSet(), } ch := make(chan net.IP) rdns := &RDNS{ diff --git a/internal/home/tls.go b/internal/home/tls.go index d2420093..57df2da6 100644 --- a/internal/home/tls.go +++ b/internal/home/tls.go @@ -14,7 +14,6 @@ import ( "net/http" "os" "path/filepath" - "reflect" "runtime" "strings" "sync" @@ -22,6 +21,7 @@ import ( "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" + "github.com/google/go-cmp/cmp" "golang.org/x/sys/cpu" ) @@ -270,8 +270,9 @@ func (t *TLSMod) handleTLSConfigure(w http.ResponseWriter, r *http.Request) { } status = validateCertificates(string(data.CertificateChainData), string(data.PrivateKeyData), data.ServerName) restartHTTPS := false + t.confLock.Lock() - if !reflect.DeepEqual(t.conf, data) { + if !cmp.Equal(t.conf, data) { log.Printf("tls config settings have changed, will restart HTTPS server") restartHTTPS = true } diff --git a/internal/home/whois.go b/internal/home/whois.go index 040e7210..d7543faa 100644 --- a/internal/home/whois.go +++ b/internal/home/whois.go @@ -10,10 +10,10 @@ import ( "time" "github.com/AdguardTeam/AdGuardHome/internal/aghio" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/golibs/cache" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" ) const ( @@ -107,7 +107,7 @@ func whoisParse(data string) (m strmap) { v = trimValue(v) case "descr", "netname": k = "orgname" - v = aghstrings.Coalesce(orgname, v) + v = stringutil.Coalesce(orgname, v) orgname = v case "whois": k = "whois" diff --git a/internal/querylog/http.go b/internal/querylog/http.go index f81552c2..7d7c0493 100644 --- a/internal/querylog/http.go +++ b/internal/querylog/http.go @@ -9,9 +9,9 @@ import ( "strings" "time" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/golibs/jsonutil" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/stringutil" "golang.org/x/net/idna" ) @@ -160,7 +160,7 @@ func (l *queryLog) parseSearchCriterion(q url.Values, name string, ct criterionT asciiVal = "" } case ctFilteringStatus: - if !aghstrings.InSlice(filteringStatusValues, val) { + if !stringutil.InSlice(filteringStatusValues, val) { return false, sc, fmt.Errorf("invalid value %s", val) } default: diff --git a/internal/version/version.go b/internal/version/version.go index e882c190..90bbd7dd 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -8,7 +8,7 @@ import ( "strconv" "strings" - "github.com/AdguardTeam/AdGuardHome/internal/aghstrings" + "github.com/AdguardTeam/golibs/stringutil" ) // Channel constants. @@ -93,16 +93,16 @@ func fmtModule(m *debug.Module) (formatted string) { b := &strings.Builder{} - aghstrings.WriteToBuilder(b, m.Path) + stringutil.WriteToBuilder(b, m.Path) if ver := m.Version; ver != "" { sep := modInfoAtSep if ver == "(devel)" { sep = modInfoDevSep } - aghstrings.WriteToBuilder(b, sep, ver) + stringutil.WriteToBuilder(b, sep, ver) } if sum := m.Sum; sum != "" { - aghstrings.WriteToBuilder(b, modInfoSumLeft, sum, modInfoSumRight) + stringutil.WriteToBuilder(b, modInfoSumLeft, sum, modInfoSumRight) } return b.String() @@ -142,7 +142,7 @@ const ( func Verbose() (v string) { b := &strings.Builder{} - aghstrings.WriteToBuilder( + stringutil.WriteToBuilder( b, vFmtAGHHdr, nl, @@ -156,15 +156,15 @@ func Verbose() (v string) { runtime.Version(), ) if buildtime != "" { - aghstrings.WriteToBuilder(b, nl, vFmtTimeHdr, buildtime) + stringutil.WriteToBuilder(b, nl, vFmtTimeHdr, buildtime) } - aghstrings.WriteToBuilder(b, nl, vFmtGOOSHdr, nl, vFmtGOARCHHdr) + stringutil.WriteToBuilder(b, nl, vFmtGOOSHdr, nl, vFmtGOARCHHdr) if goarm != "" { - aghstrings.WriteToBuilder(b, nl, vFmtGOARMHdr, "v", goarm) + stringutil.WriteToBuilder(b, nl, vFmtGOARMHdr, "v", goarm) } else if gomips != "" { - aghstrings.WriteToBuilder(b, nl, vFmtGOMIPSHdr, gomips) + stringutil.WriteToBuilder(b, nl, vFmtGOMIPSHdr, gomips) } - aghstrings.WriteToBuilder(b, nl, vFmtRaceHdr, strconv.FormatBool(isRace)) + stringutil.WriteToBuilder(b, nl, vFmtRaceHdr, strconv.FormatBool(isRace)) info, ok := debug.ReadBuildInfo() if !ok { @@ -175,10 +175,10 @@ func Verbose() (v string) { return b.String() } - aghstrings.WriteToBuilder(b, nl, vFmtDepsHdr) + stringutil.WriteToBuilder(b, nl, vFmtDepsHdr) for _, dep := range info.Deps { if depStr := fmtModule(dep); depStr != "" { - aghstrings.WriteToBuilder(b, nltb, depStr) + stringutil.WriteToBuilder(b, nltb, depStr) } } diff --git a/scripts/hooks/pre-commit b/scripts/hooks/pre-commit index 6c2e5d34..b52735b1 100755 --- a/scripts/hooks/pre-commit +++ b/scripts/hooks/pre-commit @@ -4,29 +4,32 @@ set -e -f -u # Show all temporary todos to the programmer but don't fail the commit # if there are any, because the commit could be in a temporary branch. -git grep -e 'TODO.*!!' -- ':!HACKING.md' ':!scripts/hooks/pre-commit' | cat || : +git grep -e 'TODO.*!!' -- ':!scripts/hooks/pre-commit' | cat || : + +verbose="${VERBOSE:-0}" +readonly verbose if [ "$( git diff --cached --name-only -- 'client/*.js' )" ] then - make js-lint js-test + make VERBOSE="$verbose" js-lint js-test fi if [ "$( git diff --cached --name-only -- 'client2/*.js' 'client2/*.ts' 'client2/*.tsx' )" ] then - make js-beta-lint js-beta-test + make VERBOSE="$verbose" js-beta-lint js-beta-test fi if [ "$( git diff --cached --name-only -- '*.go' '*.mod' '*.sh' 'Makefile' )" ] then - make go-os-check go-lint go-test + make VERBOSE="$verbose" go-os-check go-lint go-test fi if [ "$( git diff --cached --name-only -- '*.md' '*.yaml' '*.yml' )" ] then - make txt-lint + make VERBOSE="$verbose" txt-lint fi if [ "$( git diff --cached --name-only -- './openapi/openapi.yaml' )" ] then - make openapi-lint + make VERBOSE="$verbose" openapi-lint fi diff --git a/scripts/make/go-lint.sh b/scripts/make/go-lint.sh index 1a94ae6b..d3585f19 100644 --- a/scripts/make/go-lint.sh +++ b/scripts/make/go-lint.sh @@ -73,11 +73,31 @@ esac # Simple Analyzers -# blocklist_imports is a simple check against unwanted packages. Package -# io/ioutil is soft-deprecated. Packages errors and log are replaced by our own -# packages in the github.com/AdguardTeam/golibs module. +# blocklist_imports is a simple check against unwanted packages. The following +# packages are banned: +# +# * Package io/ioutil is soft-deprecated. +# +# * Packages errors and log are replaced by our own packages in the +# github.com/AdguardTeam/golibs module. +# +# * Package reflect is often an overkill, and for deep comparisons there are +# much better functions in module github.com/google/go-cmp. Which is +# already our indirect dependency and which may or may not enter the stdlib +# at some point. +# +# See https://github.com/golang/go/issues/45200. +# +# * Package unsafe is… unsafe. +# blocklist_imports() { - git grep -F -e '"errors"' -e '"io/ioutil"' -e '"log"' -- '*.go' || exit 0; + git grep\ + -e '[[:space:]]"errors"$'\ + -e '[[:space:]]"io/ioutil"$'\ + -e '[[:space:]]"log"$'\ + -e '[[:space:]]"reflect"$'\ + -e '[[:space:]]"unsafe"$'\ + -- '*.go' || exit 0; } # method_const is a simple check against the usage of some raw strings and @@ -181,8 +201,7 @@ gocyclo --over 17 ./internal/dhcpd/ ./internal/dnsforward/\ # Apply stricter standards to new or vetted code gocyclo --over 10 ./internal/aghio/ ./internal/aghnet/ ./internal/aghos/\ - ./internal/aghstrings/ ./internal/aghtest/ ./internal/tools/\ - ./internal/version/ ./main.go + ./internal/aghtest/ ./internal/tools/ ./internal/version/ ./main.go gosec --quiet $go_files