// Test gets results of the earlier Next() call, & returns if we should continue! func (obj *PkgResAutoEdges) Test(input []bool) bool { if !obj.testIsNext { log.Fatal("Expecting a call to Next()") } // ack the svcUID's... if x := obj.svcUIDs; len(x) > 0 { if y := len(x); y != len(input) { log.Fatalf("Expecting %d value(s)!", y) } obj.svcUIDs = []ResUID{} // empty obj.testIsNext = false return true } count := len(obj.fileList) if count != len(input) { log.Fatalf("Expecting %d value(s)!", count) } obj.testIsNext = false // set after all the errors paths are past // while i do believe this algorithm generates the *correct* result, i // don't know if it does so in the optimal way. improvements welcome! // the basic logic is: // 0) Next() returns whatever is in fileList // 1) Test() computes the dirname of each file, and removes duplicates // and dirname's that have been in the path of an ack from input results // 2) It then simplifies the list by removing the common path prefixes // 3) Lastly, the remaining set of files (dirs) is used as new fileList // 4) We then iterate in (0) until the fileList is empty! var dirs = make([]string, count) done := []string{} for i := 0; i < count; i++ { dir := util.Dirname(obj.fileList[i]) // dirname of /foo/ should be / dirs[i] = dir if input[i] { done = append(done, dir) } } nodupes := util.StrRemoveDuplicatesInList(dirs) // remove duplicates nodones := util.StrFilterElementsInList(done, nodupes) // filter out done noempty := util.StrFilterElementsInList([]string{""}, nodones) // remove the "" from / obj.fileList = util.RemoveCommonFilePrefixes(noempty) // magic if len(obj.fileList) == 0 { // nothing more, don't continue return false } return true // continue, there are more files! }
// NewRemotes builds a Remotes struct. func NewRemotes(clientURLs, remoteURLs []string, noop bool, remotes []string, fileWatch chan string, cConns uint16, interactive bool, sshPrivIdRsa string, caching bool, depth uint16, prefix string, converger cv.Converger, convergerCb func(func(map[string]bool) error) (func(), error), flags Flags) *Remotes { return &Remotes{ clientURLs: clientURLs, remoteURLs: remoteURLs, noop: noop, remotes: util.StrRemoveDuplicatesInList(remotes), fileWatch: fileWatch, cConns: cConns, interactive: interactive, sshPrivIdRsa: sshPrivIdRsa, caching: caching, depth: depth, prefix: prefix, converger: converger, convergerCb: convergerCb, sshmap: make(map[string]*SSH), exitChan: make(chan struct{}), semaphore: NewSemaphore(int(cConns)), hostnames: make([]string, len(remotes)), cuids: make(map[string]cv.ConvergerUID), flags: flags, } }