func DoTestNodeRelPath(t *testing.T, repo fs.NodeRepo) { tg := treegen.New() treeSpec := tg.D("foo", tg.F("bar", tg.B(42, 65537))) path := treegen.TestTree(t, treeSpec) defer os.RemoveAll(path) dir, errors := fs.IndexDir(path, repo) assert.Equalf(t, 0, len(errors), "%v", errors) assert.Equal(t, "", fs.RelPath(dir)) assert.Equal(t, "foo", fs.RelPath(dir.SubDirs()[0])) assert.Equal(t, filepath.Join("foo", "bar"), fs.RelPath(dir.SubDirs()[0].Files()[0])) assert.Equal(t, filepath.Join("foo", "bar"), fs.RelPath(dir.SubDirs()[0].Files()[0])) }
func main() { store, err := clnt.Connect("127.0.0.1:5640") if err != nil { die("Failed to connect", err) } err = store.Refresh() if err != nil { die("Failed to refresh", err) } fs.Walk(store.Root(), func(node fs.Node) bool { switch node.(type) { case *fs.Dir: fmt.Printf("d\t%s\t%s\n", node.Strong(), fs.RelPath(node.(fs.FsNode))) return true case *fs.File: fmt.Printf("f\t%s\t%s\n", node.Strong(), fs.RelPath(node.(fs.FsNode))) } return false }) }
func (plan *PatchPlan) SetMode(errors chan<- os.Error) { fs.Walk(plan.srcStore.Repo().Root(), func(srcNode fs.Node) bool { var err os.Error srcFsNode, is := srcNode.(fs.FsNode) if !is { return false } srcPath := fs.RelPath(srcFsNode) if absPath := plan.dstStore.Resolve(srcPath); absPath != "" { err = os.Chmod(absPath, srcFsNode.Mode()) } else { err = os.NewError(fmt.Sprintf("Expected %s not found in destination", srcPath)) } if err != nil && errors != nil { errors <- err } _, is = srcNode.(fs.Dir) return is }) }
func NewPatchPlan(srcStore fs.BlockStore, dstStore fs.LocalStore) *PatchPlan { plan := &PatchPlan{srcStore: srcStore, dstStore: dstStore} plan.dstFileUnmatch = make(map[string]fs.File) fs.Walk(dstStore.Repo().Root(), func(dstNode fs.Node) bool { dstFile, isDstFile := dstNode.(fs.File) if isDstFile { plan.dstFileUnmatch[fs.RelPath(dstFile)] = dstFile } return !isDstFile }) relocRefs := make(map[string]int) // Find all the FsNode matches fs.Walk(srcStore.Repo().Root(), func(srcNode fs.Node) bool { // Ignore non-FsNodes srcFsNode, isSrcFsNode := srcNode.(fs.FsNode) if !isSrcFsNode { return false } // log.Printf("In src: %s", fs.RelPath(srcFsNode)) srcFile, isSrcFile := srcNode.(fs.File) srcPath := fs.RelPath(srcFsNode) // Remove this srcPath from dst unmatched, if it was present plan.dstFileUnmatch[srcPath] = nil, false var srcStrong string if isSrcFile { srcStrong = srcFile.Info().Strong } else if srcDir, isSrcDir := srcNode.(fs.Dir); isSrcDir { srcStrong = srcDir.Info().Strong } var dstNode fs.FsNode var hasDstNode bool dstNode, hasDstNode = dstStore.Repo().File(srcStrong) if !hasDstNode { dstNode, hasDstNode = dstStore.Repo().Dir(srcStrong) } isDstFile := false if hasDstNode { _, isDstFile = dstNode.(fs.File) } dstFilePath := dstStore.Resolve(srcPath) dstFileInfo, _ := os.Stat(dstFilePath) // Resolve dst node that matches strong checksum with source if hasDstNode && isSrcFile == isDstFile { dstPath := fs.RelPath(dstNode) relocRefs[dstPath]++ // dstPath will be used in this cmd, inc ref count // log.Printf("srcPath=%s dstPath=%s", srcPath, dstPath) if srcPath != dstPath { // Local dst file needs to be renamed or copied to src path from := &LocalPath{LocalStore: dstStore, RelPath: dstPath} to := &LocalPath{LocalStore: dstStore, RelPath: srcPath} plan.Cmds = append(plan.Cmds, &Transfer{From: from, To: to, relocRefs: relocRefs}) } else { // Same path, keep it where it is plan.Cmds = append(plan.Cmds, &Keep{ Path: &LocalPath{LocalStore: dstStore, RelPath: srcPath}}) } // If its a file, figure out what to do with it } else if isSrcFile { switch { // Destination is not a file, so get rid of whatever is there first case dstFileInfo != nil && !dstFileInfo.IsRegular(): plan.Cmds = append(plan.Cmds, &Conflict{ Path: &LocalPath{LocalStore: dstStore, RelPath: srcPath}, FileInfo: dstFileInfo}) fallthrough // Destination file does not exist, so full source copy needed case dstFileInfo == nil: plan.Cmds = append(plan.Cmds, &SrcFileDownload{ SrcFile: srcFile, Path: &LocalPath{LocalStore: dstStore, RelPath: srcPath}}) break // Destination file exists, add block-level commands default: plan.appendFilePlan(srcFile, srcPath) break } // If its a directory, check for conflicting files of same name } else { if dstFileInfo != nil && !dstFileInfo.IsDirectory() { plan.Cmds = append(plan.Cmds, &Conflict{ Path: &LocalPath{LocalStore: dstStore, RelPath: dstFilePath}, FileInfo: dstFileInfo}) } } return !isSrcFile }) return plan }