From 6aa96dc7b79804f50d62ae8dac42ee7625750a27 Mon Sep 17 00:00:00 2001 From: Virgil Date: Tue, 31 Mar 2026 05:18:17 +0000 Subject: [PATCH] refactor(ax): align remaining example names and walk APIs --- datanode/medium_test.go | 10 +++++----- io.go | 6 +++--- node/node.go | 26 ++++++++++++++++++-------- node/node_test.go | 22 +++++++++++----------- s3/s3.go | 6 +++--- s3/s3_test.go | 6 +++--- sigil/crypto_sigil.go | 18 +++++++++++++----- sigil/crypto_sigil_test.go | 18 +++++++++--------- 8 files changed, 65 insertions(+), 47 deletions(-) diff --git a/datanode/medium_test.go b/datanode/medium_test.go index bd5e8ec..77e68af 100644 --- a/datanode/medium_test.go +++ b/datanode/medium_test.go @@ -94,14 +94,14 @@ func TestClient_Delete_Good(t *testing.T) { } func TestClient_Delete_Bad(t *testing.T) { - m := New() + medium := New() - // Example: m.Delete("ghost.txt") - assert.Error(t, m.Delete("ghost.txt")) + // Example: medium.Delete("ghost.txt") + assert.Error(t, medium.Delete("ghost.txt")) // Delete non-empty dir - require.NoError(t, m.Write("dir/file.txt", "content")) - assert.Error(t, m.Delete("dir")) + require.NoError(t, medium.Write("dir/file.txt", "content")) + assert.Error(t, medium.Delete("dir")) } func TestClient_Delete_DirectoryInspectionFailure_Bad(t *testing.T) { diff --git a/io.go b/io.go index 0d9a32c..f10901b 100644 --- a/io.go +++ b/io.go @@ -52,10 +52,10 @@ type Medium interface { // Example: writer, _ := medium.WriteStream("logs/app.log") WriteStream(path string) (goio.WriteCloser, error) - // Example: ok := medium.Exists("config/app.yaml") + // Example: exists := medium.Exists("config/app.yaml") Exists(path string) bool - // Example: ok := medium.IsDir("config") + // Example: isDirectory := medium.IsDir("config") IsDir(path string) bool } @@ -163,7 +163,7 @@ func EnsureDir(medium Medium, path string) error { return medium.EnsureDir(path) } -// Example: ok := io.IsFile(medium, "config/app.yaml") +// Example: isFile := io.IsFile(medium, "config/app.yaml") func IsFile(medium Medium, path string) bool { return medium.IsFile(path) } diff --git a/node/node.go b/node/node.go index 541973d..45de545 100644 --- a/node/node.go +++ b/node/node.go @@ -124,7 +124,7 @@ func (node *Node) LoadTar(data []byte) error { // Example: _ = nodeTree.WalkNode("config", func(_ string, _ fs.DirEntry, _ error) error { return nil }) func (node *Node) WalkNode(root string, fn fs.WalkDirFunc) error { - return fs.WalkDir(node, root, fn) + return node.Walk(root, fn) } // Example: options := node.WalkOptions{MaxDepth: 1, SkipErrors: true} @@ -134,17 +134,22 @@ type WalkOptions struct { SkipErrors bool } -// Example: _ = nodeTree.WalkWithOptions(".", callback, node.WalkOptions{MaxDepth: 1, SkipErrors: true}) -func (node *Node) WalkWithOptions(root string, fn fs.WalkDirFunc, options WalkOptions) error { - if options.SkipErrors { +// Example: _ = nodeTree.Walk(".", func(_ string, _ fs.DirEntry, _ error) error { return nil }, node.WalkOptions{MaxDepth: 1, SkipErrors: true}) +func (node *Node) Walk(root string, fn fs.WalkDirFunc, options ...WalkOptions) error { + walkOptions := WalkOptions{} + if len(options) > 0 { + walkOptions = options[0] + } + + if walkOptions.SkipErrors { if _, err := node.Stat(root); err != nil { return nil } } return fs.WalkDir(node, root, func(entryPath string, entry fs.DirEntry, err error) error { - if options.Filter != nil && err == nil { - if !options.Filter(entryPath, entry) { + if walkOptions.Filter != nil && err == nil { + if !walkOptions.Filter(entryPath, entry) { if entry != nil && entry.IsDir() { return fs.SkipDir } @@ -154,11 +159,11 @@ func (node *Node) WalkWithOptions(root string, fn fs.WalkDirFunc, options WalkOp result := fn(entryPath, entry, err) - if result == nil && options.MaxDepth > 0 && entry != nil && entry.IsDir() && entryPath != root { + if result == nil && walkOptions.MaxDepth > 0 && entry != nil && entry.IsDir() && entryPath != root { rel := core.TrimPrefix(entryPath, root) rel = core.TrimPrefix(rel, "/") depth := len(core.Split(rel, "/")) - if depth >= options.MaxDepth { + if depth >= walkOptions.MaxDepth { return fs.SkipDir } } @@ -167,6 +172,11 @@ func (node *Node) WalkWithOptions(root string, fn fs.WalkDirFunc, options WalkOp }) } +// Example: _ = nodeTree.WalkWithOptions(".", func(_ string, _ fs.DirEntry, _ error) error { return nil }, node.WalkOptions{MaxDepth: 1, SkipErrors: true}) +func (node *Node) WalkWithOptions(root string, fn fs.WalkDirFunc, options WalkOptions) error { + return node.Walk(root, fn, options) +} + // Example: content, _ := nodeTree.ReadFile("config/app.yaml") func (node *Node) ReadFile(name string) ([]byte, error) { name = core.TrimPrefix(name, "/") diff --git a/node/node_test.go b/node/node_test.go index 934324d..8880c4e 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -259,17 +259,17 @@ func TestNode_Exists_RootAndEmptyPath_Good(t *testing.T) { } // --------------------------------------------------------------------------- -// WalkWithOptions +// Walk // --------------------------------------------------------------------------- -func TestNode_WalkWithOptions_Default_Good(t *testing.T) { +func TestNode_Walk_Default_Good(t *testing.T) { n := New() n.AddData("foo.txt", []byte("foo")) n.AddData("bar/baz.txt", []byte("baz")) n.AddData("bar/qux.txt", []byte("qux")) var paths []string - err := n.WalkWithOptions(".", func(p string, d fs.DirEntry, err error) error { + err := n.Walk(".", func(p string, d fs.DirEntry, err error) error { paths = append(paths, p) return nil }, WalkOptions{}) @@ -279,11 +279,11 @@ func TestNode_WalkWithOptions_Default_Good(t *testing.T) { assert.Equal(t, []string{".", "bar", "bar/baz.txt", "bar/qux.txt", "foo.txt"}, paths) } -func TestNode_WalkWithOptions_Default_Bad(t *testing.T) { +func TestNode_Walk_Default_Bad(t *testing.T) { n := New() var called bool - err := n.WalkWithOptions("nonexistent", func(p string, d fs.DirEntry, err error) error { + err := n.Walk("nonexistent", func(p string, d fs.DirEntry, err error) error { called = true assert.Error(t, err) assert.ErrorIs(t, err, fs.ErrNotExist) @@ -293,7 +293,7 @@ func TestNode_WalkWithOptions_Default_Bad(t *testing.T) { assert.ErrorIs(t, err, fs.ErrNotExist) } -func TestNode_WalkWithOptions_CallbackError_Good(t *testing.T) { +func TestNode_Walk_CallbackError_Good(t *testing.T) { n := New() n.AddData("a/b.txt", []byte("b")) n.AddData("a/c.txt", []byte("c")) @@ -301,7 +301,7 @@ func TestNode_WalkWithOptions_CallbackError_Good(t *testing.T) { // Stop walk early with a custom error. walkErr := core.NewError("stop walking") var paths []string - err := n.WalkWithOptions(".", func(p string, d fs.DirEntry, err error) error { + err := n.Walk(".", func(p string, d fs.DirEntry, err error) error { if p == "a/b.txt" { return walkErr } @@ -312,7 +312,7 @@ func TestNode_WalkWithOptions_CallbackError_Good(t *testing.T) { assert.Equal(t, walkErr, err, "Walk must propagate the callback error") } -func TestNode_WalkWithOptions_Good(t *testing.T) { +func TestNode_Walk_Good(t *testing.T) { n := New() n.AddData("root.txt", []byte("root")) n.AddData("a/a1.txt", []byte("a1")) @@ -321,7 +321,7 @@ func TestNode_WalkWithOptions_Good(t *testing.T) { t.Run("MaxDepth", func(t *testing.T) { var paths []string - err := n.WalkWithOptions(".", func(p string, d fs.DirEntry, err error) error { + err := n.Walk(".", func(p string, d fs.DirEntry, err error) error { paths = append(paths, p) return nil }, WalkOptions{MaxDepth: 1}) @@ -333,7 +333,7 @@ func TestNode_WalkWithOptions_Good(t *testing.T) { t.Run("Filter", func(t *testing.T) { var paths []string - err := n.WalkWithOptions(".", func(p string, d fs.DirEntry, err error) error { + err := n.Walk(".", func(p string, d fs.DirEntry, err error) error { paths = append(paths, p) return nil }, WalkOptions{Filter: func(p string, d fs.DirEntry) bool { @@ -347,7 +347,7 @@ func TestNode_WalkWithOptions_Good(t *testing.T) { t.Run("SkipErrors", func(t *testing.T) { var called bool - err := n.WalkWithOptions("nonexistent", func(p string, d fs.DirEntry, err error) error { + err := n.Walk("nonexistent", func(p string, d fs.DirEntry, err error) error { called = true return err }, WalkOptions{SkipErrors: true}) diff --git a/s3/s3.go b/s3/s3.go index 456defc..5ca8fad 100644 --- a/s3/s3.go +++ b/s3/s3.go @@ -168,7 +168,7 @@ func (medium *Medium) EnsureDir(directoryPath string) error { return nil } -// Example: ok := medium.IsFile("reports/daily.txt") +// Example: isFile := medium.IsFile("reports/daily.txt") func (medium *Medium) IsFile(filePath string) bool { key := medium.objectKey(filePath) if key == "" { @@ -498,7 +498,7 @@ func (medium *Medium) WriteStream(filePath string) (goio.WriteCloser, error) { return medium.Create(filePath) } -// Example: ok := medium.Exists("reports/daily.txt") +// Example: exists := medium.Exists("reports/daily.txt") func (medium *Medium) Exists(filePath string) bool { key := medium.objectKey(filePath) if key == "" { @@ -528,7 +528,7 @@ func (medium *Medium) Exists(filePath string) bool { return len(listOutput.Contents) > 0 || len(listOutput.CommonPrefixes) > 0 } -// Example: ok := medium.IsDir("reports") +// Example: isDirectory := medium.IsDir("reports") func (medium *Medium) IsDir(filePath string) bool { key := medium.objectKey(filePath) if key == "" { diff --git a/s3/s3_test.go b/s3/s3_test.go index 692a893..8334eab 100644 --- a/s3/s3_test.go +++ b/s3/s3_test.go @@ -294,9 +294,9 @@ func TestS3_ReadWrite_Prefix_Good(t *testing.T) { } func TestS3_EnsureDir_Good(t *testing.T) { - m, _ := newTestMedium(t) - // Example: err := m.EnsureDir("any/path") - err := m.EnsureDir("any/path") + medium, _ := newTestMedium(t) + // Example: err := medium.EnsureDir("any/path") + err := medium.EnsureDir("any/path") assert.NoError(t, err) } diff --git a/sigil/crypto_sigil.go b/sigil/crypto_sigil.go index 98537ed..798c24f 100644 --- a/sigil/crypto_sigil.go +++ b/sigil/crypto_sigil.go @@ -170,7 +170,10 @@ func (obfuscator *ShuffleMaskObfuscator) deriveMask(entropy []byte, length int) return mask } -// Example: cipherSigil, _ := sigil.NewChaChaPolySigilWithObfuscator(key, &sigil.ShuffleMaskObfuscator{}) +// Example: cipherSigil, _ := sigil.NewChaChaPolySigil( +// Example: key, +// Example: &sigil.ShuffleMaskObfuscator{}, +// Example: ) type ChaChaPolySigil struct { Key []byte Obfuscator PreObfuscator @@ -180,7 +183,7 @@ type ChaChaPolySigil struct { // Example: cipherSigil, _ := sigil.NewChaChaPolySigil([]byte("0123456789abcdef0123456789abcdef")) // Example: ciphertext, _ := cipherSigil.In([]byte("payload")) // Example: plaintext, _ := cipherSigil.Out(ciphertext) -func NewChaChaPolySigil(key []byte) (*ChaChaPolySigil, error) { +func NewChaChaPolySigil(key []byte, obfuscators ...PreObfuscator) (*ChaChaPolySigil, error) { if len(key) != 32 { return nil, InvalidKeyError } @@ -188,21 +191,26 @@ func NewChaChaPolySigil(key []byte) (*ChaChaPolySigil, error) { keyCopy := make([]byte, 32) copy(keyCopy, key) + obfuscator := PreObfuscator(&XORObfuscator{}) + if len(obfuscators) > 0 && obfuscators[0] != nil { + obfuscator = obfuscators[0] + } + return &ChaChaPolySigil{ Key: keyCopy, - Obfuscator: &XORObfuscator{}, + Obfuscator: obfuscator, randomReader: rand.Reader, }, nil } -// Example: cipherSigil, _ := sigil.NewChaChaPolySigilWithObfuscator( +// Example: cipherSigil, _ := sigil.NewChaChaPolySigil( // Example: []byte("0123456789abcdef0123456789abcdef"), // Example: &sigil.ShuffleMaskObfuscator{}, // Example: ) // Example: ciphertext, _ := cipherSigil.In([]byte("payload")) // Example: plaintext, _ := cipherSigil.Out(ciphertext) func NewChaChaPolySigilWithObfuscator(key []byte, obfuscator PreObfuscator) (*ChaChaPolySigil, error) { - cipherSigil, err := NewChaChaPolySigil(key) + cipherSigil, err := NewChaChaPolySigil(key, obfuscator) if err != nil { return nil, err } diff --git a/sigil/crypto_sigil_test.go b/sigil/crypto_sigil_test.go index d90fc0a..7f1425c 100644 --- a/sigil/crypto_sigil_test.go +++ b/sigil/crypto_sigil_test.go @@ -186,30 +186,30 @@ func TestCryptoSigil_NewChaChaPolySigil_EmptyKey_Bad(t *testing.T) { assert.ErrorIs(t, err, InvalidKeyError) } -// ── NewChaChaPolySigilWithObfuscator ─────────────────────────────── +// ── NewChaChaPolySigil Custom Obfuscator ─────────────────────────── -func TestCryptoSigil_NewChaChaPolySigilWithObfuscator_Good(t *testing.T) { +func TestCryptoSigil_NewChaChaPolySigil_CustomObfuscator_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) ob := &ShuffleMaskObfuscator{} - s, err := NewChaChaPolySigilWithObfuscator(key, ob) + s, err := NewChaChaPolySigil(key, ob) require.NoError(t, err) assert.Equal(t, ob, s.Obfuscator) } -func TestCryptoSigil_NewChaChaPolySigilWithObfuscator_NilObfuscator_Good(t *testing.T) { +func TestCryptoSigil_NewChaChaPolySigil_CustomObfuscatorNil_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, err := NewChaChaPolySigilWithObfuscator(key, nil) + s, err := NewChaChaPolySigil(key, nil) require.NoError(t, err) // Falls back to default XORObfuscator. assert.IsType(t, &XORObfuscator{}, s.Obfuscator) } -func TestCryptoSigil_NewChaChaPolySigilWithObfuscator_InvalidKey_Bad(t *testing.T) { - _, err := NewChaChaPolySigilWithObfuscator([]byte("bad"), &XORObfuscator{}) +func TestCryptoSigil_NewChaChaPolySigil_CustomObfuscator_InvalidKey_Bad(t *testing.T) { + _, err := NewChaChaPolySigil([]byte("bad"), &XORObfuscator{}) assert.ErrorIs(t, err, InvalidKeyError) } @@ -233,11 +233,11 @@ func TestCryptoSigil_ChaChaPolySigil_RoundTrip_Good(t *testing.T) { assert.Equal(t, plaintext, decrypted) } -func TestCryptoSigil_ChaChaPolySigil_WithShuffleMask_Good(t *testing.T) { +func TestCryptoSigil_ChaChaPolySigil_CustomShuffleMask_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, err := NewChaChaPolySigilWithObfuscator(key, &ShuffleMaskObfuscator{}) + s, err := NewChaChaPolySigil(key, &ShuffleMaskObfuscator{}) require.NoError(t, err) plaintext := []byte("shuffle mask pre-obfuscation layer")