Skip to content

Commit

Permalink
feat(go_serving): add ResolveVName to Unit interface (#5474)
Browse files Browse the repository at this point in the history
* feat(go_serving): add ResolveVName to Unit interface

* chore: rename method to address comments
  • Loading branch information
shahms committed Dec 8, 2022
1 parent 8876908 commit 90ee7a3
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
1 change: 1 addition & 0 deletions kythe/go/platform/kcd/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package(default_visibility = ["//kythe:default_visibility"])
go_library(
name = "kcd",
srcs = ["kcd.go"],
deps = ["//kythe/proto:storage_go_proto"],
)

go_test(
Expand Down
6 changes: 6 additions & 0 deletions kythe/go/platform/kcd/kcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import (
"regexp"
"strings"
"time"

spb "kythe.io/kythe/proto/storage_go_proto"
)

// Reader represents read-only access to an underlying storage layer used to
Expand Down Expand Up @@ -244,6 +246,10 @@ type Unit interface {
// Digest produces a unique string representation of a unit sufficient to
// serve as a content-addressable digest.
Digest() string

// LookupVName looks up and returns the VName for the given file path
// or nil if it could not be found or the operation is unsupported.
LookupVName(path string) *spb.VName
}

// Index represents the indexable terms of a compilation.
Expand Down
46 changes: 46 additions & 0 deletions kythe/go/platform/kcd/kythe/units.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"crypto/sha256"
"encoding/hex"
"fmt"
"path"
"sort"
"strings"

Expand Down Expand Up @@ -82,6 +83,29 @@ func (u Unit) Index() kcd.Index {
return idx
}

// LookupVName satisfies part of the kcd.Unit interface.
func (u Unit) LookupVName(inputPath string) *spb.VName {
inputPath = u.pathKey(inputPath)
for _, ri := range u.Proto.RequiredInput {
if ri.Info == nil {
continue
}
qp := u.pathKey(ri.Info.GetPath())
if qp == inputPath {
v := proto.Clone(ri.GetVName()).(*spb.VName)
if v.GetCorpus() == "" {
v.Corpus = u.Proto.GetVName().GetCorpus()
v.Root = u.Proto.GetVName().GetRoot()
}
if v.GetPath() == "" {
v.Path = inputPath
}
return v
}
}
return nil
}

// Canonicalize satisfies part of the kcd.Unit interface. It orders required
// inputs by the digest of their contents, orders environment variables and
// source paths by name, and orders compilation details by their type URL.
Expand Down Expand Up @@ -129,6 +153,28 @@ func (u Unit) Digest() string {
return hex.EncodeToString(sha.Sum(nil)[:])
}

// pathKey returns a cleaned path, relative to the compilation working directory.
func (u Unit) pathKey(inputPath string) string {
root := path.Clean(u.Proto.GetWorkingDirectory())
if root == "" {
root = "/"
}

if path.IsAbs(inputPath) {
inputPath = path.Clean(inputPath)
} else {
inputPath = path.Join(root, inputPath)
}

var prefix string
if root == "/" {
prefix = root
} else {
prefix = root + "/"
}
return strings.TrimPrefix(inputPath, prefix)
}

// ConvertUnit reports whether v can be converted to a Kythe kcd.Unit, and if
// so returns the appropriate implementation.
func ConvertUnit(v interface{}) (kcd.Unit, bool) {
Expand Down
43 changes: 43 additions & 0 deletions kythe/go/platform/kcd/kythe/units_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,49 @@ func TestCanonicalization(t *testing.T) {
}
}

func TestLookupVName(t *testing.T) {
unit := Unit{Proto: &apb.CompilationUnit{
VName: &spb.VName{Corpus: "DefaultCorpus", Root: "DefaultRoot"},
RequiredInput: []*apb.CompilationUnit_FileInput{
{Info: &apb.FileInfo{Path: "/absolute/path/file.go"},
VName: &spb.VName{Corpus: "Corpus", Root: "Root", Path: "abspath/file.go"},
},
{Info: &apb.FileInfo{Path: "/build/absolute/path/file.go"},
VName: &spb.VName{Corpus: "Corpus", Root: "Root", Path: "buildrelpath/file.go"},
},
{Info: &apb.FileInfo{Path: "relative/file.go"},
VName: &spb.VName{Corpus: "Corpus", Root: "Root", Path: "relpath/file.go"},
},
{Info: &apb.FileInfo{Path: "missing/vname/corpus/file.go"},
VName: &spb.VName{Path: "missing/corpus/file.go"},
},
{Info: &apb.FileInfo{Path: "missing/vname/path/file.go"},
VName: &spb.VName{Corpus: "Corpus", Root: "Root"},
},
},
WorkingDirectory: "/build",
}}
tests := []struct {
path string
want *spb.VName
}{
{"missing/file.go", nil},
{"/absolute/path/file.go", &spb.VName{Corpus: "Corpus", Root: "Root", Path: "abspath/file.go"}},
{"/build/absolute/path/file.go", &spb.VName{Corpus: "Corpus", Root: "Root", Path: "buildrelpath/file.go"}},
{"relative/file.go", &spb.VName{Corpus: "Corpus", Root: "Root", Path: "relpath/file.go"}},
{"./relative/file.go", &spb.VName{Corpus: "Corpus", Root: "Root", Path: "relpath/file.go"}},
{"/build/relative/file.go", &spb.VName{Corpus: "Corpus", Root: "Root", Path: "relpath/file.go"}},
{"missing/vname/corpus/file.go", &spb.VName{Corpus: "DefaultCorpus", Root: "DefaultRoot", Path: "missing/corpus/file.go"}},
{"missing/vname/path/file.go", &spb.VName{Corpus: "Corpus", Root: "Root", Path: "missing/vname/path/file.go"}},
}
for _, test := range tests {
got := unit.LookupVName(test.path)
if !reflect.DeepEqual(got, test.want) {
t.Errorf("VName for %s: got %+q, want %+q", test.path, got, test.want)
}
}
}

func keys(v interface{}) (keys []string) {
switch t := v.(type) {
case []*apb.CompilationUnit_FileInput:
Expand Down

0 comments on commit 90ee7a3

Please sign in to comment.