diff --git a/.vscode/settings.json b/.vscode/settings.json index f0483af..f052364 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -83,6 +83,7 @@ "nicksnyder", "nolint", "nolintlint", + "Nuxx", "onsi", "outdir", "Persistable", diff --git a/internal/laboratory/directory-tree-builder.go b/hydra/virtual-tree.go similarity index 65% rename from internal/laboratory/directory-tree-builder.go rename to hydra/virtual-tree.go index 49e453c..b94d266 100644 --- a/internal/laboratory/directory-tree-builder.go +++ b/hydra/virtual-tree.go @@ -1,10 +1,11 @@ -package lab +package hydra import ( "bytes" "encoding/xml" "fmt" "os" + "os/exec" "path/filepath" "strings" "testing/fstest" @@ -14,47 +15,69 @@ import ( "github.com/snivilised/traverse/internal/third/lo" ) -const ( - offset = 2 - tabSize = 2 - doWrite = true -) +// Nuxx is a luna.MemFS factory hardcoded to Musico +func Nuxx(verbose bool, portions ...string) (fS *luna.MemFS) { + fS = luna.NewMemFS() + + musico( + newMemWriteProvider(fS, os.ReadFile, verbose, portions...), + verbose, + ) + + return fS +} -func Musico(verbose bool, portions ...string) (fS *luna.MemFS, root string) { +// CustomTree is a luna.MemFS factory, equivalent to Nuxx that is populated by an +// alternative xml file. index is the full path the xml index file and +// tree is the name of the root element in the file (for Nuxx, this would be +// "MUSICO"). The tree can be filtered by specifying 'portions'. +func CustomTree(index, element string, verbose bool, + portions ...string, +) (fS *luna.MemFS, err error) { fS = luna.NewMemFS() - root = Provision( - NewMemWriteProvider(fS, os.ReadFile, portions...), + err = custom( + index, + element, + newMemWriteProvider(fS, os.ReadFile, verbose, portions...), verbose, - portions..., ) - return fS, root + return fS, err } -func Provision(provider *IOProvider, verbose bool, portions ...string) (root string) { - repo := Repo("") - root = filepath.Join(repo, "test", "data", "MUSICO") - index := Join(repo, "test/data/musico-index.xml") +// index is the full path to the xml index to load, including the xml file name +// tree is the name of the root element of the tree +func custom(index, tree string, provider *IOProvider, verbose bool) error { + if _, err := os.Stat(index); err != nil { + return err + } - if err := ensure(index, provider, verbose); err != nil { + if err := ensure(index, tree, provider, verbose); err != nil { fmt.Printf("provision failed %v\n", err.Error()) - return "" } - if verbose { - fmt.Printf("\n🤖 re-generated tree at '%v' (filters: '%v')\n\n", - root, strings.Join(portions, ", "), - ) - } + return nil +} + +const ( + offset = 2 + tabSize = 2 + doWrite = true +) - return root +func musico(provider *IOProvider, verbose bool) { + repo := Repo("") + index := Combine(repo, "test/data/musico-index.xml") + + if err := ensure(index, "MUSICO", provider, verbose); err != nil { + fmt.Printf("provision failed %v\n", err.Error()) + } } -// ensure -func ensure(index string, provider *IOProvider, verbose bool) error { - builder := directoryTreeBuilder{ - tree: "MUSICO", +func ensure(index, tree string, provider *IOProvider, verbose bool) error { + builder := virtualTree{ + tree: tree, stack: collections.NewStack[string](), index: index, doWrite: doWrite, @@ -74,8 +97,9 @@ func ensure(index string, provider *IOProvider, verbose bool) error { return builder.walk() } -func NewMemWriteProvider(fS *luna.MemFS, +func newMemWriteProvider(fS *luna.MemFS, indexReader readFile, + verbose bool, portions ...string, ) *IOProvider { filter := lo.Ternary(len(portions) > 0, @@ -93,6 +117,12 @@ func NewMemWriteProvider(fS *luna.MemFS, }), ) + if verbose { + fmt.Printf("\n🤖 re-generating tree (filters: '%v')\n\n", + strings.Join(portions, ", "), + ) + } + // PS: to check the existence of a path in an fs in production // code, use fs.Stat(fsys, path) instead of os.Stat/os.Lstat @@ -230,8 +260,8 @@ func (fn matcher) match(portion string) bool { return fn(portion) } -// directoryTreeBuilder -type directoryTreeBuilder struct { +// virtualTree +type virtualTree struct { tree string full string stack *collections.Stack[string] @@ -244,7 +274,7 @@ type directoryTreeBuilder struct { show display } -func (r *directoryTreeBuilder) read() (*Directory, error) { +func (r *virtualTree) read() (*Directory, error) { data, err := r.provider.file.in.read(r.index) if err != nil { @@ -260,16 +290,16 @@ func (r *directoryTreeBuilder) read() (*Directory, error) { return &tree.Root, nil } -func (r *directoryTreeBuilder) pad() string { +func (r *virtualTree) pad() string { return string(bytes.Repeat([]byte{' '}, (r.depth+offset)*tabSize)) } -func (r *directoryTreeBuilder) refill() string { +func (r *virtualTree) refill() string { segments := r.stack.Content() return filepath.Join(segments...) } -func (r *directoryTreeBuilder) inc(name string) { +func (r *virtualTree) inc(name string) { r.stack.Push(name) r.full = r.refill() @@ -277,7 +307,7 @@ func (r *directoryTreeBuilder) inc(name string) { r.padding = r.pad() } -func (r *directoryTreeBuilder) dec() { +func (r *virtualTree) dec() { _, _ = r.stack.Pop() r.full = r.refill() @@ -285,7 +315,7 @@ func (r *directoryTreeBuilder) dec() { r.padding = r.pad() } -func (r *directoryTreeBuilder) walk() error { +func (r *virtualTree) walk() error { top, err := r.read() if err != nil { @@ -297,7 +327,7 @@ func (r *directoryTreeBuilder) walk() error { return r.dir(*top, true) } -func (r *directoryTreeBuilder) dir(dir Directory, isRoot bool) error { //nolint:gocritic // performance is not a concern +func (r *virtualTree) dir(dir Directory, isRoot bool) error { //nolint:gocritic // performance is not a concern if !isRoot { // We dont to add the root because only the descendents of the root // should be added @@ -322,7 +352,7 @@ func (r *directoryTreeBuilder) dir(dir Directory, isRoot bool) error { //nolint: } for _, file := range dir.Files { - full := Join(r.full, file.Name) + full := Combine(r.full, file.Name) if r.doWrite { if err := r.provider.file.out.write( @@ -340,3 +370,26 @@ func (r *directoryTreeBuilder) dir(dir Directory, isRoot bool) error { //nolint: return nil } + +// remember to remove Join and Repo from lab + +// Combine creates a path from the parent combined with the relative path. The relative +// path is a file system path so should only contain forward slashes, not the standard +// file path separator as denoted by filepath.Separator, typically used when interacting +// with the local file system. Do not use trailing "/". +func Combine(parent, relative string) string { + if relative == "" { + return parent + } + + return parent + "/" + relative +} + +// Repo gets the path of the repo with relative joined on +func Repo(relative string) string { + cmd := exec.Command("git", "rev-parse", "--show-toplevel") + output, _ := cmd.Output() + repo := strings.TrimSpace(string(output)) + + return Combine(repo, relative) +} diff --git a/internal/feat/hiber/hibernate_test.go b/internal/feat/hiber/hibernate_test.go index 776095a..0998658 100644 --- a/internal/feat/hiber/hibernate_test.go +++ b/internal/feat/hiber/hibernate_test.go @@ -12,6 +12,7 @@ import ( tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/internal/third/lo" @@ -19,8 +20,7 @@ import ( var _ = Describe("feature", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -28,10 +28,15 @@ var _ = Describe("feature", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, - lab.Static.RetroWave, "edm", + var ( + err error ) - Expect(root).NotTo(BeEmpty()) + + repo := hydra.Repo("") + index := hydra.Combine(repo, "test/data/musico-index.xml") + fS, err = hydra.CustomTree(index, "MUSICO", verbose, lab.Static.RetroWave, "edm") + + Expect(err).To(Succeed()) Expect(li18ngo.Use()).To(Succeed()) }) diff --git a/internal/feat/hiber/with-filter_test.go b/internal/feat/hiber/with-filter_test.go index 8c42abc..37758eb 100644 --- a/internal/feat/hiber/with-filter_test.go +++ b/internal/feat/hiber/with-filter_test.go @@ -12,6 +12,7 @@ import ( "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/pref" @@ -19,8 +20,7 @@ import ( var _ = Describe("feature", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -28,10 +28,7 @@ var _ = Describe("feature", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, - lab.Static.RetroWave, "edm", - ) - Expect(root).NotTo(BeEmpty()) + fS = hydra.Nuxx(verbose, lab.Static.RetroWave, "edm") Expect(li18ngo.Use()).To(Succeed()) }) diff --git a/internal/feat/sampling/navigator-sample_test.go b/internal/feat/sampling/navigator-sample_test.go index 74e39c0..fd6b309 100644 --- a/internal/feat/sampling/navigator-sample_test.go +++ b/internal/feat/sampling/navigator-sample_test.go @@ -10,6 +10,7 @@ import ( tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/internal/third/lo" @@ -19,8 +20,7 @@ import ( var _ = Describe("feature", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -28,10 +28,7 @@ var _ = Describe("feature", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, - lab.Static.RetroWave, "edm", - ) - Expect(root).NotTo(BeEmpty()) + fS = hydra.Nuxx(verbose, lab.Static.RetroWave, "edm") Expect(li18ngo.Use()).To(Succeed()) }) diff --git a/internal/filtering/filter-custom_test.go b/internal/filtering/filter-custom_test.go index 2ab8d90..92a8861 100644 --- a/internal/filtering/filter-custom_test.go +++ b/internal/filtering/filter-custom_test.go @@ -9,6 +9,7 @@ import ( "github.com/snivilised/nefilim/luna" tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/internal/third/lo" @@ -17,8 +18,7 @@ import ( var _ = Describe("NavigatorFilterCustom", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -26,10 +26,7 @@ var _ = Describe("NavigatorFilterCustom", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, - lab.Static.RetroWave, - ) - Expect(root).NotTo(BeEmpty()) + fS = hydra.Nuxx(verbose, lab.Static.RetroWave) Expect(li18ngo.Use()).To(Succeed()) }) diff --git a/internal/filtering/filter-extended-glob_test.go b/internal/filtering/filter-extended-glob_test.go index 1291e85..39b2874 100644 --- a/internal/filtering/filter-extended-glob_test.go +++ b/internal/filtering/filter-extended-glob_test.go @@ -10,6 +10,7 @@ import ( tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/internal/third/lo" @@ -18,8 +19,7 @@ import ( var _ = Describe("filtering", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -27,10 +27,7 @@ var _ = Describe("filtering", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, - "rock", - ) - Expect(root).NotTo(BeEmpty()) + fS = hydra.Nuxx(verbose, "rock") Expect(li18ngo.Use()).To(Succeed()) }) diff --git a/internal/filtering/filter-glob_test.go b/internal/filtering/filter-glob_test.go index fb1c31c..639fffc 100644 --- a/internal/filtering/filter-glob_test.go +++ b/internal/filtering/filter-glob_test.go @@ -11,6 +11,7 @@ import ( tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/internal/third/lo" @@ -19,8 +20,7 @@ import ( var _ = Describe("NavigatorFilterGlob", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -28,10 +28,7 @@ var _ = Describe("NavigatorFilterGlob", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, - lab.Static.RetroWave, - ) - Expect(root).NotTo(BeEmpty()) + fS = hydra.Nuxx(verbose, lab.Static.RetroWave) Expect(li18ngo.Use()).To(Succeed()) }) diff --git a/internal/filtering/filter-hybrid_test.go b/internal/filtering/filter-hybrid_test.go index 55be050..b350f58 100644 --- a/internal/filtering/filter-hybrid_test.go +++ b/internal/filtering/filter-hybrid_test.go @@ -11,6 +11,7 @@ import ( tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/locale" @@ -19,8 +20,7 @@ import ( var _ = Describe("feature", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -28,10 +28,7 @@ var _ = Describe("feature", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, - lab.Static.RetroWave, - ) - Expect(root).NotTo(BeEmpty()) + fS = hydra.Nuxx(verbose, lab.Static.RetroWave) Expect(li18ngo.Use( func(o *li18ngo.UseOptions) { o.From.Sources = li18ngo.TranslationFiles{ diff --git a/internal/filtering/filter-poly_test.go b/internal/filtering/filter-poly_test.go index 4a1e99c..a2eda33 100644 --- a/internal/filtering/filter-poly_test.go +++ b/internal/filtering/filter-poly_test.go @@ -11,6 +11,7 @@ import ( tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/internal/third/lo" @@ -20,8 +21,7 @@ import ( var _ = Describe("feature", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -29,10 +29,7 @@ var _ = Describe("feature", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, - lab.Static.RetroWave, - ) - Expect(root).NotTo(BeEmpty()) + fS = hydra.Nuxx(verbose, lab.Static.RetroWave) Expect(li18ngo.Use()).To(Succeed()) }) diff --git a/internal/filtering/filter-regex_test.go b/internal/filtering/filter-regex_test.go index 5d103ad..c95f735 100644 --- a/internal/filtering/filter-regex_test.go +++ b/internal/filtering/filter-regex_test.go @@ -10,6 +10,7 @@ import ( tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/core" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/internal/third/lo" @@ -18,8 +19,7 @@ import ( var _ = Describe("feature", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -27,10 +27,9 @@ var _ = Describe("feature", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, + fS = hydra.Nuxx(verbose, lab.Static.RetroWave, "PROGRESSIVE-HOUSE", ) - Expect(root).NotTo(BeEmpty()) Expect(li18ngo.Use()).To(Succeed()) }) diff --git a/internal/kernel/navigator-folders-with-files_test.go b/internal/kernel/navigator-folders-with-files_test.go index d1215a3..569c994 100644 --- a/internal/kernel/navigator-folders-with-files_test.go +++ b/internal/kernel/navigator-folders-with-files_test.go @@ -10,6 +10,7 @@ import ( "github.com/snivilised/nefilim/luna" tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/locale" @@ -17,8 +18,7 @@ import ( var _ = Describe("NavigatorFoldersWithFiles", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -26,10 +26,7 @@ var _ = Describe("NavigatorFoldersWithFiles", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, - lab.Static.RetroWave, - ) - Expect(root).NotTo(BeEmpty()) + fS = hydra.Nuxx(verbose, lab.Static.RetroWave) Expect(li18ngo.Use( func(o *li18ngo.UseOptions) { o.From.Sources = li18ngo.TranslationFiles{ diff --git a/internal/kernel/navigator-simple_test.go b/internal/kernel/navigator-simple_test.go index 3f3f9dd..2debdd5 100644 --- a/internal/kernel/navigator-simple_test.go +++ b/internal/kernel/navigator-simple_test.go @@ -11,6 +11,7 @@ import ( "github.com/snivilised/nefilim/luna" tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/enums" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/services" "github.com/snivilised/traverse/internal/third/lo" @@ -19,8 +20,7 @@ import ( var _ = Describe("NavigatorUniversal", Ordered, func() { var ( - fS *luna.MemFS - root string + fS *luna.MemFS ) BeforeAll(func() { @@ -28,11 +28,10 @@ var _ = Describe("NavigatorUniversal", Ordered, func() { verbose = false ) - fS, root = lab.Musico(verbose, + fS = hydra.Nuxx(verbose, lab.Static.RetroWave, filepath.Join("rock", "metal"), ) - Expect(root).NotTo(BeEmpty()) Expect(li18ngo.Use( func(o *li18ngo.UseOptions) { o.From.Sources = li18ngo.TranslationFiles{ diff --git a/scripts/coverage-exclusion-list.txt b/scripts/coverage-exclusion-list.txt index 914b755..03e6733 100644 --- a/scripts/coverage-exclusion-list.txt +++ b/scripts/coverage-exclusion-list.txt @@ -1,3 +1,4 @@ github.com/snivilised/traverse/enums +github.com/snivilised/traverse/hydra github.com/snivilised/traverse/internal/third github.com/snivilised/traverse/internal/laboratory/ diff --git a/tapable/tapable_test.go b/tapable/tapable_test.go index 03c6650..521ba78 100644 --- a/tapable/tapable_test.go +++ b/tapable/tapable_test.go @@ -9,6 +9,7 @@ import ( "github.com/snivilised/nefilim/luna" tv "github.com/snivilised/traverse" "github.com/snivilised/traverse/core" + "github.com/snivilised/traverse/hydra" lab "github.com/snivilised/traverse/internal/laboratory" "github.com/snivilised/traverse/internal/opts" "github.com/snivilised/traverse/pref" @@ -19,6 +20,7 @@ const ( spoofed = "spoofed" respoofed = "re-spoofed" verbose = false + root = "foo-bar" ) var ( @@ -36,14 +38,12 @@ var _ = Describe("Tapable", Ordered, func() { o *pref.Options err error fS *luna.MemFS - root string ) BeforeAll(func() { - fS, root = lab.Musico(verbose, + fS = hydra.Nuxx(verbose, lab.Static.RetroWave, ) - Expect(root).NotTo(BeEmpty()) }) BeforeEach(func() {