diff --git a/go/tools/gazelle/generator/generator_test.go b/go/tools/gazelle/generator/generator_test.go index 54c03a27aa..21ceeee511 100644 --- a/go/tools/gazelle/generator/generator_test.go +++ b/go/tools/gazelle/generator/generator_test.go @@ -55,6 +55,13 @@ func TestGenerator(t *testing.T) { }, }, }, + "lib/relativeimporter": { + { + Call: &bzl.CallExpr{ + X: &bzl.LiteralExpr{Token: "go_library"}, + }, + }, + }, "bin": { { Call: &bzl.CallExpr{ @@ -108,6 +115,13 @@ func TestGenerator(t *testing.T) { stub.fixtures["lib/internal/deep"][1].Call, }, }, + { + Path: "lib/relativeimporter/BUILD", + Stmt: []bzl.Expr{ + loadExpr("go_library"), + stub.fixtures["lib/relativeimporter"][0].Call, + }, + }, { Path: "bin/BUILD", Stmt: []bzl.Expr{ diff --git a/go/tools/gazelle/rules/generator.go b/go/tools/gazelle/rules/generator.go index 521a2583fb..721458323d 100644 --- a/go/tools/gazelle/rules/generator.go +++ b/go/tools/gazelle/rules/generator.go @@ -64,7 +64,7 @@ func NewGenerator(goPrefix string) Generator { return &generator{ goPrefix: goPrefix, r: resolverFunc(func(importpath, dir string) (label, error) { - if importpath != goPrefix && !strings.HasPrefix(importpath, goPrefix+"/") && !strings.HasPrefix(importpath, "./") { + if importpath != goPrefix && !strings.HasPrefix(importpath, goPrefix+"/") && !isRelative(importpath) { return e.resolve(importpath, dir) } return r.resolve(importpath, dir) @@ -202,3 +202,8 @@ func isStandard(importpath string) bool { seg := strings.SplitN(importpath, "/", 2)[0] return !strings.Contains(seg, ".") } + +// isRelative determines if an importpath is relative. +func isRelative(importpath string) bool { + return strings.HasPrefix(importpath, "./") || strings.HasPrefix(importpath, "..") +} diff --git a/go/tools/gazelle/rules/generator_test.go b/go/tools/gazelle/rules/generator_test.go index c4166e04df..14ea8388d3 100644 --- a/go/tools/gazelle/rules/generator_test.go +++ b/go/tools/gazelle/rules/generator_test.go @@ -93,6 +93,17 @@ func TestGenerator(t *testing.T) { ) `, }, + { + dir: "lib/relativeimporter", + want: ` + go_library( + name = "go_default_library", + srcs = ["importer.go"], + visibility = ["//visibility:public"], + deps = ["//lib/internal/deep:go_default_library"], + ) + `, + }, { dir: "bin", want: ` diff --git a/go/tools/gazelle/rules/resolve_structured.go b/go/tools/gazelle/rules/resolve_structured.go index 6c66f9f120..c13d7575c8 100644 --- a/go/tools/gazelle/rules/resolve_structured.go +++ b/go/tools/gazelle/rules/resolve_structured.go @@ -30,8 +30,8 @@ type structuredResolver struct { // resolve takes a Go importpath within the same respository as r.goPrefix // and resolves it into a label in Bazel. func (r structuredResolver) resolve(importpath, dir string) (label, error) { - if strings.HasPrefix(importpath, "./") { - importpath = path.Join(r.goPrefix, dir, importpath[2:]) + if isRelative(importpath) { + importpath = path.Clean(path.Join(r.goPrefix, dir, importpath)) } if importpath == r.goPrefix { diff --git a/go/tools/gazelle/testdata/repo/lib/relativeimporter/importer.go b/go/tools/gazelle/testdata/repo/lib/relativeimporter/importer.go new file mode 100644 index 0000000000..5463d9794e --- /dev/null +++ b/go/tools/gazelle/testdata/repo/lib/relativeimporter/importer.go @@ -0,0 +1,24 @@ +/* Copyright 2016 The Bazel Authors. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package relativeimporter + +import ( + "log" + + "../internal/deep" +) + +func think() { + t := &deep.Thought{} + log.Println(t.Compute()) +}