From 610c06e6589770d950d8fd4e01efd90b132fcff5 Mon Sep 17 00:00:00 2001 From: Noah Campbell Date: Wed, 4 Sep 2013 22:28:59 -0700 Subject: Introduce source.Filesystem This provides an abstraction over how files are processed by Hugo. This allows for alternatives like CMS systems or Dropbox, etc. --- source/content_directory_test.go | 25 ++++++++++++++ source/filesystem.go | 72 ++++++++++++++++++++++++++++++++++++++++ source/filesystem_test.go | 32 ++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 source/content_directory_test.go create mode 100644 source/filesystem.go create mode 100644 source/filesystem_test.go (limited to 'source') 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()) + } +} -- cgit v1.2.3