From f072d55e6d43fda481d8a6fa898041294a810a0a Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 12 Sep 2022 09:19:06 +0200 Subject: [PATCH] dev: add doc about internal package extracted from Go (#3204) --- .golangci.yml | 9 ++++----- internal/cache/cache.go | 9 ++++----- internal/cache/readme.md | 18 ++++++++++++++++++ internal/renameio/readme.md | 10 ++++++++++ internal/renameio/umask_test.go | 2 +- internal/robustio/readme.md | 6 ++++++ internal/robustio/robustio.go | 6 +++--- internal/robustio/robustio_darwin.go | 14 +++----------- internal/robustio/robustio_flaky.go | 13 ++++++------- internal/robustio/robustio_other.go | 2 +- internal/robustio/robustio_windows.go | 17 +++++++---------- pkg/golinters/goanalysis/runner_action.go | 3 ++- 12 files changed, 65 insertions(+), 44 deletions(-) create mode 100644 internal/cache/readme.md create mode 100644 internal/renameio/readme.md create mode 100644 internal/robustio/readme.md diff --git a/.golangci.yml b/.golangci.yml index 6ed4e879..3e0c4511 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -138,9 +138,8 @@ issues: run: timeout: 5m - go: '1.17' # TODO(ldez): we force to use an old version of Go for the CI and the tests. skip-dirs: - - test/testdata_etc - - internal/cache - - internal/renameio - - internal/robustio + - test/testdata_etc # test files + - internal/cache # extracted from Go code + - internal/renameio # extracted from Go code + - internal/robustio # extracted from Go code diff --git a/internal/cache/cache.go b/internal/cache/cache.go index fefb3998..e9638c8e 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -51,7 +51,6 @@ type Cache struct { // to share a cache directory (for example, if the directory were stored // in a network file system). File locking is notoriously unreliable in // network file systems and may not suffice to protect the cache. -// func Open(dir string) (*Cache, error) { info, err := os.Stat(dir) if err != nil { @@ -159,7 +158,7 @@ func (c *Cache) get(id ActionID) (Entry, error) { defer f.Close() entry := make([]byte, entrySize+1) // +1 to detect whether f is too long if n, readErr := io.ReadFull(f, entry); n != entrySize || readErr != io.ErrUnexpectedEOF { - return failed(fmt.Errorf("read %d/%d bytes from %s with error %s", n, entrySize, fileName, readErr)) + return failed(fmt.Errorf("read %d/%d bytes from %s with error %w", n, entrySize, fileName, readErr)) } if entry[0] != 'v' || entry[1] != '1' || entry[2] != ' ' || entry[3+hexSize] != ' ' || entry[3+hexSize+1+hexSize] != ' ' || entry[3+hexSize+1+hexSize+1+20] != ' ' || entry[entrySize-1] != '\n' { return failed(fmt.Errorf("bad data in %s", fileName)) @@ -181,7 +180,7 @@ func (c *Cache) get(id ActionID) (Entry, error) { } size, err := strconv.ParseInt(string(esize[i:]), 10, 64) if err != nil || size < 0 { - return failed(fmt.Errorf("failed to parse esize int from %s with error %s", fileName, err)) + return failed(fmt.Errorf("failed to parse esize int from %s with error %w", fileName, err)) } i = 0 for i < len(etime) && etime[i] == ' ' { @@ -189,7 +188,7 @@ func (c *Cache) get(id ActionID) (Entry, error) { } tm, err := strconv.ParseInt(string(etime[i:]), 10, 64) if err != nil || tm < 0 { - return failed(fmt.Errorf("failed to parse etime int from %s with error %s", fileName, err)) + return failed(fmt.Errorf("failed to parse etime int from %s with error %w", fileName, err)) } if err = c.used(fileName); err != nil { @@ -498,7 +497,7 @@ func (c *Cache) copyFile(file io.ReadSeeker, out OutputID, size int64) error { return err } if n, wErr := h.Write(buf); n != len(buf) { - return fmt.Errorf("wrote to hash %d/%d bytes with error %s", n, len(buf), wErr) + return fmt.Errorf("wrote to hash %d/%d bytes with error %w", n, len(buf), wErr) } sum := h.Sum(nil) diff --git a/internal/cache/readme.md b/internal/cache/readme.md new file mode 100644 index 00000000..b469711e --- /dev/null +++ b/internal/cache/readme.md @@ -0,0 +1,18 @@ +# cache + +Extracted from go/src/cmd/go/internal/cache/ +I don't know what version of Go this package was pulled from. + +Adapted for golangci-lint: +- https://github.com/golangci/golangci-lint/pull/699 +- https://github.com/golangci/golangci-lint/pull/779 +- https://github.com/golangci/golangci-lint/pull/788 +- https://github.com/golangci/golangci-lint/pull/808 +- https://github.com/golangci/golangci-lint/pull/1063 +- https://github.com/golangci/golangci-lint/pull/1070 +- https://github.com/golangci/golangci-lint/pull/1162 +- https://github.com/golangci/golangci-lint/pull/2318 +- https://github.com/golangci/golangci-lint/pull/2352 +- https://github.com/golangci/golangci-lint/pull/3012 +- https://github.com/golangci/golangci-lint/pull/3096 +- https://github.com/golangci/golangci-lint/pull/3204 diff --git a/internal/renameio/readme.md b/internal/renameio/readme.md new file mode 100644 index 00000000..36ec6ed4 --- /dev/null +++ b/internal/renameio/readme.md @@ -0,0 +1,10 @@ +# renameio + +Extracted from go/src/cmd/go/internal/renameio/ +I don't know what version of Go this package was pulled from. + +Adapted for golangci-lint: +- https://github.com/golangci/golangci-lint/pull/699 +- https://github.com/golangci/golangci-lint/pull/808 +- https://github.com/golangci/golangci-lint/pull/1063 +- https://github.com/golangci/golangci-lint/pull/3204 diff --git a/internal/renameio/umask_test.go b/internal/renameio/umask_test.go index 921a2bdb..3f1795fb 100644 --- a/internal/renameio/umask_test.go +++ b/internal/renameio/umask_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !plan9,!windows,!js +//go:build !plan9 && !windows && !js package renameio diff --git a/internal/robustio/readme.md b/internal/robustio/readme.md new file mode 100644 index 00000000..7c7ba048 --- /dev/null +++ b/internal/robustio/readme.md @@ -0,0 +1,6 @@ +# robustio + +Extracted from go1.19.1/src/cmd/go/internal/robustio + +There is only one modification: +- ERROR_SHARING_VIOLATION extracted from go1.19.1/src/internal/syscall/windows/syscall_windows.go to remove the dependencies to `internal/syscall/windows` diff --git a/internal/robustio/robustio.go b/internal/robustio/robustio.go index ce3dbbde..15b33773 100644 --- a/internal/robustio/robustio.go +++ b/internal/robustio/robustio.go @@ -42,9 +42,9 @@ func RemoveAll(path string) error { // in this package attempt to mitigate. // // Errors considered ephemeral include: -// - syscall.ERROR_ACCESS_DENIED -// - syscall.ERROR_FILE_NOT_FOUND -// - internal/syscall/windows.ERROR_SHARING_VIOLATION +// - syscall.ERROR_ACCESS_DENIED +// - syscall.ERROR_FILE_NOT_FOUND +// - internal/syscall/windows.ERROR_SHARING_VIOLATION // // This set may be expanded in the future; programs must not rely on the // non-ephemerality of any given error. diff --git a/internal/robustio/robustio_darwin.go b/internal/robustio/robustio_darwin.go index 1ac0d10d..99fd8ebc 100644 --- a/internal/robustio/robustio_darwin.go +++ b/internal/robustio/robustio_darwin.go @@ -5,7 +5,7 @@ package robustio import ( - "os" + "errors" "syscall" ) @@ -13,16 +13,8 @@ const errFileNotFound = syscall.ENOENT // isEphemeralError returns true if err may be resolved by waiting. func isEphemeralError(err error) bool { - switch werr := err.(type) { - case *os.PathError: - err = werr.Err - case *os.LinkError: - err = werr.Err - case *os.SyscallError: - err = werr.Err - - } - if errno, ok := err.(syscall.Errno); ok { + var errno syscall.Errno + if errors.As(err, &errno) { return errno == errFileNotFound } return false diff --git a/internal/robustio/robustio_flaky.go b/internal/robustio/robustio_flaky.go index 6cc2f03d..c56e36ca 100644 --- a/internal/robustio/robustio_flaky.go +++ b/internal/robustio/robustio_flaky.go @@ -2,20 +2,19 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build windows darwin +//go:build windows || darwin package robustio import ( + "errors" "math/rand" "os" "syscall" "time" ) -const arbitraryTimeout = 500 * time.Millisecond - -const ERROR_SHARING_VIOLATION = 32 +const arbitraryTimeout = 2000 * time.Millisecond // retry retries ephemeral errors from f up to an arbitrary timeout // to work around filesystem flakiness on Windows and Darwin. @@ -32,7 +31,8 @@ func retry(f func() (err error, mayRetry bool)) error { return err } - if errno, ok := err.(syscall.Errno); ok && (lowestErrno == 0 || errno < lowestErrno) { + var errno syscall.Errno + if errors.As(err, &errno) && (lowestErrno == 0 || errno < lowestErrno) { bestErr = err lowestErrno = errno } else if bestErr == nil { @@ -78,8 +78,7 @@ func readFile(filename string) ([]byte, error) { // Unlike in rename, we do not retry errFileNotFound here: it can occur // as a spurious error, but the file may also genuinely not exist, so the // increase in robustness is probably not worth the extra latency. - - return err, isEphemeralError(err) && err != errFileNotFound + return err, isEphemeralError(err) && !errors.Is(err, errFileNotFound) }) return b, err } diff --git a/internal/robustio/robustio_other.go b/internal/robustio/robustio_other.go index b7d01b34..da9a46e4 100644 --- a/internal/robustio/robustio_other.go +++ b/internal/robustio/robustio_other.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//+build !windows,!darwin +//go:build !windows && !darwin package robustio diff --git a/internal/robustio/robustio_windows.go b/internal/robustio/robustio_windows.go index a35237d4..fe172895 100644 --- a/internal/robustio/robustio_windows.go +++ b/internal/robustio/robustio_windows.go @@ -5,23 +5,20 @@ package robustio import ( - "os" + "errors" "syscall" ) const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND +// ERROR_SHARING_VIOLATION (ldez) extract from go1.19.1/src/internal/syscall/windows/syscall_windows.go. +// This is the only modification of this file. +const ERROR_SHARING_VIOLATION syscall.Errno = 32 + // isEphemeralError returns true if err may be resolved by waiting. func isEphemeralError(err error) bool { - switch werr := err.(type) { - case *os.PathError: - err = werr.Err - case *os.LinkError: - err = werr.Err - case *os.SyscallError: - err = werr.Err - } - if errno, ok := err.(syscall.Errno); ok { + var errno syscall.Errno + if errors.As(err, &errno) { switch errno { case syscall.ERROR_ACCESS_DENIED, syscall.ERROR_FILE_NOT_FOUND, diff --git a/pkg/golinters/goanalysis/runner_action.go b/pkg/golinters/goanalysis/runner_action.go index 50ea64c5..d6f40a0c 100644 --- a/pkg/golinters/goanalysis/runner_action.go +++ b/pkg/golinters/goanalysis/runner_action.go @@ -3,6 +3,7 @@ package goanalysis import ( "fmt" "go/types" + "io" "reflect" "runtime/debug" "time" @@ -331,7 +332,7 @@ func (act *action) loadPersistedFacts() bool { var facts []Fact key := fmt.Sprintf("%s/facts", act.a.Name) if err := act.r.pkgCache.Get(act.pkg, pkgcache.HashModeNeedAllDeps, key, &facts); err != nil { - if err != pkgcache.ErrMissing { + if !errors.Is(err, pkgcache.ErrMissing) && !errors.Is(err, io.EOF) { act.r.log.Warnf("Failed to get persisted facts: %s", err) }