Skip to content

dev: add doc about internal package extracted from Go #3204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 4 additions & 5 deletions internal/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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))
Expand All @@ -181,15 +180,15 @@ 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] == ' ' {
i++
}
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 {
Expand Down Expand Up @@ -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)
Expand Down
18 changes: 18 additions & 0 deletions internal/cache/readme.md
Original file line number Diff line number Diff line change
@@ -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
10 changes: 10 additions & 0 deletions internal/renameio/readme.md
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion internal/renameio/umask_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 6 additions & 0 deletions internal/robustio/readme.md
Original file line number Diff line number Diff line change
@@ -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`
6 changes: 3 additions & 3 deletions internal/robustio/robustio.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
14 changes: 3 additions & 11 deletions internal/robustio/robustio_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,16 @@
package robustio

import (
"os"
"errors"
"syscall"
)

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
Expand Down
13 changes: 6 additions & 7 deletions internal/robustio/robustio_flaky.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion internal/robustio/robustio_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
17 changes: 7 additions & 10 deletions internal/robustio/robustio_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion pkg/golinters/goanalysis/runner_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package goanalysis
import (
"fmt"
"go/types"
"io"
"reflect"
"runtime/debug"
"time"
Expand Down Expand Up @@ -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)
}

Expand Down