func compareDirectories(request *subproto.UpdateRequest, state *state, subDirectory, requiredDirectory *filesystem.Directory, parentName string, filter *filter.Filter) { requiredPathName := path.Join(parentName, requiredDirectory.Name) // First look for entries that should be deleted. makeSubDirectory := false if subDirectory == nil { makeSubDirectory = true } else { subPathName := path.Join(parentName, subDirectory.Name) for name, subEntry := range subDirectory.EntriesByName { pathname := path.Join(subPathName, entryName(subEntry)) if filter.Match(pathname) { continue } if _, ok := requiredDirectory.EntriesByName[name]; !ok { request.PathsToDelete = append(request.PathsToDelete, pathname) fmt.Printf("Delete: %s\n", pathname) // HACK } } if !filesystem.CompareDirectoriesMetadata(subDirectory, requiredDirectory, os.Stdout) { fmt.Printf("Different directory: %s...\n", requiredPathName) // HACK makeSubDirectory = true // TODO(rgooch): Update metadata. } } if makeSubDirectory { var newdir subproto.Directory newdir.Name = requiredPathName newdir.Mode = requiredDirectory.Mode newdir.Uid = requiredDirectory.Uid newdir.Gid = requiredDirectory.Gid request.DirectoriesToMake = append(request.DirectoriesToMake, newdir) } for name, requiredEntry := range requiredDirectory.EntriesByName { pathname := path.Join(requiredPathName, entryName(requiredEntry)) if filter.Match(pathname) { continue } if subDirectory == nil { compareEntries(request, state, nil, requiredEntry, requiredPathName, filter) } else { if subEntry, ok := subDirectory.EntriesByName[name]; ok { compareEntries(request, state, subEntry, requiredEntry, requiredPathName, filter) } else { compareEntries(request, state, nil, requiredEntry, requiredPathName, filter) } } } }
func compareDirectories(request *subproto.UpdateRequest, state *state, subDirectory, requiredDirectory *filesystem.DirectoryInode, myPathName string, filter *filter.Filter) { // First look for entries that should be deleted. if subDirectory != nil { for name := range subDirectory.EntriesByName { pathname := path.Join(myPathName, name) if filter.Match(pathname) { continue } if _, ok := requiredDirectory.EntriesByName[name]; !ok { request.PathsToDelete = append(request.PathsToDelete, pathname) } } } for name, requiredEntry := range requiredDirectory.EntriesByName { pathname := path.Join(myPathName, name) if filter.Match(pathname) { continue } var subEntry *filesystem.DirectoryEntry if subDirectory != nil { if se, ok := subDirectory.EntriesByName[name]; ok { subEntry = se } } if subEntry == nil { addEntry(request, state, requiredEntry, pathname) } else { compareEntries(request, state, subEntry, requiredEntry, pathname, filter) } // If a directory: descend (possibly with the directory for the sub). requiredInode := requiredEntry.Inode() if requiredInode, ok := requiredInode.(*filesystem.DirectoryInode); ok { var subInode *filesystem.DirectoryInode if subEntry != nil { if si, ok := subEntry.Inode().(*filesystem.DirectoryInode); ok { subInode = si } } compareDirectories(request, state, subInode, requiredInode, pathname, filter) } } }
// Returns true if there is a failure due to missing computed files. func (sub *Sub) compareDirectories(request *subproto.UpdateRequest, subDirectory, requiredDirectory *filesystem.DirectoryInode, myPathName string, deleteMissingComputedFiles bool, logger *log.Logger) bool { // First look for entries that should be deleted. if sub.filter != nil && subDirectory != nil { for name := range subDirectory.EntriesByName { pathname := path.Join(myPathName, name) if sub.filter.Match(pathname) { continue } if _, ok := requiredDirectory.EntriesByName[name]; !ok { request.PathsToDelete = append(request.PathsToDelete, pathname) } } } for name, requiredEntry := range requiredDirectory.EntriesByName { pathname := path.Join(myPathName, name) if sub.filter != nil && sub.filter.Match(pathname) { continue } var subEntry *filesystem.DirectoryEntry if subDirectory != nil { if se, ok := subDirectory.EntriesByName[name]; ok { subEntry = se } } requiredInode := requiredEntry.Inode() if _, ok := requiredInode.(*filesystem.ComputedRegularInode); ok { // Replace with computed file. inode, ok := sub.ComputedInodes[pathname] if !ok { if deleteMissingComputedFiles { if subEntry != nil { request.PathsToDelete = append(request.PathsToDelete, pathname) } continue } logger.Printf( "compareDirectories(%s): missing computed file: %s\n", sub, pathname) return true } setComputedFileMtime(inode, subEntry) newEntry := new(filesystem.DirectoryEntry) newEntry.Name = name newEntry.InodeNumber = requiredEntry.InodeNumber newEntry.SetInode(inode) requiredEntry = newEntry } if subEntry == nil { sub.addEntry(request, requiredEntry, pathname) } else { sub.compareEntries(request, subEntry, requiredEntry, pathname) } // If a directory: descend (possibly with the directory for the sub). if requiredInode, ok := requiredInode.(*filesystem.DirectoryInode); ok { var subInode *filesystem.DirectoryInode if subEntry != nil { if si, ok := subEntry.Inode().(*filesystem.DirectoryInode); ok { subInode = si } } sub.compareDirectories(request, subInode, requiredInode, pathname, deleteMissingComputedFiles, logger) } } return false }