summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-01-10 10:55:03 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-02-04 11:37:25 +0700
commitc71e1b106e6011d148cac899f83c4685dee33a22 (patch)
treec5c7090f0c2398c7771e4908ebcc97aa7714ffd2
parent0ada40591216572b0e4c6a8ab986b0aa4fb13c13 (diff)
all: Refactor to nonglobal file systems
Updates #2701 Fixes #2951
-rw-r--r--commands/benchmark.go5
-rw-r--r--commands/gendoc.go4
-rw-r--r--commands/genman.go4
-rw-r--r--commands/hugo.go135
-rw-r--r--commands/import_jekyll.go25
-rw-r--r--commands/new.go71
-rw-r--r--commands/new_test.go82
-rw-r--r--commands/server.go19
-rw-r--r--commands/undraft.go9
-rw-r--r--create/content.go10
-rw-r--r--create/content_test.go33
-rw-r--r--deps/deps.go115
-rw-r--r--helpers/configProvider.go14
-rw-r--r--helpers/path.go26
-rw-r--r--helpers/path_test.go8
-rw-r--r--helpers/pathspec.go28
-rw-r--r--helpers/pathspec_test.go22
-rw-r--r--helpers/pygments.go2
-rw-r--r--helpers/url_test.go12
-rw-r--r--hugofs/fs.go84
-rw-r--r--hugofs/fs_test.go60
-rw-r--r--hugolib/alias_test.go40
-rw-r--r--hugolib/case_insensitive_test.go67
-rw-r--r--hugolib/config_test.go6
-rw-r--r--hugolib/datafiles_test.go34
-rw-r--r--hugolib/embedded_shortcodes_test.go20
-rw-r--r--hugolib/gitinfo.go5
-rw-r--r--hugolib/handler_page.go1
-rw-r--r--hugolib/handler_test.go46
-rw-r--r--hugolib/hugo_sites.go230
-rw-r--r--hugolib/hugo_sites_build.go2
-rw-r--r--hugolib/hugo_sites_build_test.go268
-rw-r--r--hugolib/i18n.go5
-rw-r--r--hugolib/menu_test.go24
-rw-r--r--hugolib/node_as_page_test.go341
-rw-r--r--hugolib/page.go62
-rw-r--r--hugolib/page_permalink_test.go3
-rw-r--r--hugolib/page_test.go76
-rw-r--r--hugolib/pagination.go11
-rw-r--r--hugolib/pagination_test.go73
-rw-r--r--hugolib/permalinks.go6
-rw-r--r--hugolib/robotstxt_test.go28
-rw-r--r--hugolib/rss_test.go18
-rw-r--r--hugolib/shortcode.go19
-rw-r--r--hugolib/shortcode_test.go113
-rw-r--r--hugolib/site.go288
-rw-r--r--hugolib/siteJSONEncode_test.go15
-rw-r--r--hugolib/site_render.go12
-rw-r--r--hugolib/site_test.go296
-rw-r--r--hugolib/site_url_test.go28
-rw-r--r--hugolib/sitemap_test.go28
-rw-r--r--hugolib/taxonomy.go19
-rw-r--r--hugolib/taxonomy_test.go13
-rw-r--r--hugolib/template_engines_test.go99
-rw-r--r--hugolib/template_test.go68
-rw-r--r--hugolib/testhelpers_test.go53
-rw-r--r--source/filesystem.go15
-rw-r--r--source/filesystem_test.go15
-rw-r--r--target/file.go4
-rw-r--r--target/htmlredirect.go4
-rw-r--r--target/page.go4
-rw-r--r--target/page_test.go6
-rw-r--r--tpl/amber_compiler.go42
-rw-r--r--tpl/template.go170
-rw-r--r--tpl/template_funcs.go92
-rw-r--r--tpl/template_funcs_test.go189
-rw-r--r--tpl/template_i18n.go1
-rw-r--r--tpl/template_resources.go19
-rw-r--r--tpl/template_resources_test.go32
-rw-r--r--tpl/template_test.go110
-rw-r--r--tplapi/template.go28
71 files changed, 2202 insertions, 1714 deletions
diff --git a/commands/benchmark.go b/commands/benchmark.go
index a879e8941..42966c67a 100644
--- a/commands/benchmark.go
+++ b/commands/benchmark.go
@@ -49,10 +49,13 @@ func init() {
func benchmark(cmd *cobra.Command, args []string) error {
cfg, err := InitializeConfig(benchmarkCmd)
+
if err != nil {
return err
}
+ c := commandeer{cfg}
+
var memProf *os.File
if memProfileFile != "" {
memProf, err = os.Create(memProfileFile)
@@ -79,7 +82,7 @@ func benchmark(cmd *cobra.Command, args []string) error {
t := time.Now()
for i := 0; i < benchmarkTimes; i++ {
- if err = resetAndBuildSites(cfg, false); err != nil {
+ if err = c.resetAndBuildSites(false); err != nil {
return err
}
}
diff --git a/commands/gendoc.go b/commands/gendoc.go
index 046d3839c..5ffd084e1 100644
--- a/commands/gendoc.go
+++ b/commands/gendoc.go
@@ -51,9 +51,9 @@ for rendering in Hugo.`,
if !strings.HasSuffix(gendocdir, helpers.FilePathSeparator) {
gendocdir += helpers.FilePathSeparator
}
- if found, _ := helpers.Exists(gendocdir, hugofs.Os()); !found {
+ if found, _ := helpers.Exists(gendocdir, hugofs.Os); !found {
jww.FEEDBACK.Println("Directory", gendocdir, "does not exist, creating...")
- hugofs.Os().MkdirAll(gendocdir, 0777)
+ hugofs.Os.MkdirAll(gendocdir, 0777)
}
now := time.Now().Format(time.RFC3339)
prepender := func(filename string) string {
diff --git a/commands/genman.go b/commands/genman.go
index d1f54ae31..f7a3a424d 100644
--- a/commands/genman.go
+++ b/commands/genman.go
@@ -41,9 +41,9 @@ in the "man" directory under the current directory.`,
if !strings.HasSuffix(genmandir, helpers.FilePathSeparator) {
genmandir += helpers.FilePathSeparator
}
- if found, _ := helpers.Exists(genmandir, hugofs.Os()); !found {
+ if found, _ := helpers.Exists(genmandir, hugofs.Os); !found {
jww.FEEDBACK.Println("Directory", genmandir, "does not exist, creating...")
- hugofs.Os().MkdirAll(genmandir, 0777)
+ hugofs.Os.MkdirAll(genmandir, 0777)
}
cmd.Root().DisableAutoGenTag = true
diff --git a/commands/hugo.go b/commands/hugo.go
index f4204cad1..566e68603 100644
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -40,6 +40,7 @@ import (
"github.com/spf13/afero"
"github.com/spf13/cobra"
"github.com/spf13/fsync"
+ "github.com/spf13/hugo/deps"
"github.com/spf13/hugo/helpers"
"github.com/spf13/hugo/hugolib"
"github.com/spf13/hugo/livereload"
@@ -50,6 +51,10 @@ import (
"github.com/spf13/viper"
)
+type commandeer struct {
+ deps.DepsCfg
+}
+
// Hugo represents the Hugo sites to build. This variable is exported as it
// is used by at least one external library (the Hugo caddy plugin). We should
// provide a cleaner external API, but until then, this is it.
@@ -119,12 +124,14 @@ Complete documentation is available at http://gohugo.io/.`,
return err
}
+ c := commandeer{cfg}
+
if buildWatch {
viper.Set("disableLiveReload", true)
- watchConfig(cfg)
+ c.watchConfig()
}
- return build(cfg)
+ return c.build()
},
}
@@ -268,9 +275,9 @@ func init() {
}
// InitializeConfig initializes a config file with sensible default configuration flags.
-func InitializeConfig(subCmdVs ...*cobra.Command) (hugolib.DepsCfg, error) {
+func InitializeConfig(subCmdVs ...*cobra.Command) (deps.DepsCfg, error) {
- var cfg hugolib.DepsCfg
+ var cfg deps.DepsCfg
if err := hugolib.LoadGlobalConfig(source, cfgFile); err != nil {
return cfg, err
@@ -323,34 +330,34 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (hugolib.DepsCfg, error) {
viper.Set("cacheDir", cacheDir)
}
+ // Init file systems. This may be changed at a later point.
+ cfg.Fs = hugofs.NewDefault()
+
cacheDir = viper.GetString("cacheDir")
if cacheDir != "" {
if helpers.FilePathSeparator != cacheDir[len(cacheDir)-1:] {
cacheDir = cacheDir + helpers.FilePathSeparator
}
- isDir, err := helpers.DirExists(cacheDir, hugofs.Source())
+ isDir, err := helpers.DirExists(cacheDir, cfg.Fs.Source)
utils.CheckErr(err)
if !isDir {
mkdir(cacheDir)
}
viper.Set("cacheDir", cacheDir)
} else {
- viper.Set("cacheDir", helpers.GetTempDir("hugo_cache", hugofs.Source()))
+ viper.Set("cacheDir", helpers.GetTempDir("hugo_cache", cfg.Fs.Source))
}
jww.INFO.Println("Using config file:", viper.ConfigFileUsed())
- // Init file systems. This may be changed at a later point.
- hugofs.InitDefaultFs()
-
themeDir := helpers.GetThemeDir()
if themeDir != "" {
- if _, err := hugofs.Source().Stat(themeDir); os.IsNotExist(err) {
+ if _, err := cfg.Fs.Source.Stat(themeDir); os.IsNotExist(err) {
return cfg, newSystemError("Unable to find theme Directory:", themeDir)
}
}
- themeVersionMismatch, minVersion := isThemeVsHugoVersionMismatch()
+ themeVersionMismatch, minVersion := isThemeVsHugoVersionMismatch(cfg.Fs.Source)
if themeVersionMismatch {
jww.ERROR.Printf("Current theme does not support Hugo version %s. Minimum version required is %s\n",
@@ -447,12 +454,12 @@ func flagChanged(flags *flag.FlagSet, key string) bool {
return flag.Changed
}
-func watchConfig(cfg hugolib.DepsCfg) {
+func (c commandeer) watchConfig() {
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
jww.FEEDBACK.Println("Config file changed:", e.Name)
// Force a full rebuild
- utils.CheckErr(recreateAndBuildSites(cfg, true))
+ utils.CheckErr(c.recreateAndBuildSites(true))
if !viper.GetBool("disableLiveReload") {
// Will block forever trying to write to a channel that nobody is reading if livereload isn't initialized
livereload.ForceRefresh()
@@ -460,39 +467,40 @@ func watchConfig(cfg hugolib.DepsCfg) {
})
}
-func build(cfg hugolib.DepsCfg, watches ...bool) error {
+func (c commandeer) build(watches ...bool) error {
// Hugo writes the output to memory instead of the disk.
// This is only used for benchmark testing. Cause the content is only visible
// in memory.
if renderToMemory {
- hugofs.SetDestination(new(afero.MemMapFs))
+ c.Fs.Destination = new(afero.MemMapFs)
// Rendering to memoryFS, publish to Root regardless of publishDir.
viper.Set("publishDir", "/")
}
- if err := copyStatic(); err != nil {
+ if err := c.copyStatic(); err != nil {
return fmt.Errorf("Error copying static files to %s: %s", helpers.AbsPathify(viper.GetString("publishDir")), err)
}
watch := false
if len(watches) > 0 && watches[0] {
watch = true
}
- if err := buildSites(cfg, buildWatch || watch); err != nil {
+ if err := c.buildSites(buildWatch || watch); err != nil {
return fmt.Errorf("Error building site: %s", err)
}
if buildWatch {
jww.FEEDBACK.Println("Watching for changes in", helpers.AbsPathify(viper.GetString("contentDir")))
jww.FEEDBACK.Println("Press Ctrl+C to stop")
- utils.CheckErr(newWatcher(cfg, 0))
+ utils.CheckErr(c.newWatcher(0))
}
return nil
}
-func getStaticSourceFs() afero.Fs {
- source := hugofs.Source()
- themeDir, err := helpers.GetThemeStaticDirPath()
+func (c commandeer) getStaticSourceFs() afero.Fs {
+ source := c.Fs.Source
+ pathSpec := helpers.NewPathSpec(c.Fs, viper.GetViper())
+ themeDir, err := pathSpec.GetThemeStaticDirPath()
staticDir := helpers.GetStaticDirPath() + helpers.FilePathSeparator
useTheme := true
@@ -532,12 +540,12 @@ func getStaticSourceFs() afero.Fs {
jww.INFO.Println("using a UnionFS for static directory comprised of:")
jww.INFO.Println("Base:", themeDir)
jww.INFO.Println("Overlay:", staticDir)
- base := afero.NewReadOnlyFs(afero.NewBasePathFs(hugofs.Source(), themeDir))
- overlay := afero.NewReadOnlyFs(afero.NewBasePathFs(hugofs.Source(), staticDir))
+ base := afero.NewReadOnlyFs(afero.NewBasePathFs(source, themeDir))
+ overlay := afero.NewReadOnlyFs(afero.NewBasePathFs(source, staticDir))
return afero.NewCopyOnWriteFs(base, overlay)
}
-func copyStatic() error {
+func (c commandeer) copyStatic() error {
publishDir := helpers.AbsPathify(viper.GetString("publishDir")) + helpers.FilePathSeparator
// If root, remove the second '/'
@@ -546,7 +554,7 @@ func copyStatic() error {
}
// Includes both theme/static & /static
- staticSourceFs := getStaticSourceFs()
+ staticSourceFs := c.getStaticSourceFs()
if staticSourceFs == nil {
jww.WARN.Println("No static directories found to sync")
@@ -557,7 +565,7 @@ func copyStatic() error {
syncer.NoTimes = viper.GetBool("noTimes")
syncer.NoChmod = viper.GetBool("noChmod")
syncer.SrcFs = staticSourceFs
- syncer.DestFs = hugofs.Destination()
+ syncer.DestFs = c.Fs.Destination
// Now that we are using a unionFs for the static directories
// We can effectively clean the publishDir on initial sync
syncer.Delete = viper.GetBool("cleanDestinationDir")
@@ -572,7 +580,7 @@ func copyStatic() error {
}
// getDirList provides NewWatcher() with a list of directories to watch for changes.
-func getDirList() []string {
+func (c commandeer) getDirList() []string {
var a []string
dataDir := helpers.AbsPathify(viper.GetString("dataDir"))
i18nDir := helpers.AbsPathify(viper.GetString("i18nDir"))
@@ -621,7 +629,7 @@ func getDirList() []string {
jww.ERROR.Printf("Cannot read symbolic link '%s', error was: %s", path, err)
return nil
}
- linkfi, err := hugofs.Source().Stat(link)
+ linkfi, err := c.Fs.Source.Stat(link)
if err != nil {
jww.ERROR.Printf("Cannot stat '%s', error was: %s", link, err)
return nil
@@ -642,25 +650,25 @@ func getDirList() []string {
return nil
}
- helpers.SymbolicWalk(hugofs.Source(), dataDir, walker)
- helpers.SymbolicWalk(hugofs.Source(), helpers.AbsPathify(viper.GetString("contentDir")), walker)
- helpers.SymbolicWalk(hugofs.Source(), i18nDir, walker)
- helpers.SymbolicWalk(hugofs.Source(), helpers.AbsPathify(viper.GetString("layoutDir")), walker)
+ helpers.SymbolicWalk(c.Fs.Source, dataDir, walker)
+ helpers.SymbolicWalk(c.Fs.Source, helpers.AbsPathify(viper.GetString("contentDir")), walker)
+ helpers.SymbolicWalk(c.Fs.Source, i18nDir, walker)
+ helpers.SymbolicWalk(c.Fs.Source, helpers.AbsPathify(viper.GetString("layoutDir")), walker)
- helpers.SymbolicWalk(hugofs.Source(), staticDir, walker)
+ helpers.SymbolicWalk(c.Fs.Source, staticDir, walker)
if helpers.ThemeSet() {
- helpers.SymbolicWalk(hugofs.Source(), filepath.Join(themesDir, "layouts"), walker)
- helpers.SymbolicWalk(hugofs.Source(), filepath.Join(themesDir, "static"), walker)
- helpers.SymbolicWalk(hugofs.Source(), filepath.Join(themesDir, "i18n"), walker)
- helpers.SymbolicWalk(hugofs.Source(), filepath.Join(themesDir, "data"), walker)
+ helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "layouts"), walker)
+ helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "static"), walker)
+ helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "i18n"), walker)
+ helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "data"), walker)
}
return a
}
-func recreateAndBuildSites(cfg hugolib.DepsCfg, watching bool) (err error) {
- if err := initSites(cfg); err != nil {
+func (c commandeer) recreateAndBuildSites(watching bool) (err error) {
+ if err := c.initSites(); err != nil {
return err
}
if !quiet {
@@ -669,9 +677,9 @@ func recreateAndBuildSites(cfg hugolib.DepsCfg, watching bool) (err error) {
return Hugo.Build(hugolib.BuildCfg{CreateSitesFromConfig: true, Watching: watching, PrintStats: !quiet})
}
-func resetAndBuildSites(cfg hugolib.DepsCfg, watching bool) (err error) {
- if err := initSites(cfg); err != nil {
- return err
+func (c commandeer) resetAndBuildSites(watching bool) (err error) {
+ if err = c.initSites(); err != nil {
+ return
}
if !quiet {
jww.FEEDBACK.Println("Started building sites ...")
@@ -679,12 +687,12 @@ func resetAndBuildSites(cfg hugolib.DepsCfg, watching bool) (err error) {
return Hugo.Build(hugolib.BuildCfg{ResetState: true, Watching: watching, PrintStats: !quiet})
}
-func initSites(cfg hugolib.DepsCfg) error {
+func (c commandeer) initSites() error {
if Hugo != nil {
return nil
}
- h, err := hugolib.NewHugoSitesFromConfiguration(cfg)
+ h, err := hugolib.NewHugoSitesFromConfiguration(c.DepsCfg)
if err != nil {
return err
@@ -694,8 +702,8 @@ func initSites(cfg hugolib.DepsCfg) error {
return nil
}
-func buildSites(cfg hugolib.DepsCfg, watching bool) (err error) {
- if err := initSites(cfg); err != nil {
+func (c commandeer) buildSites(w