hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

hugo.go (5932B)

    1 // Copyright 2018 The Hugo Authors. All rights reserved.
    2 //
    3 // Licensed under the Apache License, Version 2.0 (the "License");
    4 // you may not use this file except in compliance with the License.
    5 // You may obtain a copy of the License at
    6 // http://www.apache.org/licenses/LICENSE-2.0
    7 //
    8 // Unless required by applicable law or agreed to in writing, software
    9 // distributed under the License is distributed on an "AS IS" BASIS,
   10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   11 // See the License for the specific language governing permissions and
   12 // limitations under the License.
   13 
   14 package hugo
   15 
   16 import (
   17 	"fmt"
   18 	"html/template"
   19 	"os"
   20 	"path/filepath"
   21 	"runtime/debug"
   22 	"sort"
   23 	"strings"
   24 	"sync"
   25 	"time"
   26 
   27 	"github.com/gohugoio/hugo/hugofs/files"
   28 
   29 	"github.com/spf13/afero"
   30 
   31 	"github.com/gohugoio/hugo/config"
   32 	"github.com/gohugoio/hugo/hugofs"
   33 )
   34 
   35 const (
   36 	EnvironmentDevelopment = "development"
   37 	EnvironmentProduction  = "production"
   38 )
   39 
   40 var (
   41 	// vendorInfo contains vendor notes about the current build.
   42 	vendorInfo string
   43 )
   44 
   45 // Info contains information about the current Hugo environment
   46 type Info struct {
   47 	CommitHash string
   48 	BuildDate  string
   49 
   50 	// The build environment.
   51 	// Defaults are "production" (hugo) and "development" (hugo server).
   52 	// This can also be set by the user.
   53 	// It can be any string, but it will be all lower case.
   54 	Environment string
   55 
   56 	// version of go that the Hugo binary was built with
   57 	GoVersion string
   58 
   59 	deps []*Dependency
   60 }
   61 
   62 // Version returns the current version as a comparable version string.
   63 func (i Info) Version() VersionString {
   64 	return CurrentVersion.Version()
   65 }
   66 
   67 // Generator a Hugo meta generator HTML tag.
   68 func (i Info) Generator() template.HTML {
   69 	return template.HTML(fmt.Sprintf(`<meta name="generator" content="Hugo %s" />`, CurrentVersion.String()))
   70 }
   71 
   72 func (i Info) IsProduction() bool {
   73 	return i.Environment == EnvironmentProduction
   74 }
   75 
   76 func (i Info) IsExtended() bool {
   77 	return IsExtended
   78 }
   79 
   80 // Deps gets a list of dependencies for this Hugo build.
   81 func (i Info) Deps() []*Dependency {
   82 	return i.deps
   83 }
   84 
   85 // NewInfo creates a new Hugo Info object.
   86 func NewInfo(environment string, deps []*Dependency) Info {
   87 	if environment == "" {
   88 		environment = EnvironmentProduction
   89 	}
   90 	var (
   91 		commitHash string
   92 		buildDate  string
   93 		goVersion  string
   94 	)
   95 
   96 	bi := getBuildInfo()
   97 	if bi != nil {
   98 		commitHash = bi.Revision
   99 		buildDate = bi.RevisionTime
  100 		goVersion = bi.GoVersion
  101 	}
  102 
  103 	return Info{
  104 		CommitHash:  commitHash,
  105 		BuildDate:   buildDate,
  106 		Environment: environment,
  107 		deps:        deps,
  108 		GoVersion:   goVersion,
  109 	}
  110 }
  111 
  112 // GetExecEnviron creates and gets the common os/exec environment used in the
  113 // external programs we interact with via os/exec, e.g. postcss.
  114 func GetExecEnviron(workDir string, cfg config.Provider, fs afero.Fs) []string {
  115 	var env []string
  116 	nodepath := filepath.Join(workDir, "node_modules")
  117 	if np := os.Getenv("NODE_PATH"); np != "" {
  118 		nodepath = workDir + string(os.PathListSeparator) + np
  119 	}
  120 	config.SetEnvVars(&env, "NODE_PATH", nodepath)
  121 	config.SetEnvVars(&env, "PWD", workDir)
  122 	config.SetEnvVars(&env, "HUGO_ENVIRONMENT", cfg.GetString("environment"))
  123 	config.SetEnvVars(&env, "HUGO_ENV", cfg.GetString("environment"))
  124 
  125 	if fs != nil {
  126 		fis, err := afero.ReadDir(fs, files.FolderJSConfig)
  127 		if err == nil {
  128 			for _, fi := range fis {
  129 				key := fmt.Sprintf("HUGO_FILE_%s", strings.ReplaceAll(strings.ToUpper(fi.Name()), ".", "_"))
  130 				value := fi.(hugofs.FileMetaInfo).Meta().Filename
  131 				config.SetEnvVars(&env, key, value)
  132 			}
  133 		}
  134 	}
  135 
  136 	return env
  137 }
  138 
  139 type buildInfo struct {
  140 	VersionControlSystem string
  141 	Revision             string
  142 	RevisionTime         string
  143 	Modified             bool
  144 
  145 	GoOS   string
  146 	GoArch string
  147 
  148 	*debug.BuildInfo
  149 }
  150 
  151 var bInfo *buildInfo
  152 var bInfoInit sync.Once
  153 
  154 func getBuildInfo() *buildInfo {
  155 	bInfoInit.Do(func() {
  156 		bi, ok := debug.ReadBuildInfo()
  157 		if !ok {
  158 			return
  159 		}
  160 
  161 		bInfo = &buildInfo{BuildInfo: bi}
  162 
  163 		for _, s := range bInfo.Settings {
  164 			switch s.Key {
  165 			case "vcs":
  166 				bInfo.VersionControlSystem = s.Value
  167 			case "vcs.revision":
  168 				bInfo.Revision = s.Value
  169 			case "vcs.time":
  170 				bInfo.RevisionTime = s.Value
  171 			case "vcs.modified":
  172 				bInfo.Modified = s.Value == "true"
  173 			case "GOOS":
  174 				bInfo.GoOS = s.Value
  175 			case "GOARCH":
  176 				bInfo.GoArch = s.Value
  177 			}
  178 		}
  179 
  180 	})
  181 
  182 	return bInfo
  183 }
  184 
  185 // GetDependencyList returns a sorted dependency list on the format package="version".
  186 // It includes both Go dependencies and (a manually maintained) list of C(++) dependencies.
  187 func GetDependencyList() []string {
  188 	var deps []string
  189 
  190 	formatDep := func(path, version string) string {
  191 		return fmt.Sprintf("%s=%q", path, version)
  192 	}
  193 
  194 	if IsExtended {
  195 		deps = append(
  196 			deps,
  197 			// TODO(bep) consider adding a DepsNonGo() method to these upstream projects.
  198 			formatDep("github.com/sass/libsass", "3.6.5"),
  199 			formatDep("github.com/webmproject/libwebp", "v1.2.0"),
  200 		)
  201 	}
  202 
  203 	bi := getBuildInfo()
  204 	if bi == nil {
  205 		return deps
  206 	}
  207 
  208 	for _, dep := range bi.Deps {
  209 		deps = append(deps, formatDep(dep.Path, dep.Version))
  210 	}
  211 
  212 	sort.Strings(deps)
  213 
  214 	return deps
  215 }
  216 
  217 // IsRunningAsTest reports whether we are running as a test.
  218 func IsRunningAsTest() bool {
  219 	for _, arg := range os.Args {
  220 		if strings.HasPrefix(arg, "-test") {
  221 			return true
  222 		}
  223 	}
  224 	return false
  225 }
  226 
  227 // Dependency is a single dependency, which can be either a Hugo Module or a local theme.
  228 type Dependency struct {
  229 	// Returns the path to this module.
  230 	// This will either be the module path, e.g. "github.com/gohugoio/myshortcodes",
  231 	// or the path below your /theme folder, e.g. "mytheme".
  232 	Path string
  233 
  234 	// The module version.
  235 	Version string
  236 
  237 	// Whether this dependency is vendored.
  238 	Vendor bool
  239 
  240 	// Time version was created.
  241 	Time time.Time
  242 
  243 	// In the dependency tree, this is the first module that defines this module
  244 	// as a dependency.
  245 	Owner *Dependency
  246 
  247 	// Replaced by this dependency.
  248 	Replace *Dependency
  249 }