func TestRWVFS(t *testing.T) { tmpdir, err := ioutil.TempDir("", "rwvfs-test-") if err != nil { t.Fatal("TempDir", err) } defer os.RemoveAll(tmpdir) h := http.Handler(rwvfs.HTTPHandler(rwvfs.Map(map[string]string{}), nil)) httpServer := httptest.NewServer(h) defer httpServer.Close() httpURL, err := url.Parse(httpServer.URL) if err != nil { t.Fatal(err) } tests := []struct { fs rwvfs.FileSystem path string }{ {rwvfs.OS(tmpdir), "/foo"}, {rwvfs.Map(map[string]string{}), "/foo"}, {rwvfs.Sub(rwvfs.Map(map[string]string{}), "/x"), "/foo"}, {rwvfs.HTTP(httpURL, nil), "/foo"}, } for _, test := range tests { testWrite(t, test.fs, test.path) testMkdir(t, test.fs) testMkdirAll(t, test.fs) testGlob(t, test.fs) } }
func TestOS_ReadLink_ErrOutsideRoot(t *testing.T) { tmpdir1, err := ioutil.TempDir("", "rwvfs-test-") if err != nil { t.Fatal("TempDir", err) } defer os.RemoveAll(tmpdir1) tmpdir2, err := ioutil.TempDir("", "rwvfs-test-") if err != nil { t.Fatal("TempDir", err) } defer os.RemoveAll(tmpdir2) if err := ioutil.WriteFile(filepath.Join(tmpdir1, "myfile"), []byte("hello"), 0600); err != nil { t.Fatal(err) } if err := os.Symlink(filepath.Join(tmpdir1, "myfile"), filepath.Join(tmpdir2, "mylink")); err != nil { t.Fatal(err) } osfs := rwvfs.OS(tmpdir2) dst, err := osfs.(rwvfs.LinkFS).ReadLink("mylink") if want := rwvfs.ErrOutsideRoot; err != want { t.Fatalf("%s: ReadLink: got err %v, want %v", osfs, err, want) } if want := filepath.Join(tmpdir1, "myfile"); dst != want { t.Errorf("%s: ReadLink: got %q, want %q", osfs, dst, want) } }
func TestSub_ReadLink(t *testing.T) { tmpdir, err := ioutil.TempDir("", "rwvfs-test-") if err != nil { t.Fatal("TempDir", err) } defer os.RemoveAll(tmpdir) if err := os.Mkdir(filepath.Join(tmpdir, "mydir"), 0700); err != nil { t.Fatal(err) } if err := ioutil.WriteFile(filepath.Join(tmpdir, "mydir", "myfile"), []byte("hello"), 0600); err != nil { t.Fatal(err) } if err := os.Symlink(filepath.Join(tmpdir, "mydir", "myfile"), filepath.Join(tmpdir, "mydir", "mylink")); err != nil { t.Fatal(err) } osfs := rwvfs.OS(tmpdir) sub := rwvfs.Sub(osfs, "mydir") dst, err := sub.(rwvfs.LinkFS).ReadLink("mylink") if err != nil { t.Fatal(err) } if want := "myfile"; dst != want { t.Errorf("%s: ReadLink: got %q, want %q", osfs, dst, want) } }
func TestSub_Symlink(t *testing.T) { tmpdir, err := ioutil.TempDir("", "rwvfs-test-") if err != nil { t.Fatal("TempDir", err) } //defer os.RemoveAll(tmpdir) want := "hello" if err := os.Mkdir(filepath.Join(tmpdir, "mydir"), 0700); err != nil { t.Fatal(err) } if err := ioutil.WriteFile(filepath.Join(tmpdir, "mydir", "myfile"), []byte(want), 0600); err != nil { t.Fatal(err) } osfs := rwvfs.OS(tmpdir) sub := rwvfs.Sub(osfs, "mydir") if err := sub.(rwvfs.LinkFS).Symlink("myfile", "mylink"); err != nil { t.Fatal(err, osfs) } got, err := ioutil.ReadFile(filepath.Join(tmpdir, "mydir", "mylink")) if err != nil { t.Fatal(err, osfs, sub) } if string(got) != want { t.Errorf("%s: ReadLink: got %q, want %q", osfs, string(got), want) } }
// LocalRepo creates a new single-repository build store for the VCS // repository whose top-level directory is repoDir. // // The store is laid out as follows: // // . the root dir of repoStoreFS // <COMMITID>/**/* build data for a specific commit func LocalRepo(repoDir string) (RepoBuildStore, error) { storeDir := filepath.Join(repoDir, BuildDataDirName) if err := os.Mkdir(storeDir, 0700); err != nil && !os.IsExist(err) { return nil, err } fs := rwvfs.OS(storeDir) setCreateParentDirs(fs) return Repo(rwvfs.Walkable(fs)), nil }
// store returns the store specified by StoreCmd's Type and Root // options. func (c *StoreCmd) store() (interface{}, error) { fs := rwvfs.OS(c.Root) type createParents interface { CreateParentDirs(bool) } if fs, ok := fs.(createParents); ok { fs.CreateParentDirs(true) } switch c.Type { case "RepoStore": return store.NewFSRepoStore(fs), nil case "MultiRepoStore": return store.NewFSMultiRepoStore(rwvfs.Walkable(fs), nil), nil default: return nil, fmt.Errorf("unrecognized store --type value: %q (valid values are RepoStore, MultiRepoStore)", c.Type) } }
func (s *repoBuildStore) Commit(commitID string) rwvfs.WalkableFileSystem { path := s.commitPath(commitID) // Dereference path if path refers to a symlink, so that we can // walk the tree. e, _ := s.fs.Lstat(path) if e != nil && e.Mode()&os.ModeSymlink != 0 { if fs, ok := s.fs.(rwvfs.LinkFS); ok { var err error dst, err := fs.ReadLink(path) if err == nil { path = dst } else if err == rwvfs.ErrOutsideRoot && FollowCrossFSSymlinks { return rwvfs.Walkable(rwvfs.OS(dst)) } else { log.Printf("Failed to read symlink %s: %s. Using non-dereferenced path.", path, err) } } else { log.Printf("Repository build store path for commit %s is a symlink, but the current VFS %s doesn't support dereferencing symlinks.", commitID, s.fs) } } return rwvfs.Walkable(rwvfs.Sub(s.fs, path)) }