2013-12-17 19:21:03 -07:00
|
|
|
// Copyright 2013 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 imports
|
|
|
|
|
|
|
|
import (
|
2015-12-10 23:32:07 -07:00
|
|
|
"bytes"
|
2013-12-17 19:21:03 -07:00
|
|
|
"flag"
|
|
|
|
"go/build"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2015-12-10 23:32:07 -07:00
|
|
|
"runtime"
|
2014-01-26 10:47:31 -07:00
|
|
|
"sync"
|
2013-12-17 19:21:03 -07:00
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
var only = flag.String("only", "", "If non-empty, the fix test to run")
|
|
|
|
|
|
|
|
var tests = []struct {
|
2016-04-05 10:10:15 -06:00
|
|
|
name string
|
|
|
|
formatOnly bool
|
|
|
|
in, out string
|
2013-12-17 19:21:03 -07:00
|
|
|
}{
|
|
|
|
// Adding an import to an existing parenthesized import
|
|
|
|
{
|
|
|
|
name: "factored_imports_add",
|
|
|
|
in: `package foo
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
func bar() {
|
|
|
|
var b bytes.Buffer
|
|
|
|
fmt.Println(b.String())
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
var b bytes.Buffer
|
|
|
|
fmt.Println(b.String())
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Adding an import to an existing parenthesized import,
|
|
|
|
// verifying it goes into the first section.
|
|
|
|
{
|
|
|
|
name: "factored_imports_add_first_sec",
|
|
|
|
in: `package foo
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"appengine"
|
|
|
|
)
|
|
|
|
func bar() {
|
|
|
|
var b bytes.Buffer
|
|
|
|
_ = appengine.IsDevServer
|
|
|
|
fmt.Println(b.String())
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"appengine"
|
|
|
|
)
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
var b bytes.Buffer
|
|
|
|
_ = appengine.IsDevServer
|
|
|
|
fmt.Println(b.String())
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Adding an import to an existing parenthesized import,
|
|
|
|
// verifying it goes into the first section. (test 2)
|
|
|
|
{
|
|
|
|
name: "factored_imports_add_first_sec_2",
|
|
|
|
in: `package foo
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"appengine"
|
|
|
|
)
|
|
|
|
func bar() {
|
|
|
|
_ = math.NaN
|
|
|
|
_ = fmt.Sprintf
|
|
|
|
_ = appengine.IsDevServer
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"math"
|
|
|
|
|
|
|
|
"appengine"
|
|
|
|
)
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
_ = math.NaN
|
|
|
|
_ = fmt.Sprintf
|
|
|
|
_ = appengine.IsDevServer
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Adding a new import line, without parens
|
|
|
|
{
|
|
|
|
name: "add_import_section",
|
|
|
|
in: `package foo
|
|
|
|
func bar() {
|
|
|
|
var b bytes.Buffer
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import "bytes"
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
var b bytes.Buffer
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Adding two new imports, which should make a parenthesized import decl.
|
|
|
|
{
|
|
|
|
name: "add_import_paren_section",
|
|
|
|
in: `package foo
|
|
|
|
func bar() {
|
|
|
|
_, _ := bytes.Buffer, zip.NewReader
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"archive/zip"
|
|
|
|
"bytes"
|
|
|
|
)
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
_, _ := bytes.Buffer, zip.NewReader
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Make sure we don't add things twice
|
|
|
|
{
|
|
|
|
name: "no_double_add",
|
|
|
|
in: `package foo
|
|
|
|
func bar() {
|
|
|
|
_, _ := bytes.Buffer, bytes.NewReader
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import "bytes"
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
_, _ := bytes.Buffer, bytes.NewReader
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Remove unused imports, 1 of a factored block
|
|
|
|
{
|
|
|
|
name: "remove_unused_1_of_2",
|
|
|
|
in: `package foo
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
_, _ := bytes.Buffer, bytes.NewReader
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import "bytes"
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
_, _ := bytes.Buffer, bytes.NewReader
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Remove unused imports, 2 of 2
|
|
|
|
{
|
|
|
|
name: "remove_unused_2_of_2",
|
|
|
|
in: `package foo
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Remove unused imports, 1 of 1
|
|
|
|
{
|
|
|
|
name: "remove_unused_1_of_1",
|
|
|
|
in: `package foo
|
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
func bar() {
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Don't remove empty imports.
|
|
|
|
{
|
|
|
|
name: "dont_remove_empty_imports",
|
|
|
|
in: `package foo
|
|
|
|
import (
|
|
|
|
_ "image/png"
|
|
|
|
_ "image/jpeg"
|
|
|
|
)
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
_ "image/jpeg"
|
|
|
|
_ "image/png"
|
|
|
|
)
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Don't remove dot imports.
|
|
|
|
{
|
|
|
|
name: "dont_remove_dot_imports",
|
|
|
|
in: `package foo
|
|
|
|
import (
|
|
|
|
. "foo"
|
|
|
|
. "bar"
|
|
|
|
)
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
. "bar"
|
|
|
|
. "foo"
|
|
|
|
)
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Skip refs the parser can resolve.
|
|
|
|
{
|
|
|
|
name: "skip_resolved_refs",
|
|
|
|
in: `package foo
|
|
|
|
|
|
|
|
func f() {
|
|
|
|
type t struct{ Println func(string) }
|
|
|
|
fmt := t{Println: func(string) {}}
|
|
|
|
fmt.Println("foo")
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
func f() {
|
|
|
|
type t struct{ Println func(string) }
|
|
|
|
fmt := t{Println: func(string) {}}
|
|
|
|
fmt.Println("foo")
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Do not add a package we already have a resolution for.
|
|
|
|
{
|
|
|
|
name: "skip_template",
|
|
|
|
in: `package foo
|
|
|
|
|
|
|
|
import "html/template"
|
|
|
|
|
|
|
|
func f() { t = template.New("sometemplate") }
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import "html/template"
|
|
|
|
|
|
|
|
func f() { t = template.New("sometemplate") }
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Don't touch cgo
|
|
|
|
{
|
|
|
|
name: "cgo",
|
|
|
|
in: `package foo
|
|
|
|
|
|
|
|
/*
|
|
|
|
#include <foo.h>
|
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
/*
|
|
|
|
#include <foo.h>
|
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Put some things in their own section
|
|
|
|
{
|
|
|
|
name: "make_sections",
|
|
|
|
in: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
func foo () {
|
|
|
|
_, _ = os.Args, fmt.Println
|
|
|
|
_, _ = appengine.FooSomething, user.Current
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
|
|
|
|
"appengine"
|
|
|
|
"appengine/user"
|
|
|
|
)
|
|
|
|
|
|
|
|
func foo() {
|
|
|
|
_, _ = os.Args, fmt.Println
|
|
|
|
_, _ = appengine.FooSomething, user.Current
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Delete existing empty import block
|
|
|
|
{
|
|
|
|
name: "delete_empty_import_block",
|
|
|
|
in: `package foo
|
|
|
|
|
|
|
|
import ()
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Use existing empty import block
|
|
|
|
{
|
|
|
|
name: "use_empty_import_block",
|
|
|
|
in: `package foo
|
|
|
|
|
|
|
|
import ()
|
|
|
|
|
|
|
|
func f() {
|
|
|
|
_ = fmt.Println
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
func f() {
|
|
|
|
_ = fmt.Println
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Blank line before adding new section.
|
|
|
|
{
|
|
|
|
name: "blank_line_before_new_group",
|
|
|
|
in: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
)
|
|
|
|
|
|
|
|
func f() {
|
|
|
|
_ = net.Dial
|
|
|
|
_ = fmt.Printf
|
|
|
|
_ = snappy.Foo
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
|
|
|
|
"code.google.com/p/snappy-go/snappy"
|
|
|
|
)
|
|
|
|
|
|
|
|
func f() {
|
|
|
|
_ = net.Dial
|
|
|
|
_ = fmt.Printf
|
|
|
|
_ = snappy.Foo
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Blank line between standard library and third-party stuff.
|
|
|
|
{
|
|
|
|
name: "blank_line_separating_std_and_third_party",
|
|
|
|
in: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"code.google.com/p/snappy-go/snappy"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
)
|
|
|
|
|
|
|
|
func f() {
|
|
|
|
_ = net.Dial
|
|
|
|
_ = fmt.Printf
|
|
|
|
_ = snappy.Foo
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package foo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
|
|
|
|
"code.google.com/p/snappy-go/snappy"
|
|
|
|
)
|
|
|
|
|
|
|
|
func f() {
|
|
|
|
_ = net.Dial
|
|
|
|
_ = fmt.Printf
|
|
|
|
_ = snappy.Foo
|
|
|
|
}
|
2013-12-18 10:09:37 -07:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// golang.org/issue/6884
|
|
|
|
{
|
|
|
|
name: "issue 6884",
|
|
|
|
in: `package main
|
|
|
|
|
|
|
|
// A comment
|
|
|
|
func main() {
|
|
|
|
fmt.Println("Hello, world")
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
// A comment
|
|
|
|
func main() {
|
|
|
|
fmt.Println("Hello, world")
|
|
|
|
}
|
2014-02-07 18:03:34 -07:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// golang.org/issue/7132
|
|
|
|
{
|
|
|
|
name: "issue 7132",
|
|
|
|
in: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"gu"
|
|
|
|
"github.com/foo/bar"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
a = bar.a
|
|
|
|
b = gu.a
|
|
|
|
c = fmt.Printf
|
|
|
|
)
|
|
|
|
`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"gu"
|
|
|
|
|
|
|
|
"github.com/foo/bar"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
a = bar.a
|
|
|
|
b = gu.a
|
|
|
|
c = fmt.Printf
|
|
|
|
)
|
2014-03-25 07:37:10 -06:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "renamed package",
|
|
|
|
in: `package main
|
|
|
|
|
|
|
|
var _ = str.HasPrefix
|
|
|
|
`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import str "strings"
|
|
|
|
|
|
|
|
var _ = str.HasPrefix
|
2013-12-17 19:21:03 -07:00
|
|
|
`,
|
|
|
|
},
|
2014-04-28 15:15:33 -06:00
|
|
|
|
|
|
|
{
|
|
|
|
name: "fragment with main",
|
|
|
|
in: `func main(){fmt.Println("Hello, world")}`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
func main() { fmt.Println("Hello, world") }
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "fragment without main",
|
|
|
|
in: `func notmain(){fmt.Println("Hello, world")}`,
|
|
|
|
out: `import "fmt"
|
|
|
|
|
|
|
|
func notmain() { fmt.Println("Hello, world") }`,
|
|
|
|
},
|
go.tools/astutil: fix edge case in DeleteImport causing merging of import sections.
The issue occurs only when deleting an import that has a blank line immediately preceding,
and other imports before that.
Currently, DeleteImport assumes there's a blank line-sized hole left behind
where the import was, and always deletes it. That blank line-sized hole is there in all cases
except the above edge case.
This fix checks for that edge case, and does not remove the blank line-sized hole.
The CL also adds a previously failing test case that catches this scenario. After the change to
DeleteImport, the new test passes (along with all other tests).
Fixes golang/go#7679.
Note that there is no attempt to ensure the result *ast.File and *token.FileSet are perfectly
matching to what you would get if you printed the AST and parsed it back. This is how the
rest of the package and the current tests work (i.e., they only check that printing the AST gives
the correct output).
Changing that is very hard, if not impossible, at least not
without resorting to manipulating AST via printing, text manipulation and parsing.
This is okay for most usages, but it does create potential problems. For example,
astutil.Imports() currently only works correctly on freshly parsed AST. If that AST
is manipulated via astutil funcs, then Imports() may not always generate correct
output. However, thas is a separate issue and should be treated as such.
LGTM=bradfitz
R=golang-codereviews, gobot, adonovan, bradfitz
CC=golang-codereviews
https://golang.org/cl/92250045
2014-05-19 15:04:30 -06:00
|
|
|
|
|
|
|
// Remove first import within in a 2nd/3rd/4th/etc. section.
|
|
|
|
// golang.org/issue/7679
|
|
|
|
{
|
|
|
|
name: "issue 7679",
|
|
|
|
in: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/foo/bar"
|
|
|
|
"github.com/foo/qux"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
var _ = fmt.Println
|
|
|
|
//var _ = bar.A
|
|
|
|
var _ = qux.B
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/foo/qux"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
var _ = fmt.Println
|
|
|
|
//var _ = bar.A
|
|
|
|
var _ = qux.B
|
|
|
|
}
|
2014-05-20 15:02:16 -06:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Blank line can be added before all types of import declarations.
|
|
|
|
// golang.org/issue/7866
|
|
|
|
{
|
|
|
|
name: "issue 7866",
|
|
|
|
in: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
renamed_bar "github.com/foo/bar"
|
|
|
|
|
|
|
|
. "github.com/foo/baz"
|
|
|
|
"io"
|
|
|
|
|
|
|
|
_ "github.com/foo/qux"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
_, _, _, _, _ = fmt.Errorf, io.Copy, strings.Contains, renamed_bar.A, B
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
renamed_bar "github.com/foo/bar"
|
|
|
|
|
|
|
|
"io"
|
|
|
|
|
|
|
|
. "github.com/foo/baz"
|
|
|
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
_ "github.com/foo/qux"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
_, _, _, _, _ = fmt.Errorf, io.Copy, strings.Contains, renamed_bar.A, B
|
|
|
|
}
|
2014-07-28 18:15:17 -06:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Non-idempotent comment formatting
|
|
|
|
// golang.org/issue/8035
|
|
|
|
{
|
|
|
|
name: "issue 8035",
|
|
|
|
in: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt" // A
|
|
|
|
"go/ast" // B
|
|
|
|
_ "launchpad.net/gocheck" // C
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() { _, _ = fmt.Print, ast.Walk }
|
|
|
|
`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt" // A
|
|
|
|
"go/ast" // B
|
|
|
|
|
|
|
|
_ "launchpad.net/gocheck" // C
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() { _, _ = fmt.Print, ast.Walk }
|
2014-08-14 12:51:51 -06:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Failure to delete all duplicate imports
|
|
|
|
// golang.org/issue/8459
|
|
|
|
{
|
|
|
|
name: "issue 8459",
|
|
|
|
in: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"log"
|
|
|
|
"math"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() { fmt.Println("pi:", math.Pi) }
|
|
|
|
`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"math"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() { fmt.Println("pi:", math.Pi) }
|
2015-03-25 12:52:44 -06:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Too aggressive prefix matching
|
|
|
|
// golang.org/issue/9961
|
|
|
|
{
|
|
|
|
name: "issue 9961",
|
|
|
|
in: `package p
|
|
|
|
|
|
|
|
import (
|
|
|
|
"zip"
|
|
|
|
|
|
|
|
"rsc.io/p"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ = fmt.Print
|
|
|
|
_ = zip.Store
|
|
|
|
_ p.P
|
|
|
|
_ = regexp.Compile
|
|
|
|
)
|
|
|
|
`,
|
|
|
|
out: `package p
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"regexp"
|
|
|
|
"zip"
|
|
|
|
|
|
|
|
"rsc.io/p"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ = fmt.Print
|
|
|
|
_ = zip.Store
|
|
|
|
_ p.P
|
|
|
|
_ = regexp.Compile
|
|
|
|
)
|
2015-08-07 09:16:12 -06:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Unused named import is mistaken for unnamed import
|
|
|
|
// golang.org/issue/8149
|
|
|
|
{
|
|
|
|
name: "issue 8149",
|
|
|
|
in: `package main
|
|
|
|
|
|
|
|
import foo "fmt"
|
|
|
|
|
|
|
|
func main() { fmt.Println() }
|
|
|
|
`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import "fmt"
|
2016-02-25 12:09:00 -07:00
|
|
|
|
|
|
|
func main() { fmt.Println() }
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Unused named import is mistaken for unnamed import
|
|
|
|
// golang.org/issue/8149
|
|
|
|
{
|
|
|
|
name: "issue 8149",
|
|
|
|
in: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
x "fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() { fmt.Println() }
|
|
|
|
`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import "fmt"
|
2015-08-07 09:16:12 -06:00
|
|
|
|
|
|
|
func main() { fmt.Println() }
|
2016-04-05 10:10:15 -06:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
|
|
|
|
// FormatOnly
|
|
|
|
{
|
|
|
|
name: "format only",
|
|
|
|
formatOnly: true,
|
|
|
|
in: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"golang.org/x/foo"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {}
|
|
|
|
`,
|
|
|
|
out: `package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"golang.org/x/foo"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {}
|
go.tools/astutil: fix edge case in DeleteImport causing merging of import sections.
The issue occurs only when deleting an import that has a blank line immediately preceding,
and other imports before that.
Currently, DeleteImport assumes there's a blank line-sized hole left behind
where the import was, and always deletes it. That blank line-sized hole is there in all cases
except the above edge case.
This fix checks for that edge case, and does not remove the blank line-sized hole.
The CL also adds a previously failing test case that catches this scenario. After the change to
DeleteImport, the new test passes (along with all other tests).
Fixes golang/go#7679.
Note that there is no attempt to ensure the result *ast.File and *token.FileSet are perfectly
matching to what you would get if you printed the AST and parsed it back. This is how the
rest of the package and the current tests work (i.e., they only check that printing the AST gives
the correct output).
Changing that is very hard, if not impossible, at least not
without resorting to manipulating AST via printing, text manipulation and parsing.
This is okay for most usages, but it does create potential problems. For example,
astutil.Imports() currently only works correctly on freshly parsed AST. If that AST
is manipulated via astutil funcs, then Imports() may not always generate correct
output. However, thas is a separate issue and should be treated as such.
LGTM=bradfitz
R=golang-codereviews, gobot, adonovan, bradfitz
CC=golang-codereviews
https://golang.org/cl/92250045
2014-05-19 15:04:30 -06:00
|
|
|
`,
|
|
|
|
},
|
2013-12-17 19:21:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestFixImports(t *testing.T) {
|
|
|
|
simplePkgs := map[string]string{
|
|
|
|
"appengine": "appengine",
|
|
|
|
"bytes": "bytes",
|
2015-03-25 12:52:44 -06:00
|
|
|
"fmt": "fmt",
|
|
|
|
"math": "math",
|
|
|
|
"os": "os",
|
|
|
|
"p": "rsc.io/p",
|
|
|
|
"regexp": "regexp",
|
2013-12-17 19:21:03 -07:00
|
|
|
"snappy": "code.google.com/p/snappy-go/snappy",
|
2014-03-25 07:37:10 -06:00
|
|
|
"str": "strings",
|
2015-03-25 12:52:44 -06:00
|
|
|
"user": "appengine/user",
|
|
|
|
"zip": "archive/zip",
|
2013-12-17 19:21:03 -07:00
|
|
|
}
|
2015-12-10 23:32:07 -07:00
|
|
|
old := findImport
|
|
|
|
defer func() {
|
|
|
|
findImport = old
|
|
|
|
}()
|
|
|
|
findImport = func(pkgName string, symbols map[string]bool, filename string) (string, bool, error) {
|
2014-03-25 07:37:10 -06:00
|
|
|
return simplePkgs[pkgName], pkgName == "str", nil
|
2013-12-17 19:21:03 -07:00
|
|
|
}
|
|
|
|
|
2014-04-28 15:15:33 -06:00
|
|
|
options := &Options{
|
|
|
|
TabWidth: 8,
|
|
|
|
TabIndent: true,
|
|
|
|
Comments: true,
|
|
|
|
Fragment: true,
|
|
|
|
}
|
|
|
|
|
2013-12-17 19:21:03 -07:00
|
|
|
for _, tt := range tests {
|
2016-04-05 10:10:15 -06:00
|
|
|
options.FormatOnly = tt.formatOnly
|
2013-12-17 19:21:03 -07:00
|
|
|
if *only != "" && tt.name != *only {
|
|
|
|
continue
|
|
|
|
}
|
2014-04-28 15:15:33 -06:00
|
|
|
buf, err := Process(tt.name+".go", []byte(tt.in), options)
|
2013-12-17 19:21:03 -07:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("error on %q: %v", tt.name, err)
|
|
|
|
continue
|
|
|
|
}
|
2013-12-18 04:44:50 -07:00
|
|
|
if got := string(buf); got != tt.out {
|
2013-12-17 19:21:03 -07:00
|
|
|
t.Errorf("results diff on %q\nGOT:\n%s\nWANT:\n%s\n", tt.name, got, tt.out)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-07 14:47:49 -06:00
|
|
|
// Test support for packages in GOPATH that are actually symlinks.
|
|
|
|
// Also test that a symlink loop does not block the process.
|
|
|
|
func TestImportSymlinks(t *testing.T) {
|
2016-07-17 10:24:21 -06:00
|
|
|
switch runtime.GOOS {
|
|
|
|
case "windows", "plan9":
|
|
|
|
t.Skip("skipping test on %q as there are no symlinks", runtime.GOOS)
|
2016-06-07 14:47:49 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
newGoPath, err := ioutil.TempDir("", "symlinktest")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(newGoPath)
|
|
|
|
|
|
|
|
targetPath := newGoPath + "/target"
|
|
|
|
if err := os.MkdirAll(targetPath, 0755); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if err := ioutil.WriteFile(targetPath+"/f.go", []byte("package mypkg\nvar Foo = 123\n"), 0666); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
symlinkPath := newGoPath + "/src/x/mypkg"
|
|
|
|
if err := os.MkdirAll(filepath.Dir(symlinkPath), 0755); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if err := os.Symlink(targetPath, symlinkPath); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add a symlink loop.
|
|
|
|
if err := os.Symlink(newGoPath+"/src/x", newGoPath+"/src/x/apkg"); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
withEmptyGoPath(func() {
|
|
|
|
build.Default.GOPATH = newGoPath
|
2016-06-07 14:47:49 -06:00
|
|
|
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
input := `package p
|
2016-06-07 14:47:49 -06:00
|
|
|
|
|
|
|
var (
|
|
|
|
_ = fmt.Print
|
|
|
|
_ = mypkg.Foo
|
|
|
|
)
|
|
|
|
`
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
output := `package p
|
2016-06-07 14:47:49 -06:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"x/mypkg"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ = fmt.Print
|
|
|
|
_ = mypkg.Foo
|
|
|
|
)
|
|
|
|
`
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
buf, err := Process(newGoPath+"/src/myotherpkg/toformat.go", []byte(input), &Options{})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if got := string(buf); got != output {
|
|
|
|
t.Fatalf("results differ\nGOT:\n%s\nWANT:\n%s\n", got, output)
|
|
|
|
}
|
|
|
|
})
|
2016-06-07 14:47:49 -06:00
|
|
|
}
|
|
|
|
|
2016-04-13 15:57:13 -06:00
|
|
|
// Test for correctly identifying the name of a vendored package when it
|
|
|
|
// differs from its directory name. In this test, the import line
|
|
|
|
// "mypkg.com/mypkg.v1" would be removed if goimports wasn't able to detect
|
|
|
|
// that the package name is "mypkg".
|
|
|
|
func TestFixImportsVendorPackage(t *testing.T) {
|
|
|
|
// Skip this test on go versions with no vendor support.
|
|
|
|
if _, err := os.Stat(filepath.Join(runtime.GOROOT(), "src/vendor")); err != nil {
|
|
|
|
t.Skip(err)
|
|
|
|
}
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
testConfig{
|
|
|
|
gopathFiles: map[string]string{
|
|
|
|
"mypkg.com/outpkg/vendor/mypkg.com/mypkg.v1/f.go": "package mypkg\nvar Foo = 123\n",
|
|
|
|
},
|
|
|
|
}.test(t, func(t *goimportTest) {
|
|
|
|
input := `package p
|
2016-04-13 15:57:13 -06:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"mypkg.com/mypkg.v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ = fmt.Print
|
|
|
|
_ = mypkg.Foo
|
|
|
|
)
|
|
|
|
`
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
buf, err := Process(filepath.Join(t.gopath, "src/mypkg.com/outpkg/toformat.go"), []byte(input), &Options{})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if got := string(buf); got != input {
|
|
|
|
t.Fatalf("results differ\nGOT:\n%s\nWANT:\n%s\n", got, input)
|
|
|
|
}
|
|
|
|
})
|
2016-04-13 15:57:13 -06:00
|
|
|
}
|
|
|
|
|
2013-12-17 19:21:03 -07:00
|
|
|
func TestFindImportGoPath(t *testing.T) {
|
|
|
|
goroot, err := ioutil.TempDir("", "goimports-")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(goroot)
|
2014-01-26 10:47:31 -07:00
|
|
|
|
|
|
|
origStdlib := stdlib
|
|
|
|
defer func() {
|
|
|
|
stdlib = origStdlib
|
|
|
|
}()
|
|
|
|
stdlib = nil
|
|
|
|
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
withEmptyGoPath(func() {
|
|
|
|
// Test against imaginary bits/bytes package in std lib
|
|
|
|
bytesDir := filepath.Join(goroot, "src", "pkg", "bits", "bytes")
|
|
|
|
for _, tag := range build.Default.ReleaseTags {
|
|
|
|
// Go 1.4 rearranged the GOROOT tree to remove the "pkg" path component.
|
|
|
|
if tag == "go1.4" {
|
|
|
|
bytesDir = filepath.Join(goroot, "src", "bits", "bytes")
|
|
|
|
}
|
2014-10-12 15:44:37 -06:00
|
|
|
}
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
if err := os.MkdirAll(bytesDir, 0755); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
bytesSrcPath := filepath.Join(bytesDir, "bytes.go")
|
|
|
|
bytesPkgPath := "bits/bytes"
|
|
|
|
bytesSrc := []byte(`package bytes
|
2013-12-17 19:21:03 -07:00
|
|
|
|
|
|
|
type Buffer2 struct {}
|
|
|
|
`)
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
if err := ioutil.WriteFile(bytesSrcPath, bytesSrc, 0775); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
build.Default.GOROOT = goroot
|
2013-12-17 19:21:03 -07:00
|
|
|
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
got, rename, err := findImportGoPath("bytes", map[string]bool{"Buffer2": true}, "x.go")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if got != bytesPkgPath || rename {
|
|
|
|
t.Errorf(`findImportGoPath("bytes", Buffer2 ...)=%q, %t, want "%s", false`, got, rename, bytesPkgPath)
|
|
|
|
}
|
2013-12-17 19:21:03 -07:00
|
|
|
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
got, rename, err = findImportGoPath("bytes", map[string]bool{"Missing": true}, "x.go")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if got != "" || rename {
|
|
|
|
t.Errorf(`findImportGoPath("bytes", Missing ...)=%q, %t, want "", false`, got, rename)
|
|
|
|
}
|
|
|
|
})
|
2013-12-17 19:21:03 -07:00
|
|
|
}
|
2014-01-26 10:47:31 -07:00
|
|
|
|
imports: special case rand.Read, prevent math/rand by chance
In Go 1.7, math/rand.Read was added. Previously, the only package
containing "rand.Read" was "crypto/rand".
goimports was updated to know that, and zstdlib.go contains a note
that it's ambiguous:
"rand.Perm": "math/rand",
"rand.Prime": "crypto/rand",
"rand.Rand": "math/rand",
// "rand.Read" is ambiguous
"rand.Reader": "crypto/rand",
"rand.Seed": "math/rand",
"rand.Source": "math/rand",
The intention originally was that such ambiguous things would
never be resolved, even randomly.
But a later change added support for build.Default.SrcDirs, which
meant GOROOT was also searched for ambiguous things. Or maybe I forget
the history.
In any case, when goimports tried to resolve "rand.Read", the
findImportStdlib check was returning nothing, which lead to the
$GOROOT being searched, where math/rand was picked by chance. That's a
dangerous default when the intentional might've been crypto/rand.
Special case it and prefer crypto/rand if there's no more specific
clue either way.
Change-Id: Ib5f8f297f72fa309d5ca9b15a37493df2e17567c
Reviewed-on: https://go-review.googlesource.com/24847
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2016-07-11 16:38:22 -06:00
|
|
|
func withEmptyGoPath(fn func()) {
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
dirScanMu.Lock()
|
2016-07-16 15:48:20 -06:00
|
|
|
scanGoRootOnce = sync.Once{}
|
|
|
|
scanGoPathOnce = sync.Once{}
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
dirScan = nil
|
2016-07-15 12:28:37 -06:00
|
|
|
ignoredDirs = nil
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
dirScanMu.Unlock()
|
|
|
|
|
2015-12-10 23:32:07 -07:00
|
|
|
oldGOPATH := build.Default.GOPATH
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
oldGOROOT := build.Default.GOROOT
|
2015-12-10 23:32:07 -07:00
|
|
|
build.Default.GOPATH = ""
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
visitedSymlinks.m = nil
|
|
|
|
testHookScanDir = func(string) {}
|
2015-12-10 23:32:07 -07:00
|
|
|
defer func() {
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
testHookScanDir = func(string) {}
|
2015-12-10 23:32:07 -07:00
|
|
|
build.Default.GOPATH = oldGOPATH
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
build.Default.GOROOT = oldGOROOT
|
2015-12-10 23:32:07 -07:00
|
|
|
}()
|
imports: special case rand.Read, prevent math/rand by chance
In Go 1.7, math/rand.Read was added. Previously, the only package
containing "rand.Read" was "crypto/rand".
goimports was updated to know that, and zstdlib.go contains a note
that it's ambiguous:
"rand.Perm": "math/rand",
"rand.Prime": "crypto/rand",
"rand.Rand": "math/rand",
// "rand.Read" is ambiguous
"rand.Reader": "crypto/rand",
"rand.Seed": "math/rand",
"rand.Source": "math/rand",
The intention originally was that such ambiguous things would
never be resolved, even randomly.
But a later change added support for build.Default.SrcDirs, which
meant GOROOT was also searched for ambiguous things. Or maybe I forget
the history.
In any case, when goimports tried to resolve "rand.Read", the
findImportStdlib check was returning nothing, which lead to the
$GOROOT being searched, where math/rand was picked by chance. That's a
dangerous default when the intentional might've been crypto/rand.
Special case it and prefer crypto/rand if there's no more specific
clue either way.
Change-Id: Ib5f8f297f72fa309d5ca9b15a37493df2e17567c
Reviewed-on: https://go-review.googlesource.com/24847
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2016-07-11 16:38:22 -06:00
|
|
|
fn()
|
|
|
|
}
|
2015-12-10 23:32:07 -07:00
|
|
|
|
imports: special case rand.Read, prevent math/rand by chance
In Go 1.7, math/rand.Read was added. Previously, the only package
containing "rand.Read" was "crypto/rand".
goimports was updated to know that, and zstdlib.go contains a note
that it's ambiguous:
"rand.Perm": "math/rand",
"rand.Prime": "crypto/rand",
"rand.Rand": "math/rand",
// "rand.Read" is ambiguous
"rand.Reader": "crypto/rand",
"rand.Seed": "math/rand",
"rand.Source": "math/rand",
The intention originally was that such ambiguous things would
never be resolved, even randomly.
But a later change added support for build.Default.SrcDirs, which
meant GOROOT was also searched for ambiguous things. Or maybe I forget
the history.
In any case, when goimports tried to resolve "rand.Read", the
findImportStdlib check was returning nothing, which lead to the
$GOROOT being searched, where math/rand was picked by chance. That's a
dangerous default when the intentional might've been crypto/rand.
Special case it and prefer crypto/rand if there's no more specific
clue either way.
Change-Id: Ib5f8f297f72fa309d5ca9b15a37493df2e17567c
Reviewed-on: https://go-review.googlesource.com/24847
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2016-07-11 16:38:22 -06:00
|
|
|
func TestFindImportInternal(t *testing.T) {
|
|
|
|
withEmptyGoPath(func() {
|
|
|
|
// Check for src/internal/race, not just src/internal,
|
|
|
|
// so that we can run this test also against go1.5
|
|
|
|
// (which doesn't contain that file).
|
|
|
|
_, err := os.Stat(filepath.Join(runtime.GOROOT(), "src/internal/race"))
|
|
|
|
if err != nil {
|
|
|
|
t.Skip(err)
|
|
|
|
}
|
2015-12-10 23:32:07 -07:00
|
|
|
|
imports: special case rand.Read, prevent math/rand by chance
In Go 1.7, math/rand.Read was added. Previously, the only package
containing "rand.Read" was "crypto/rand".
goimports was updated to know that, and zstdlib.go contains a note
that it's ambiguous:
"rand.Perm": "math/rand",
"rand.Prime": "crypto/rand",
"rand.Rand": "math/rand",
// "rand.Read" is ambiguous
"rand.Reader": "crypto/rand",
"rand.Seed": "math/rand",
"rand.Source": "math/rand",
The intention originally was that such ambiguous things would
never be resolved, even randomly.
But a later change added support for build.Default.SrcDirs, which
meant GOROOT was also searched for ambiguous things. Or maybe I forget
the history.
In any case, when goimports tried to resolve "rand.Read", the
findImportStdlib check was returning nothing, which lead to the
$GOROOT being searched, where math/rand was picked by chance. That's a
dangerous default when the intentional might've been crypto/rand.
Special case it and prefer crypto/rand if there's no more specific
clue either way.
Change-Id: Ib5f8f297f72fa309d5ca9b15a37493df2e17567c
Reviewed-on: https://go-review.googlesource.com/24847
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2016-07-11 16:38:22 -06:00
|
|
|
got, rename, err := findImportGoPath("race", map[string]bool{"Acquire": true}, filepath.Join(runtime.GOROOT(), "src/math/x.go"))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if got != "internal/race" || rename {
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
t.Errorf(`findImportGoPath("race", Acquire ...) = %q, %t; want "internal/race", false`, got, rename)
|
imports: special case rand.Read, prevent math/rand by chance
In Go 1.7, math/rand.Read was added. Previously, the only package
containing "rand.Read" was "crypto/rand".
goimports was updated to know that, and zstdlib.go contains a note
that it's ambiguous:
"rand.Perm": "math/rand",
"rand.Prime": "crypto/rand",
"rand.Rand": "math/rand",
// "rand.Read" is ambiguous
"rand.Reader": "crypto/rand",
"rand.Seed": "math/rand",
"rand.Source": "math/rand",
The intention originally was that such ambiguous things would
never be resolved, even randomly.
But a later change added support for build.Default.SrcDirs, which
meant GOROOT was also searched for ambiguous things. Or maybe I forget
the history.
In any case, when goimports tried to resolve "rand.Read", the
findImportStdlib check was returning nothing, which lead to the
$GOROOT being searched, where math/rand was picked by chance. That's a
dangerous default when the intentional might've been crypto/rand.
Special case it and prefer crypto/rand if there's no more specific
clue either way.
Change-Id: Ib5f8f297f72fa309d5ca9b15a37493df2e17567c
Reviewed-on: https://go-review.googlesource.com/24847
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2016-07-11 16:38:22 -06:00
|
|
|
}
|
2015-12-10 23:32:07 -07:00
|
|
|
|
imports: special case rand.Read, prevent math/rand by chance
In Go 1.7, math/rand.Read was added. Previously, the only package
containing "rand.Read" was "crypto/rand".
goimports was updated to know that, and zstdlib.go contains a note
that it's ambiguous:
"rand.Perm": "math/rand",
"rand.Prime": "crypto/rand",
"rand.Rand": "math/rand",
// "rand.Read" is ambiguous
"rand.Reader": "crypto/rand",
"rand.Seed": "math/rand",
"rand.Source": "math/rand",
The intention originally was that such ambiguous things would
never be resolved, even randomly.
But a later change added support for build.Default.SrcDirs, which
meant GOROOT was also searched for ambiguous things. Or maybe I forget
the history.
In any case, when goimports tried to resolve "rand.Read", the
findImportStdlib check was returning nothing, which lead to the
$GOROOT being searched, where math/rand was picked by chance. That's a
dangerous default when the intentional might've been crypto/rand.
Special case it and prefer crypto/rand if there's no more specific
clue either way.
Change-Id: Ib5f8f297f72fa309d5ca9b15a37493df2e17567c
Reviewed-on: https://go-review.googlesource.com/24847
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2016-07-11 16:38:22 -06:00
|
|
|
// should not be able to use internal from outside that tree
|
|
|
|
got, rename, err = findImportGoPath("race", map[string]bool{"Acquire": true}, filepath.Join(runtime.GOROOT(), "x.go"))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if got != "" || rename {
|
|
|
|
t.Errorf(`findImportGoPath("race", Acquire ...)=%q, %t, want "", false`, got, rename)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// rand.Read should prefer crypto/rand.Read, not math/rand.Read.
|
|
|
|
func TestFindImportRandRead(t *testing.T) {
|
|
|
|
withEmptyGoPath(func() {
|
|
|
|
file := filepath.Join(runtime.GOROOT(), "src/foo/x.go") // dummy
|
|
|
|
tests := []struct {
|
|
|
|
syms []string
|
|
|
|
want string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
syms: []string{"Read"},
|
|
|
|
want: "crypto/rand",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
syms: []string{"Read", "NewZipf"},
|
|
|
|
want: "math/rand",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
syms: []string{"NewZipf"},
|
|
|
|
want: "math/rand",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
syms: []string{"Read", "Prime"},
|
|
|
|
want: "crypto/rand",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
m := map[string]bool{}
|
|
|
|
for _, sym := range tt.syms {
|
|
|
|
m[sym] = true
|
|
|
|
}
|
|
|
|
got, _, err := findImportGoPath("rand", m, file)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("for %q: %v", tt.syms, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if got != tt.want {
|
|
|
|
t.Errorf("for %q, findImportGoPath = %q; want %q", tt.syms, got, tt.want)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2015-12-10 23:32:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestFindImportVendor(t *testing.T) {
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
testConfig{
|
|
|
|
gorootFiles: map[string]string{
|
|
|
|
"vendor/golang.org/x/net/http2/hpack/huffman.go": "package hpack\nfunc HuffmanDecode() { }\n",
|
|
|
|
},
|
|
|
|
}.test(t, func(t *goimportTest) {
|
|
|
|
got, rename, err := findImportGoPath("hpack", map[string]bool{"HuffmanDecode": true}, filepath.Join(t.goroot, "src/math/x.go"))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
want := "golang.org/x/net/http2/hpack"
|
|
|
|
if got != want || rename {
|
|
|
|
t.Errorf(`findImportGoPath("hpack", HuffmanDecode ...) = %q, %t; want %q, false`, got, rename, want)
|
|
|
|
}
|
|
|
|
})
|
2015-12-10 23:32:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestProcessVendor(t *testing.T) {
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
withEmptyGoPath(func() {
|
|
|
|
_, err := os.Stat(filepath.Join(runtime.GOROOT(), "src/vendor"))
|
|
|
|
if err != nil {
|
|
|
|
t.Skip(err)
|
|
|
|
}
|
2015-12-10 23:32:07 -07:00
|
|
|
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
target := filepath.Join(runtime.GOROOT(), "src/math/x.go")
|
|
|
|
out, err := Process(target, []byte("package http\nimport \"bytes\"\nfunc f() { strings.NewReader(); hpack.HuffmanDecode() }\n"), nil)
|
2015-12-10 23:32:07 -07:00
|
|
|
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-12-10 23:32:07 -07:00
|
|
|
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
want := "golang_org/x/net/http2/hpack"
|
|
|
|
if _, err := os.Stat(filepath.Join(runtime.GOROOT(), "src/vendor", want)); os.IsNotExist(err) {
|
|
|
|
want = "golang.org/x/net/http2/hpack"
|
|
|
|
}
|
|
|
|
|
|
|
|
if !bytes.Contains(out, []byte(want)) {
|
|
|
|
t.Fatalf("Process(%q) did not add expected hpack import %q; got:\n%s", target, want, out)
|
|
|
|
}
|
|
|
|
})
|
2015-12-10 23:32:07 -07:00
|
|
|
}
|
|
|
|
|
2014-01-26 10:47:31 -07:00
|
|
|
func TestFindImportStdlib(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
pkg string
|
|
|
|
symbols []string
|
|
|
|
want string
|
|
|
|
}{
|
|
|
|
{"http", []string{"Get"}, "net/http"},
|
|
|
|
{"http", []string{"Get", "Post"}, "net/http"},
|
|
|
|
{"http", []string{"Get", "Foo"}, ""},
|
|
|
|
{"bytes", []string{"Buffer"}, "bytes"},
|
|
|
|
{"ioutil", []string{"Discard"}, "io/ioutil"},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
2014-03-25 07:37:10 -06:00
|
|
|
got, rename, ok := findImportStdlib(tt.pkg, strSet(tt.symbols))
|
2014-01-26 10:47:31 -07:00
|
|
|
if (got != "") != ok {
|
|
|
|
t.Error("findImportStdlib return value inconsistent")
|
|
|
|
}
|
2014-03-25 07:37:10 -06:00
|
|
|
if got != tt.want || rename {
|
|
|
|
t.Errorf("findImportStdlib(%q, %q) = %q, %t; want %q, false", tt.pkg, tt.symbols, got, rename, tt.want)
|
2014-01-26 10:47:31 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
cmd/goimports, imports: make goimports great again
I felt the burn of my laptop on my legs, spinning away while processing
goimports, and felt that it was time to make goimports great again.
Over the past few years goimports fell into a slow state of disrepair
with too many feature additions and no attention to the performance
death by a thousand cuts. This was particularly terrible on OS X with
its lackluster filesystem buffering.
This CL makes goimports stronger, together with various optimizations
and more visibility into what goimports is doing.
* adds more internal documentation
* avoids scanning $GOPATH for answers when running goimports on a file
under $GOROOT (for Go core hackers)
* don't read all $GOROOT & $GOPATH directories' Go code looking for
their package names until much later. Require the package name of
missing imports to be present in the last two directory path
components. Then only try importing them in order from best to
worst (shortest to longest, as before), so we can stop early.
* when adding imports, add names to imports when the imported package name
doesn't match the baes of its import path. For example:
import foo "example.net/foo/v1"
* don't read all *.go files in a package directory once the first file
in a directory has revealed itself to be a package we're not looking
for. For example, if we're looking for the right "client" for "client.Foo",
we used to consider a directory "bar/client" as a candidate and read
all 50 of its *.go files instead of stopping after its first *.go
file had a "package main" line.
* add some fast paths to remove allocations
* add some fast paths to remove disk I/O when looking up the base
package name of a standard library import (of existing imports in a
file, which are very common)
* adds a special case for import "C", to avoid some disk I/O.
* add a -verbose flag to goimports for debugging
On my Mac laptop with a huge $GOPATH, with a test file like:
package foo
import (
"fmt"
"net/http"
)
/*
*/
import "C"
var _ = cloudbilling.New
var _ = http.NewRequest
var _ = client.New
... this took like 10 seconds before, and now 1.3 seconds. (Still
slow; disk-based caching can come later)
Updates golang/go#16367 (goimports is slow)
Updates golang/go#16384 (refactor TestRename is broken on Windows)
Change-Id: I97e85d3016afc9f2ad5501f97babad30c7989183
Reviewed-on: https://go-review.googlesource.com/24941
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-14 18:08:27 -06:00
|
|
|
type testConfig struct {
|
|
|
|
// gorootFiles optionally specifies the complete contents of GOROOT to use,
|
|
|
|
// If nil, the normal current $GOROOT is used.
|
|
|
|
gorootFiles map[string]string // paths relative to $GOROOT/src to contents
|
|
|
|
|
|
|
|
// gopathFiles is like gorootFiles, but for $GOPATH.
|
|
|
|
// If nil, there is no GOPATH, though.
|
|
|
|
gopathFiles map[string]string // paths relative to $GOPATH/src to contents
|
|
|
|
}
|
|
|
|
|
|
|
|
func mustTempDir(t *testing.T, prefix string) string {
|
|
|
|
dir, err := ioutil.TempDir("", prefix)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
return dir
|
|
|
|
}
|
|
|
|
|
|
|
|
func mapToDir(destDir string, files map[string]string) error {
|
|
|
|
for path, contents := range files {
|
|
|
|
file := filepath.Join(destDir, "src", path)
|
|
|
|
if err := os.MkdirAll(filepath.Dir(file), 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := ioutil.WriteFile(file, []byte(contents), 0644); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c testConfig) test(t *testing.T, fn func(*goimportTest)) {
|
|
|
|
var goroot string
|
|
|
|
var gopath string
|
|
|
|
|
|
|
|
if c.gorootFiles != nil {
|
|
|
|
goroot = mustTempDir(t, "goroot-")
|
|
|
|
defer os.RemoveAll(goroot)
|
|
|
|
if err := mapToDir(goroot, c.gorootFiles); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if c.gopathFiles != nil {
|
|
|
|
gopath = mustTempDir(t, "gopath-")
|
|
|
|
defer os.RemoveAll(gopath)
|
|
|
|
if err := mapToDir(gopath, c.gopathFiles); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
withEmptyGoPath(func() {
|
|
|
|
if goroot != "" {
|
|
|
|
build.Default.GOROOT = goroot
|
|
|
|
}
|
|
|
|
build.Default.GOPATH = gopath
|
|
|
|
|
|
|
|
it := &goimportTest{
|
|
|
|
T: t,
|
|
|
|
goroot: build.Default.GOROOT,
|
|
|
|
gopath: gopath,
|
|
|
|
ctx: &build.Default,
|
|
|
|
}
|
|
|
|
fn(it)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
type goimportTest struct {
|
|
|
|
*testing.T
|
|
|
|
ctx *build.Context
|
|
|
|
goroot string
|
|
|
|
gopath string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tests that added imports are renamed when the import path's base doesn't
|
|
|
|
// match its package name. For example, we want to generate:
|
|
|
|
//
|
|
|
|
// import cloudbilling "google.golang.org/api/cloudbilling/v1"
|
|
|
|
func TestRenameWhenPackageNameMismatch(t *testing.T) {
|
|
|
|
testConfig{
|
|
|
|
gopathFiles: map[string]string{
|
|
|
|
"foo/bar/v1/x.go": "package bar \n const X = 1",
|
|
|
|
},
|
|
|
|
}.test(t, func(t *goimportTest) {
|
|
|
|
buf, err := Process(t.gopath+"/src/test/t.go", []byte("package main \n const Y = bar.X"), &Options{})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
const want = `package main
|
|
|
|
|
|
|
|
import bar "foo/bar/v1"
|
|
|
|
|
|
|
|
const Y = bar.X
|
|
|
|
`
|
|
|
|
if string(buf) != want {
|
|
|
|
t.Errorf("Got:\n%s\nWant:\n%s", buf, want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tests that running goimport on files in GOROOT (for people hacking
|
|
|
|
// on Go itself) don't cause the GOPATH to be scanned (which might be
|
|
|
|
// much bigger).
|
|
|
|
func TestOptimizationWhenInGoroot(t *testing.T) {
|
|
|
|
testConfig{
|
|
|
|
gopathFiles: map[string]string{
|
|
|
|
"foo/foo.go": "package foo\nconst X = 1\n",
|
|
|
|
},
|
|
|
|
}.test(t, func(t *goimportTest) {
|
|
|
|
testHookScanDir = func(dir string) {
|
|
|
|
if dir != filepath.Join(build.Default.GOROOT, "src") {
|
|
|
|
t.Errorf("unexpected dir scan of %s", dir)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const in = "package foo\n\nconst Y = bar.X\n"
|
|
|
|
buf, err := Process(t.goroot+"/src/foo/foo.go", []byte(in), nil)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if string(buf) != in {
|
|
|
|
t.Errorf("got:\n%q\nwant unchanged:\n%q\n", in, buf)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tests that "package documentation" files are ignored.
|
|
|
|
func TestIgnoreDocumentationPackage(t *testing.T) {
|
|
|
|
testConfig{
|
|
|
|
gopathFiles: map[string]string{
|
|
|
|
"foo/foo.go": "package foo\nconst X = 1\n",
|
|
|
|
"foo/doc.go": "package documentation \n // just to confuse things\n",
|
|
|
|
},
|
|
|
|
}.test(t, func(t *goimportTest) {
|
|
|
|
const in = "package x\n\nconst Y = foo.X\n"
|
|
|
|
const want = "package x\n\nimport \"foo\"\n\nconst Y = foo.X\n"
|
|
|
|
buf, err := Process(t.gopath+"/src/x/x.go", []byte(in), nil)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if string(buf) != want {
|
|
|
|
t.Errorf("wrong output.\ngot:\n%q\nwant:\n%q\n", in, want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-07-15 09:24:26 -06:00
|
|
|
// Tests importPathToNameGoPathParse and in particular that it stops
|
|
|
|
// after finding the first non-documentation package name, not
|
|
|
|
// reporting an error on inconsistent package names (since it should
|
|
|
|
// never make it that far).
|
|
|
|
func TestImportPathToNameGoPathParse(t *testing.T) {
|
|
|
|
testConfig{
|
|
|
|
gopathFiles: map[string]string{
|
|
|
|
"example.net/pkg/doc.go": "package documentation\n", // ignored
|
|
|
|
"example.net/pkg/gen.go": "package main\n", // also ignored
|
|
|
|
"example.net/pkg/pkg.go": "package the_pkg_name_to_find\n and this syntax error is ignored because of parser.PackageClauseOnly",
|
|
|
|
"example.net/pkg/z.go": "package inconsistent\n", // inconsistent but ignored
|
|
|
|
},
|
|
|
|
}.test(t, func(t *goimportTest) {
|
|
|
|
got, err := importPathToNameGoPathParse("example.net/pkg", filepath.Join(t.gopath, "src", "other.net"))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
const want = "the_pkg_name_to_find"
|
|
|
|
if got != want {
|
|
|
|
t.Errorf("importPathToNameGoPathParse(..) = %q; want %q", got, want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-07-15 12:28:37 -06:00
|
|
|
func TestIgnoreConfiguration(t *testing.T) {
|
|
|
|
testConfig{
|
|
|
|
gopathFiles: map[string]string{
|
|
|
|
".goimportsignore": "# comment line\n\n example.net", // tests comment, blank line, whitespace trimming
|
|
|
|
"example.net/pkg/pkg.go": "package pkg\nconst X = 1",
|
|
|
|
"otherwise-longer-so-worse.example.net/foo/pkg/pkg.go": "package pkg\nconst X = 1",
|
|
|
|
},
|
|
|
|
}.test(t, func(t *goimportTest) {
|
|
|
|
const in = "package x\n\nconst _ = pkg.X\n"
|
|
|
|
const want = "package x\n\nimport \"otherwise-longer-so-worse.example.net/foo/pkg\"\n\nconst _ = pkg.X\n"
|
|
|
|
buf, err := Process(t.gopath+"/src/x/x.go", []byte(in), nil)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if string(buf) != want {
|
|
|
|
t.Errorf("wrong output.\ngot:\n%q\nwant:\n%q\n", buf, want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2014-01-26 10:47:31 -07:00
|
|
|
func strSet(ss []string) map[string]bool {
|
|
|
|
m := make(map[string]bool)
|
|
|
|
for _, s := range ss {
|
|
|
|
m[s] = true
|
|
|
|
}
|
|
|
|
return m
|
|
|
|
}
|
2016-07-18 15:58:52 -06:00
|
|
|
|
|
|
|
func TestPkgIsCandidate(t *testing.T) {
|
|
|
|
tests := [...]struct {
|
|
|
|
filename string
|
|
|
|
pkgIdent string
|
|
|
|
pkg *pkg
|
|
|
|
want bool
|
|
|
|
}{
|
|
|
|
// normal match
|
|
|
|
0: {
|
|
|
|
filename: "/gopath/src/my/pkg/pkg.go",
|
|
|
|
pkgIdent: "client",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/client",
|
|
|
|
importPath: "client",
|
|
|
|
importPathShort: "client",
|
|
|
|
},
|
|
|
|
want: true,
|
|
|
|
},
|
|
|
|
// not a match
|
|
|
|
1: {
|
|
|
|
filename: "/gopath/src/my/pkg/pkg.go",
|
|
|
|
pkgIdent: "zzz",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/client",
|
|
|
|
importPath: "client",
|
|
|
|
importPathShort: "client",
|
|
|
|
},
|
|
|
|
want: false,
|
|
|
|
},
|
|
|
|
// would be a match, but "client" appears too deep.
|
|
|
|
2: {
|
|
|
|
filename: "/gopath/src/my/pkg/pkg.go",
|
|
|
|
pkgIdent: "client",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/client/foo/foo/foo",
|
|
|
|
importPath: "client/foo/foo",
|
|
|
|
importPathShort: "client/foo/foo",
|
|
|
|
},
|
|
|
|
want: false,
|
|
|
|
},
|
|
|
|
// not an exact match, but substring is good enough.
|
|
|
|
3: {
|
|
|
|
filename: "/gopath/src/my/pkg/pkg.go",
|
|
|
|
pkgIdent: "client",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/foo/go-client",
|
|
|
|
importPath: "foo/go-client",
|
|
|
|
importPathShort: "foo/go-client",
|
|
|
|
},
|
|
|
|
want: true,
|
|
|
|
},
|
|
|
|
// "internal" package, and not visible
|
|
|
|
4: {
|
|
|
|
filename: "/gopath/src/my/pkg/pkg.go",
|
|
|
|
pkgIdent: "client",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/foo/internal/client",
|
|
|
|
importPath: "foo/internal/client",
|
|
|
|
importPathShort: "foo/internal/client",
|
|
|
|
},
|
|
|
|
want: false,
|
|
|
|
},
|
|
|
|
// "internal" package but visible
|
|
|
|
5: {
|
|
|
|
filename: "/gopath/src/foo/bar.go",
|
|
|
|
pkgIdent: "client",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/foo/internal/client",
|
|
|
|
importPath: "foo/internal/client",
|
|
|
|
importPathShort: "foo/internal/client",
|
|
|
|
},
|
|
|
|
want: true,
|
|
|
|
},
|
|
|
|
// "vendor" package not visible
|
|
|
|
6: {
|
|
|
|
filename: "/gopath/src/foo/bar.go",
|
|
|
|
pkgIdent: "client",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/other/vendor/client",
|
|
|
|
importPath: "other/vendor/client",
|
|
|
|
importPathShort: "client",
|
|
|
|
},
|
|
|
|
want: false,
|
|
|
|
},
|
|
|
|
// "vendor" package, visible
|
|
|
|
7: {
|
|
|
|
filename: "/gopath/src/foo/bar.go",
|
|
|
|
pkgIdent: "client",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/foo/vendor/client",
|
|
|
|
importPath: "other/foo/client",
|
|
|
|
importPathShort: "client",
|
|
|
|
},
|
|
|
|
want: true,
|
|
|
|
},
|
|
|
|
// Ignore hyphens.
|
|
|
|
8: {
|
|
|
|
filename: "/gopath/src/foo/bar.go",
|
|
|
|
pkgIdent: "socketio",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/foo/socket-io",
|
|
|
|
importPath: "foo/socket-io",
|
|
|
|
importPathShort: "foo/socket-io",
|
|
|
|
},
|
|
|
|
want: true,
|
|
|
|
},
|
|
|
|
// Ignore case.
|
|
|
|
9: {
|
|
|
|
filename: "/gopath/src/foo/bar.go",
|
|
|
|
pkgIdent: "fooprod",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/foo/FooPROD",
|
|
|
|
importPath: "foo/FooPROD",
|
|
|
|
importPathShort: "foo/FooPROD",
|
|
|
|
},
|
|
|
|
want: true,
|
|
|
|
},
|
|
|
|
// Ignoring both hyphens and case together.
|
|
|
|
10: {
|
|
|
|
filename: "/gopath/src/foo/bar.go",
|
|
|
|
pkgIdent: "fooprod",
|
|
|
|
pkg: &pkg{
|
|
|
|
dir: "/gopath/src/foo/Foo-PROD",
|
|
|
|
importPath: "foo/Foo-PROD",
|
|
|
|
importPathShort: "foo/Foo-PROD",
|
|
|
|
},
|
|
|
|
want: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for i, tt := range tests {
|
|
|
|
got := pkgIsCandidate(tt.filename, tt.pkgIdent, tt.pkg)
|
|
|
|
if got != tt.want {
|
|
|
|
t.Errorf("test %d. pkgIsCandidate(%q, %q, %+v) = %v; want %v",
|
|
|
|
i, tt.filename, tt.pkgIdent, *tt.pkg, got, tt.want)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|