diff --git a/commands/hugo.go b/commands/hugo.go index 376438fcb..e93aec563 100644 --- a/commands/hugo.go +++ b/commands/hugo.go @@ -133,6 +133,7 @@ var ( canonifyURLs bool cleanDestination bool enableRobotsTXT bool + enableGitInfo bool disable404 bool disableRSS bool disableSitemap bool @@ -237,6 +238,7 @@ func initHugoBuildCommonFlags(cmd *cobra.Command) { cmd.Flags().BoolVar(&uglyURLs, "uglyURLs", false, "if true, use /filename.html instead of /filename/") cmd.Flags().BoolVar(&canonifyURLs, "canonifyURLs", false, "if true, all relative URLs will be canonicalized using baseURL") cmd.Flags().StringVarP(&baseURL, "baseURL", "b", "", "hostname (and path) to the root, e.g. http://spf13.com/") + cmd.Flags().BoolVar(&enableGitInfo, "enableGitInfo", false, "Add Git revision, date and author info to the pages") cmd.Flags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program") cmd.Flags().BoolVar(&pluralizeListTitles, "pluralizeListTitles", true, "Pluralize titles in lists using inflect") @@ -319,6 +321,9 @@ func InitializeConfig(subCmdVs ...*cobra.Command) error { if flagChanged(cmdV.Flags(), "enableRobotsTXT") { viper.Set("enableRobotsTXT", enableRobotsTXT) } + if flagChanged(cmdV.Flags(), "enableGitInfo") { + viper.Set("enableGitInfo", enableGitInfo) + } if flagChanged(cmdV.Flags(), "pluralizeListTitles") { viper.Set("pluralizeListTitles", pluralizeListTitles) } diff --git a/docs/config.toml b/docs/config.toml index b5d159334..17161dd5e 100644 --- a/docs/config.toml +++ b/docs/config.toml @@ -2,6 +2,7 @@ title = "Hugo: A Fast and Flexible Website Generator" baseurl = "http://gohugo.io/" MetaDataFormat = "yaml" pluralizeListTitles = false +enableGitInfo = true [blackfriday] plainIDAnchors = true diff --git a/docs/layouts/partials/footer.html b/docs/layouts/partials/footer.html index 6756e57cf..2d0dbe0e8 100644 --- a/docs/layouts/partials/footer.html +++ b/docs/layouts/partials/footer.html @@ -1,6 +1,6 @@
diff --git a/hugolib/config.go b/hugolib/config.go index 2dfe128a6..94477b75a 100644 --- a/hugolib/config.go +++ b/hugolib/config.go @@ -106,4 +106,5 @@ func loadDefaultSettings() { viper.SetDefault("defaultContentLanguage", "en") viper.SetDefault("defaultContentLanguageInSubdir", false) viper.SetDefault("enableMissingTranslationPlaceholders", false) + viper.SetDefault("enableGitInfo", false) } diff --git a/hugolib/gitinfo.go b/hugolib/gitinfo.go new file mode 100644 index 000000000..e2c22281d --- /dev/null +++ b/hugolib/gitinfo.go @@ -0,0 +1,67 @@ +// Copyright 2016-present 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 ( + "path" + "path/filepath" + "strings" + + "github.com/bep/gitmap" + "github.com/spf13/hugo/helpers" + jww "github.com/spf13/jwalterweatherman" + "github.com/spf13/viper" +) + +func (h *HugoSites) assembleGitInfo() { + if !viper.GetBool("enableGitInfo") { + return + } + + var ( + workingDir = viper.GetString("workingDir") + contentDir = viper.GetString("contentDir") + ) + + gitRepo, err := gitmap.Map(workingDir, "") + if err != nil { + jww.ERROR.Printf("Got error reading Git log: %s", err) + return + } + + gitMap := gitRepo.Files + repoPath := filepath.FromSlash(gitRepo.TopLevelAbsPath) + + // The Hugo site may be placed in a sub folder in the Git repo, + // one example being the Hugo docs. + // We have to find the root folder to the Hugo site below the Git root. + contentRoot := strings.TrimPrefix(workingDir, repoPath) + contentRoot = strings.TrimPrefix(contentRoot, helpers.FilePathSeparator) + + s := h.Sites[0] + + for _, p := range s.AllPages { + // Git normalizes file paths on this form: + filename := path.Join(contentRoot, contentDir, filepath.ToSlash(p.Path())) + g, ok := gitMap[filename] + if !ok { + jww.ERROR.Printf("Failed to find GitInfo for %q", filename) + return + } + + p.GitInfo = g + p.Lastmod = p.GitInfo.AuthorDate + } + +} diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go index 23ea75791..27add9976 100644 --- a/hugolib/hugo_sites.go +++ b/hugolib/hugo_sites.go @@ -216,6 +216,9 @@ func (h *HugoSites) Build(config BuildCfg) error { } } + // TODO(bep) make a more logical grouping of these. + h.assembleGitInfo() + for _, s := range h.Sites { if err := s.postProcess(); err != nil { return err @@ -288,6 +291,7 @@ func (h *HugoSites) Rebuild(config BuildCfg, events ...fsnotify.Event) error { h.setupTranslations(firstSite) if changed.source { + h.assembleGitInfo() for _, s := range h.Sites { if err := s.postProcess(); err != nil { return err diff --git a/hugolib/page.go b/hugolib/page.go index 79889cd3f..7d7c22fd9 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -19,6 +19,8 @@ import ( "fmt" "reflect" + "github.com/bep/gitmap" + "github.com/mitchellh/mapstructure" "github.com/spf13/hugo/helpers" "github.com/spf13/hugo/parser" @@ -94,6 +96,8 @@ type Page struct { Source Position `json:"-"` Node + + GitInfo *gitmap.GitInfo } type Source struct { diff --git a/vendor/vendor.json b/vendor/vendor.json index cc7efc56e..7fdfc7b26 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -20,6 +20,12 @@ "revision": "5bd2802263f21d8788851d5305584c82a5c75d7e", "revisionTime": "2016-07-26T15:08:25Z" }, + { + "checksumSHA1": "dIidE/pUkqulIvTkuMBTpH3/lnU=", + "path": "github.com/bep/gitmap", + "revision": "a1a71abe12823e27ae7507189fe2e914ba9626ac", + "revisionTime": "2016-10-29T14:53:16Z" + }, { "checksumSHA1": "K8wTIgrK5sl+LmQs8CD/orvKsAM=", "path": "github.com/bep/inflect",