aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <m.shulhan@gmail.com>2019-09-27 00:24:56 +0700
committerShulhan <m.shulhan@gmail.com>2019-09-27 00:49:49 +0700
commit41294ceedd738cc44fe01dd0011ba7087a5d37fb (patch)
tree6651a2855c9ba5967c2307aaa232d793b0183f71
parentf11baff970aef80d39e39397b0569c47e23ad5da (diff)
downloadpakakeh.go-41294ceedd738cc44fe01dd0011ba7087a5d37fb.tar.xz
memfs: add method to add file directly as child of root
-rw-r--r--CHANGELOG.adoc2
-rw-r--r--CHANGELOG.html3
-rw-r--r--lib/memfs/memfs.go48
-rw-r--r--lib/memfs/memfs_test.go86
-rw-r--r--lib/memfs/testdata/direct/add/file1
-rw-r--r--lib/memfs/testdata/direct/add/file21
6 files changed, 141 insertions, 0 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index c5a34b05..8e24d10c 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -15,6 +15,8 @@ This library is released each month, usually at the first week of month.
* ints: add function to merge two slices by distance
+* memfs: add method to add file directly as child of root
+
* memfs: add method to Search content of files
* sanitize: new package to sanitize markup document into plain text
diff --git a/CHANGELOG.html b/CHANGELOG.html
index 6c14f8b7..b4795591 100644
--- a/CHANGELOG.html
+++ b/CHANGELOG.html
@@ -124,6 +124,9 @@
<p>ints: add function to merge two slices by distance</p>
</li>
<li>
+<p>memfs: add method to add file directly as child of root</p>
+</li>
+<li>
<p>memfs: add method to Search content of files</p>
</li>
<li>
diff --git a/lib/memfs/memfs.go b/lib/memfs/memfs.go
index 68d100a3..53bccc05 100644
--- a/lib/memfs/memfs.go
+++ b/lib/memfs/memfs.go
@@ -109,6 +109,54 @@ func New(includes, excludes []string, withContent bool) (mfs *MemFS, err error)
}
//
+// AddFile add the file directly as child of root.
+// The directory and subdirectories in the path will be keep as separated
+// nodes,
+//
+func (mfs *MemFS) AddFile(path string) (*Node, error) {
+ if len(path) == 0 {
+ return nil, nil
+ }
+
+ var parent *Node
+
+ path = filepath.ToSlash(filepath.Clean(path))
+ paths := strings.Split(path, "/")
+ path = ""
+
+ for _, p := range paths {
+ path = filepath.Join(path, p)
+ node, _ := mfs.Get(path)
+ if node != nil {
+ parent = node
+ continue
+ }
+
+ fi, err := os.Stat(path)
+ if err != nil {
+ return nil, fmt.Errorf("memfs.AddFile: " + err.Error())
+ }
+
+ node, err = NewNode(parent, fi, mfs.withContent)
+ if err != nil {
+ return nil, fmt.Errorf("memfs.AddFile: " + err.Error())
+ }
+
+ if parent == nil {
+ mfs.root.Childs = append(mfs.root.Childs, node)
+ } else {
+ parent.Childs = append(parent.Childs, node)
+ }
+
+ mfs.pn.v[node.Path] = node
+
+ parent = node
+ }
+
+ return parent, nil
+}
+
+//
// ContentEncode encode each node's content into specific encoding, in other
// words this method can be used to compress the content of file in memory
// or before being served or written.
diff --git a/lib/memfs/memfs_test.go b/lib/memfs/memfs_test.go
index 778e2529..a289ef32 100644
--- a/lib/memfs/memfs_test.go
+++ b/lib/memfs/memfs_test.go
@@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"testing"
+ "time"
"github.com/shuLhan/share/lib/test"
)
@@ -14,6 +15,88 @@ var (
_testWD string
)
+func TestAddFile(t *testing.T) {
+ cases := []struct {
+ desc string
+ path string
+ exp *Node
+ expError string
+ }{{
+ desc: "With empty path",
+ }, {
+ desc: "With path is not exist",
+ path: "is/not/exist",
+ expError: "memfs.AddFile: stat is: no such file or directory",
+ }, {
+ desc: "With file exist",
+ path: "testdata/direct/add/file",
+ exp: &Node{
+ SysPath: "testdata/direct/add/file",
+ Path: "testdata/direct/add/file",
+ Name: "file",
+ ContentType: "text/plain; charset=utf-8",
+ Size: 22,
+ V: []byte("Test direct add file.\n"),
+ },
+ }, {
+ desc: "With directories exist",
+ path: "testdata/direct/add/file2",
+ exp: &Node{
+ SysPath: "testdata/direct/add/file2",
+ Path: "testdata/direct/add/file2",
+ Name: "file2",
+ ContentType: "text/plain; charset=utf-8",
+ Size: 24,
+ V: []byte("Test direct add file 2.\n"),
+ },
+ }}
+
+ mfs, err := New(nil, nil, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ err = mfs.Mount("testdata")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ for _, c := range cases {
+ t.Log(c.desc)
+
+ got, err := mfs.AddFile(c.path)
+ if err != nil {
+ test.Assert(t, "error", c.expError, err.Error(), true)
+ continue
+ }
+
+ if got != nil {
+ got.ModTime = time.Time{}
+ got.Mode = 0
+ got.Parent = nil
+ got.Childs = nil
+ }
+
+ test.Assert(t, "AddFile", c.exp, got, true)
+
+ if c.exp != nil {
+ got, err := mfs.Get(c.path)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if got != nil {
+ got.ModTime = time.Time{}
+ got.Mode = 0
+ got.Parent = nil
+ got.Childs = nil
+ }
+
+ test.Assert(t, "Get", c.exp, got, true)
+ }
+ }
+}
+
func TestGet(t *testing.T) {
// Limit file size to allow testing Get from disk on file "index.js".
MaxFileSize = 15
@@ -121,6 +204,7 @@ func TestMount(t *testing.T) {
desc: "With directory",
excs: []string{
"memfs_generate.go$",
+ "direct$",
},
dir: filepath.Join(_testWD, "testdata"),
expMapKeys: []string{
@@ -143,6 +227,7 @@ func TestMount(t *testing.T) {
excs: []string{
`.*\.js$`,
"memfs_generate.go$",
+ "direct$",
},
dir: filepath.Join(_testWD, "testdata"),
expMapKeys: []string{
@@ -164,6 +249,7 @@ func TestMount(t *testing.T) {
},
excs: []string{
"memfs_generate.go$",
+ "direct$",
},
dir: filepath.Join(_testWD, "testdata"),
expMapKeys: []string{
diff --git a/lib/memfs/testdata/direct/add/file b/lib/memfs/testdata/direct/add/file
new file mode 100644
index 00000000..9271a628
--- /dev/null
+++ b/lib/memfs/testdata/direct/add/file
@@ -0,0 +1 @@
+Test direct add file.
diff --git a/lib/memfs/testdata/direct/add/file2 b/lib/memfs/testdata/direct/add/file2
new file mode 100644
index 00000000..1ecf20bb
--- /dev/null
+++ b/lib/memfs/testdata/direct/add/file2
@@ -0,0 +1 @@
+Test direct add file 2.