Skip to content

Commit

Permalink
sync with the latest x/tools
Browse files Browse the repository at this point in the history
  • Loading branch information
mvdan committed Mar 14, 2020
1 parent 2d9f472 commit 42f6bd6
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 96 deletions.
5 changes: 3 additions & 2 deletions gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ func main() {
"golang.org/x/tools/cmd/goimports",

// These are internal goimports dependencies. Copy them.
"golang.org/x/tools/internal/imports",
"golang.org/x/tools/internal/fastwalk",
"golang.org/x/tools/internal/gocommand",
"golang.org/x/tools/internal/gopathwalk",
"golang.org/x/tools/internal/imports",
"golang.org/x/tools/internal/module",
"golang.org/x/tools/internal/fastwalk",
"golang.org/x/tools/internal/semver",
)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.14

require (
github.com/rogpeppe/go-internal v1.5.2
golang.org/x/tools v0.0.0-20200129045341-207d3de1faaf
golang.org/x/mod v0.2.0
golang.org/x/tools v0.0.0-20200313205530-4303120df7d8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
)
14 changes: 11 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,26 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/rogpeppe/go-internal v1.5.2 h1:qLvObTrvO/XRCqmkKxUlOBc48bI3efyDuAZe25QiF0w=
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20200129045341-207d3de1faaf h1:mFgR10kFfr83r2+nXf0GZC2FKrFhMSs9NdJ0YdEaGiY=
golang.org/x/tools v0.0.0-20200129045341-207d3de1faaf/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200313205530-4303120df7d8 h1:gkI/wGGwpcG5W4hLCzZNGxA4wzWBGGDStRI1MrjDl2Q=
golang.org/x/tools v0.0.0-20200313205530-4303120df7d8/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
Expand Down
2 changes: 1 addition & 1 deletion gofumports/goimports.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ func gofmtMain() {

if verbose {
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
options.Env.Debug = true
options.Env.Logf = log.Printf
}
if options.TabWidth < 0 {
fmt.Fprintf(os.Stderr, "negative tabwidth %d\n", options.TabWidth)
Expand Down
5 changes: 3 additions & 2 deletions gofumports/internal/fastwalk/fastwalk_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) e
}

func parseDirEnt(buf []byte) (consumed int, name string, typ os.FileMode) {
// golang.org/issue/15653
dirent := (*syscall.Dirent)(unsafe.Pointer(&buf[0]))
// golang.org/issue/37269
dirent := &syscall.Dirent{}
copy((*[unsafe.Sizeof(syscall.Dirent{})]byte)(unsafe.Pointer(dirent))[:], buf)
if v := unsafe.Offsetof(dirent.Reclen) + unsafe.Sizeof(dirent.Reclen); uintptr(len(buf)) < v {
panic(fmt.Sprintf("buf size of %d smaller than dirent header size %d", len(buf), v))
}
Expand Down
121 changes: 121 additions & 0 deletions gofumports/internal/gocommand/invoke.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Package gocommand is a helper for calling the go command.
package gocommand

import (
"bytes"
"context"
"fmt"
"os"
"os/exec"
"strings"
"time"
)

// An Invocation represents a call to the go command.
type Invocation struct {
Verb string
Args []string
BuildFlags []string
Env []string
WorkingDir string
Logf func(format string, args ...interface{})
}

// Run runs the invocation, returning its stdout and an error suitable for
// human consumption, including stderr.
func (i *Invocation) Run(ctx context.Context) (*bytes.Buffer, error) {
stdout, _, friendly, _ := i.RunRaw(ctx)
return stdout, friendly
}

// RunRaw is like Run, but also returns the raw stderr and error for callers
// that want to do low-level error handling/recovery.
func (i *Invocation) RunRaw(ctx context.Context) (stdout *bytes.Buffer, stderr *bytes.Buffer, friendlyError error, rawError error) {
log := i.Logf
if log == nil {
log = func(string, ...interface{}) {}
}

goArgs := []string{i.Verb}
switch i.Verb {
case "mod":
// mod needs the sub-verb before build flags.
goArgs = append(goArgs, i.Args[0])
goArgs = append(goArgs, i.BuildFlags...)
goArgs = append(goArgs, i.Args[1:]...)
case "env":
// env doesn't take build flags.
goArgs = append(goArgs, i.Args...)
default:
goArgs = append(goArgs, i.BuildFlags...)
goArgs = append(goArgs, i.Args...)
}
cmd := exec.Command("go", goArgs...)
stdout = &bytes.Buffer{}
stderr = &bytes.Buffer{}
cmd.Stdout = stdout
cmd.Stderr = stderr
// On darwin the cwd gets resolved to the real path, which breaks anything that
// expects the working directory to keep the original path, including the
// go command when dealing with modules.
// The Go stdlib has a special feature where if the cwd and the PWD are the
// same node then it trusts the PWD, so by setting it in the env for the child
// process we fix up all the paths returned by the go command.
cmd.Env = append(append([]string{}, i.Env...), "PWD="+i.WorkingDir)
cmd.Dir = i.WorkingDir

defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now())

rawError = runCmdContext(ctx, cmd)
friendlyError = rawError
if rawError != nil {
// Check for 'go' executable not being found.
if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
friendlyError = fmt.Errorf("go command required, not found: %v", ee)
}
if ctx.Err() != nil {
friendlyError = ctx.Err()
}
friendlyError = fmt.Errorf("err: %v: stderr: %s", rawError, stderr)
}
return
}

// runCmdContext is like exec.CommandContext except it sends os.Interrupt
// before os.Kill.
func runCmdContext(ctx context.Context, cmd *exec.Cmd) error {
if err := cmd.Start(); err != nil {
return err
}
resChan := make(chan error, 1)
go func() {
resChan <- cmd.Wait()
}()

select {
case err := <-resChan:
return err
case <-ctx.Done():
}
// Cancelled. Interrupt and see if it ends voluntarily.
cmd.Process.Signal(os.Interrupt)
select {
case err := <-resChan:
return err
case <-time.After(time.Second):
}
// Didn't shut down in response to interrupt. Kill it hard.
cmd.Process.Kill()
return <-resChan
}

func cmdDebugStr(cmd *exec.Cmd) string {
env := make(map[string]string)
for _, kv := range cmd.Env {
split := strings.Split(kv, "=")
k, v := split[0], split[1]
env[k] = v
}

return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v go %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], cmd.Args)
}
32 changes: 17 additions & 15 deletions gofumports/internal/gopathwalk/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import (

// Options controls the behavior of a Walk call.
type Options struct {
Debug bool // Enable debug logging
ModulesEnabled bool // Search module caches. Also disables legacy goimports ignore rules.
// If Logf is non-nil, debug logging is enabled through this function.
Logf func(format string, args ...interface{})
// Search module caches. Also disables legacy goimports ignore rules.
ModulesEnabled bool
}

// RootType indicates the type of a Root.
Expand Down Expand Up @@ -80,14 +82,14 @@ func WalkSkip(roots []Root, add func(root Root, dir string), skip func(root Root
// walkDir creates a walker and starts fastwalk with this walker.
func walkDir(root Root, add func(Root, string), skip func(root Root, dir string) bool, opts Options) {
if _, err := os.Stat(root.Path); os.IsNotExist(err) {
if opts.Debug {
log.Printf("skipping nonexistent directory: %v", root.Path)
if opts.Logf != nil {
opts.Logf("skipping nonexistent directory: %v", root.Path)
}
return
}
start := time.Now()
if opts.Debug {
log.Printf("gopathwalk: scanning %s", root.Path)
if opts.Logf != nil {
opts.Logf("gopathwalk: scanning %s", root.Path)
}
w := &walker{
root: root,
Expand All @@ -100,8 +102,8 @@ func walkDir(root Root, add func(Root, string), skip func(root Root, dir string)
log.Printf("gopathwalk: scanning directory %v: %v", root.Path, err)
}

if opts.Debug {
log.Printf("gopathwalk: scanned %s in %v", root.Path, time.Since(start))
if opts.Logf != nil {
opts.Logf("gopathwalk: scanned %s in %v", root.Path, time.Since(start))
}
}

Expand Down Expand Up @@ -130,11 +132,11 @@ func (w *walker) init() {
full := filepath.Join(w.root.Path, p)
if fi, err := os.Stat(full); err == nil {
w.ignoredDirs = append(w.ignoredDirs, fi)
if w.opts.Debug {
log.Printf("Directory added to ignore list: %s", full)
if w.opts.Logf != nil {
w.opts.Logf("Directory added to ignore list: %s", full)
}
} else if w.opts.Debug {
log.Printf("Error statting ignored directory: %v", err)
} else if w.opts.Logf != nil {
w.opts.Logf("Error statting ignored directory: %v", err)
}
}
}
Expand All @@ -145,11 +147,11 @@ func (w *walker) init() {
func (w *walker) getIgnoredDirs(path string) []string {
file := filepath.Join(path, ".goimportsignore")
slurp, err := ioutil.ReadFile(file)
if w.opts.Debug {
if w.opts.Logf != nil {
if err != nil {
log.Print(err)
w.opts.Logf("%v", err)
} else {
log.Printf("Read %s", file)
w.opts.Logf("Read %s", file)
}
}
if err != nil {
Expand Down
Loading

0 comments on commit 42f6bd6

Please sign in to comment.