Add tpl/site and tpl/hugo
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 26 Nov 2018 09:11:22 +0000 (10:11 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 6 Dec 2018 13:37:25 +0000 (14:37 +0100)
This means that the current `.Site` and ´.Hugo` is available as a globals, so you can do `site.IsServer`, `hugo.Version` etc.

Fixes #5470
Fixes #5467
Fixes #5503

39 files changed:
.gitignore
commands/commandeer.go
commands/genman.go
commands/hugo.go
commands/version.go
common/hugo/hugo.go [new file with mode: 0644]
common/hugo/hugo_test.go [new file with mode: 0644]
common/hugo/site.go [new file with mode: 0644]
common/hugo/vars_extended.go [new file with mode: 0644]
common/hugo/vars_regular.go [new file with mode: 0644]
common/hugo/version.go [new file with mode: 0644]
common/hugo/version_current.go [new file with mode: 0644]
common/hugo/version_test.go [new file with mode: 0644]
deps/deps.go
goreleaser-extended.yml
goreleaser.yml
helpers/general.go
helpers/hugo.go [deleted file]
helpers/hugo_test.go [deleted file]
htesting/test_structs.go [new file with mode: 0644]
hugolib/hugo_info.go [deleted file]
hugolib/hugo_info_test.go [deleted file]
hugolib/hugo_sites.go
hugolib/page.go
hugolib/page_test.go
hugolib/pages_language_merge_test.go
hugolib/site.go
hugolib/template_test.go
i18n/i18n_test.go
magefile.go
releaser/releaser.go
tpl/compare/compare_test.go
tpl/hugo/init.go [new file with mode: 0644]
tpl/hugo/init_test.go [new file with mode: 0644]
tpl/site/init.go [new file with mode: 0644]
tpl/site/init_test.go [new file with mode: 0644]
tpl/tplimpl/template_funcs.go
tpl/tplimpl/template_funcs_test.go
transform/metainject/hugogenerator.go

index 568492d85aaad60ea3f5248890c6bf0b41d4347e..89244f128d4f844cc426d65647a4b304094b29c5 100644 (file)
@@ -1,4 +1,4 @@
-hugo
+/hugo
 docs/public*
 /.idea
 hugo.exe
index cd2866a27cb3afaa8fbb346785b1823763685db2..b722991ab94a1df53f21c85acf8d21659285b3b1 100644 (file)
@@ -17,10 +17,11 @@ import (
        "bytes"
        "errors"
 
-       "github.com/gohugoio/hugo/common/herrors"
-
        "io/ioutil"
 
+       "github.com/gohugoio/hugo/common/herrors"
+       "github.com/gohugoio/hugo/common/hugo"
+
        jww "github.com/spf13/jwalterweatherman"
 
        "os"
@@ -105,7 +106,7 @@ func (c *commandeer) getErrorWithContext() interface{} {
        m := make(map[string]interface{})
 
        m["Error"] = errors.New(removeErrorPrefixFromLog(c.logger.Errors()))
-       m["Version"] = hugoVersionString()
+       m["Version"] = hugo.BuildVersionString()
 
        fe := herrors.UnwrapErrorWithFileContext(c.buildErr)
        if fe != nil {
@@ -379,7 +380,7 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
        if themeVersionMismatch {
                name := filepath.Base(dir)
                cfg.Logger.ERROR.Printf("%s theme does not support Hugo version %s. Minimum version required is %s\n",
-                       strings.ToUpper(name), helpers.CurrentHugoVersion.ReleaseVersion(), minVersion)
+                       strings.ToUpper(name), hugo.CurrentVersion.ReleaseVersion(), minVersion)
        }
 
        return nil
index ac4eaf8d1ee068be465ef00a4725aae0f7d97908..7200462891c1170597d8bbd26d1cb600619de71c 100644 (file)
@@ -17,6 +17,7 @@ import (
        "fmt"
        "strings"
 
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/helpers"
        "github.com/gohugoio/hugo/hugofs"
        "github.com/spf13/cobra"
@@ -45,7 +46,7 @@ in the "man" directory under the current directory.`,
                        header := &doc.GenManHeader{
                                Section: "1",
                                Manual:  "Hugo Manual",
-                               Source:  fmt.Sprintf("Hugo %s", helpers.CurrentHugoVersion),
+                               Source:  fmt.Sprintf("Hugo %s", hugo.CurrentVersion),
                        }
                        if !strings.HasSuffix(cc.genmandir, helpers.FilePathSeparator) {
                                cc.genmandir += helpers.FilePathSeparator
index 0bb15c3d19364158c47d46f66799be885bd2886f..759efc17bd0f6a53b9021698861089f7eab20854 100644 (file)
@@ -23,6 +23,7 @@ import (
        "sort"
        "sync/atomic"
 
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/pkg/errors"
 
        "github.com/gohugoio/hugo/common/herrors"
@@ -1041,7 +1042,7 @@ func (c *commandeer) isThemeVsHugoVersionMismatch(fs afero.Fs) (dir string, mism
                }
 
                if minVersion, ok := tomlMeta["min_version"]; ok {
-                       if helpers.CompareVersion(minVersion) > 0 {
+                       if hugo.CompareVersion(minVersion) > 0 {
                                return absThemeDir, true, fmt.Sprint(minVersion)
                        }
                }
index b85f53725fe7607ce160a3ea20cb2d0dd5958dce..287950a2dd74c0d9ab97aa3abec16ae298666ca8 100644 (file)
 package commands
 
 import (
-       "fmt"
-       "runtime"
-       "strings"
-
-       jww "github.com/spf13/jwalterweatherman"
-
-       "github.com/gohugoio/hugo/helpers"
-       "github.com/gohugoio/hugo/hugolib"
-       "github.com/gohugoio/hugo/resource/tocss/scss"
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/spf13/cobra"
+       jww "github.com/spf13/jwalterweatherman"
 )
 
 var _ cmder = (*versionCmd)(nil)
@@ -47,29 +40,5 @@ func newVersionCmd() *versionCmd {
 }
 
 func printHugoVersion() {
-       jww.FEEDBACK.Println(hugoVersionString())
-}
-
-func hugoVersionString() string {
-       program := "Hugo Static Site Generator"
-
-       version := "v" + helpers.CurrentHugoVersion.String()
-       if hugolib.CommitHash != "" {
-               version += "-" + strings.ToUpper(hugolib.CommitHash)
-       }
-       if scss.Supports() {
-               version += "/extended"
-       }
-
-       osArch := runtime.GOOS + "/" + runtime.GOARCH
-
-       var buildDate string
-       if hugolib.BuildDate != "" {
-               buildDate = hugolib.BuildDate
-       } else {
-               buildDate = "unknown"
-       }
-
-       return fmt.Sprintf("%s %s %s BuildDate: %s", program, version, osArch, buildDate)
-
+       jww.FEEDBACK.Println(hugo.BuildVersionString())
 }
diff --git a/common/hugo/hugo.go b/common/hugo/hugo.go
new file mode 100644 (file)
index 0000000..b93b10b
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright 2018 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 hugo
+
+import (
+       "fmt"
+       "html/template"
+)
+
+var (
+       // CommitHash contains the current Git revision. Use make to build to make
+       // sure this gets set.
+       CommitHash string
+
+       // BuildDate contains the date of the current build.
+       BuildDate string
+)
+
+// Info contains information about the current Hugo environment
+type Info struct {
+       Version    VersionString
+       Generator  template.HTML
+       CommitHash string
+       BuildDate  string
+}
+
+func NewInfo() Info {
+       return Info{
+               Version:    CurrentVersion.Version(),
+               CommitHash: CommitHash,
+               BuildDate:  BuildDate,
+               Generator:  template.HTML(fmt.Sprintf(`<meta name="generator" content="Hugo %s" />`, CurrentVersion.String())),
+       }
+}
diff --git a/common/hugo/hugo_test.go b/common/hugo/hugo_test.go
new file mode 100644 (file)
index 0000000..18a9b59
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2018 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 hugo
+
+import (
+       "fmt"
+       "testing"
+
+       "github.com/stretchr/testify/require"
+)
+
+func TestHugoInfo(t *testing.T) {
+       assert := require.New(t)
+
+       hugoInfo := NewInfo()
+
+       assert.Equal(CurrentVersion.Version(), hugoInfo.Version)
+       assert.IsType(VersionString(""), hugoInfo.Version)
+       assert.Equal(CommitHash, hugoInfo.CommitHash)
+       assert.Equal(BuildDate, hugoInfo.BuildDate)
+       assert.Contains(hugoInfo.Generator, fmt.Sprintf("Hugo %s", hugoInfo.Version))
+
+}
diff --git a/common/hugo/site.go b/common/hugo/site.go
new file mode 100644 (file)
index 0000000..0839185
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2018 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 hugo
+
+import "github.com/gohugoio/hugo/langs"
+
+// Site represents a site in the build. This is currently a very narrow interface,
+// but the actual implementation will be richer, see hugolib.SiteInfo.
+type Site interface {
+       Language() *langs.Language
+       IsServer() bool
+       Hugo() Info
+}
diff --git a/common/hugo/vars_extended.go b/common/hugo/vars_extended.go
new file mode 100644 (file)
index 0000000..20683b8
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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.
+
+// +build extended
+
+package hugo
+
+var isExtended = true
diff --git a/common/hugo/vars_regular.go b/common/hugo/vars_regular.go
new file mode 100644 (file)
index 0000000..e1ece83
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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.
+
+// +build !extended
+
+package hugo
+
+var isExtended = false
diff --git a/common/hugo/version.go b/common/hugo/version.go
new file mode 100644 (file)
index 0000000..204f8f7
--- /dev/null
@@ -0,0 +1,239 @@
+// Copyright 2018 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 hugo
+
+import (
+       "fmt"
+
+       "runtime"
+       "strings"
+
+       "github.com/gohugoio/hugo/compare"
+       "github.com/spf13/cast"
+)
+
+// Version represents the Hugo build version.
+type Version struct {
+       // Major and minor version.
+       Number float32
+
+       // Increment this for bug releases
+       PatchLevel int
+
+       // HugoVersionSuffix is the suffix used in the Hugo version string.
+       // It will be blank for release versions.
+       Suffix string
+}
+
+var (
+       _ compare.Eqer     = (*VersionString)(nil)
+       _ compare.Comparer = (*VersionString)(nil)
+)
+
+func (v Version) String() string {
+       return version(v.Number, v.PatchLevel, v.Suffix)
+}
+
+// Version returns the Hugo version.
+func (v Version) Version() VersionString {
+       return VersionString(v.String())
+}
+
+// VersionString represents a Hugo version string.
+type VersionString string
+
+func (h VersionString) String() string {
+       return string(h)
+}
+
+// Compare implements the compare.Comparer interface.
+func (h VersionString) Compare(other interface{}) int {
+       v := MustParseVersion(h.String())
+       return compareVersionsWithSuffix(v.Number, v.PatchLevel, v.Suffix, other)
+}
+
+// Eq implements the compare.Eqer interface.
+func (h VersionString) Eq(other interface{}) bool {
+       s, err := cast.ToStringE(other)
+       if err != nil {
+               return false
+       }
+       return s == h.String()
+}
+
+var versionSuffixes = []string{"-test", "-DEV"}
+
+// ParseVersion parses a version string.
+func ParseVersion(s string) (Version, error) {
+       var vv Version
+       for _, suffix := range versionSuffixes {
+               if strings.HasSuffix(s, suffix) {
+                       vv.Suffix = suffix
+                       s = strings.TrimSuffix(s, suffix)
+               }
+       }
+
+       v, p := parseVersion(s)
+
+       vv.Number = v
+       vv.PatchLevel = p
+
+       return vv, nil
+}
+
+// MustParseVersion parses a version string
+// and panics if any error occurs.
+func MustParseVersion(s string) Version {
+       vv, err := ParseVersion(s)
+       if err != nil {
+               panic(err)
+       }
+       return vv
+}
+
+// ReleaseVersion represents the release version.
+func (v Version) ReleaseVersion() Version {
+       v.Suffix = ""
+       return v
+}
+
+// Next returns the next Hugo release version.
+func (v Version) Next() Version {
+       return Version{Number: v.Number + 0.01}
+}
+
+// Prev returns the previous Hugo release version.
+func (v Version) Prev() Version {
+       return Version{Number: v.Number - 0.01}
+}
+
+// NextPatchLevel returns the next patch/bugfix Hugo version.
+// This will be a patch increment on the previous Hugo version.
+func (v Version) NextPatchLevel(level int) Version {
+       return Version{Number: v.Number - 0.01, PatchLevel: level}
+}
+
+// BuildVersionString creates a version string. This is what you see when
+// running "hugo version".
+func BuildVersionString() string {
+       program := "Hugo Static Site Generator"
+
+       version := "v" + CurrentVersion.String()
+       if CommitHash != "" {
+               version += "-" + strings.ToUpper(CommitHash)
+       }
+       if isExtended {
+               version += "/extended"
+       }
+
+       osArch := runtime.GOOS + "/" + runtime.GOARCH
+
+       var buildDate string
+       if BuildDate != "" {
+               buildDate = BuildDate
+       } else {
+               buildDate = "unknown"
+       }
+
+       return fmt.Sprintf("%s %s %s BuildDate: %s", program, version, osArch, buildDate)
+
+}
+
+func version(version float32, patchVersion int, suffix string) string {
+       if patchVersion > 0 {
+               return fmt.Sprintf("%.2f.%d%s", version, patchVersion, suffix)
+       }
+       return fmt.Sprintf("%.2f%s", version, suffix)
+}
+
+// CompareVersion compares the given version string or number against the
+// running Hugo version.
+// It returns -1 if the given version is less than, 0 if equal and 1 if greater than
+// the running version.
+func CompareVersion(version interface{}) int {
+       return compareVersionsWithSuffix(CurrentVersion.Number, CurrentVersion.PatchLevel, CurrentVersion.Suffix, version)
+}
+
+func compareVersions(inVersion float32, inPatchVersion int, in interface{}) int {
+       return compareVersionsWithSuffix(inVersion, inPatchVersion, "", in)
+}
+
+func compareVersionsWithSuffix(inVersion float32, inPatchVersion int, suffix string, in interface{}) int {
+       var c int
+       switch d := in.(type) {
+       case float64:
+               c = compareFloatVersions(inVersion, float32(d))
+       case float32:
+               c = compareFloatVersions(inVersion, d)
+       case int:
+               c = compareFloatVersions(inVersion, float32(d))
+       case int32:
+               c = compareFloatVersions(inVersion, float32(d))
+       case int64:
+               c = compareFloatVersions(inVersion, float32(d))
+       default:
+               s, err := cast.ToStringE(in)
+               if err != nil {
+                       return -1
+               }
+
+               v, err := ParseVersion(s)
+               if err != nil {
+                       return -1
+               }
+
+               if v.Number == inVersion && v.PatchLevel == inPatchVersion {
+                       return strings.Compare(suffix, v.Suffix)
+               }
+
+               if v.Number < inVersion || (v.Number == inVersion && v.PatchLevel < inPatchVersion) {
+                       return -1
+               }
+
+               return 1
+       }
+
+       if c == 0 && suffix != "" {
+               return 1
+       }
+
+       return c
+}
+
+func parseVersion(s string) (float32, int) {
+       var (
+               v float32
+               p int
+       )
+
+       if strings.Count(s, ".") == 2 {
+               li := strings.LastIndex(s, ".")
+               p = cast.ToInt(s[li+1:])
+               s = s[:li]
+       }
+
+       v = float32(cast.ToFloat64(s))
+
+       return v, p
+}
+
+func compareFloatVersions(version float32, v float32) int {
+       if v == version {
+               return 0
+       }
+       if v < version {
+               return -1
+       }
+       return 1
+}
diff --git a/common/hugo/version_current.go b/common/hugo/version_current.go
new file mode 100644 (file)
index 0000000..0a42f30
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2018 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 hugo
+
+// CurrentVersion represents the current build version.
+// This should be the only one.
+var CurrentVersion = Version{
+       Number:     0.53,
+       PatchLevel: 0,
+       Suffix:     "-DEV",
+}
diff --git a/common/hugo/version_test.go b/common/hugo/version_test.go
new file mode 100644 (file)
index 0000000..fb28750
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright 2015 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 hugo
+
+import (
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+)
+
+func TestHugoVersion(t *testing.T) {
+       assert.Equal(t, "0.15-DEV", version(0.15, 0, "-DEV"))
+       assert.Equal(t, "0.15.2-DEV", version(0.15, 2, "-DEV"))
+
+       v := Version{Number: 0.21, PatchLevel: 0, Suffix: "-DEV"}
+
+       require.Equal(t, v.ReleaseVersion().String(), "0.21")
+       require.Equal(t, "0.21-DEV", v.String())
+       require.Equal(t, "0.22", v.Next().String())
+       nextVersionString := v.Next().Version()
+       require.Equal(t, "0.22", nextVersionString.String())
+       require.True(t, nextVersionString.Eq("0.22"))
+       require.False(t, nextVersionString.Eq("0.21"))
+       require.True(t, nextVersionString.Eq(nextVersionString))
+       require.Equal(t, "0.20.3", v.NextPatchLevel(3).String())
+}
+
+func TestCompareVersions(t *testing.T) {
+       require.Equal(t, 0, compareVersions(0.20, 0, 0.20))
+       require.Equal(t, 0, compareVersions(0.20, 0, float32(0.20)))
+       require.Equal(t, 0, compareVersions(0.20, 0, float64(0.20)))
+       require.Equal(t, 1, compareVersions(0.19, 1, 0.20))
+       require.Equal(t, 1, compareVersions(0.19, 3, "0.20.2"))
+       require.Equal(t, -1, compareVersions(0.19, 1, 0.01))
+       require.Equal(t, 1, compareVersions(0, 1, 3))
+       require.Equal(t, 1, compareVersions(0, 1, int32(3)))
+       require.Equal(t, 1, compareVersions(0, 1, int64(3)))
+       require.Equal(t, 0, compareVersions(0.20, 0, "0.20"))
+       require.Equal(t, 0, compareVersions(0.20, 1, "0.20.1"))
+       require.Equal(t, -1, compareVersions(0.20, 1, "0.20"))
+       require.Equal(t, 1, compareVersions(0.20, 0, "0.20.1"))
+       require.Equal(t, 1, compareVersions(0.20, 1, "0.20.2"))
+       require.Equal(t, 1, compareVersions(0.21, 1, "0.22.1"))
+       require.Equal(t, -1, compareVersions(0.22, 0, "0.22-DEV"))
+       require.Equal(t, 1, compareVersions(0.22, 0, "0.22.1-DEV"))
+       require.Equal(t, 1, compareVersionsWithSuffix(0.22, 0, "-DEV", "0.22"))
+       require.Equal(t, -1, compareVersionsWithSuffix(0.22, 1, "-DEV", "0.22"))
+       require.Equal(t, 0, compareVersionsWithSuffix(0.22, 1, "-DEV", "0.22.1-DEV"))
+
+}
+
+func TestParseHugoVersion(t *testing.T) {
+       require.Equal(t, "0.25", MustParseVersion("0.25").String())
+       require.Equal(t, "0.25.2", MustParseVersion("0.25.2").String())
+       require.Equal(t, "0.25-test", MustParseVersion("0.25-test").String())
+       require.Equal(t, "0.25-DEV", MustParseVersion("0.25-DEV").String())
+
+}
index de6d8b52a46acd1a5f4c18bcbb2b49c2027a0f7a..46f4f77300200a8dedb8b120cfefa2ea38beb005 100644 (file)
@@ -7,6 +7,7 @@ import (
        "github.com/pkg/errors"
 
        "github.com/gohugoio/hugo/cache/filecache"
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/common/loggers"
        "github.com/gohugoio/hugo/config"
        "github.com/gohugoio/hugo/helpers"
@@ -62,8 +63,12 @@ type Deps struct {
        // The translation func to use
        Translate func(translationID string, args ...interface{}) string `json:"-"`
 
+       // The language in use. TODO(bep) consolidate with site
        Language *langs.Language
 
+       // The site building.
+       Site hugo.Site
+
        // All the output formats available for the current site.
        OutputFormatsConfig output.Formats
 
@@ -230,6 +235,7 @@ func New(cfg DepsCfg) (*Deps, error) {
                ResourceSpec:        resourceSpec,
                Cfg:                 cfg.Language,
                Language:            cfg.Language,
+               Site:                cfg.Site,
                FileCaches:          fileCaches,
                BuildStartListeners: &Listeners{},
                Timeout:             time.Duration(timeoutms) * time.Millisecond,
@@ -245,7 +251,7 @@ func New(cfg DepsCfg) (*Deps, error) {
 
 // ForLanguage creates a copy of the Deps with the language dependent
 // parts switched out.
-func (d Deps) ForLanguage(cfg DepsCfg) (*Deps, error) {
+func (d Deps) ForLanguage(cfg DepsCfg, onCreated func(d *Deps) error) (*Deps, error) {
        l := cfg.Language
        var err error
 
@@ -259,6 +265,8 @@ func (d Deps) ForLanguage(cfg DepsCfg) (*Deps, error) {
                return nil, err
        }
 
+       d.Site = cfg.Site
+
        // The resource cache is global so reuse.
        // TODO(bep) clean up these inits.
        resourceCache := d.ResourceSpec.ResourceCache
@@ -271,6 +279,12 @@ func (d Deps) ForLanguage(cfg DepsCfg) (*Deps, error) {
        d.Cfg = l
        d.Language = l
 
+       if onCreated != nil {
+               if err = onCreated(&d); err != nil {
+                       return nil, err
+               }
+       }
+
        if err := d.translationProvider.Clone(&d); err != nil {
                return nil, err
        }
@@ -299,6 +313,9 @@ type DepsCfg struct {
        // The language to use.
        Language *langs.Language
 
+       // The Site in use
+       Site hugo.Site
+
        // The configuration to use.
        Cfg config.Provider
 
index 31b52d7bae79128b87579a090b99820e0b7e6a6a..004e949539b3f436f34eaafcdb2ffd67a7cd2cc7 100644 (file)
@@ -2,7 +2,7 @@ project_name: hugo_extended
 builds:
 - binary: hugo
   ldflags:
-    - -s -w -X github.com/gohugoio/hugo/hugolib.BuildDate={{.Date}}
+    - -s -w -X github.com/gohugoio/hugo/common/hugo.BuildDate={{.Date}} -X github.com/gohugoio/hugo/common/hugo.CommitHash={{ .ShortCommit }}
     - "-extldflags '-static'"
   env:
     - CGO_ENABLED=1
index d2cdf720eb3c014408f4d99b15a951d132e48313..0e900601932d1b90207c4861dafca6b1fb99bbb4 100644 (file)
@@ -2,7 +2,7 @@ project_name: hugo
 build:
   main: main.go
   binary: hugo
-  ldflags: -s -w -X github.com/gohugoio/hugo/hugolib.BuildDate={{.Date}}
+  ldflags: -s -w -X github.com/gohugoio/hugo/common/hugo.BuildDate={{.Date}} -X github.com/gohugoio/hugo/common/hugo.CommitHash={{ .ShortCommit }}
   env:
     - CGO_ENABLED=0
   goos:
index 43a921318bb5c79e4440940185126545509634e4..cfabab5a976142155dbc3797e54bdbe02a9ff4eb 100644 (file)
@@ -27,6 +27,8 @@ import (
        "unicode"
        "unicode/utf8"
 
+       "github.com/gohugoio/hugo/common/hugo"
+
        "github.com/gohugoio/hugo/hugofs"
 
        "github.com/spf13/afero"
@@ -324,7 +326,7 @@ func InitLoggers() {
 // plenty of time to fix their templates.
 func Deprecated(object, item, alternative string, err bool) {
        if err {
-               DistinctErrorLog.Printf("%s's %s is deprecated and will be removed in Hugo %s. %s", object, item, CurrentHugoVersion.Next().ReleaseVersion(), alternative)
+               DistinctErrorLog.Printf("%s's %s is deprecated and will be removed in Hugo %s. %s", object, item, hugo.CurrentVersion.Next().ReleaseVersion(), alternative)
 
        } else {
                // Make sure the users see this while avoiding build breakage. This will not lead to an os.Exit(-1)
diff --git a/helpers/hugo.go b/helpers/hugo.go
deleted file mode 100644 (file)
index 3ad4f93..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2015 The Hugo Authors. All rights reserved.
-//
-// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 helpers
-
-import (
-       "fmt"
-       "strings"
-
-       "github.com/gohugoio/hugo/compare"
-       "github.com/spf13/cast"
-)
-
-// HugoVersion represents the Hugo build version.
-type HugoVersion struct {
-       // Major and minor version.
-       Number float32
-
-       // Increment this for bug releases
-       PatchLevel int
-
-       // HugoVersionSuffix is the suffix used in the Hugo version string.
-       // It will be blank for release versions.
-       Suffix string
-}
-
-var (
-       _ compare.Eqer     = (*HugoVersionString)(nil)
-       _ compare.Comparer = (*HugoVersionString)(nil)
-)
-
-func (v HugoVersion) String() string {
-       return hugoVersion(v.Number, v.PatchLevel, v.Suffix)
-}
-
-// Version returns the Hugo version.
-func (v HugoVersion) Version() HugoVersionString {
-       return HugoVersionString(v.String())
-}
-
-// HugoVersionString represents a Hugo version string.
-type HugoVersionString string
-
-func (h HugoVersionString) String() string {
-       return string(h)
-}
-
-// Compare implements the compare.Comparer interface.
-func (h HugoVersionString) Compare(other interface{}) int {
-       v := MustParseHugoVersion(h.String())
-       return compareVersionsWithSuffix(v.Number, v.PatchLevel, v.Suffix, other)
-}
-
-// Eq implements the compare.Eqer interface.
-func (h HugoVersionString) Eq(other interface{}) bool {
-       s, err := cast.ToStringE(other)
-       if err != nil {
-               return false
-       }
-       return s == h.String()
-}
-
-var versionSuffixes = []string{"-test", "-DEV"}
-
-// ParseHugoVersion parses a version string.
-func ParseHugoVersion(s string) (HugoVersion, error) {
-       var vv HugoVersion
-       for _, suffix := range versionSuffixes {
-               if strings.HasSuffix(s, suffix) {
-                       vv.Suffix = suffix
-                       s = strings.TrimSuffix(s, suffix)
-               }
-       }
-
-       v, p := parseVersion(s)
-
-       vv.Number = v
-       vv.PatchLevel = p
-
-       return vv, nil
-}
-
-// MustParseHugoVersion parses a version string
-// and panics if any error occurs.
-func MustParseHugoVersion(s string) HugoVersion {
-       vv, err := ParseHugoVersion(s)
-       if err != nil {
-               panic(err)
-       }
-       return vv
-}
-
-// ReleaseVersion represents the release version.
-func (v HugoVersion) ReleaseVersion() HugoVersion {
-       v.Suffix = ""
-       return v
-}
-
-// Next returns the next Hugo release version.
-func (v HugoVersion) Next() HugoVersion {
-       return HugoVersion{Number: v.Number + 0.01}
-}
-
-// Prev returns the previous Hugo release version.
-func (v HugoVersion) Prev() HugoVersion {
-       return HugoVersion{Number: v.Number - 0.01}
-}
-
-// NextPatchLevel returns the next patch/bugfix Hugo version.
-// This will be a patch increment on the previous Hugo version.
-func (v HugoVersion) NextPatchLevel(level int) HugoVersion {
-       return HugoVersion{Number: v.Number - 0.01, PatchLevel: level}
-}
-
-// CurrentHugoVersion represents the current build version.
-// This should be the only one.
-var CurrentHugoVersion = HugoVersion{
-       Number:     0.53,
-       PatchLevel: 0,
-       Suffix:     "-DEV",
-}
-
-func hugoVersion(version float32, patchVersion int, suffix string) string {
-       if patchVersion > 0 {
-               return fmt.Sprintf("%.2f.%d%s", version, patchVersion, suffix)
-       }
-       return fmt.Sprintf("%.2f%s", version, suffix)
-}
-
-// CompareVersion compares the given version string or number against the
-// running Hugo version.
-// It returns -1 if the given version is less than, 0 if equal and 1 if greater than
-// the running version.
-func CompareVersion(version interface{}) int {
-       return compareVersionsWithSuffix(CurrentHugoVersion.Number, CurrentHugoVersion.PatchLevel, CurrentHugoVersion.Suffix, version)
-}
-
-func compareVersions(inVersion float32, inPatchVersion int, in interface{}) int {
-       return compareVersionsWithSuffix(inVersion, inPatchVersion, "", in)
-}
-
-func compareVersionsWithSuffix(inVersion float32, inPatchVersion int, suffix string, in interface{}) int {
-       var c int
-       switch d := in.(type) {
-       case float64:
-               c = compareFloatVersions(inVersion, float32(d))
-       case float32:
-               c = compareFloatVersions(inVersion, d)
-       case int:
-               c = compareFloatVersions(inVersion, float32(d))
-       case int32:
-               c = compareFloatVersions(inVersion, float32(d))
-       case int64:
-               c = compareFloatVersions(inVersion, float32(d))
-       default:
-               s, err := cast.ToStringE(in)
-               if err != nil {
-                       return -1
-               }
-
-               v, err := ParseHugoVersion(s)
-               if err != nil {
-                       return -1
-               }
-
-               if v.Number == inVersion && v.PatchLevel == inPatchVersion {
-                       return strings.Compare(suffix, v.Suffix)
-               }
-
-               if v.Number < inVersion || (v.Number == inVersion && v.PatchLevel < inPatchVersion) {
-                       return -1
-               }
-
-               return 1
-       }
-
-       if c == 0 && suffix != "" {
-               return 1
-       }
-
-       return c
-}
-
-func parseVersion(s string) (float32, int) {
-       var (
-               v float32
-               p int
-       )
-
-       if strings.Count(s, ".") == 2 {
-               li := strings.LastIndex(s, ".")
-               p = cast.ToInt(s[li+1:])
-               s = s[:li]
-       }
-
-       v = float32(cast.ToFloat64(s))
-
-       return v, p
-}
-
-func compareFloatVersions(version float32, v float32) int {
-       if v == version {
-               return 0
-       }
-       if v < version {
-               return -1
-       }
-       return 1
-}
diff --git a/helpers/hugo_test.go b/helpers/hugo_test.go
deleted file mode 100644 (file)
index 1c2d896..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2015 The Hugo Authors. All rights reserved.
-//
-// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 helpers
-
-import (
-       "testing"
-
-       "github.com/stretchr/testify/assert"
-       "github.com/stretchr/testify/require"
-)
-
-func TestHugoVersion(t *testing.T) {
-       assert.Equal(t, "0.15-DEV", hugoVersion(0.15, 0, "-DEV"))
-       assert.Equal(t, "0.15.2-DEV", hugoVersion(0.15, 2, "-DEV"))
-
-       v := HugoVersion{Number: 0.21, PatchLevel: 0, Suffix: "-DEV"}
-
-       require.Equal(t, v.ReleaseVersion().String(), "0.21")
-       require.Equal(t, "0.21-DEV", v.String())
-       require.Equal(t, "0.22", v.Next().String())
-       nextVersionString := v.Next().Version()
-       require.Equal(t, "0.22", nextVersionString.String())
-       require.True(t, nextVersionString.Eq("0.22"))
-       require.False(t, nextVersionString.Eq("0.21"))
-       require.True(t, nextVersionString.Eq(nextVersionString))
-       require.Equal(t, "0.20.3", v.NextPatchLevel(3).String())
-}
-
-func TestCompareVersions(t *testing.T) {
-       require.Equal(t, 0, compareVersions(0.20, 0, 0.20))
-       require.Equal(t, 0, compareVersions(0.20, 0, float32(0.20)))
-       require.Equal(t, 0, compareVersions(0.20, 0, float64(0.20)))
-       require.Equal(t, 1, compareVersions(0.19, 1, 0.20))
-       require.Equal(t, 1, compareVersions(0.19, 3, "0.20.2"))
-       require.Equal(t, -1, compareVersions(0.19, 1, 0.01))
-       require.Equal(t, 1, compareVersions(0, 1, 3))
-       require.Equal(t, 1, compareVersions(0, 1, int32(3)))
-       require.Equal(t, 1, compareVersions(0, 1, int64(3)))
-       require.Equal(t, 0, compareVersions(0.20, 0, "0.20"))
-       require.Equal(t, 0, compareVersions(0.20, 1, "0.20.1"))
-       require.Equal(t, -1, compareVersions(0.20, 1, "0.20"))
-       require.Equal(t, 1, compareVersions(0.20, 0, "0.20.1"))
-       require.Equal(t, 1, compareVersions(0.20, 1, "0.20.2"))
-       require.Equal(t, 1, compareVersions(0.21, 1, "0.22.1"))
-       require.Equal(t, -1, compareVersions(0.22, 0, "0.22-DEV"))
-       require.Equal(t, 1, compareVersions(0.22, 0, "0.22.1-DEV"))
-       require.Equal(t, 1, compareVersionsWithSuffix(0.22, 0, "-DEV", "0.22"))
-       require.Equal(t, -1, compareVersionsWithSuffix(0.22, 1, "-DEV", "0.22"))
-       require.Equal(t, 0, compareVersionsWithSuffix(0.22, 1, "-DEV", "0.22.1-DEV"))
-
-}
-
-func TestParseHugoVersion(t *testing.T) {
-       require.Equal(t, "0.25", MustParseHugoVersion("0.25").String())
-       require.Equal(t, "0.25.2", MustParseHugoVersion("0.25.2").String())
-       require.Equal(t, "0.25-test", MustParseHugoVersion("0.25-test").String())
-       require.Equal(t, "0.25-DEV", MustParseHugoVersion("0.25-DEV").String())
-
-}
diff --git a/htesting/test_structs.go b/htesting/test_structs.go
new file mode 100644 (file)
index 0000000..168c848
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright 2018 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 htesting
+
+import (
+       "github.com/gohugoio/hugo/common/hugo"
+       "github.com/gohugoio/hugo/langs"
+       "github.com/spf13/viper"
+)
+
+type testSite struct {
+       h hugo.Info
+       l *langs.Language
+}
+
+func (t testSite) Hugo() hugo.Info {
+       return t.h
+}
+
+func (t testSite) IsServer() bool {
+       return false
+}
+
+func (t testSite) Language() *langs.Language {
+       return t.l
+}
+
+// NewTestHugoSite creates a new minimal test site.
+func NewTestHugoSite() hugo.Site {
+       return testSite{
+               h: hugo.NewInfo(),
+               l: langs.NewLanguage("en", newTestConfig()),
+       }
+}
+
+func newTestConfig() *viper.Viper {
+       v := viper.New()
+       v.Set("contentDir", "content")
+       return v
+}
diff --git a/hugolib/hugo_info.go b/hugolib/hugo_info.go
deleted file mode 100644 (file)
index 303231e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Hugo Authors. All rights reserved.
-//
-// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 hugolib
-
-import (
-       "fmt"
-       "html/template"
-
-       "github.com/gohugoio/hugo/helpers"
-)
-
-var (
-       // CommitHash contains the current Git revision. Use make to build to make
-       // sure this gets set.
-       CommitHash string
-
-       // BuildDate contains the date of the current build.
-       BuildDate string
-)
-
-var hugoInfo *HugoInfo
-
-// HugoInfo contains information about the current Hugo environment
-type HugoInfo struct {
-       Version    helpers.HugoVersionString
-       Generator  template.HTML
-       CommitHash string
-       BuildDate  string
-}
-
-func init() {
-       hugoInfo = &HugoInfo{
-               Version:    helpers.CurrentHugoVersion.Version(),
-               CommitHash: CommitHash,
-               BuildDate:  BuildDate,
-               Generator:  template.HTML(fmt.Sprintf(`<meta name="generator" content="Hugo %s" />`, helpers.CurrentHugoVersion.String())),
-       }
-}
diff --git a/hugolib/hugo_info_test.go b/hugolib/hugo_info_test.go
deleted file mode 100644 (file)
index 0a34330..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Hugo Authors. All rights reserved.
-//
-// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 hugolib
-
-import (
-       "fmt"
-       "testing"
-
-       "github.com/gohugoio/hugo/helpers"
-       "github.com/stretchr/testify/require"
-)
-
-func TestHugoInfo(t *testing.T) {
-       assert := require.New(t)
-
-       assert.Equal(helpers.CurrentHugoVersion.Version(), hugoInfo.Version)
-       assert.IsType(helpers.HugoVersionString(""), hugoInfo.Version)
-       assert.Equal(CommitHash, hugoInfo.CommitHash)
-       assert.Equal(BuildDate, hugoInfo.BuildDate)
-       assert.Contains(hugoInfo.Generator, fmt.Sprintf("Hugo %s", hugoInfo.Version))
-
-}
index 9cc091927c78c23e2c1c0286db3ab9c52bf15c52..043e049d7650c7809d5695b0f373dffaaeb6a7af 100644 (file)
@@ -21,12 +21,13 @@ import (
        "strings"
        "sync"
 
+       "github.com/gohugoio/hugo/publisher"
+
        "github.com/gohugoio/hugo/common/herrors"
        "github.com/gohugoio/hugo/common/loggers"
        "github.com/gohugoio/hugo/deps"
        "github.com/gohugoio/hugo/helpers"
        "github.com/gohugoio/hugo/langs"
-       "github.com/gohugoio/hugo/publisher"
 
        "github.com/gohugoio/hugo/i18n"
        "github.com/gohugoio/hugo/tpl"
@@ -224,6 +225,27 @@ func applyDeps(cfg deps.DepsCfg, sites ...*Site) error {
                        continue
                }
 
+               onCreated := func(d *deps.Deps) error {
+                       s.Deps = d
+
+                       // Set up the main publishing chain.
+                       s.publisher = publisher.NewDestinationPublisher(d.PathSpec.BaseFs.PublishFs, s.outputFormatsConfig, s.mediaTypesConfig, cfg.Cfg.GetBool("minify"))
+
+                       if err := s.initializeSiteInfo(); err != nil {
+                               return err
+                       }
+
+                       d.Site = &s.Info
+
+                       siteConfig, err := loadSiteConfig(s.Language)
+                       if err != nil {
+                               return err
+                       }
+                       s.siteConfig = siteConfig
+                       s.siteRefLinker, err = newSiteRefLinker(s.Language, s)
+                       return err
+               }
+
                cfg.Language = s.Language
                cfg.MediaTypes = s.mediaTypesConfig
                cfg.OutputFormats = s.outputFormatsConfig
@@ -238,37 +260,23 @@ func applyDeps(cfg deps.DepsCfg, sites ...*Site) error {
                        }
 
                        d.OutputFormatsConfig = s.outputFormatsConfig
-                       s.Deps = d
+
+                       if err := onCreated(d); err != nil {
+                               return err
+                       }
 
                        if err = d.LoadResources(); err != nil {
                                return err
                        }
 
                } else {
-                       d, err = d.ForLanguage(cfg)
+                       d, err = d.ForLanguage(cfg, onCreated)
                        if err != nil {
                                return err
                        }
                        d.OutputFormatsConfig = s.outputFormatsConfig
-                       s.Deps = d
                }
 
-               // Set up the main publishing chain.
-               s.publisher = publisher.NewDestinationPublisher(d.PathSpec.BaseFs.PublishFs, s.outputFormatsConfig, s.mediaTypesConfig, cfg.Cfg.GetBool("minify"))
-
-               if err := s.initializeSiteInfo(); err != nil {
-                       return err
-               }
-
-               siteConfig, err := loadSiteConfig(s.Language)
-               if err != nil {
-                       return err
-               }
-               s.siteConfig = siteConfig
-               s.siteRefLinker, err = newSiteRefLinker(s.Language, s)
-               if err != nil {
-                       return err
-               }
        }
 
        return nil
index f3e87be7de770cc36f446797ead6ff7a4548bfcd..4c48a606143869e65d59d92a2619da35bd1937e5 100644 (file)
@@ -21,6 +21,8 @@ import (
        "math/rand"
        "reflect"
 
+       "github.com/gohugoio/hugo/common/hugo"
+
        "github.com/gohugoio/hugo/common/maps"
        "github.com/gohugoio/hugo/common/urls"
        "github.com/gohugoio/hugo/media"
@@ -1873,8 +1875,8 @@ func (p *Page) copy(initContent bool) *Page {
        return &c
 }
 
-func (p *Page) Hugo() *HugoInfo {
-       return hugoInfo
+func (p *Page) Hugo() hugo.Info {
+       return p.s.Info.hugoInfo
 }
 
 // GetPage looks up a page for the given ref.
index cd8bd8ffc53e27ad5c7a277c51475148784aa96f..177ed7fb1b96b67964d2aa0132e830843e851349 100644 (file)
@@ -1436,7 +1436,7 @@ func TestIndexPageSimpleMethods(t *testing.T) {
                {func(n *Page) bool { return n.IsNode() }},
                {func(n *Page) bool { return !n.IsPage() }},
                {func(n *Page) bool { return n.Scratch() != nil }},
-               {func(n *Page) bool { return n.Hugo() != nil }},
+               {func(n *Page) bool { return n.Hugo().Version != "" }},
        } {
 
                n := s.newHomePage()
index 8a4688f166e36fb09ec649d53e7bd3114804b90b..6706af3bce1ed8b9091fa40e6397fccaea13247f 100644 (file)
@@ -66,7 +66,7 @@ func TestMergeLanguages(t *testing.T) {
 
        firstNN := nnSite.RegularPages[0]
        assert.Equal(4, len(firstNN.Sites()))
-       assert.Equal("en", firstNN.Sites().First().Language.Lang)
+       assert.Equal("en", firstNN.Sites().First().Language().Lang)
 
        nnBundle := nnSite.getPage("page", "bundle")
        enBundle := enSite.getPage("page", "bundle")
index 25eb34f05a66cd9d9ce19ff764112f5929755321..d0e6c3018e133259fe7deddd130bb049d6ebbd13 100644 (file)
@@ -36,11 +36,11 @@ import (
 
        "github.com/gohugoio/hugo/common/herrors"
 
-       _errors "github.com/pkg/errors"
-
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/common/maps"
        "github.com/gohugoio/hugo/publisher"
        "github.com/gohugoio/hugo/resource"
+       _errors "github.com/pkg/errors"
 
        "github.com/gohugoio/hugo/langs"
 
@@ -388,7 +388,7 @@ type SiteInfo struct {
        Social     SiteSocial
        *PageCollections
        Menus                          *Menus
-       Hugo                           *HugoInfo
+       hugoInfo                       hugo.Info
        Title                          string
        RSSLink                        string
        Author                         map[string]interface{}
@@ -405,17 +405,25 @@ type SiteInfo struct {
        Data                           *map[string]interface{}
        owner                          *HugoSites
        s                              *Site
-       Language                       *langs.Language
+       language                       *langs.Language
        LanguagePrefix                 string
        Languages                      langs.Languages
        defaultContentLanguageInSubdir bool
        sectionPagesMenu               string
 }
 
+func (s *SiteInfo) Language() *langs.Language {
+       return s.language
+}
+
 func (s *SiteInfo) Config() SiteConfig {
        return s.s.siteConfig
 }
 
+func (s *SiteInfo) Hugo() hugo.Info {
+       return s.hugoInfo
+}
+
 func (s *SiteInfo) String() string {
        return fmt.Sprintf("Site(%q)", s.Title)
 }
@@ -797,7 +805,10 @@ func (s *Site) processPartial(events []fsnotify.Event) (whatChanged, error) {
                                MediaTypes:    site.mediaTypesConfig,
                                OutputFormats: site.outputFormatsConfig,
                        }
-                       site.Deps, err = first.Deps.ForLanguage(depsCfg)
+                       site.Deps, err = first.Deps.ForLanguage(depsCfg, func(d *deps.Deps) error {
+                               d.Site = &site.Info
+                               return nil
+                       })
                        if err != nil {
                                return whatChanged{}, err
                        }
@@ -1122,7 +1133,7 @@ func (s *Site) initialize() (err error) {
 func (s *SiteInfo) HomeAbsURL() string {
        base := ""
        if s.IsMultiLingual() {
-               base = s.Language.Lang
+               base = s.Language().Lang
        }
        return s.owner.AbsURL(base, false)
 }
@@ -1194,7 +1205,7 @@ func (s *Site) initializeSiteInfo() error {
                Social:                         lang.GetStringMapString("social"),
                LanguageCode:                   lang.GetString("languageCode"),
                Copyright:                      lang.GetString("copyright"),
-               Language:                       lang,
+               language:                       lang,
                LanguagePrefix:                 languagePrefix,
                Languages:                      languages,
                defaultContentLanguageInSubdir: defaultContentInSubDir,
@@ -1211,6 +1222,7 @@ func (s *Site) initializeSiteInfo() error {
                Data:                           &s.Data,
                owner:                          s.owner,
                s:                              s,
+               hugoInfo:                       hugo.NewInfo(),
                // TODO(bep) make this Menu and similar into delegate methods on SiteInfo
                Taxonomies: s.Taxonomies,
        }
index 9cc523cb06323d5d5c15e0e68011bdb4b80bca30..32ede5639f08d1db29b553f8ba68f318ac518ec5 100644 (file)
@@ -236,3 +236,24 @@ Page Content
        b.AssertFileContent("public/page/index.html", "Base: Hi!?")
 
 }
+
+func TestTemplateFuncs(t *testing.T) {
+
+       b := newTestSitesBuilder(t).WithDefaultMultiSiteConfig()
+
+       homeTpl := `Site: {{ site.Language.Lang }} / {{ .Site.Language.Lang }} / {{ site.BaseURL }}
+Hugo: {{ hugo.Generator }}
+`
+
+       b.WithTemplatesAdded(
+               "index.html", homeTpl,
+               "index.fr.html", homeTpl,
+       )
+
+       b.CreateSites().Build(BuildCfg{})
+
+       b.AssertFileContent("public/en/index.html", "Site: en / en / http://example.com/blog",
+               "Hugo: <meta name=\"generator\" content=\"Hugo")
+       b.AssertFileContent("public/fr/index.html", "Site: fr / fr / http://example.com/blog")
+
+}
index 84b7384d075b4ecd605f79d03a9e59fc138d5cae..5db539d30dfc53b949b99278ee2733159d38e7e2 100644 (file)
@@ -20,6 +20,7 @@ import (
        "github.com/gohugoio/hugo/tpl/tplimpl"
 
        "github.com/gohugoio/hugo/common/loggers"
+       "github.com/gohugoio/hugo/htesting"
        "github.com/gohugoio/hugo/langs"
        "github.com/spf13/afero"
 
@@ -183,6 +184,7 @@ func newDepsConfig(tp *TranslationProvider, cfg config.Provider, fs *hugofs.Fs)
        l.Set("i18nDir", "i18n")
        return deps.DepsCfg{
                Language:            l,
+               Site:                htesting.NewTestHugoSite(),
                Cfg:                 cfg,
                Fs:                  fs,
                Logger:              logger,
index e7ec106d74aa8ee1ab6facffd5b49249b06cc60a..cd873dd770b906f035a7bad12ebf9335ec760a50 100644 (file)
@@ -21,10 +21,10 @@ import (
 
 const (
        packageName  = "github.com/gohugoio/hugo"
-       noGitLdflags = "-X $PACKAGE/hugolib.BuildDate=$BUILD_DATE"
+       noGitLdflags = "-X $PACKAGE/common/hugo.BuildDate=$BUILD_DATE"
 )
 
-var ldflags = "-X $PACKAGE/hugolib.CommitHash=$COMMIT_HASH -X $PACKAGE/hugolib.BuildDate=$BUILD_DATE"
+var ldflags = "-X $PACKAGE/common/hugo.CommitHash=$COMMIT_HASH -X $PACKAGE/common/hugo.BuildDate=$BUILD_DATE"
 
 // allow user to override go executable by running as GOEXE=xxx make ... on unix-like systems
 var goexe = "go"
index 0738fb81c9deddb876d5d3ecc9985deb562f1bf9..0c0765a719aeed5bcf15a67d27c09fad7aac1ffc 100644 (file)
@@ -25,9 +25,8 @@ import (
        "regexp"
        "strings"
 
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/pkg/errors"
-
-       "github.com/gohugoio/hugo/helpers"
 )
 
 const commitPrefix = "releaser:"
@@ -52,8 +51,8 @@ type ReleaseHandler struct {
        git func(args ...string) (string, error)
 }
 
-func (r ReleaseHandler) calculateVersions() (helpers.HugoVersion, helpers.HugoVersion) {
-       newVersion := helpers.MustParseHugoVersion(r.cliVersion)
+func (r ReleaseHandler) calculateVersions() (hugo.Version, hugo.Version) {
+       newVersion := hugo.MustParseVersion(r.cliVersion)
        finalVersion := newVersion.Next()
        finalVersion.PatchLevel = 0
 
@@ -261,14 +260,14 @@ func (r *ReleaseHandler) release(releaseNotesFile string) error {
        return nil
 }
 
-func (r *ReleaseHandler) bumpVersions(ver helpers.HugoVersion) error {
+func (r *ReleaseHandler) bumpVersions(ver hugo.Version) error {
        toDev := ""
 
        if ver.Suffix != "" {
                toDev = ver.Suffix
        }
 
-       if err := r.replaceInFile("helpers/hugo.go",
+       if err := r.replaceInFile("common/hugo/version_current.go",
                `Number:(\s{4,})(.*),`, fmt.Sprintf(`Number:${1}%.2f,`, ver.Number),
                `PatchLevel:(\s*)(.*),`, fmt.Sprintf(`PatchLevel:${1}%d,`, ver.PatchLevel),
                `Suffix:(\s{4,})".*",`, fmt.Sprintf(`Suffix:${1}"%s",`, toDev)); err != nil {
index 61a84a629ecac6eb6913dee601395338b0deaa93..d83680e534f95f22c7a602d64f60dc4c41e1a4d0 100644 (file)
@@ -21,8 +21,7 @@ import (
        "testing"
        "time"
 
-       "github.com/gohugoio/hugo/helpers"
-
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/spf13/cast"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
@@ -173,17 +172,17 @@ func doTestCompare(t *testing.T, tp tstCompareType, funcUnderTest func(a, b inte
                {tstEqerType1("a"), tstEqerType2("a"), 0},
                {tstEqerType2("a"), tstEqerType1("a"), 0},
                {tstEqerType2("a"), tstEqerType1("b"), -1},
-               {helpers.MustParseHugoVersion("0.32.1").Version(), helpers.MustParseHugoVersion("0.32").Version(), 1},
-               {helpers.MustParseHugoVersion("0.35").Version(), helpers.MustParseHugoVersion("0.32").Version(), 1},
-               {helpers.MustParseHugoVersion("0.36").Version(), helpers.MustParseHugoVersion("0.36").Version(), 0},
-               {helpers.MustParseHugoVersion("0.32").Version(), helpers.MustParseHugoVersion("0.36").Version(), -1},
-               {helpers.MustParseHugoVersion("0.32").Version(), "0.36", -1},
-               {"0.36", helpers.MustParseHugoVersion("0.32").Version(), 1},
-               {"0.36", helpers.MustParseHugoVersion("0.36").Version(), 0},
-               {"0.37", helpers.MustParseHugoVersion("0.37-DEV").Version(), 1},
-               {"0.37-DEV", helpers.MustParseHugoVersion("0.37").Version(), -1},
-               {"0.36", helpers.MustParseHugoVersion("0.37-DEV").Version(), -1},
-               {"0.37-DEV", helpers.MustParseHugoVersion("0.37-DEV").Version(), 0},
+               {hugo.MustParseVersion("0.32.1").Version(), hugo.MustParseVersion("0.32").Version(), 1},
+               {hugo.MustParseVersion("0.35").Version(), hugo.MustParseVersion("0.32").Version(), 1},
+               {hugo.MustParseVersion("0.36").Version(), hugo.MustParseVersion("0.36").Version(), 0},
+               {hugo.MustParseVersion("0.32").Version(), hugo.MustParseVersion("0.36").Version(), -1},
+               {hugo.MustParseVersion("0.32").Version(), "0.36", -1},
+               {"0.36", hugo.MustParseVersion("0.32").Version(), 1},
+               {"0.36", hugo.MustParseVersion("0.36").Version(), 0},
+               {"0.37", hugo.MustParseVersion("0.37-DEV").Version(), 1},
+               {"0.37-DEV", hugo.MustParseVersion("0.37").Version(), -1},
+               {"0.36", hugo.MustParseVersion("0.37-DEV").Version(), -1},
+               {"0.37-DEV", hugo.MustParseVersion("0.37-DEV").Version(), 0},
        } {
                result := funcUnderTest(test.left, test.right)
                success := false
diff --git a/tpl/hugo/init.go b/tpl/hugo/init.go
new file mode 100644 (file)
index 0000000..5b6d5b9
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2018 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 site
+
+import (
+       "github.com/gohugoio/hugo/deps"
+       "github.com/gohugoio/hugo/htesting"
+       "github.com/gohugoio/hugo/tpl/internal"
+)
+
+const name = "hugo"
+
+func init() {
+       f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
+
+               h := htesting.NewTestHugoSite().Hugo()
+
+               ns := &internal.TemplateFuncsNamespace{
+                       Name:    name,
+                       Context: func(args ...interface{}) interface{} { return h },
+               }
+
+               // We just add the Hugo struct as the namespace here. No method mappings.
+
+               return ns
+
+       }
+
+       internal.AddTemplateFuncsNamespace(f)
+}
diff --git a/tpl/hugo/init_test.go b/tpl/hugo/init_test.go
new file mode 100644 (file)
index 0000000..6061276
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2017 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 site
+
+import (
+       "testing"
+
+       "github.com/gohugoio/hugo/htesting"
+
+       "github.com/gohugoio/hugo/deps"
+       "github.com/gohugoio/hugo/tpl/internal"
+       "github.com/stretchr/testify/require"
+)
+
+func TestInit(t *testing.T) {
+       var found bool
+       var ns *internal.TemplateFuncsNamespace
+       s := htesting.NewTestHugoSite()
+
+       for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
+               ns = nsf(&deps.Deps{Site: s})
+               if ns.Name == name {
+                       found = true
+                       break
+               }
+       }
+
+       require.True(t, found)
+       require.IsType(t, s.Hugo(), ns.Context())
+}
diff --git a/tpl/site/init.go b/tpl/site/init.go
new file mode 100644 (file)
index 0000000..4f5df0b
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright 2018 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 site
+
+import (
+       "github.com/gohugoio/hugo/deps"
+
+       "github.com/gohugoio/hugo/tpl/internal"
+)
+
+const name = "site"
+
+func init() {
+       f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
+
+               s := d.Site
+               ns := &internal.TemplateFuncsNamespace{
+                       Name:    name,
+                       Context: func(args ...interface{}) interface{} { return s },
+               }
+
+               if s == nil {
+                       panic("no Site")
+               }
+
+               // We just add the Site as the namespace here. No method mappings.
+
+               return ns
+
+       }
+
+       internal.AddTemplateFuncsNamespace(f)
+}
diff --git a/tpl/site/init_test.go b/tpl/site/init_test.go
new file mode 100644 (file)
index 0000000..00704d9
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2017 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache 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://www.apache.org/licenses/LICENSE-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 site
+
+import (
+       "testing"
+
+       "github.com/gohugoio/hugo/deps"
+       "github.com/gohugoio/hugo/htesting"
+       "github.com/gohugoio/hugo/tpl/internal"
+       "github.com/stretchr/testify/require"
+)
+
+func TestInit(t *testing.T) {
+       var found bool
+       var ns *internal.TemplateFuncsNamespace
+       s := htesting.NewTestHugoSite()
+
+       for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
+               ns = nsf(&deps.Deps{Site: s})
+               if ns.Name == name {
+                       found = true
+                       break
+               }
+       }
+
+       require.True(t, found)
+       require.IsType(t, s, ns.Context())
+}
index 27ffcd97a75e3ef7d06ae857afc0e82d42547b73..09bb9381a26048a0ca556e51e3cd83e8fff7ec88 100644 (file)
@@ -30,6 +30,7 @@ import (
        _ "github.com/gohugoio/hugo/tpl/data"
        _ "github.com/gohugoio/hugo/tpl/encoding"
        _ "github.com/gohugoio/hugo/tpl/fmt"
+       _ "github.com/gohugoio/hugo/tpl/hugo"
        _ "github.com/gohugoio/hugo/tpl/images"
        _ "github.com/gohugoio/hugo/tpl/inflect"
        _ "github.com/gohugoio/hugo/tpl/lang"
@@ -39,6 +40,7 @@ import (
        _ "github.com/gohugoio/hugo/tpl/path"
        _ "github.com/gohugoio/hugo/tpl/resources"
        _ "github.com/gohugoio/hugo/tpl/safe"
+       _ "github.com/gohugoio/hugo/tpl/site"
        _ "github.com/gohugoio/hugo/tpl/strings"
        _ "github.com/gohugoio/hugo/tpl/templates"
        _ "github.com/gohugoio/hugo/tpl/time"
index 04bb4941a7ebc1d61a99d9326db32b91570f3846..22387dc016f435cbd7884e7ad9df1764797c2587 100644 (file)
@@ -21,10 +21,12 @@ import (
        "testing"
        "time"
 
+       "github.com/gohugoio/hugo/htesting"
+
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/common/loggers"
        "github.com/gohugoio/hugo/config"
        "github.com/gohugoio/hugo/deps"
-       "github.com/gohugoio/hugo/helpers"
        "github.com/gohugoio/hugo/hugofs"
        "github.com/gohugoio/hugo/i18n"
        "github.com/gohugoio/hugo/langs"
@@ -57,6 +59,7 @@ func newDepsConfig(cfg config.Provider) deps.DepsCfg {
        l := langs.NewLanguage("en", cfg)
        return deps.DepsCfg{
                Language:            l,
+               Site:                htesting.NewTestHugoSite(),
                Cfg:                 cfg,
                Fs:                  hugofs.NewMem(l),
                Logger:              logger,
@@ -98,7 +101,7 @@ func TestTemplateFuncsExamples(t *testing.T) {
        data.Title = "**BatMan**"
        data.Section = "blog"
        data.Params = map[string]interface{}{"langCode": "en"}
-       data.Hugo = map[string]interface{}{"Version": helpers.MustParseHugoVersion("0.36.1").Version()}
+       data.Hugo = map[string]interface{}{"Version": hugo.MustParseVersion("0.36.1").Version()}
 
        for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
                ns := nsf(d)
index 513b21228ee7ebe72867a32a306fc47a60cce0b6..5f3a8f63b5087f4a6466cd3d1077b0045d653178 100644 (file)
@@ -18,12 +18,13 @@ import (
        "fmt"
        "regexp"
 
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/helpers"
        "github.com/gohugoio/hugo/transform"
 )
 
 var metaTagsCheck = regexp.MustCompile(`(?i)<meta\s+name=['|"]?generator['|"]?`)
-var hugoGeneratorTag = fmt.Sprintf(`<meta name="generator" content="Hugo %s" />`, helpers.CurrentHugoVersion)
+var hugoGeneratorTag = fmt.Sprintf(`<meta name="generator" content="Hugo %s" />`, hugo.CurrentVersion)
 
 // HugoGenerator injects a meta generator tag for Hugo if none present.
 func HugoGenerator(ft transform.FromTo) error {