Skip to content

butuzov/mirror

Repository files navigation

mirror Stand with Ukraine Code Coverage build status

mirror suggests use of alternative functions/methods in order to gain performance boosts by avoiding unnecessary []byte/string conversion calls. See MIRROR_FUNCS.md list of mirror functions you can use in go's stdlib.

Linter Use Cases

github.com/argoproj/argo-cd

// Before
func IsValidHostname(hostname string, fqdn bool) bool {
  if !fqdn {
    return validHostNameRegexp.Match([]byte(hostname)) || validIPv6Regexp.Match([]byte(hostname))
  } else {
    return validFQDNRegexp.Match([]byte(hostname))
  }
}

// After: With alternative method (and lost `else` case)
func IsValidHostname(hostname string, fqdn bool) bool {
  if !fqdn {
    return validHostNameRegexp.MatchString(hostname) || validIPv6Regexp.MatchString(hostname)
  }

  return validFQDNRegexp.MatchString(hostname)
}

Install

go install github.com/butuzov/mirror/cmd/mirror@latest

golangci-lint

golangci-lint supports mirror since v1.53.0

How to use

You run mirror with go vet:

go vet -vettool=$(which mirror) ./...
# github.com/jcmoraisjr/haproxy-ingress/pkg/common/net/ssl
pkg/common/net/ssl/ssl.go:64:11: avoid allocations with (*os.File).WriteString
pkg/common/net/ssl/ssl.go:161:12: avoid allocations with (*os.File).WriteString
pkg/common/net/ssl/ssl.go:166:3: avoid allocations with (*os.File).WriteString

Can be called directly:

mirror ./...
# https://github.com/cosmtrek/air
/air/runner/util.go:149:6: avoid allocations with (*regexp.Regexp).MatchString
/air/runner/util.go:173:14: avoid allocations with (*os.File).WriteString

With golangci-lint

golangci-lint run --no-config --disable-all -Emirror
# github.com/argoproj/argo-cd
test/e2e/fixture/app/actions.go:83:11: avoid allocations with (*os.File).WriteString (mirror)
	_, err = tmpFile.Write([]byte(data))
	         ^
server/server.go:1166:9: avoid allocations with (*regexp.Regexp).MatchString (mirror)
	return mainJsBundleRegex.Match([]byte(filename))
	       ^
server/account/account.go:91:6: avoid allocations with (*regexp.Regexp).MatchString (mirror)
	if !validPasswordRegexp.Match([]byte(q.NewPassword)) {
	    ^
server/badge/badge.go:52:20: avoid allocations with (*regexp.Regexp).FindAllStringSubmatchIndex (mirror)
	for _, v := range re.FindAllSubmatchIndex([]byte(str), -1) {
	                  ^
util/cert/cert.go:82:10: avoid allocations with (*regexp.Regexp).MatchString (mirror)
		return validHostNameRegexp.Match([]byte(hostname)) || validIPv6Regexp.Match([]byte(hostname))

Command line

  • You can add checks for _test.go files with cli option --with-tests

golangci-lint

With golangci-lint tests are checked by default and can be can be turned off by using the regular golangci-lint ways to do it:

  • flag --tests (e.g. --tests=false)
  • flag --skip-files (e.g. --skip-files="_test.go")
  • yaml confguration run.skip-files:
    run:
      skip-files:
        - '(.+)_test\.go'
  • yaml confguration issues.exclude-rules:
      issues:
        exclude-rules:
          - path: '(.+)_test\.go'
            linters:
              - mirror

Contributing

# Update Assets (testdata/(strings|bytes|os|utf8|maphash|regexp|bufio).go)
(task|make) generated
# Run Tests
(task|make) tests
# Lint Code
(task|make) lints

About

Use right mirror functions for string/[]byte performance bust

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published