Create symlinks for Copyfile and Linkfile entries. Change-Id: Idc45362eb75842bafe1b8292cb6ec2ff34e4f854
diff --git a/populate/e2e_test.go b/populate/e2e_test.go index 9f141cf..6cd51d2 100644 --- a/populate/e2e_test.go +++ b/populate/e2e_test.go
@@ -134,6 +134,56 @@ return &fix, nil } +func TestCopyEntries(t *testing.T) { + fixture, err := newFixture() + if err != nil { + t.Fatal(err) + } + defer fixture.Cleanup() + + // We avoid talking to gitiles by inserting entries into the + // cache manually. + if err := fixture.cache.Tree.Add(gitID(ids[0]), &gitiles.Tree{ + ID: ids[0], + Entries: []gitiles.TreeEntry{ + { + Mode: 0100644, + Name: "a", + Type: "blob", + ID: ids[1], + Size: newInt(42), + }, + }, + }); err != nil { + t.Fatal(err) + } + + if err := fixture.addWorkspace("m", &manifest.Manifest{ + Project: []manifest.Project{{ + Name: "platform/project", + Path: "p", + Revision: ids[0], + Copyfile: []manifest.Copyfile{ + {Src: "a", Dest: "bla"}, + }, + }}}); err != nil { + t.Fatalf("addWorkspace: %v", err) + } + + ws := filepath.Join(fixture.dir, "ws") + roRoot := filepath.Join(fixture.dir, "mnt", "m") + if _, _, err := Checkout(roRoot, ws); err != nil { + t.Fatalf("Checkout: %v", err) + } + + if dest, err := os.Readlink(filepath.Join(ws, "bla")); err != nil { + t.Fatal(err) + } else if want := filepath.Join(roRoot, "bla"); dest != want { + t.Fatalf("Readlink(ws/sub): got %q, want %q", dest, want) + } + +} + func TestFUSESymlink(t *testing.T) { fixture, err := newFixture() if err != nil {
diff --git a/populate/populate.go b/populate/populate.go index 37cd82c..1654efd 100644 --- a/populate/populate.go +++ b/populate/populate.go
@@ -109,6 +109,13 @@ } } } + + for _, c := range ro.copied { + if err := os.Symlink(filepath.Join(roRoot, c), filepath.Join(rwRoot, c)); err != nil && !os.IsExist(err) { + return err + } + } + return nil }
diff --git a/populate/populate_test.go b/populate/populate_test.go index 141d458..bc4f0d4 100644 --- a/populate/populate_test.go +++ b/populate/populate_test.go
@@ -145,9 +145,10 @@ children: map[string]*repoTree{ "build": buildT, }, - entries: map[string]*fileInfo{ - "Makefile": &fileInfo{}, - "Android.bp": &fileInfo{}, + entries: map[string]*fileInfo{}, + copied: []string{ + "Android.bp", + "Makefile", }, }
diff --git a/populate/repotree.go b/populate/repotree.go index 283350e..94f068c 100644 --- a/populate/repotree.go +++ b/populate/repotree.go
@@ -22,6 +22,7 @@ "log" "os" "path/filepath" + "sort" "strings" git "github.com/libgit2/git2go" @@ -35,9 +36,6 @@ type fileInfo struct { // the SHA1 of the file. This can be nil if getting it was too expensive. sha1 *git.Oid - - // We can't do chtimes on symlinks. - isLink bool } // repoTree is a nested set of Git repositories. @@ -47,6 +45,9 @@ // files in this repository. entries map[string]*fileInfo + + // paths that are instantiated with Copyfile or Linkfile. + copied []string } // findParentRepo recursively finds the deepest child that is a prefix @@ -102,12 +103,13 @@ for _, p := range mf.Project { for _, c := range p.Copyfile { - root.entries[c.Dest] = &fileInfo{} + root.copied = append(root.copied, c.Dest) } for _, c := range p.Linkfile { - root.entries[c.Dest] = &fileInfo{} + root.copied = append(root.copied, c.Dest) } } + sort.Strings(root.copied) return root, nil } @@ -132,10 +134,6 @@ } t.entries[e.Name] = fi - - if e.Target != nil { - fi.isLink = true - } } return nil