diff options
author | Noah Campbell <noahcampbell@gmail.com> | 2013-09-21 04:03:43 +0400 |
---|---|---|
committer | Noah Campbell <noahcampbell@gmail.com> | 2013-09-21 04:03:43 +0400 |
commit | 52e8c7a0ac76f4aa1fff8ff30a6d5074bd459347 (patch) | |
tree | fcabd15f6b496589edcf56be200f865177606a70 /source | |
parent | 784077da4dcc3476f61bbf99c5f873b71694dd64 (diff) |
Section is determined by the source, not the url
This change allows for top level html content to exists.
Diffstat (limited to 'source')
-rw-r--r-- | source/filesystem.go | 65 | ||||
-rw-r--r-- | source/filesystem_linux_test.go | 13 | ||||
-rw-r--r-- | source/filesystem_test.go | 65 | ||||
-rw-r--r-- | source/filesystem_windows_test.go | 15 | ||||
-rw-r--r-- | source/inmemory.go | 34 |
5 files changed, 166 insertions, 26 deletions
diff --git a/source/filesystem.go b/source/filesystem.go index da3983aec..6c9f4e7c1 100644 --- a/source/filesystem.go +++ b/source/filesystem.go @@ -1,8 +1,10 @@ package source import ( + "errors" "io" "os" + "path" "path/filepath" ) @@ -11,8 +13,11 @@ type Input interface { } type File struct { - Name string - Contents io.Reader + name string + LogicalName string + Contents io.Reader + Section string + Dir string } type Filesystem struct { @@ -26,32 +31,66 @@ func (f *Filesystem) Files() []*File { return f.files } -func (f *Filesystem) add(name string, reader io.Reader) { +var errMissingBaseDir = errors.New("source: missing base directory") + +func (f *Filesystem) add(name string, reader io.Reader) (err error) { + + if name, err = f.getRelativePath(name); err != nil { + return err + } + + dir, logical := path.Split(name) + _, section := path.Split(path.Dir(name)) + if section == "." { + section = "" + } + + f.files = append(f.files, &File{ + name: name, + LogicalName: logical, + Contents: reader, + Section: section, + Dir: dir, + }) + return +} + +func (f *Filesystem) getRelativePath(name string) (final string, err error) { + if filepath.IsAbs(name) && f.Base == "" { + return "", errMissingBaseDir + } + name = filepath.Clean(name) + base := filepath.Clean(f.Base) + + name, err = filepath.Rel(base, name) + if err != nil { + return "", err + } name = filepath.ToSlash(name) - f.files = append(f.files, &File{Name: name, Contents: reader}) + return name, nil } func (f *Filesystem) captureFiles() { - walker := func(path string, fi os.FileInfo, err error) error { + walker := func(filePath string, fi os.FileInfo, err error) error { if err != nil { return nil } if fi.IsDir() { - if f.avoid(path) { + if f.avoid(filePath) { return filepath.SkipDir } return nil } else { - if ignoreDotFile(path) { + if ignoreDotFile(filePath) { return nil } - file, err := os.Open(path) + file, err := os.Open(filePath) if err != nil { return err } - f.add(path, file) + f.add(filePath, file) return nil } } @@ -59,15 +98,15 @@ func (f *Filesystem) captureFiles() { filepath.Walk(f.Base, walker) } -func (f *Filesystem) avoid(path string) bool { +func (f *Filesystem) avoid(filePath string) bool { for _, avoid := range f.AvoidPaths { - if avoid == path { + if avoid == filePath { return true } } return false } -func ignoreDotFile(path string) bool { - return filepath.Base(path)[0] == '.' +func ignoreDotFile(filePath string) bool { + return filepath.Base(filePath)[0] == '.' } diff --git a/source/filesystem_linux_test.go b/source/filesystem_linux_test.go new file mode 100644 index 000000000..d3e09b261 --- /dev/null +++ b/source/filesystem_linux_test.go @@ -0,0 +1,13 @@ +package source + +// +// NOTE, any changes here need to be reflected in filesystem_windows_test.go +// +var platformBase = "foo/bar/boo/" +var platformPaths = []TestPath{ + {"foobar", "foobar", "aaa", "", ""}, + {"b/1file", "1file", "aaa", "b", "b/"}, + {"c/d/2file", "2file", "aaa", "d", "c/d/"}, + {"/e/f/3file", "3file", "aaa", "f", "e/f/"}, + {"section\\foo.rss", "foo.rss", "aaa", "section", "section/"}, +} diff --git a/source/filesystem_test.go b/source/filesystem_test.go index 2aac9b0dc..b885d2f24 100644 --- a/source/filesystem_test.go +++ b/source/filesystem_test.go @@ -2,6 +2,8 @@ package source import ( "bytes" + "path" + "path/filepath" "testing" ) @@ -12,21 +14,58 @@ func TestEmptySourceFilesystem(t *testing.T) { } } +type TestPath struct { + filename string + logical string + content string + section string + dir string +} + 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") - } + tests := platformPaths + for _, test := range tests { + base := platformBase + srcDefault := new(Filesystem) + srcWithBase := &Filesystem{ + Base: base, + } - f := src.Files()[0] - if f.Name != "foobar" { - t.Errorf("File name should be 'foobar', got: %s", f.Name) - } + for _, src := range []*Filesystem{srcDefault, srcWithBase} { + p := test.filename + if !filepath.IsAbs(test.filename) { + p = path.Join(src.Base, test.filename) + } + + if err := src.add(p, bytes.NewReader([]byte(test.content))); err != nil { + if err == errMissingBaseDir { + continue + } + t.Fatalf("%s add returned and error: %s", p, err) + } + + if len(src.Files()) != 1 { + t.Fatalf("%s Files() should return 1 file", p) + } + + f := src.Files()[0] + if f.LogicalName != test.logical { + t.Errorf("Filename (Base: %q) expected: %q, got: %q", src.Base, test.logical, f.LogicalName) + } + + b := new(bytes.Buffer) + b.ReadFrom(f.Contents) + if b.String() != test.content { + t.Errorf("File (Base: %q) contents should be %q, got: %q", src.Base, test.content, b.String()) + } + + if f.Section != test.section { + t.Errorf("File section (Base: %q) expected: %q, got: %q", src.Base, test.section, f.Section) + } - b := new(bytes.Buffer) - b.ReadFrom(f.Contents) - if b.String() != "aaa" { - t.Errorf("File contents should be 'aaa', got: %s", b.String()) + if f.Dir != test.dir { + t.Errorf("Dir path (Base: %q) expected: %q, got: %q", src.Base, test.dir, f.Dir) + } + } } } diff --git a/source/filesystem_windows_test.go b/source/filesystem_windows_test.go new file mode 100644 index 000000000..b9ecd5354 --- /dev/null +++ b/source/filesystem_windows_test.go @@ -0,0 +1,15 @@ +package source + +// +// NOTE, any changes here need to be reflected in filesystem_linux_test.go +// + +// Note the case of the volume drive. It must be the same in all examples. +var platformBase = "C:\\foo\\" +var platformPaths = []TestPath{ + {"foobar", "foobar", "aaa", "", ""}, + {"b\\1file", "1file", "aaa", "b", "b/"}, + {"c\\d\\2file", "2file", "aaa", "d", "c/d/"}, + {"C:\\foo\\e\\f\\3file", "3file", "aaa", "f", "e/f/"}, // note volume case is equal to platformBase + {"section\\foo.rss", "foo.rss", "aaa", "section", "section/"}, +} diff --git a/source/inmemory.go b/source/inmemory.go new file mode 100644 index 000000000..7c76469fe --- /dev/null +++ b/source/inmemory.go @@ -0,0 +1,34 @@ +package source + +import ( + "bytes" + "fmt" + "path" +) + +type ByteSource struct { + Name string + Content []byte + Section string +} + +func (b *ByteSource) String() string { + return fmt.Sprintf("%s %s %s", b.Name, b.Section, string(b.Content)) +} + +type InMemorySource struct { + ByteSource []ByteSource +} + +func (i *InMemorySource) Files() (files []*File) { + files = make([]*File, len(i.ByteSource)) + for i, fake := range i.ByteSource { + files[i] = &File{ + LogicalName: fake.Name, + Contents: bytes.NewReader(fake.Content), + Section: fake.Section, + Dir: path.Dir(fake.Name), + } + } + return +} |