diff --git a/hypha.go b/hypha.go index acfa736..b1437b6 100644 --- a/hypha.go +++ b/hypha.go @@ -284,44 +284,43 @@ func setHeaderLinks() { } } -// Index finds all hypha files in the full `path` and saves them to HyphaStorage. This function is recursive. -func Index(path string) { - nodes, err := ioutil.ReadDir(path) - if err != nil { - log.Fatal(err) - } - - for _, node := range nodes { - // If this hypha looks like it can be a hypha path, go deeper. Do not touch the .git and static folders for they have an admnistrative importance! - if node.IsDir() && isCanonicalName(node.Name()) && node.Name() != ".git" && node.Name() != "static" { - Index(filepath.Join(path, node.Name())) - continue - } - - var ( - hyphaPartPath = filepath.Join(path, node.Name()) - hyphaName, isText, skip = mimetype.DataFromFilename(hyphaPartPath) - hyphaData *HyphaData - ) - if !skip { - // Reuse the entry for existing hyphae, create a new one for those that do not exist yet. - if hd, ok := HyphaStorage[hyphaName]; ok { - hyphaData = hd - } else { - hyphaData = &HyphaData{} - HyphaStorage[hyphaName] = hyphaData - hyphae.IncrementCount() - } - if isText { - hyphaData.TextPath = hyphaPartPath - } else { - // Notify the user about binary part collisions. It's a design decision to just use any of them, it's the user's fault that they have screwed up the folder structure, but the engine should at least let them know, right? - if hyphaData.BinaryPath != "" { - log.Println("There is a file collision for binary part of a hypha:", hyphaData.BinaryPath, "and", hyphaPartPath, "-- going on with the latter") - } - hyphaData.BinaryPath = hyphaPartPath - } - } - +func HyphaToTemporaryWorkaround(h *hyphae.Hypha) *HyphaData { + return &HyphaData{ + Name: h.Name, + TextPath: h.TextPath, + BinaryPath: h.BinaryPath, } } + +// MergeIn merges in content file paths from a different hypha object. Prints warnings sometimes. +func (h *HyphaData) MergeIn(oh *hyphae.Hypha) { + if h.TextPath == "" && oh.TextPath != "" { + h.TextPath = oh.TextPath + } + if oh.BinaryPath != "" { + if h.BinaryPath != "" { + log.Println("There is a file collision for binary part of a hypha:", h.BinaryPath, "and", oh.BinaryPath, "-- going on with the latter") + } + h.BinaryPath = oh.BinaryPath + } +} + +// Index finds all hypha files in the full `path` and saves them to HyphaStorage. This function is recursive. +func Index(path string) { + ch := make(chan *hyphae.Hypha, 5) + + go func() { + hyphae.Index(path, 0, ch) + close(ch) + }() + + for h := range ch { + if oldHypha, ok := HyphaStorage[h.Name]; ok { + oldHypha.MergeIn(h) + } else { + HyphaStorage[h.Name] = HyphaToTemporaryWorkaround(h) + hyphae.IncrementCount() + } + } + +} diff --git a/hyphae/files.go b/hyphae/files.go new file mode 100644 index 0000000..4c97a78 --- /dev/null +++ b/hyphae/files.go @@ -0,0 +1,44 @@ +package hyphae + +import ( + "io/ioutil" + "log" + "path/filepath" + + "github.com/bouncepaw/mycorrhiza/mimetype" + "github.com/bouncepaw/mycorrhiza/util" +) + +// Index finds all hypha files in the full `path` and sends them to the channel. Handling of duplicate entries and attachment and counting them is up to the caller. +func Index(path string, nestLevel uint, ch chan *Hypha) { + nodes, err := ioutil.ReadDir(path) + if err != nil { + log.Fatal(err) + } + + for _, node := range nodes { + // If this hypha looks like it can be a hypha path, go deeper. Do not touch the .git and static folders for they have an admnistrative importance! + if node.IsDir() && + util.IsCanonicalName(node.Name()) && + node.Name() != ".git" && + !(nestLevel == 0 && node.Name() == "static") { + Index(filepath.Join(path, node.Name()), nestLevel+1, ch) + continue + } + + var ( + hyphaPartPath = filepath.Join(path, node.Name()) + hyphaName, isText, skip = mimetype.DataFromFilename(hyphaPartPath) + hypha = &Hypha{Name: hyphaName} + ) + if !skip { + if isText { + hypha.TextPath = hyphaPartPath + } else { + hypha.BinaryPath = hyphaPartPath + } + ch <- hypha + } + + } +}