Repository: kythe/kythe
Pull request #5348 (2022-08-11 21:20:49)

chore(go): remove support for kindex


Patch:
diff --git a/kythe/go/extractors/bazel/BUILD b/kythe/go/extractors/bazel/BUILD
index 6986a5ac8..0301a24ab 100644
--- a/kythe/go/extractors/bazel/BUILD
+++ b/kythe/go/extractors/bazel/BUILD
@@ -14,7 +14,6 @@ go_library(
     visibility = [PUBLIC_VISIBILITY],
     deps = [
         "//kythe/go/extractors/bazel/treeset",
-        "//kythe/go/platform/kindex",
         "//kythe/go/platform/kzip",
         "//kythe/go/util/ptypes",
         "//kythe/go/util/vnameutil",
diff --git a/kythe/go/extractors/bazel/extutil/BUILD b/kythe/go/extractors/bazel/extutil/BUILD
index 46648be91..fc1dc8517 100644
--- a/kythe/go/extractors/bazel/extutil/BUILD
+++ b/kythe/go/extractors/bazel/extutil/BUILD
@@ -5,13 +5,13 @@ package(default_visibility = ["//kythe:default_visibility"])
 
 # A library to support Bazel extractors switching between .kzip and .kindex
 # output, for temporary use in migrating away from .kindex files.
+# TODO: refactor this now that kindex is gone
 go_library(
     name = "extutil",
     srcs = ["extutil.go"],
     visibility = [PUBLIC_VISIBILITY],
     deps = [
         "//kythe/go/extractors/bazel",
-        "//kythe/go/platform/kindex",
         "//kythe/go/platform/kzip",
         "//third_party/bazel:extra_actions_base_go_proto",
     ],
diff --git a/kythe/go/extractors/bazel/settings.go b/kythe/go/extractors/bazel/settings.go
index 944f85466..befc7b8f0 100644
--- a/kythe/go/extractors/bazel/settings.go
+++ b/kythe/go/extractors/bazel/settings.go
@@ -78,7 +78,7 @@ func (s *Settings) SetFlags(f *flag.FlagSet, prefix string) func() {
 	// A default usage message the caller may use to populate flag.Usage.
 	return func() {
 		fmt.Fprintf(f.Output(),
-			`Usage: %s [options] -corpus C -language L -extra_action f.xa -output f.kindex
+			`Usage: %s [options] -corpus C -language L -extra_action f.xa -output f.kzip
 
 Read an ExtraActionInput protobuf message from the designated -extra_action
 file[*] and generate a Kythe compilation record in the specified -output file.
diff --git a/kythe/go/extractors/cmd/bazel/bazel_go_extractor/bazel_go_extractor.go b/kythe/go/extractors/cmd/bazel/bazel_go_extractor/bazel_go_extractor.go
index 5880e4a51..979f2a21d 100644
--- a/kythe/go/extractors/cmd/bazel/bazel_go_extractor/bazel_go_extractor.go
+++ b/kythe/go/extractors/cmd/bazel/bazel_go_extractor/bazel_go_extractor.go
@@ -49,7 +49,7 @@ Extract a Kythe compilation record for Go from a Bazel extra action.
 
 Arguments:
  <extra-action> is a file containing a wire format ExtraActionInfo protobuf.
- <output-file>  is the path where the output kindex file is written.
+ <output-file>  is the path where the output kzip file is written.
  <vname-config> is the path of a VName configuration JSON file.
 
 Flags:
diff --git a/kythe/go/extractors/constants/constants.go b/kythe/go/extractors/constants/constants.go
index 99f092dae..5075211f6 100644
--- a/kythe/go/extractors/constants/constants.go
+++ b/kythe/go/extractors/constants/constants.go
@@ -92,7 +92,7 @@ var (
 		// -Xbootclasspath/p:/opt/kythe/extractors/javac9_tools.jar
 		"KYTHE_JAVA_RUNTIME_OPTIONS",
 		// If set to a file ending in '.kzip', this will cause the extractor to
-		// output a .kzip file instead of multiple .kindex files.
+		// output a .kzip file.
 		// Note this does not obviate the need to set KYTHE_OUTPUT_DIRECTORY.
 		"KYTHE_OUTPUT_FILE",
 	)
diff --git a/kythe/go/extractors/golang/BUILD b/kythe/go/extractors/golang/BUILD
index 3efcc4a55..418e99fb1 100644
--- a/kythe/go/extractors/golang/BUILD
+++ b/kythe/go/extractors/golang/BUILD
@@ -11,7 +11,7 @@ go_library(
     deps = [
         "//kythe/go/extractors/govname",
         "//kythe/go/platform/analysis",
-        "//kythe/go/platform/kindex",
+        "//kythe/go/platform/kzip",
         "//kythe/go/platform/vfs",
         "//kythe/go/util/ptypes",
         "//kythe/proto:analysis_go_proto",
diff --git a/kythe/go/extractors/golang/golang.go b/kythe/go/extractors/golang/golang.go
index 66666ab6e..79d558082 100644
--- a/kythe/go/extractors/golang/golang.go
+++ b/kythe/go/extractors/golang/golang.go
@@ -45,7 +45,7 @@ import (
 
 	"kythe.io/kythe/go/extractors/govname"
 	"kythe.io/kythe/go/platform/analysis"
-	"kythe.io/kythe/go/platform/kindex"
+	"kythe.io/kythe/go/platform/kzip"
 	"kythe.io/kythe/go/platform/vfs"
 	"kythe.io/kythe/go/util/ptypes"
 
@@ -355,7 +355,7 @@ func (p *Package) EachUnit(ctx context.Context, f func(cu *apb.CompilationUnit,
 			if err != nil {
 				return fmt.Errorf("opening input: %v", err)
 			}
-			fd, err := kindex.FileData(ri.Info.Path, rc)
+			fd, err := kzip.FileData(ri.Info.Path, rc)
 			rc.Close()
 			if err != nil {
 				return fmt.Errorf("reading input: %v", err)
diff --git a/kythe/go/platform/kcd/kzipdb/kzipdb.go b/kythe/go/platform/kcd/kzipdb/kzipdb.go
index f7d29e926..93e54ec2f 100644
--- a/kythe/go/platform/kcd/kzipdb/kzipdb.go
+++ b/kythe/go/platform/kcd/kzipdb/kzipdb.go
@@ -15,7 +15,7 @@
  */
 
 // Package kzipdb implements kcd.Reader using a kzip file as its backing
-// store. See also: http://www.kythe.io/docs/kythe-index-pack.html.
+// store. See also: http://www.kythe.io/docs/kythe-kzip.html.
 package kzipdb // import "kythe.io/kythe/go/platform/kcd/kzipdb"
 
 import (
diff --git a/kythe/go/platform/kindex/BUILD b/kythe/go/platform/kindex/BUILD
deleted file mode 100644
index 90167fe60..000000000
--- a/kythe/go/platform/kindex/BUILD
+++ /dev/null
@@ -1,33 +0,0 @@
-load("//tools:build_rules/shims.bzl", "go_library", "go_test")
-
-package(default_visibility = ["//kythe:default_visibility"])
-
-go_library(
-    name = "kindex",
-    srcs = ["kindex.go"],
-    deprecation = "Please use //kythe/go/platform/kzip",
-    deps = [
-        "//kythe/go/platform/analysis",
-        "//kythe/go/platform/delimited",
-        "//kythe/go/platform/vfs",
-        "//kythe/go/util/ptypes",
-        "//kythe/proto:analysis_go_proto",
-        "//kythe/proto:storage_go_proto",
-        "@com_github_golang_protobuf//proto:go_default_library",
-    ],
-)
-
-go_test(
-    name = "kindex_test",
-    size = "small",
-    srcs = ["kindex_test.go"],
-    library = "kindex",
-    visibility = ["//visibility:private"],
-    deps = [
-        "//kythe/proto:analysis_go_proto",
-        "//kythe/proto:go_go_proto",
-        "//kythe/proto:storage_go_proto",
-        "@com_github_golang_protobuf//proto:go_default_library",
-        "@io_bazel_rules_go//proto/wkt:any_go_proto",
-    ],
-)
diff --git a/kythe/go/platform/kindex/kindex.go b/kythe/go/platform/kindex/kindex.go
deleted file mode 100644
index 23519f9a7..000000000
--- a/kythe/go/platform/kindex/kindex.go
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright 2014 The Kythe 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 kindex implements an interface to compilation index files which are
-// standalone CompilationUnits with all of their required inputs.
-//
-// Example: Reading an index file.
-//
-//	c, err := kindex.Open("path/to/unit.kindex")
-//	if err != nil {
-//	  log.Fatal(err)
-//	}
-//
-// Example: Writing an index file.
-//
-//	var buf bytes.Buffer
-//	c.WriteTo(&buf)
-//
-// On disk, a kindex file is a GZip compressed stream of varint-prefixed data
-// blocks containing wire-format protobuf messages.  The first message is a
-// CompilationUnit, the remaining messages are FileData messages, one for each
-// of the required inputs for the CompilationUnit.
-//
-// These proto messages are defined in //kythe/proto:analysis_proto
-package kindex // import "kythe.io/kythe/go/platform/kindex"
-
-import (
-	"bytes"
-	"compress/gzip"
-	"context"
-	"crypto/sha256"
-	"encoding/hex"
-	"fmt"
-	"io"
-	"os"
-	"sync"
-
-	"kythe.io/kythe/go/platform/analysis"
-	"kythe.io/kythe/go/platform/delimited"
-	"kythe.io/kythe/go/platform/vfs"
-	"kythe.io/kythe/go/util/ptypes"
-
-	"github.com/golang/protobuf/proto"
-
-	apb "kythe.io/kythe/proto/analysis_go_proto"
-	spb "kythe.io/kythe/proto/storage_go_proto"
-)
-
-// Extension is the standard file extension for Kythe compilation index files.
-const Extension = ".kindex"
-
-// Compilation is a CompilationUnit with the contents for all of its required inputs.
-type Compilation struct {
-	Proto *apb.CompilationUnit `json:"compilation"`
-	Files []*apb.FileData      `json:"files"`
-}
-
-// Open opens a kindex file at the given path (using vfs.Open) and reads
-// its contents into memory.
-func Open(ctx context.Context, path string) (*Compilation, error) {
-	f, err := vfs.Open(ctx, path)
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-	return New(f)
-}
-
-// New reads a kindex file from r, which is expected to be positioned at the
-// beginning of an index file or a data source of equivalent format.
-func New(r io.Reader) (*Compilation, error) {
-	gz, err := gzip.NewReader(r)
-	if err != nil {
-		return nil, err
-	}
-	rd := delimited.NewReader(gz)
-
-	// The first block is the CompilationUnit message.
-	cu := new(apb.CompilationUnit)
-	if rec, err := rd.Next(); err != nil {
-		return nil, err
-	} else if err := proto.Unmarshal(rec, cu); err != nil {
-		return nil, err
-	}
-
-	// All the subsequent blocks are FileData messages.
-	var files []*apb.FileData
-	for {
-		rec, err := rd.Next()
-		if err == io.EOF {
-			break
-		} else if err != nil {
-			return nil, err
-		}
-
-		fd := new(apb.FileData)
-		if err := proto.Unmarshal(rec, fd); err != nil {
-			return nil, err
-		}
-		files = append(files, fd)
-	}
-
-	return &Compilation{
-		Proto: cu,
-		Files: files,
-	}, nil
-}
-
-// Fetch implements the analysis.Fetcher interface for files attached to c.
-// If digest == "", files are matched by path only.
-func (c *Compilation) Fetch(path, digest string) ([]byte, error) {
-	for _, f := range c.Files {
-		info := f.GetInfo()
-		fp := info.Path
-		fd := info.Digest
-		if path == fp && (digest == "" || digest == fd) {
-			return f.Content, nil
-		}
-		if digest != "" && digest == fd {
-			return f.Content, nil
-		}
-	}
-	return nil, os.ErrNotExist
-}
-
-// WriteTo implements the io.WriterTo interface, writing the contents of the
-// Compilation in index file format.  Returns the total number of bytes written
-// after GZip compression was applied.
-func (c *Compilation) WriteTo(w io.Writer) (int64, error) {
-	gz, err := gzip.NewWriterLevel(w, gzip.BestCompression)
-	if err != nil {
-		return 0, err
-	}
-	dw := delimited.NewWriter(gz)
-
-	buf := proto.NewBuffer(nil)
-	if err := buf.Marshal(c.Proto); err != nil {
-		gz.Close()
-		return 0, fmt.Errorf("marshalling compilation: %v", err)
-	}
-
-	var total int64
-
-	nw, err := dw.WriteRecord(buf.Bytes())
-	total += int64(nw)
-	if err != nil {
-		gz.Close()
-		return total, fmt.Errorf("writing compilation: %v", err)
-	}
-
-	for _, file := range c.Files {
-		buf.Reset()
-		if err := buf.Marshal(file); err != nil {
-			gz.Close()
-			return total, fmt.Errorf("marshaling file data: %v", err)
-		}
-		nw, err := dw.WriteRecord(buf.Bytes())
-		total += int64(nw)
-		if err != nil {
-			gz.Close()
-			return total, fmt.Errorf("writing file data: %v", err)
-		}
-	}
-	if err := gz.Close(); err != nil {
-		return total, err
-	}
-	return total, nil
-}
-
-// FromUnit creates a compilation index by fetching all the required inputs of
-// unit from f.
-func FromUnit(unit *apb.CompilationUnit, f analysis.Fetcher) (*Compilation, error) {
-	errc := make(chan error)
-	inputs := make([]*apb.FileData, len(unit.RequiredInput))
-	var wg sync.WaitGroup
-	for i := range unit.RequiredInput {
-		wg.Add(1)
-		go func(i int) {
-			defer wg.Done()
-
-			in := unit.RequiredInput[i].GetInfo()
-			data, err := f.Fetch(in.Path, in.Digest)
-			if err != nil {
-				errc <- err
-				return
-			}
-			inputs[i] = &apb.FileData{
-				Content: data,
-				Info: &apb.FileInfo{
-					Path:   in.Path,
-					Digest: in.Digest,
-				},
-			}
-		}(i)
-	}
-	go func() { wg.Wait(); close(errc) }()
-	var err error
-	for e := range errc {
-		if err == nil {
-			err = e
-		}
-	}
-	if err != nil {
-		return nil, err
-	}
-	return &Compilation{
-		Proto: unit,
-		Files: inputs,
-	}, nil
-}
-
-// Unit returns the CompilationUnit associated with c, creating a new empty one
-// if necessary.
-func (c *Compilation) Unit() *apb.CompilationUnit {
-	if c.Proto == nil {
-		c.Proto = new(apb.CompilationUnit)
-	}
-	return c.Proto
-}
-
-// AddFile adds an input file to the compilation by fully reading r.  The file
-// is added to the required inputs, attributed to the designated path, and also
-// to the file data slice.  If v != nil it is used as the vname of the input
-// added.
-func (c *Compilation) AddFile(path string, r io.Reader, v *spb.VName, details ...proto.Message) error {
-	var anys []*ptypes.Any
-	for _, d := range details {
-		any, err := ptypes.MarshalAny(d)
-		if err != nil {
-			return fmt.Errorf("unable to marshal %T to Any: %v", d, err)
-		}
-		anys = append(anys, any)
-	}
-	fd, err := FileData(path, r)
-	if err != nil {
-		return err
-	}
-	c.Files = append(c.Files, fd)
-	unit := c.Unit()
-	unit.RequiredInput = append(unit.RequiredInput, &apb.CompilationUnit_FileInput{
-		VName:   v,
-		Info:    fd.Info,
-		Details: anys,
-	})
-	return nil
-}
-
-// AddDetails adds the specified details message to the compilation.
-func (c *Compilation) AddDetails(msg proto.Message) error {
-	details, err := ptypes.MarshalAny(msg)
-	if err != nil {
-		return err
-	}
-	unit := c.Unit()
-	unit.Details = append(unit.Details, details)
-	return nil
-}
-
-// FileData creates a file data protobuf message by fully reading the contents
-// of r, having the designated path.
-func FileData(path string, r io.Reader) (*apb.FileData, error) {
-	var buf bytes.Buffer
-	hash := sha256.New()
-
-	w := io.MultiWriter(&buf, hash)
-	if _, err := io.Copy(w, r); err != nil {
-		return nil, err
-	}
-	digest := hex.EncodeToString(hash.Sum(nil))
-	return &apb.FileData{
-		Content: buf.Bytes(),
-		Info: &apb.FileInfo{
-			Path:   path,
-			Digest: digest,
-		},
-	}, nil
-}
diff --git a/kythe/go/platform/kzip/kzip.go b/kythe/go/platform/kzip/kzip.go
index f5d15d0fd..592411a06 100644
--- a/kythe/go/platform/kzip/kzip.go
+++ b/kythe/go/platform/kzip/kzip.go
@@ -651,3 +651,23 @@ type File interface {
 	io.ReaderAt
 	io.Seeker
 }
+
+// FileData creates a file data protobuf message by fully reading the contents
+// of r, having the designated path.
+func FileData(path string, r io.Reader) (*apb.FileData, error) {
+	var buf bytes.Buffer
+	hash := sha256.New()
+
+	w := io.MultiWriter(&buf, hash)
+	if _, err := io.Copy(w, r); err != nil {
+		return nil, err
+	}
+	digest := hex.EncodeToString(hash.Sum(nil))
+	return &apb.FileData{
+		Content: buf.Bytes(),
+		Info: &apb.FileInfo{
+			Path:   path,
+			Digest: digest,
+		},
+	}, nil
+}
diff --git a/kythe/go/storage/tools/write_entries/write_entries.go b/kythe/go/storage/tools/write_entries/write_entries.go
index 427c71a6a..1ddb9eb9e 100644
--- a/kythe/go/storage/tools/write_entries/write_entries.go
+++ b/kythe/go/storage/tools/write_entries/write_entries.go
@@ -25,7 +25,7 @@
 //
 //	java_indexer_server --port 8181 &
 //	graphstore --port 9999 &
-//	analysis_driver --analyzer localhost:8181 /tmp/compilation.kindex | \
+//	analysis_driver --analyzer localhost:8181 /tmp/compilation.kzip | \
 //	  write_entries --workers 10 --graphstore localhost:9999
 //
 // Example:


Test patch:
diff --git a/kythe/go/extractors/bazel/extractor_test.go b/kythe/go/extractors/bazel/extractor_test.go
index eaccec1c6..b0c1ff41e 100644
--- a/kythe/go/extractors/bazel/extractor_test.go
+++ b/kythe/go/extractors/bazel/extractor_test.go
@@ -30,7 +30,6 @@ import (
 	"strings"
 	"testing"
 
-	"kythe.io/kythe/go/platform/kindex"
 	"kythe.io/kythe/go/platform/kzip"
 	"kythe.io/kythe/go/util/ptypes"
 
@@ -284,7 +283,7 @@ func TestFetchInputs(t *testing.T) {
 		filepath.Join(tmp, "bad.h"), // does not exist
 	}
 	err = cfg.fetchInputs(context.Background(), paths, func(i int, r io.Reader) error {
-		fd, err := kindex.FileData(paths[i], r)
+		fd, err := kzip.FileData(paths[i], r)
 		if err == nil {
 			fds = append(fds, fd)
 		}
diff --git a/kythe/go/platform/kindex/kindex_test.go b/kythe/go/platform/kindex/kindex_test.go
deleted file mode 100644
index f71c9c6eb..000000000
--- a/kythe/go/platform/kindex/kindex_test.go
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright 2015 The Kythe 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 kindex
-
-import (
-	"bytes"
-	"log"
-	"os"
-	"strings"
-	"testing"
-
-	"github.com/golang/protobuf/proto"
-
-	anypb "github.com/golang/protobuf/ptypes/any"
-	apb "kythe.io/kythe/proto/analysis_go_proto"
-	gopb "kythe.io/kythe/proto/go_go_proto"
-	spb "kythe.io/kythe/proto/storage_go_proto"
-)
-
-// A fakeFetcher maps file "paths" to their contents.
-// The digest is ignored.
-type fakeFetcher map[string]string
-
-func (f fakeFetcher) Fetch(path, digest string) ([]byte, error) {
-	data, ok := f[path]
-	if !ok {
-		return nil, os.ErrNotExist
-	}
-	return []byte(data), nil
-}
-
-func TestRoundTrip(t *testing.T) {
-	data := fakeFetcher{
-		"input 1": "Yesterday, upon the stair",
-		"input 2": "I saw a man who wasn't there",
-		"input 3": "He wasn't there again today",
-		"input 4": "Oh, how I wish he'd go away",
-	}
-	unit := &apb.CompilationUnit{
-		VName: &spb.VName{
-			Corpus:    "test",
-			Path:      "magic/test/unit",
-			Signature: "成功",
-		},
-		WorkingDirectory: "/usr/local/src",
-		RequiredInput: []*apb.CompilationUnit_FileInput{
-			{Info: &apb.FileInfo{
-				Path: "input 1",
-			}},
-			{Info: &apb.FileInfo{
-				Path: "input 2",
-			}},
-			{Info: &apb.FileInfo{
-				Path: "input 3",
-			}},
-		},
-		Argument:   []string{"go", "ask", "your", "mother"},
-		SourceFile: []string{"input 2"},
-	}
-
-	// Pack a unit and its data into a Compilation record.
-	before, err := FromUnit(unit, data)
-	if err != nil {
-		t.Fatalf("FromUnit failed: %v\ninput: %+v", err, unit)
-	}
-
-	// Write the record out in wire format.
-	var buf bytes.Buffer
-	if _, err := before.WriteTo(&buf); err != nil {
-		t.Fatalf("before.WriteTo failed: %v\ninput: %+v", err, before)
-	}
-
-	// Read the wire format back in.
-	after, err := New(&buf)
-	if err != nil {
-		t.Fatalf("Read(buf) failed: %v\ninput: %q", err, buf.String())
-	}
-
-	// Verify that we got an equivalent proto message.
-	if !proto.Equal(before.Proto, after.Proto) {
-		t.Errorf("Unit protos do not match\nbefore: %+v\nafter:  %+v", before.Proto, after.Proto)
-	}
-
-	// Verify that we got the expected file contents.
-	for _, ri := range after.Files {
-		path := ri.GetInfo().Path
-		got := string(ri.Content)
-		want, ok := data[path]
-		if !ok {
-			t.Errorf("Unexpected input for path %q: %q", path, got)
-		} else if got != want {
-			t.Errorf("Wrong data for path %q: got %q, want %q", path, got, want)
-		}
-	}
-
-	// Verify that we got everything we put in.
-	if got, want := len(after.Files), len(before.Files); got != want {
-		t.Errorf("Wrong number of files: got %d, want %d", got, want)
-	}
-}
-
-func mustFD(path, data string) *apb.FileData {
-	fd, err := FileData(path, strings.NewReader(data))
-	if err != nil {
-		log.Panicf("Unable to construct FileData for %q: %v", path, err)
-	}
-	return fd
-}
-
-func TestFetch(t *testing.T) {
-	const magic = "xyzzy"
-	const magicDigest = "184858a00fd7971f810848266ebcecee5e8b69972c5ffaed622f5ee078671aed"
-	idx := &Compilation{
-		Files: []*apb.FileData{
-			mustFD("A", "A is for Amy, who fell down the stairs"),
-			mustFD("B", "B is for Basil, assaulted by bears"),
-			mustFD("C", "C is for Clara, who wasted away"),
-			mustFD("D", "D is for Desmond, thrown out of a sleigh"),
-			mustFD("E", "E is for Ernest, who choked on a peach"),
-			mustFD("X", magic),
-		},
-	}
-	numGood := len(idx.Files)
-
-	// Basic path resolution should work, ignoring the digest.
-	for i, path := range []string{"A", "B", "C", "D", "E", "X", "F", "G"} {
-		got, err := idx.Fetch(path, "")
-		if err != nil && i < numGood {
-			t.Errorf("Fetch %q: unexpected error: %v", path, err)
-		} else if err == nil && i >= numGood {
-			t.Errorf("Fetch %q: unexpectedly succeeded with %q", path, got)
-		}
-	}
-
-	// A path lookup with an incorrect digest should fail.
-	if got, err := idx.Fetch("A", "bogusdigestvalue"); err == nil {
-		t.Errorf("Fetch A with bogus digest: got %q, wanted error", got)
-	}
-
-	// A digest lookup on its own should work.
-	if raw, err := idx.Fetch("", magicDigest); err != nil {
-		t.Errorf("Fetch %q: unexpected error: %v", magicDigest, err)
-	} else if got := string(raw); got != magic {
-		t.Errorf("Fetch %q: got %q, want %q", magicDigest, got, magic)
-	}
-}
-
-func TestAdders(t *testing.T) {
-	var cu Compilation
-
-	if err := cu.AddFile("foo", strings.NewReader(""), nil, &gopb.GoPackageInfo{
-		ImportPath: "vanity.io/foo",
-	}); err != nil {
-		t.Errorf("AddFile failed: %v", err)
-	}
-	if err := cu.AddDetails(&gopb.GoDetails{
-		Goroot: "plover",
-	}); err != nil {
-		t.Errorf("AddDetails failed: %v", err)
-	}
-	unit := cu.Unit()
-	unit.VName = &spb.VName{Language: "go", Corpus: "kythe"}
-	unit.Argument = []string{"this", "isn't", "an", "argument"}
-	unit.OutputKey = "blathe.a"
-	unit.SourceFile = []string{"foo"}
-
-	want := &apb.CompilationUnit{
-		VName: &spb.VName{
-			Language: "go",
-			Corpus:   "kythe",
-		},
-		RequiredInput: []*apb.CompilationUnit_FileInput{{
-			Info: &apb.FileInfo{
-				Path:   "foo",
-				Digest: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
-			},
-			Details: []*anypb.Any{{
-				TypeUrl: "kythe.io/proto/kythe.proto.GoPackageInfo",
-				Value:   []byte("\n\rvanity.io/foo"),
-			}},
-		}},
-		SourceFile: []string{"foo"},
-		OutputKey:  "blathe.a",
-		Argument:   []string{"this", "isn't", "an", "argument"},
-		Details: []*anypb.Any{{
-			TypeUrl: "kythe.io/proto/kythe.proto.GoDetails",
-			Value:   []byte("\x1a\x06plover"),
-		}},
-	}
-	if got := cu.Unit(); !proto.Equal(got, want) {
-		t.Errorf("Incorrect proto constructed:\n got: %+v\nwant: %+v", got, want)
-	}
-	wantFile := &apb.FileData{
-		Content: []byte(""),
-		Info: &apb.FileInfo{
-			Path:   "foo",
-			Digest: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
-		},
-	}
-	if n := len(cu.Files); n != 1 {
-		t.Errorf("Wrong number of files: got %d, wanted 1", n)
-	} else if got := cu.Files[0]; !proto.Equal(got, wantFile) {
-		t.Errorf("Wrong file data:\n got: %+v\nwant: %+v", got, want)
-	}
-}