// Copyright 2021 Fahmi Akbar Wildana <~drsensor/public-inbox@lists.sr.ht> // SPDX-License-Identifier: FSFAP package utils import ( "path/filepath" "sort" "strings" ) // BUG: probably 🤔 (plus it's not optimized) // BUG: updir `..` not handled properly // TODO: handle absoulute path // TODO: document this algorithm step-by-step-explain-output as Stack Overflow question func NearestWorkDirs(paths []string) []string { if !sort.StringsAreSorted(paths) { sort.Strings(paths) } var workdir []string keys := map[string]bool{} reset := func() { paths = workdir workdir = []string{} keys = map[string]bool{} } depths := map[string]int{} // depth of path for _, entry := range paths { if filepath.Ext(entry) != "" { entry = filepath.Dir(entry) } if _, isDuplicate := keys[entry]; !isDuplicate { keys[entry] = true workdir = append(workdir, entry) if spath := SlicePath(entry); spath[0] == ".." { k := Count(spath, "..") depths[filepath.Join(spath[:k]...)] = len(spath[k:]) } else { depths[spath[0]] = len(spath) } } } reset() counts := map[string]int{} // count spath[0] for _, entry := range paths { spath := SlicePath(entry) if depths[spath[0]] == 1 && len(spath) > 1 { entry = filepath.Dir(entry) } if _, isDuplicate := keys[entry]; !isDuplicate { keys[entry] = true workdir = append(workdir, entry) if spath := SlicePath(entry); spath[0] != ".." { counts[spath[0]]++ } } } reset() for _, entry := range paths { // dedupe based on spath[0] if spath := SlicePath(entry); counts[spath[0]] > 1 && len(spath) > 1 { entry = filepath.Join(spath[:len(spath)-depths[spath[0]]+1]...) } if _, isDuplicate := keys[entry]; !isDuplicate { keys[entry] = true workdir = append(workdir, entry) } } return workdir } func SlicePath(pathfile string) []string { return strings.Split(filepath.ToSlash(pathfile), "/") }