Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

packages: extract importpath from proto go_package options #54

Merged
merged 1 commit into from
Dec 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/fileinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ type fileInfo struct {
// This may be read from a package comment (in Go) or a go_package
// option (in proto). This field is empty for files that don't specify
// an import path.
// TODO(#874): extract from Go files
importPath string

// category is the type of file, based on extension.
Expand Down
1 change: 1 addition & 0 deletions packages/fileinfo_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
// If the file can't be read, an error will be logged, and partial information
// will be returned.
// This function is intended to match go/build.Context.Import.
// TODD(#53): extract canonical import path
func goFileInfo(c *config.Config, dir, rel, name string) fileInfo {
info := fileNameInfo(dir, rel, name)
fset := token.NewFileSet()
Expand Down
12 changes: 8 additions & 4 deletions packages/fileinfo_go_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,12 +357,16 @@ import "C"
if err := ioutil.WriteFile(goFile, content, 0644); err != nil {
t.Fatal(err)
}
c := &config.Config{RepoRoot: repo}
c := &config.Config{
RepoRoot: repo,
GoPrefix: "example.com/repo",
}
got := buildPackage(c, sub, "sub", []string{"sub.go"}, nil, nil, false)
want := &Package{
Name: "sub",
Dir: sub,
Rel: "sub",
Name: "sub",
Dir: sub,
Rel: "sub",
ImportPath: "example.com/repo/sub",
Library: GoTarget{
Sources: PlatformStrings{
Generic: []string{"sub.go"},
Expand Down
42 changes: 30 additions & 12 deletions packages/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ type Package struct {
// Components in Rel are separated with slashes.
Rel string

// ImportPath is the string used to import this package in Go.
ImportPath string

Library, Binary, Test, XTest GoTarget
Proto ProtoTarget

Expand Down Expand Up @@ -95,18 +98,6 @@ func (p *Package) IsCommand() bool {
return p.Name == "main"
}

// ImportPath returns the inferred Go import path for this package.
// TODO(jayconrod): extract canonical import paths from comments on
// package statements.
func (p *Package) ImportPath(c *config.Config) string {
if p.Rel == c.GoPrefixRel {
return c.GoPrefix
} else {
fromPrefixRel := strings.TrimPrefix(p.Rel, c.GoPrefixRel+"/")
return path.Join(c.GoPrefix, fromPrefixRel)
}
}

func (t *GoTarget) HasGo() bool {
return t.Sources.HasGo()
}
Expand Down Expand Up @@ -158,6 +149,7 @@ type packageBuilder struct {
library, binary, test, xtest goTargetBuilder
proto protoTargetBuilder
hasTestdata bool
importPath, importPathFile string
}

type goTargetBuilder struct {
Expand Down Expand Up @@ -224,6 +216,15 @@ func (pb *packageBuilder) addFile(c *config.Config, info fileInfo, cgo bool) err
pb.proto.hasPbGo = true
}

if info.importPath != "" {
if pb.importPath == "" {
pb.importPath = info.importPath
pb.importPathFile = info.path
} else if pb.importPath != info.importPath {
return fmt.Errorf("found import comments %q (%s) and %q (%s)", pb.importPath, pb.importPathFile, info.importPath, info.path)
}
}

return nil
}

Expand Down Expand Up @@ -256,11 +257,28 @@ func (pb *packageBuilder) firstGoFile() string {
return ""
}

func (pb *packageBuilder) inferImportPath(c *config.Config) error {
if pb.importPath != "" {
log.Panic("importPath already set")
}
if pb.rel == c.GoPrefixRel {
if c.GoPrefix == "" {
return fmt.Errorf("in directory %q, prefix is empty, so importpath would be empty for rules. Set a prefix with a '# gazelle:prefix' comment or with -go_prefix on the command line.", pb.dir)
}
pb.importPath = c.GoPrefix
} else {
fromPrefixRel := strings.TrimPrefix(pb.rel, c.GoPrefixRel+"/")
pb.importPath = path.Join(c.GoPrefix, fromPrefixRel)
}
return nil
}

func (pb *packageBuilder) build() *Package {
return &Package{
Name: pb.name,
Dir: pb.dir,
Rel: pb.rel,
ImportPath: pb.importPath,
Library: pb.library.build(),
Binary: pb.binary.build(),
Test: pb.test.build(),
Expand Down
16 changes: 11 additions & 5 deletions packages/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,15 @@ func buildPackage(c *config.Config, dir, rel string, pkgFiles, otherFiles, genFi
// or I/O errors. We should keep the file in the srcs list and let the
// compiler deal with the error.
for _, info := range pkgFilesWithUnknownPackage {
pkg.addFile(c, info, cgo)
if err := pkg.addFile(c, info, cgo); err != nil {
log.Print(err)
}
}

// Process the other static files.
for _, file := range otherFiles {
info := otherFileInfo(dir, rel, file)
err = pkg.addFile(c, info, cgo)
if err != nil {
if err := pkg.addFile(c, info, cgo); err != nil {
log.Print(err)
}
}
Expand All @@ -292,12 +293,17 @@ func buildPackage(c *config.Config, dir, rel string, pkgFiles, otherFiles, genFi
continue
}
info := fileNameInfo(dir, rel, f)
err := pkg.addFile(c, info, cgo)
if err != nil {
if err := pkg.addFile(c, info, cgo); err != nil {
log.Print(err)
}
}

if pkg.importPath == "" {
if err := pkg.inferImportPath(c); err != nil {
log.Print(err)
return nil
}
}
return pkg.build()
}

Expand Down
Loading