// useModifiedFiles augments the provided build.Context by the // mapping from file names to alternative contents. func useModifiedFiles(orig *build.Context, modified map[string][]byte) *build.Context { rc := func(data []byte) (io.ReadCloser, error) { return ioutil.NopCloser(bytes.NewBuffer(data)), nil } copy := *orig // make a copy ctxt := © ctxt.OpenFile = func(path string) (io.ReadCloser, error) { // Fast path: names match exactly. if content, ok := modified[path]; ok { return rc(content) } // Slow path: check for same file under a different // alias, perhaps due to a symbolic link. for filename, content := range modified { if sameFile(path, filename) { return rc(content) } } return buildutil.OpenFile(orig, path) } return ctxt }
// readFile is like ioutil.ReadFile, but // it goes through the virtualized build.Context. func readFile(ctxt *build.Context, filename string) ([]byte, error) { rc, err := buildutil.OpenFile(ctxt, filename) if err != nil { return nil, err } defer rc.Close() var buf bytes.Buffer if _, err := io.Copy(&buf, rc); err != nil { return nil, err } return buf.Bytes(), nil }
func TestOverlay(t *testing.T) { ctx := &build.Default ov := map[string][]byte{ "/somewhere/a.go": []byte("file contents"), } names := []string{"/somewhere/a.go", "/somewhere//a.go"} ctx = buildutil.OverlayContext(ctx, ov) for _, name := range names { f, err := buildutil.OpenFile(ctx, name) if err != nil { t.Errorf("unexpected error %v", err) } b, err := ioutil.ReadAll(f) if err != nil { t.Errorf("unexpected error %v", err) } if got, expected := string(b), string(ov["/somewhere/a.go"]); got != expected { t.Errorf("read %q, expected %q", got, expected) } } }