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 }{ {rwvfs.OS(tmpdir)}, {rwvfs.Map(map[string]string{})}, {rwvfs.Sub(rwvfs.Map(map[string]string{}), "/x")}, {rwvfs.HTTP(httpURL, nil)}, {rwvfs.Union(rwvfs.Map(map[string]string{}), rwvfs.Map(map[string]string{}))}, } for _, test := range tests { testutil.Write(t, test.fs) testutil.Mkdir(t, test.fs) testutil.MkdirAll(t, test.fs) testutil.Glob(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 }
func (c *Config) fs() FileSystem { if c.FS != nil { return c.FS } dir, err := os.Getwd() if err != nil { dir = "." } return NewFileSystem(rwvfs.OS(dir)) }
func newTestFS() rwvfs.WalkableFileSystem { switch *fsType { case "map": fs := rwvfs.Map(map[string]string{}) return rwvfs.Walkable(rwvfs.Sub(fs, "/testdata")) case "os": tmpDir, err := ioutil.TempDir("", "srclib-test") if err != nil { log.Fatal(err) } fs := rwvfs.OS(tmpDir) setCreateParentDirs(fs) return rwvfs.Walkable(fs) default: log.Fatalf("unrecognized -test.fs option: %q", *fsType) panic("unreachable") } }
// 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 main() { log.SetFlags(0) flag.Parse() dir, err := filepath.Abs(*storageDir) if err != nil { log.Fatal(err) } log.Printf("Serving %s on %s", dir, *httpAddr) var logTo io.Writer if *verbose { logTo = os.Stderr } else { logTo = ioutil.Discard } http.Handle("/", rwvfs.HTTPHandlerWithDelay(rwvfs.OS(dir), logTo, time.Duration(*delay)*time.Millisecond)) log.Fatal(http.ListenAndServe(*httpAddr, nil)) }
func TestMaker_Run(t *testing.T) { tmpDir, err := ioutil.TempDir("", "makex") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) conf := &Config{ ParallelJobs: 1, FS: NewFileSystem(rwvfs.OS(tmpDir)), } target := "x" mf := &Makefile{ Rules: []Rule{ &BasicRule{ TargetFile: target, RecipeCmds: []string{"touch " + filepath.ToSlash(filepath.Join(tmpDir, target))}, }, }, } if isFile(conf.FS, target) { t.Fatalf("target %s exists before running Makefile; want it to not exist yet", target) } mk := conf.NewMaker(mf, target) err = mk.Run() if err != nil { t.Fatalf("Run failed: %s", err) } if !isFile(conf.FS, target) { t.Fatalf("target %s does not exist after running Makefile; want it to exist", target) } }
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)) }