From 141f3e19e0a9ba873b0cece6071b1187daa81d8d Mon Sep 17 00:00:00 2001 From: spf13 Date: Sat, 1 Nov 2014 11:57:29 -0400 Subject: [PATCH] Migrating Hugo to Afero for filesystem calls. --- commands/hugo.go | 11 ++++++++--- commands/new.go | 17 +++++++++-------- commands/server.go | 5 ++++- create/content.go | 3 ++- helpers/path.go | 39 +++++++++++++++++++++------------------ hugofs/fs.go | 21 +++++++++++++++++++++ hugolib/page.go | 5 +++-- hugolib/site.go | 3 ++- target/file.go | 3 ++- target/htmlredirect.go | 3 ++- 10 files changed, 74 insertions(+), 36 deletions(-) create mode 100644 hugofs/fs.go diff --git a/commands/hugo.go b/commands/hugo.go index e3d8efa0f..810a71444 100644 --- a/commands/hugo.go +++ b/commands/hugo.go @@ -23,9 +23,10 @@ import ( "sync" "time" - "github.com/mostafah/fsync" "github.com/spf13/cobra" + "github.com/spf13/fsync" "github.com/spf13/hugo/helpers" + "github.com/spf13/hugo/hugofs" "github.com/spf13/hugo/hugolib" "github.com/spf13/hugo/livereload" "github.com/spf13/hugo/utils" @@ -223,6 +224,10 @@ func copyStatic() error { publishDir := helpers.AbsPathify(viper.GetString("PublishDir")) + "/" + syncer := fsync.NewSyncer() + syncer.SrcFs = hugofs.SourceFs + syncer.DestFs = hugofs.DestinationFS + if themeSet() { themeDir := helpers.AbsPathify("themes/"+viper.GetString("theme")) + "/static/" if _, err := os.Stat(themeDir); os.IsNotExist(err) { @@ -232,12 +237,12 @@ func copyStatic() error { // Copy Static to Destination jww.INFO.Println("syncing from", themeDir, "to", publishDir) - utils.CheckErr(fsync.Sync(publishDir, themeDir), fmt.Sprintf("Error copying static files of theme to %s", publishDir)) + utils.CheckErr(syncer.Sync(publishDir, themeDir), fmt.Sprintf("Error copying static files of theme to %s", publishDir)) } // Copy Static to Destination jww.INFO.Println("syncing from", staticDir, "to", publishDir) - return fsync.Sync(publishDir, staticDir) + return syncer.Sync(publishDir, staticDir) } func getDirList() []string { diff --git a/commands/new.go b/commands/new.go index b9ab8ac4f..4fc566b4f 100644 --- a/commands/new.go +++ b/commands/new.go @@ -21,6 +21,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/hugo/create" "github.com/spf13/hugo/helpers" + "github.com/spf13/hugo/hugofs" "github.com/spf13/hugo/parser" jww "github.com/spf13/jwalterweatherman" "github.com/spf13/viper" @@ -115,9 +116,9 @@ func NewSite(cmd *cobra.Command, args []string) { jww.FATAL.Fatalln(err) } - if x, _ := helpers.Exists(createpath); x { - y, _ := helpers.IsDir(createpath) - if z, _ := helpers.IsEmpty(createpath); y && z { + if x, _ := helpers.Exists(createpath, hugofs.SourceFs); x { + y, _ := helpers.IsDir(createpath, hugofs.SourceFs) + if z, _ := helpers.IsEmpty(createpath, hugofs.SourceFs); y && z { jww.INFO.Println(createpath, "already exists and is empty") } else { jww.FATAL.Fatalln(createpath, "already exists and is not empty") @@ -143,7 +144,7 @@ func NewTheme(cmd *cobra.Command, args []string) { createpath := helpers.AbsPathify(path.Join("themes", args[0])) jww.INFO.Println("creating theme at", createpath) - if x, _ := helpers.Exists(createpath); x { + if x, _ := helpers.Exists(createpath, hugofs.SourceFs); x { jww.FATAL.Fatalln(createpath, "already exists") } @@ -185,7 +186,7 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. `) - err := helpers.WriteToDisk(path.Join(createpath, "LICENSE.md"), bytes.NewReader(by)) + err := helpers.WriteToDisk(path.Join(createpath, "LICENSE.md"), bytes.NewReader(by), hugofs.SourceFs) if err != nil { jww.FATAL.Fatalln(err) } @@ -205,7 +206,7 @@ func mkdir(x ...string) { func touchFile(x ...string) { inpath := path.Join(x...) mkdir(filepath.Dir(inpath)) - err := helpers.WriteToDisk(inpath, bytes.NewReader([]byte{})) + err := helpers.WriteToDisk(inpath, bytes.NewReader([]byte{}), hugofs.SourceFs) if err != nil { jww.FATAL.Fatalln(err) } @@ -227,7 +228,7 @@ func createThemeMD(inpath string) (err error) { return err } - err = helpers.WriteToDisk(path.Join(inpath, "theme.toml"), bytes.NewReader(by)) + err = helpers.WriteToDisk(path.Join(inpath, "theme.toml"), bytes.NewReader(by), hugofs.SourceFs) if err != nil { return } @@ -244,7 +245,7 @@ func createConfig(inpath string, kind string) (err error) { return err } - err = helpers.WriteToDisk(path.Join(inpath, "config."+kind), bytes.NewReader(by)) + err = helpers.WriteToDisk(path.Join(inpath, "config."+kind), bytes.NewReader(by), hugofs.SourceFs) if err != nil { return } diff --git a/commands/server.go b/commands/server.go index 4d2a7335d..6b62dca70 100644 --- a/commands/server.go +++ b/commands/server.go @@ -24,8 +24,10 @@ import ( "strings" "time" + "github.com/spf13/afero" "github.com/spf13/cobra" "github.com/spf13/hugo/helpers" + "github.com/spf13/hugo/hugofs" jww "github.com/spf13/jwalterweatherman" "github.com/spf13/viper" ) @@ -111,7 +113,8 @@ func serve(port int) { jww.FEEDBACK.Printf("Web Server is available at %s\n", viper.GetString("BaseUrl")) fmt.Println("Press ctrl+c to stop") - fileserver := http.FileServer(http.Dir(helpers.AbsPathify(viper.GetString("PublishDir")))) + httpFs := &afero.HttpFs{SourceFs: hugofs.DestinationFS} + fileserver := http.FileServer(httpFs.Dir(helpers.AbsPathify(viper.GetString("PublishDir")))) u, err := url.Parse(viper.GetString("BaseUrl")) if err != nil { diff --git a/create/content.go b/create/content.go index bb0f029dc..2b185c876 100644 --- a/create/content.go +++ b/create/content.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cast" "github.com/spf13/hugo/helpers" + "github.com/spf13/hugo/hugofs" "github.com/spf13/hugo/hugolib" "github.com/spf13/hugo/parser" jww "github.com/spf13/jwalterweatherman" @@ -131,7 +132,7 @@ func FindArchetype(kind string) (outpath string) { for _, p := range pathsToCheck { curpath := path.Join(x, p) jww.DEBUG.Println("checking", curpath, "for archetypes") - if exists, _ := helpers.Exists(curpath); exists { + if exists, _ := helpers.Exists(curpath, hugofs.SourceFs); exists { jww.INFO.Println("curpath: " + curpath) return curpath } diff --git a/helpers/path.go b/helpers/path.go index ace9432ac..8230d15c9 100644 --- a/helpers/path.go +++ b/helpers/path.go @@ -24,6 +24,7 @@ import ( "strings" "unicode" + "github.com/spf13/afero" "github.com/spf13/viper" ) @@ -71,8 +72,8 @@ func ReplaceExtension(path string, newExt string) string { } // Check if Exists && is Directory -func DirExists(path string) (bool, error) { - fi, err := os.Stat(path) +func DirExists(path string, fs afero.Fs) (bool, error) { + fi, err := fs.Stat(path) if err == nil && fi.IsDir() { return true, nil } @@ -82,24 +83,24 @@ func DirExists(path string) (bool, error) { return false, err } -func IsDir(path string) (bool, error) { - fi, err := os.Stat(path) +func IsDir(path string, fs afero.Fs) (bool, error) { + fi, err := fs.Stat(path) if err != nil { return false, err } return fi.IsDir(), nil } -func IsEmpty(path string) (bool, error) { - if b, _ := Exists(path); !b { +func IsEmpty(path string, fs afero.Fs) (bool, error) { + if b, _ := Exists(path, fs); !b { return false, fmt.Errorf("%q path does not exist", path) } - fi, err := os.Stat(path) + fi, err := fs.Stat(path) if err != nil { return false, err } if fi.IsDir() { - f, err := os.Open(path) + f, err := fs.Open(path) if err != nil { return false, err } @@ -112,8 +113,8 @@ func IsEmpty(path string) (bool, error) { } // Check if File / Directory Exists -func Exists(path string) (bool, error) { - _, err := os.Stat(path) +func Exists(path string, fs afero.Fs) (bool, error) { + _, err := fs.Stat(path) if err == nil { return true, nil } @@ -267,18 +268,18 @@ func FindCWD() (string, error) { return path, nil } -func SafeWriteToDisk(inpath string, r io.Reader) (err error) { +func SafeWriteToDisk(inpath string, r io.Reader, fs afero.Fs) (err error) { dir, _ := filepath.Split(inpath) ospath := filepath.FromSlash(dir) if ospath != "" { - err = os.MkdirAll(ospath, 0777) // rwx, rw, r + err = fs.MkdirAll(ospath, 0777) // rwx, rw, r if err != nil { return } } - exists, err := Exists(inpath) + exists, err := Exists(inpath, fs) if err != nil { return } @@ -286,7 +287,7 @@ func SafeWriteToDisk(inpath string, r io.Reader) (err error) { return fmt.Errorf("%v already exists", inpath) } - file, err := os.Create(inpath) + file, err := fs.Create(inpath) if err != nil { return } @@ -296,18 +297,20 @@ func SafeWriteToDisk(inpath string, r io.Reader) (err error) { return } -func WriteToDisk(inpath string, r io.Reader) (err error) { +func WriteToDisk(inpath string, r io.Reader, fs afero.Fs) (err error) { dir, _ := filepath.Split(inpath) ospath := filepath.FromSlash(dir) if ospath != "" { - err = os.MkdirAll(ospath, 0777) // rwx, rw, r + err = fs.MkdirAll(ospath, 0777) // rwx, rw, r if err != nil { - panic(err) + if err != os.ErrExist { + panic(err) + } } } - file, err := os.Create(inpath) + file, err := fs.Create(inpath) if err != nil { return } diff --git a/hugofs/fs.go b/hugofs/fs.go new file mode 100644 index 000000000..2fe3cbf71 --- /dev/null +++ b/hugofs/fs.go @@ -0,0 +1,21 @@ +// Copyright © 2013-14 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 hugofs + +import "github.com/spf13/afero" + +var SourceFs = new(afero.OsFs) +var DestinationFS = new(afero.OsFs) + +//var DestinationFS = new(afero.MemMapFs) diff --git a/hugolib/page.go b/hugolib/page.go index 5ca1ffb52..ba9b1a6db 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/cast" "github.com/spf13/hugo/helpers" + "github.com/spf13/hugo/hugofs" "github.com/spf13/hugo/parser" "github.com/spf13/hugo/source" jww "github.com/spf13/jwalterweatherman" @@ -597,9 +598,9 @@ func (page *Page) saveSource(by []byte, inpath string, safe bool) (err error) { jww.INFO.Println("creating", inpath) if safe { - err = helpers.SafeWriteToDisk(inpath, bytes.NewReader(by)) + err = helpers.SafeWriteToDisk(inpath, bytes.NewReader(by), hugofs.SourceFs) } else { - err = helpers.WriteToDisk(inpath, bytes.NewReader(by)) + err = helpers.WriteToDisk(inpath, bytes.NewReader(by), hugofs.SourceFs) } if err != nil { return diff --git a/hugolib/site.go b/hugolib/site.go index 5a700764d..c9473930c 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -28,6 +28,7 @@ import ( "bitbucket.org/pkg/inflect" "github.com/spf13/cast" "github.com/spf13/hugo/helpers" + "github.com/spf13/hugo/hugofs" "github.com/spf13/hugo/source" "github.com/spf13/hugo/target" "github.com/spf13/hugo/transform" @@ -312,7 +313,7 @@ func (s *Site) absPublishDir() string { } func (s *Site) checkDirectories() (err error) { - if b, _ := helpers.DirExists(s.absContentDir()); !b { + if b, _ := helpers.DirExists(s.absContentDir(), hugofs.SourceFs); !b { return fmt.Errorf("No source directory found, expecting to find it at " + s.absContentDir()) } return diff --git a/target/file.go b/target/file.go index f70558098..fa4e79681 100644 --- a/target/file.go +++ b/target/file.go @@ -6,6 +6,7 @@ import ( "path" "github.com/spf13/hugo/helpers" + "github.com/spf13/hugo/hugofs" ) type Publisher interface { @@ -34,7 +35,7 @@ func (fs *Filesystem) Publish(path string, r io.Reader) (err error) { return } - return helpers.WriteToDisk(translated, r) + return helpers.WriteToDisk(translated, r, hugofs.DestinationFS) } func (fs *Filesystem) Translate(src string) (dest string, err error) { diff --git a/target/htmlredirect.go b/target/htmlredirect.go index 73a769f87..6ccfb73d3 100644 --- a/target/htmlredirect.go +++ b/target/htmlredirect.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/spf13/hugo/helpers" + "github.com/spf13/hugo/hugofs" ) const ALIAS = "" @@ -68,5 +69,5 @@ func (h *HTMLRedirectAlias) Publish(path string, permalink template.HTML) (err e return } - return helpers.WriteToDisk(path, buffer) + return helpers.WriteToDisk(path, buffer, hugofs.DestinationFS) }