From 5dfc1dedb8ac53b7a2d3823d06808ae86f90b3d9 Mon Sep 17 00:00:00 2001 From: spf13 Date: Thu, 16 Oct 2014 20:20:09 -0400 Subject: Big refactor of how source files are used. Also added default destination extension option. --- source/file.go | 114 ++++++++++++++++++++++++++++++++++++++++++++++ source/filesystem.go | 86 +++++++++++++++++----------------- source/filesystem_test.go | 17 +++---- source/inmemory.go | 11 +---- 4 files changed, 167 insertions(+), 61 deletions(-) create mode 100644 source/file.go (limited to 'source') diff --git a/source/file.go b/source/file.go new file mode 100644 index 000000000..ce1469d5d --- /dev/null +++ b/source/file.go @@ -0,0 +1,114 @@ +// Copyright © 2014 Steve Francia . +// +// Licensed under the Simple Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://opensource.org/licenses/Simple-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package source + +import ( + "io" + "path" + "path/filepath" + "strings" + + "github.com/spf13/hugo/helpers" +) + +type File struct { + relpath string // Original Full Path eg. /Users/Home/Hugo/foo.txt + logicalName string // foo.txt + Contents io.Reader + section string // The first directory + dir string // The full directory Path (minus file name) + ext string // Just the ext (eg txt) + uniqueId string // MD5 of the filename +} + +func (f *File) UniqueId() string { + if f.uniqueId == "" { + f.uniqueId = helpers.Md5String(f.LogicalName()) + } + return f.uniqueId +} + +// Filename without extension +func (f *File) BaseFileName() string { + return helpers.Filename(f.LogicalName()) +} + +func (f *File) Section() string { + if f.section != "" { + return f.section + } else { + f.section = helpers.GuessSection(f.Dir()) + return f.section + } +} + +func (f *File) LogicalName() string { + if f.logicalName != "" { + return f.logicalName + } else { + _, f.logicalName = path.Split(f.relpath) + return f.logicalName + } +} + +//func (f *File) SetDir(dir string) { +//f.dir = dir +//} + +func (f *File) Dir() string { + if f.dir != "" { + return f.dir + } else { + f.dir, _ = path.Split(f.relpath) + return f.dir + } +} + +func (f *File) Extension() string { + if f.ext != "" { + return f.ext + } else { + f.ext = strings.TrimPrefix(filepath.Ext(f.LogicalName()), ".") + return f.ext + } +} + +func (f *File) Ext() string { + return f.Extension() +} + +func (f *File) Path() string { + return f.relpath +} + +func NewFileWithContents(relpath string, content io.Reader) *File { + file := NewFile(relpath) + file.Contents = content + return file +} + +func NewFile(relpath string) *File { + return &File{ + relpath: relpath, + } +} + +func NewFileFromAbs(base, fullpath string, content io.Reader) (f *File, err error) { + var name string + if name, err = helpers.GetRelativePath(fullpath, base); err != nil { + return nil, err + } + + return NewFileWithContents(name, content), nil +} diff --git a/source/filesystem.go b/source/filesystem.go index 3a176d7ba..d89149dc6 100644 --- a/source/filesystem.go +++ b/source/filesystem.go @@ -1,34 +1,56 @@ +// Copyright © 2014 Steve Francia . +// +// Licensed under the Simple Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://opensource.org/licenses/Simple-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package source import ( "bytes" - "errors" "io" "io/ioutil" "os" - "path" "path/filepath" "strings" + + "github.com/spf13/hugo/helpers" ) type Input interface { Files() []*File } -type File struct { - name string - LogicalName string - Contents io.Reader - Section string - Dir string -} - type Filesystem struct { files []*File Base string AvoidPaths []string } +func (f *Filesystem) FilesByExts(exts ...string) []*File { + var newFiles []*File + + if len(exts) == 0 { + return f.Files() + } + + for _, x := range f.Files() { + for _, e := range exts { + if x.Ext() == strings.TrimPrefix(e, ".") { + newFiles = append(newFiles, x) + } + } + } + return newFiles +} + func (f *Filesystem) Files() []*File { if len(f.files) < 1 { f.captureFiles() @@ -36,47 +58,23 @@ func (f *Filesystem) Files() []*File { return f.files } -var errMissingBaseDir = errors.New("source: missing base directory") - func (f *Filesystem) add(name string, reader io.Reader) (err error) { + var file *File - if name, err = f.getRelativePath(name); err != nil { - return err - } - - // section should be the first part of the path - dir, logical := path.Split(name) - parts := strings.Split(dir, "/") - section := parts[0] + //if f.Base == "" { + //file = NewFileWithContents(name, reader) + //} else { + file, err = NewFileFromAbs(f.Base, name, reader) + //} - if section == "." { - section = "" + if err == nil { + f.files = append(f.files, file) } - - f.files = append(f.files, &File{ - name: name, - LogicalName: logical, - Contents: reader, - Section: section, - Dir: dir, - }) - - return + return err } 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) - return name, nil + return helpers.GetRelativePath(name, f.Base) } func (f *Filesystem) captureFiles() { diff --git a/source/filesystem_test.go b/source/filesystem_test.go index b885d2f24..d2639310e 100644 --- a/source/filesystem_test.go +++ b/source/filesystem_test.go @@ -32,16 +32,17 @@ func TestAddFile(t *testing.T) { } 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 { + if err.Error() == "source: missing base directory" { continue } - t.Fatalf("%s add returned and error: %s", p, err) + t.Fatalf("%s add returned an error: %s", p, err) } if len(src.Files()) != 1 { @@ -49,8 +50,8 @@ func TestAddFile(t *testing.T) { } f := src.Files()[0] - if f.LogicalName != test.logical { - t.Errorf("Filename (Base: %q) expected: %q, got: %q", src.Base, test.logical, f.LogicalName) + if f.LogicalName() != test.logical { + t.Errorf("Filename (Base: %q) expected: %q, got: %q", src.Base, test.logical, f.LogicalName()) } b := new(bytes.Buffer) @@ -59,12 +60,12 @@ func TestAddFile(t *testing.T) { 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) + if f.Section() != test.section { + t.Errorf("File section (Base: %q) expected: %q, got: %q", src.Base, test.section, f.Section()) } - if f.Dir != test.dir { - t.Errorf("Dir path (Base: %q) expected: %q, got: %q", src.Base, test.dir, f.Dir) + 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/inmemory.go b/source/inmemory.go index 7c76469fe..c30aa3836 100644 --- a/source/inmemory.go +++ b/source/inmemory.go @@ -3,17 +3,15 @@ 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)) + return fmt.Sprintf("%s %s", b.Name, string(b.Content)) } type InMemorySource struct { @@ -23,12 +21,7 @@ type InMemorySource struct { 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), - } + files[i] = NewFileWithContents(fake.Name, bytes.NewReader(fake.Content)) } return } -- cgit v1.2.3