github.com/kovansky/hugo@v0.92.3-0.20220224232819-63076e4ff19f/common/hugo/hugo.go (about)

     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  	"time"
    25  
    26  	"github.com/gohugoio/hugo/hugofs/files"
    27  
    28  	"github.com/spf13/afero"
    29  
    30  	"github.com/gohugoio/hugo/config"
    31  	"github.com/gohugoio/hugo/hugofs"
    32  )
    33  
    34  const (
    35  	EnvironmentDevelopment = "development"
    36  	EnvironmentProduction  = "production"
    37  )
    38  
    39  var (
    40  	// commitHash contains the current Git revision.
    41  	// Use mage to build to make sure this gets set.
    42  	commitHash string
    43  
    44  	// buildDate contains the date of the current build.
    45  	buildDate string
    46  
    47  	// vendorInfo contains vendor notes about the current build.
    48  	vendorInfo string
    49  )
    50  
    51  // Info contains information about the current Hugo environment
    52  type Info struct {
    53  	CommitHash string
    54  	BuildDate  string
    55  
    56  	// The build environment.
    57  	// Defaults are "production" (hugo) and "development" (hugo server).
    58  	// This can also be set by the user.
    59  	// It can be any string, but it will be all lower case.
    60  	Environment string
    61  
    62  	deps []*Dependency
    63  }
    64  
    65  // Version returns the current version as a comparable version string.
    66  func (i Info) Version() VersionString {
    67  	return CurrentVersion.Version()
    68  }
    69  
    70  // Generator a Hugo meta generator HTML tag.
    71  func (i Info) Generator() template.HTML {
    72  	return template.HTML(fmt.Sprintf(`<meta name="generator" content="Hugo %s" />`, CurrentVersion.String()))
    73  }
    74  
    75  func (i Info) IsProduction() bool {
    76  	return i.Environment == EnvironmentProduction
    77  }
    78  
    79  func (i Info) IsExtended() bool {
    80  	return IsExtended
    81  }
    82  
    83  // Deps gets a list of dependencies for this Hugo build.
    84  func (i Info) Deps() []*Dependency {
    85  	return i.deps
    86  }
    87  
    88  // NewInfo creates a new Hugo Info object.
    89  func NewInfo(environment string, deps []*Dependency) Info {
    90  	if environment == "" {
    91  		environment = EnvironmentProduction
    92  	}
    93  	return Info{
    94  		CommitHash:  commitHash,
    95  		BuildDate:   buildDate,
    96  		Environment: environment,
    97  		deps:        deps,
    98  	}
    99  }
   100  
   101  // GetExecEnviron creates and gets the common os/exec environment used in the
   102  // external programs we interact with via os/exec, e.g. postcss.
   103  func GetExecEnviron(workDir string, cfg config.Provider, fs afero.Fs) []string {
   104  	var env []string
   105  	nodepath := filepath.Join(workDir, "node_modules")
   106  	if np := os.Getenv("NODE_PATH"); np != "" {
   107  		nodepath = workDir + string(os.PathListSeparator) + np
   108  	}
   109  	config.SetEnvVars(&env, "NODE_PATH", nodepath)
   110  	config.SetEnvVars(&env, "PWD", workDir)
   111  	config.SetEnvVars(&env, "HUGO_ENVIRONMENT", cfg.GetString("environment"))
   112  	config.SetEnvVars(&env, "HUGO_ENV", cfg.GetString("environment"))
   113  
   114  	if fs != nil {
   115  		fis, err := afero.ReadDir(fs, files.FolderJSConfig)
   116  		if err == nil {
   117  			for _, fi := range fis {
   118  				key := fmt.Sprintf("HUGO_FILE_%s", strings.ReplaceAll(strings.ToUpper(fi.Name()), ".", "_"))
   119  				value := fi.(hugofs.FileMetaInfo).Meta().Filename
   120  				config.SetEnvVars(&env, key, value)
   121  			}
   122  		}
   123  	}
   124  
   125  	return env
   126  }
   127  
   128  // GetDependencyList returns a sorted dependency list on the format package="version".
   129  // It includes both Go dependencies and (a manually maintained) list of C(++) dependencies.
   130  func GetDependencyList() []string {
   131  	var deps []string
   132  
   133  	formatDep := func(path, version string) string {
   134  		return fmt.Sprintf("%s=%q", path, version)
   135  	}
   136  
   137  	if IsExtended {
   138  		deps = append(
   139  			deps,
   140  			// TODO(bep) consider adding a DepsNonGo() method to these upstream projects.
   141  			formatDep("github.com/sass/libsass", "3.6.5"),
   142  			formatDep("github.com/webmproject/libwebp", "v1.2.0"),
   143  		)
   144  	}
   145  
   146  	bi, ok := debug.ReadBuildInfo()
   147  	if !ok {
   148  		return deps
   149  	}
   150  
   151  	for _, dep := range bi.Deps {
   152  		deps = append(deps, formatDep(dep.Path, dep.Version))
   153  	}
   154  
   155  	sort.Strings(deps)
   156  
   157  	return deps
   158  }
   159  
   160  // IsRunningAsTest reports whether we are running as a test.
   161  func IsRunningAsTest() bool {
   162  	for _, arg := range os.Args {
   163  		if strings.HasPrefix(arg, "-test") {
   164  			return true
   165  		}
   166  	}
   167  	return false
   168  }
   169  
   170  // Dependency is a single dependency, which can be either a Hugo Module or a local theme.
   171  type Dependency struct {
   172  	// Returns the path to this module.
   173  	// This will either be the module path, e.g. "github.com/gohugoio/myshortcodes",
   174  	// or the path below your /theme folder, e.g. "mytheme".
   175  	Path string
   176  
   177  	// The module version.
   178  	Version string
   179  
   180  	// Whether this dependency is vendored.
   181  	Vendor bool
   182  
   183  	// Time version was created.
   184  	Time time.Time
   185  
   186  	// In the dependency tree, this is the first module that defines this module
   187  	// as a dependency.
   188  	Owner *Dependency
   189  
   190  	// Replaced by this dependency.
   191  	Replace *Dependency
   192  }