all: Refactor to nonglobal file systems

Updates #2701
Fixes #2951
This commit is contained in:
Bjørn Erik Pedersen
2017-01-10 10:55:03 +01:00
parent 0ada405912
commit c71e1b106e
71 changed files with 2219 additions and 1731 deletions

View File

@@ -29,7 +29,6 @@ import (
// TODO(bep) Get rid of these.
var (
currentConfigProvider ConfigProvider
currentPathSpec *PathSpec
)
// ConfigProvider provides the configuration settings for Hugo.
@@ -52,24 +51,13 @@ func Config() ConfigProvider {
return viper.Get("currentContentLanguage").(ConfigProvider)
}
// CurrentPathSpec returns the current PathSpec.
// If it is not set, a new will be created based in the currently active Hugo config.
func CurrentPathSpec() *PathSpec {
if currentPathSpec != nil {
return currentPathSpec
}
// Some tests rely on this. We will fix that, eventually.
return NewPathSpecFromConfig(Config())
}
// InitConfigProviderForCurrentContentLanguage does what it says.
func InitConfigProviderForCurrentContentLanguage() {
currentConfigProvider = viper.Get("CurrentContentLanguage").(ConfigProvider)
currentPathSpec = NewPathSpecFromConfig(currentConfigProvider)
}
// ResetConfigProvider is used in tests.
func ResetConfigProvider() {
currentConfigProvider = nil
currentPathSpec = nil
}

View File

@@ -23,8 +23,6 @@ import (
"strings"
"unicode"
"github.com/spf13/hugo/hugofs"
"github.com/spf13/afero"
"github.com/spf13/viper"
"golang.org/x/text/transform"
@@ -196,29 +194,29 @@ func GetRelativeThemeDir() string {
// GetThemeStaticDirPath returns the theme's static dir path if theme is set.
// If theme is set and the static dir doesn't exist, an error is returned.
func GetThemeStaticDirPath() (string, error) {
return getThemeDirPath("static")
func (p *PathSpec) GetThemeStaticDirPath() (string, error) {
return p.getThemeDirPath("static")
}
// GetThemeDataDirPath returns the theme's data dir path if theme is set.
// If theme is set and the data dir doesn't exist, an error is returned.
func GetThemeDataDirPath() (string, error) {
return getThemeDirPath("data")
func (p *PathSpec) GetThemeDataDirPath() (string, error) {
return p.getThemeDirPath("data")
}
// GetThemeI18nDirPath returns the theme's i18n dir path if theme is set.
// If theme is set and the i18n dir doesn't exist, an error is returned.
func GetThemeI18nDirPath() (string, error) {
return getThemeDirPath("i18n")
func (p *PathSpec) GetThemeI18nDirPath() (string, error) {
return p.getThemeDirPath("i18n")
}
func getThemeDirPath(path string) (string, error) {
func (p *PathSpec) getThemeDirPath(path string) (string, error) {
if !ThemeSet() {
return "", ErrThemeUndefined
}
themeDir := filepath.Join(GetThemeDir(), path)
if _, err := hugofs.Source().Stat(themeDir); os.IsNotExist(err) {
if _, err := p.fs.Source.Stat(themeDir); os.IsNotExist(err) {
return "", fmt.Errorf("Unable to find %s directory for theme %s in %s", path, viper.GetString("theme"), themeDir)
}
@@ -228,17 +226,17 @@ func getThemeDirPath(path string) (string, error) {
// GetThemesDirPath gets the static files directory of the current theme, if there is one.
// Ignores underlying errors.
// TODO(bep) Candidate for deprecation?
func GetThemesDirPath() string {
dir, _ := getThemeDirPath("static")
func (p *PathSpec) GetThemesDirPath() string {
dir, _ := p.getThemeDirPath("static")
return dir
}
// MakeStaticPathRelative makes a relative path to the static files directory.
// It does so by taking either the project's static path or the theme's static
// path into consideration.
func MakeStaticPathRelative(inPath string) (string, error) {
func (p *PathSpec) MakeStaticPathRelative(inPath string) (string, error) {
staticDir := GetStaticDirPath()
themeStaticDir := GetThemesDirPath()
themeStaticDir := p.GetThemesDirPath()
return makePathRelative(inPath, staticDir, themeStaticDir)
}

View File

@@ -30,6 +30,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/spf13/afero"
"github.com/spf13/hugo/hugofs"
"github.com/spf13/viper"
)
@@ -64,7 +65,8 @@ func TestMakePath(t *testing.T) {
for _, test := range tests {
viper.Set("removePathAccents", test.removeAccents)
p := NewPathSpecFromConfig(viper.GetViper())
p := NewPathSpec(hugofs.NewMem(), viper.GetViper())
output := p.MakePath(test.input)
if output != test.expected {
t.Errorf("Expected %#v, got %#v\n", test.expected, output)
@@ -77,7 +79,7 @@ func TestMakePathSanitized(t *testing.T) {
defer viper.Reset()
initCommonTestConfig()
p := NewPathSpecFromConfig(viper.GetViper())
p := NewPathSpec(hugofs.NewMem(), viper.GetViper())
tests := []struct {
input string
@@ -105,7 +107,7 @@ func TestMakePathSanitizedDisablePathToLower(t *testing.T) {
initCommonTestConfig()
viper.Set("disablePathToLower", true)
p := NewPathSpecFromConfig(viper.GetViper())
p := NewPathSpec(hugofs.NewMem(), viper.GetViper())
tests := []struct {
input string

View File

@@ -13,6 +13,12 @@
package helpers
import (
"fmt"
"github.com/spf13/hugo/hugofs"
)
// PathSpec holds methods that decides how paths in URLs and files in Hugo should look like.
type PathSpec struct {
disablePathToLower bool
@@ -33,11 +39,27 @@ type PathSpec struct {
defaultContentLanguageInSubdir bool
defaultContentLanguage string
multilingual bool
// The file systems to use
fs *hugofs.Fs
}
// NewPathSpecFromConfig creats a new PathSpec from the given ConfigProvider.
func NewPathSpecFromConfig(config ConfigProvider) *PathSpec {
func (p PathSpec) String() string {
return fmt.Sprintf("PathSpec, language %q, prefix %q, multilingual: %T", p.currentContentLanguage.Lang, p.getLanguagePrefix(), p.multilingual)
}
// NewPathSpec creats a new PathSpec from the given filesystems and ConfigProvider.
func NewPathSpec(fs *hugofs.Fs, config ConfigProvider) *PathSpec {
currCl, ok := config.Get("currentContentLanguage").(*Language)
if !ok {
// TODO(bep) globals
currCl = NewLanguage("en")
}
return &PathSpec{
fs: fs,
disablePathToLower: config.GetBool("disablePathToLower"),
removePathAccents: config.GetBool("removePathAccents"),
uglyURLs: config.GetBool("uglyURLs"),
@@ -45,7 +67,7 @@ func NewPathSpecFromConfig(config ConfigProvider) *PathSpec {
multilingual: config.GetBool("multilingual"),
defaultContentLanguageInSubdir: config.GetBool("defaultContentLanguageInSubdir"),
defaultContentLanguage: config.GetString("defaultContentLanguage"),
currentContentLanguage: config.Get("currentContentLanguage").(*Language),
currentContentLanguage: currCl,
paginatePath: config.GetString("paginatePath"),
}
}

View File

@@ -16,6 +16,8 @@ package helpers
import (
"testing"
"github.com/spf13/hugo/hugofs"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)
@@ -31,15 +33,15 @@ func TestNewPathSpecFromConfig(t *testing.T) {
viper.Set("canonifyURLs", true)
viper.Set("paginatePath", "side")
pathSpec := NewPathSpecFromConfig(viper.GetViper())
p := NewPathSpec(hugofs.NewMem(), viper.GetViper())
require.True(t, pathSpec.canonifyURLs)
require.True(t, pathSpec.defaultContentLanguageInSubdir)
require.True(t, pathSpec.disablePathToLower)
require.True(t, pathSpec.multilingual)
require.True(t, pathSpec.removePathAccents)
require.True(t, pathSpec.uglyURLs)
require.Equal(t, "no", pathSpec.defaultContentLanguage)
require.Equal(t, "no", pathSpec.currentContentLanguage.Lang)
require.Equal(t, "side", pathSpec.paginatePath)
require.True(t, p.canonifyURLs)
require.True(t, p.defaultContentLanguageInSubdir)
require.True(t, p.disablePathToLower)
require.True(t, p.multilingual)
require.True(t, p.removePathAccents)
require.True(t, p.uglyURLs)
require.Equal(t, "no", p.defaultContentLanguage)
require.Equal(t, "no", p.currentContentLanguage.Lang)
require.Equal(t, "side", p.paginatePath)
}

View File

@@ -60,7 +60,7 @@ func Highlight(code, lang, optsStr string) string {
io.WriteString(hash, lang)
io.WriteString(hash, options)
fs := hugofs.Os()
fs := hugofs.Os
ignoreCache := viper.GetBool("ignoreCache")
cacheDir := viper.GetString("cacheDir")

View File

@@ -18,6 +18,7 @@ import (
"strings"
"testing"
"github.com/spf13/hugo/hugofs"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -26,7 +27,7 @@ import (
func TestURLize(t *testing.T) {
initCommonTestConfig()
p := NewPathSpecFromConfig(viper.GetViper())
p := NewPathSpec(hugofs.NewMem(), viper.GetViper())
tests := []struct {
input string
@@ -85,9 +86,11 @@ func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
{"http//foo", "http://base/path", "http://base/path/MULTIhttp/foo"},
}
p := NewPathSpec(hugofs.NewMem(), viper.GetViper())
for _, test := range tests {
viper.Set("baseURL", test.baseURL)
p := NewPathSpecFromConfig(viper.GetViper())
output := p.AbsURL(test.input, addLanguage)
expected := test.expected
if multilingual && addLanguage {
@@ -164,7 +167,7 @@ func doTestRelURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
for i, test := range tests {
viper.Set("baseURL", test.baseURL)
viper.Set("canonifyURLs", test.canonify)
p := NewPathSpecFromConfig(viper.GetViper())
p := NewPathSpec(hugofs.NewMem(), viper.GetViper())
output := p.RelURL(test.input, addLanguage)
@@ -247,9 +250,10 @@ func TestURLPrep(t *testing.T) {
{false, "/section/name.html", "/section/name/"},
{true, "/section/name/index.html", "/section/name.html"},
}
for i, d := range data {
viper.Set("uglyURLs", d.ugly)
p := NewPathSpecFromConfig(viper.GetViper())
p := NewPathSpec(hugofs.NewMem(), viper.GetViper())
output := p.URLPrep(d.input)
if d.output != output {