Skip to content

Commit

Permalink
gofumports: manually add the missing internal files
Browse files Browse the repository at this point in the history
We're going to fix gen.go properly. But for now, add the files manually
to unbreak the build on non-Linux systems.

Fixes #21.
  • Loading branch information
mvdan committed Jun 27, 2019
1 parent 6df84ed commit c16825b
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 0 deletions.
13 changes: 13 additions & 0 deletions gofumports/internal/fastwalk/fastwalk_dirent_fileno.go
@@ -0,0 +1,13 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build freebsd openbsd netbsd

package fastwalk

import "syscall"

func direntInode(dirent *syscall.Dirent) uint64 {
return uint64(dirent.Fileno)
}
13 changes: 13 additions & 0 deletions gofumports/internal/fastwalk/fastwalk_dirent_namlen_bsd.go
@@ -0,0 +1,13 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin freebsd openbsd netbsd

package fastwalk

import "syscall"

func direntNamlen(dirent *syscall.Dirent) uint64 {
return uint64(dirent.Namlen)
}
37 changes: 37 additions & 0 deletions gofumports/internal/fastwalk/fastwalk_portable.go
@@ -0,0 +1,37 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build appengine !linux,!darwin,!freebsd,!openbsd,!netbsd

package fastwalk

import (
"io/ioutil"
"os"
)

// readDir calls fn for each directory entry in dirName.
// It does not descend into directories or follow symlinks.
// If fn returns a non-nil error, readDir returns with that error
// immediately.
func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) error) error {
fis, err := ioutil.ReadDir(dirName)
if err != nil {
return err
}
skipFiles := false
for _, fi := range fis {
if fi.Mode().IsRegular() && skipFiles {
continue
}
if err := fn(dirName, fi.Name(), fi.Mode()&os.ModeType); err != nil {
if err == SkipFiles {
skipFiles = true
continue
}
return err
}
}
return nil
}
239 changes: 239 additions & 0 deletions gofumports/internal/fastwalk/fastwalk_test.go
@@ -0,0 +1,239 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package fastwalk_test

import (
"bytes"
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"runtime"
"sort"
"strings"
"sync"
"testing"

"golang.org/x/tools/internal/fastwalk"
)

func formatFileModes(m map[string]os.FileMode) string {
var keys []string
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
var buf bytes.Buffer
for _, k := range keys {
fmt.Fprintf(&buf, "%-20s: %v\n", k, m[k])
}
return buf.String()
}

func testFastWalk(t *testing.T, files map[string]string, callback func(path string, typ os.FileMode) error, want map[string]os.FileMode) {
tempdir, err := ioutil.TempDir("", "test-fast-walk")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tempdir)
for path, contents := range files {
file := filepath.Join(tempdir, "/src", path)
if err := os.MkdirAll(filepath.Dir(file), 0755); err != nil {
t.Fatal(err)
}
var err error
if strings.HasPrefix(contents, "LINK:") {
err = os.Symlink(strings.TrimPrefix(contents, "LINK:"), file)
} else {
err = ioutil.WriteFile(file, []byte(contents), 0644)
}
if err != nil {
t.Fatal(err)
}
}
got := map[string]os.FileMode{}
var mu sync.Mutex
if err := fastwalk.Walk(tempdir, func(path string, typ os.FileMode) error {
mu.Lock()
defer mu.Unlock()
if !strings.HasPrefix(path, tempdir) {
t.Fatalf("bogus prefix on %q, expect %q", path, tempdir)
}
key := filepath.ToSlash(strings.TrimPrefix(path, tempdir))
if old, dup := got[key]; dup {
t.Fatalf("callback called twice for key %q: %v -> %v", key, old, typ)
}
got[key] = typ
return callback(path, typ)
}); err != nil {
t.Fatalf("callback returned: %v", err)
}
if !reflect.DeepEqual(got, want) {
t.Errorf("walk mismatch.\n got:\n%v\nwant:\n%v", formatFileModes(got), formatFileModes(want))
}
}

func TestFastWalk_Basic(t *testing.T) {
testFastWalk(t, map[string]string{
"foo/foo.go": "one",
"bar/bar.go": "two",
"skip/skip.go": "skip",
},
func(path string, typ os.FileMode) error {
return nil
},
map[string]os.FileMode{
"": os.ModeDir,
"/src": os.ModeDir,
"/src/bar": os.ModeDir,
"/src/bar/bar.go": 0,
"/src/foo": os.ModeDir,
"/src/foo/foo.go": 0,
"/src/skip": os.ModeDir,
"/src/skip/skip.go": 0,
})
}

func TestFastWalk_LongFileName(t *testing.T) {
longFileName := strings.Repeat("x", 255)

testFastWalk(t, map[string]string{
longFileName: "one",
},
func(path string, typ os.FileMode) error {
return nil
},
map[string]os.FileMode{
"": os.ModeDir,
"/src": os.ModeDir,
"/src/" + longFileName: 0,
},
)
}

func TestFastWalk_Symlink(t *testing.T) {
switch runtime.GOOS {
case "windows", "plan9":
t.Skipf("skipping on %s", runtime.GOOS)
}
testFastWalk(t, map[string]string{
"foo/foo.go": "one",
"bar/bar.go": "LINK:../foo.go",
"symdir": "LINK:foo",
},
func(path string, typ os.FileMode) error {
return nil
},
map[string]os.FileMode{
"": os.ModeDir,
"/src": os.ModeDir,
"/src/bar": os.ModeDir,
"/src/bar/bar.go": os.ModeSymlink,
"/src/foo": os.ModeDir,
"/src/foo/foo.go": 0,
"/src/symdir": os.ModeSymlink,
})
}

func TestFastWalk_SkipDir(t *testing.T) {
testFastWalk(t, map[string]string{
"foo/foo.go": "one",
"bar/bar.go": "two",
"skip/skip.go": "skip",
},
func(path string, typ os.FileMode) error {
if typ == os.ModeDir && strings.HasSuffix(path, "skip") {
return filepath.SkipDir
}
return nil
},
map[string]os.FileMode{
"": os.ModeDir,
"/src": os.ModeDir,
"/src/bar": os.ModeDir,
"/src/bar/bar.go": 0,
"/src/foo": os.ModeDir,
"/src/foo/foo.go": 0,
"/src/skip": os.ModeDir,
})
}

func TestFastWalk_SkipFiles(t *testing.T) {
// Directory iteration order is undefined, so there's no way to know
// which file to expect until the walk happens. Rather than mess
// with the test infrastructure, just mutate want.
var mu sync.Mutex
want := map[string]os.FileMode{
"": os.ModeDir,
"/src": os.ModeDir,
"/src/zzz": os.ModeDir,
"/src/zzz/c.go": 0,
}

testFastWalk(t, map[string]string{
"a_skipfiles.go": "a",
"b_skipfiles.go": "b",
"zzz/c.go": "c",
},
func(path string, typ os.FileMode) error {
if strings.HasSuffix(path, "_skipfiles.go") {
mu.Lock()
defer mu.Unlock()
want["/src/"+filepath.Base(path)] = 0
return fastwalk.SkipFiles
}
return nil
},
want)
if len(want) != 5 {
t.Errorf("saw too many files: wanted 5, got %v (%v)", len(want), want)
}
}

func TestFastWalk_TraverseSymlink(t *testing.T) {
switch runtime.GOOS {
case "windows", "plan9":
t.Skipf("skipping on %s", runtime.GOOS)
}

testFastWalk(t, map[string]string{
"foo/foo.go": "one",
"bar/bar.go": "two",
"skip/skip.go": "skip",
"symdir": "LINK:foo",
},
func(path string, typ os.FileMode) error {
if typ == os.ModeSymlink {
return fastwalk.TraverseLink
}
return nil
},
map[string]os.FileMode{
"": os.ModeDir,
"/src": os.ModeDir,
"/src/bar": os.ModeDir,
"/src/bar/bar.go": 0,
"/src/foo": os.ModeDir,
"/src/foo/foo.go": 0,
"/src/skip": os.ModeDir,
"/src/skip/skip.go": 0,
"/src/symdir": os.ModeSymlink,
"/src/symdir/foo.go": 0,
})
}

var benchDir = flag.String("benchdir", runtime.GOROOT(), "The directory to scan for BenchmarkFastWalk")

func BenchmarkFastWalk(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
err := fastwalk.Walk(*benchDir, func(path string, typ os.FileMode) error { return nil })
if err != nil {
b.Fatal(err)
}
}
}

0 comments on commit c16825b

Please sign in to comment.