Make LazyFileReader use the Afero source fs

Fixes #2317
This commit is contained in:
Bjørn Erik Pedersen 2016-07-30 15:14:41 +02:00
parent 9489272681
commit a0859dc672
4 changed files with 30 additions and 22 deletions

View file

@ -836,7 +836,7 @@ func (s *Site) reReadFile(absFilePath string) (*source.File, error) {
jww.INFO.Println("rereading", absFilePath) jww.INFO.Println("rereading", absFilePath)
var file *source.File var file *source.File
reader, err := source.NewLazyFileReader(absFilePath) reader, err := source.NewLazyFileReader(hugofs.Source(), absFilePath)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -14,13 +14,14 @@
package source package source
import ( import (
"github.com/spf13/hugo/hugofs"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings" "strings"
"github.com/spf13/hugo/hugofs"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/spf13/hugo/helpers" "github.com/spf13/hugo/helpers"
@ -84,7 +85,7 @@ func (f *Filesystem) captureFiles() {
return err return err
} }
if b { if b {
rd, err := NewLazyFileReader(filePath) rd, err := NewLazyFileReader(hugofs.Source(), filePath)
if err != nil { if err != nil {
return err return err
} }

View file

@ -19,14 +19,15 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"os" "github.com/spf13/afero"
) )
// LazyFileReader is an io.Reader implementation to postpone reading the file // LazyFileReader is an io.Reader implementation to postpone reading the file
// contents until it is really needed. It keeps filename and file contents once // contents until it is really needed. It keeps filename and file contents once
// it is read. // it is read.
type LazyFileReader struct { type LazyFileReader struct {
fs afero.Fs
filename string filename string
contents *bytes.Reader contents *bytes.Reader
pos int64 pos int64
@ -35,13 +36,13 @@ type LazyFileReader struct {
// NewLazyFileReader creates and initializes a new LazyFileReader of filename. // NewLazyFileReader creates and initializes a new LazyFileReader of filename.
// It checks whether the file can be opened. If it fails, it returns nil and an // It checks whether the file can be opened. If it fails, it returns nil and an
// error. // error.
func NewLazyFileReader(filename string) (*LazyFileReader, error) { func NewLazyFileReader(fs afero.Fs, filename string) (*LazyFileReader, error) {
f, err := os.Open(filename) f, err := fs.Open(filename)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer f.Close() defer f.Close()
return &LazyFileReader{filename: filename, contents: nil, pos: 0}, nil return &LazyFileReader{fs: fs, filename: filename, contents: nil, pos: 0}, nil
} }
// Filename returns a file name which LazyFileReader keeps // Filename returns a file name which LazyFileReader keeps
@ -55,7 +56,7 @@ func (l *LazyFileReader) Filename() string {
// the file. // the file.
func (l *LazyFileReader) Read(p []byte) (n int, err error) { func (l *LazyFileReader) Read(p []byte) (n int, err error) {
if l.contents == nil { if l.contents == nil {
b, err := ioutil.ReadFile(l.filename) b, err := afero.ReadFile(l.fs, l.filename)
if err != nil { if err != nil {
return 0, fmt.Errorf("failed to read content from %s: %s", l.filename, err.Error()) return 0, fmt.Errorf("failed to read content from %s: %s", l.filename, err.Error())
} }
@ -80,7 +81,7 @@ func (l *LazyFileReader) Seek(offset int64, whence int) (pos int64, err error) {
case 1: case 1:
pos = l.pos + offset pos = l.pos + offset
case 2: case 2:
fi, err := os.Stat(l.filename) fi, err := l.fs.Stat(l.filename)
if err != nil { if err != nil {
return 0, fmt.Errorf("failed to get %q info: %s", l.filename, err.Error()) return 0, fmt.Errorf("failed to get %q info: %s", l.filename, err.Error())
} }
@ -115,7 +116,7 @@ func (l *LazyFileReader) WriteTo(w io.Writer) (n int64, err error) {
l.pos += n l.pos += n
return n, err return n, err
} }
f, err := os.Open(l.filename) f, err := l.fs.Open(l.filename)
if err != nil { if err != nil {
return 0, fmt.Errorf("failed to open %s to read content: %s", l.filename, err.Error()) return 0, fmt.Errorf("failed to open %s to read content: %s", l.filename, err.Error())
} }

View file

@ -19,25 +19,29 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"testing" "testing"
"github.com/spf13/afero"
) )
func TestNewLazyFileReader(t *testing.T) { func TestNewLazyFileReader(t *testing.T) {
fs := afero.NewOsFs()
filename := "itdoesnotexistfile" filename := "itdoesnotexistfile"
_, err := NewLazyFileReader(filename) _, err := NewLazyFileReader(fs, filename)
if err == nil { if err == nil {
t.Errorf("NewLazyFileReader %s: error expected but no error is returned", filename) t.Errorf("NewLazyFileReader %s: error expected but no error is returned", filename)
} }
filename = "lazy_file_reader_test.go" filename = "lazy_file_reader_test.go"
_, err = NewLazyFileReader(filename) _, err = NewLazyFileReader(fs, filename)
if err != nil { if err != nil {
t.Errorf("NewLazyFileReader %s: %v", filename, err) t.Errorf("NewLazyFileReader %s: %v", filename, err)
} }
} }
func TestFilename(t *testing.T) { func TestFilename(t *testing.T) {
fs := afero.NewOsFs()
filename := "lazy_file_reader_test.go" filename := "lazy_file_reader_test.go"
rd, err := NewLazyFileReader(filename) rd, err := NewLazyFileReader(fs, filename)
if err != nil { if err != nil {
t.Fatalf("NewLazyFileReader %s: %v", filename, err) t.Fatalf("NewLazyFileReader %s: %v", filename, err)
} }
@ -47,18 +51,19 @@ func TestFilename(t *testing.T) {
} }
func TestRead(t *testing.T) { func TestRead(t *testing.T) {
fs := afero.NewOsFs()
filename := "lazy_file_reader_test.go" filename := "lazy_file_reader_test.go"
fi, err := os.Stat(filename) fi, err := fs.Stat(filename)
if err != nil { if err != nil {
t.Fatalf("os.Stat: %v", err) t.Fatalf("os.Stat: %v", err)
} }
b, err := ioutil.ReadFile(filename) b, err := afero.ReadFile(fs, filename)
if err != nil { if err != nil {
t.Fatalf("ioutil.ReadFile: %v", err) t.Fatalf("ioutil.ReadFile: %v", err)
} }
rd, err := NewLazyFileReader(filename) rd, err := NewLazyFileReader(fs, filename)
if err != nil { if err != nil {
t.Fatalf("NewLazyFileReader %s: %v", filename, err) t.Fatalf("NewLazyFileReader %s: %v", filename, err)
} }
@ -92,9 +97,9 @@ func TestSeek(t *testing.T) {
moveto int64 moveto int64
expected []byte expected []byte
} }
fs := afero.NewOsFs()
filename := "lazy_file_reader_test.go" filename := "lazy_file_reader_test.go"
b, err := ioutil.ReadFile(filename) b, err := afero.ReadFile(fs, filename)
if err != nil { if err != nil {
t.Fatalf("ioutil.ReadFile: %v", err) t.Fatalf("ioutil.ReadFile: %v", err)
} }
@ -108,7 +113,7 @@ func TestSeek(t *testing.T) {
{seek: 3, expected: nil}, {seek: 3, expected: nil},
{seek: os.SEEK_SET, offset: -1, expected: nil}, {seek: os.SEEK_SET, offset: -1, expected: nil},
} { } {
rd, err := NewLazyFileReader(filename) rd, err := NewLazyFileReader(fs, filename)
if err != nil { if err != nil {
t.Errorf("[%d] NewLazyFileReader %s: %v", i, filename, err) t.Errorf("[%d] NewLazyFileReader %s: %v", i, filename, err)
continue continue
@ -140,7 +145,7 @@ func TestSeek(t *testing.T) {
} }
// cache case // cache case
rd, err := NewLazyFileReader(filename) rd, err := NewLazyFileReader(fs, filename)
if err != nil { if err != nil {
t.Fatalf("NewLazyFileReader %s: %v", filename, err) t.Fatalf("NewLazyFileReader %s: %v", filename, err)
} }
@ -185,6 +190,7 @@ func TestSeek(t *testing.T) {
} }
func TestWriteTo(t *testing.T) { func TestWriteTo(t *testing.T) {
fs := afero.NewOsFs()
filename := "lazy_file_reader_test.go" filename := "lazy_file_reader_test.go"
fi, err := os.Stat(filename) fi, err := os.Stat(filename)
if err != nil { if err != nil {
@ -196,7 +202,7 @@ func TestWriteTo(t *testing.T) {
t.Fatalf("ioutil.ReadFile: %v", err) t.Fatalf("ioutil.ReadFile: %v", err)
} }
rd, err := NewLazyFileReader(filename) rd, err := NewLazyFileReader(fs, filename)
if err != nil { if err != nil {
t.Fatalf("NewLazyFileReader %s: %v", filename, err) t.Fatalf("NewLazyFileReader %s: %v", filename, err)
} }