summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorNoah Campbell <noahcampbell@gmail.com>2013-09-04 22:28:59 -0700
committerNoah Campbell <noahcampbell@gmail.com>2013-09-04 22:42:52 -0700
commit610c06e6589770d950d8fd4e01efd90b132fcff5 (patch)
tree859f0cb1ce70875175d3910e4ccd05fdd8173393 /source
parentd4d9da9f3a6358e8325d0c3f973a5842ef3be039 (diff)
Introduce source.Filesystem
This provides an abstraction over how files are processed by Hugo. This allows for alternatives like CMS systems or Dropbox, etc.
Diffstat (limited to 'source')
-rw-r--r--source/content_directory_test.go25
-rw-r--r--source/filesystem.go72
-rw-r--r--source/filesystem_test.go32
3 files changed, 129 insertions, 0 deletions
diff --git a/source/content_directory_test.go b/source/content_directory_test.go
new file mode 100644
index 000000000..7f0616046
--- /dev/null
+++ b/source/content_directory_test.go
@@ -0,0 +1,25 @@
+package source
+
+import (
+ "testing"
+)
+
+func TestIgnoreDotFiles(t *testing.T) {
+ tests := []struct {
+ path string
+ ignore bool
+ }{
+ {"barfoo.md", false},
+ {"foobar/barfoo.md", false},
+ {"foobar/.barfoo.md", true},
+ {".barfoo.md", true},
+ {".md", true},
+ {"", true},
+ }
+
+ for _, test := range tests {
+ if ignored := ignoreDotFile(test.path); test.ignore != ignored {
+ t.Errorf("File not ignored. Expected: %t, got: %t", test.ignore, ignored)
+ }
+ }
+}
diff --git a/source/filesystem.go b/source/filesystem.go
new file mode 100644
index 000000000..5434431aa
--- /dev/null
+++ b/source/filesystem.go
@@ -0,0 +1,72 @@
+package source
+
+import (
+ "io"
+ "os"
+ "path/filepath"
+)
+
+type Input interface {
+ Files() []*File
+}
+
+type File struct {
+ Name string
+ Contents io.Reader
+}
+
+type Filesystem struct {
+ files []*File
+ Base string
+ AvoidPaths []string
+}
+
+func (f *Filesystem) Files() []*File {
+ f.captureFiles()
+ return f.files
+}
+
+func (f *Filesystem) add(name string, reader io.Reader) {
+ f.files = append(f.files, &File{Name: name, Contents: reader})
+}
+
+func (f *Filesystem) captureFiles() {
+
+ walker := func(path string, fi os.FileInfo, err error) error {
+ if err != nil {
+ return nil
+ }
+
+ if fi.IsDir() {
+ if f.avoid(path) {
+ return filepath.SkipDir
+ }
+ return nil
+ } else {
+ if ignoreDotFile(path) {
+ return nil
+ }
+ file, err := os.Open(path)
+ if err != nil {
+ return err
+ }
+ f.add(path, file)
+ return nil
+ }
+ }
+
+ filepath.Walk(f.Base, walker)
+}
+
+func (f *Filesystem) avoid(path string) bool {
+ for _, avoid := range f.AvoidPaths {
+ if avoid == path {
+ return true
+ }
+ }
+ return false
+}
+
+func ignoreDotFile(path string) bool {
+ return filepath.Base(path)[0] == '.'
+}
diff --git a/source/filesystem_test.go b/source/filesystem_test.go
new file mode 100644
index 000000000..2aac9b0dc
--- /dev/null
+++ b/source/filesystem_test.go
@@ -0,0 +1,32 @@
+package source
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestEmptySourceFilesystem(t *testing.T) {
+ src := new(Filesystem)
+ if len(src.Files()) != 0 {
+ t.Errorf("new filesystem should contain 0 files.")
+ }
+}
+
+func TestAddFile(t *testing.T) {
+ src := new(Filesystem)
+ src.add("foobar", bytes.NewReader([]byte("aaa")))
+ if len(src.Files()) != 1 {
+ t.Errorf("Files() should return 1 file")
+ }
+
+ f := src.Files()[0]
+ if f.Name != "foobar" {
+ t.Errorf("File name should be 'foobar', got: %s", f.Name)
+ }
+
+ b := new(bytes.Buffer)
+ b.ReadFrom(f.Contents)
+ if b.String() != "aaa" {
+ t.Errorf("File contents should be 'aaa', got: %s", b.String())
+ }
+}