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

     1  // Copyright 2019 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 modules provides a client that can be used to manage Hugo Components,
    15  // what's referred to as Hugo Modules. Hugo Modules is built on top of Go Modules,
    16  // but also supports vendoring and components stored directly in the themes dir.
    17  package modules
    18  
    19  import (
    20  	"time"
    21  
    22  	"github.com/gohugoio/hugo/config"
    23  )
    24  
    25  var _ Module = (*moduleAdapter)(nil)
    26  
    27  type Module interface {
    28  
    29  	// Optional config read from the configFilename above.
    30  	Cfg() config.Provider
    31  
    32  	// The decoded module config and mounts.
    33  	Config() Config
    34  
    35  	// Optional configuration filenames (e.g. "/themes/mytheme/config.json").
    36  	// This will be added to the special configuration watch list when in
    37  	// server mode.
    38  	ConfigFilenames() []string
    39  
    40  	// Directory holding files for this module.
    41  	Dir() string
    42  
    43  	// This module is disabled.
    44  	Disabled() bool
    45  
    46  	// Returns whether this is a Go Module.
    47  	IsGoMod() bool
    48  
    49  	// Any directory remappings.
    50  	Mounts() []Mount
    51  
    52  	// In the dependency tree, this is the first module that defines this module
    53  	// as a dependency.
    54  	Owner() Module
    55  
    56  	// Returns the path to this module.
    57  	// This will either be the module path, e.g. "github.com/gohugoio/myshortcodes",
    58  	// or the path below your /theme folder, e.g. "mytheme".
    59  	Path() string
    60  
    61  	// Replaced by this module.
    62  	Replace() Module
    63  
    64  	// Returns whether Dir points below the _vendor dir.
    65  	Vendor() bool
    66  
    67  	// The module version.
    68  	Version() string
    69  
    70  	// Time version was created.
    71  	Time() time.Time
    72  
    73  	// Whether this module's dir is a watch candidate.
    74  	Watch() bool
    75  }
    76  
    77  type Modules []Module
    78  
    79  type moduleAdapter struct {
    80  	path       string
    81  	dir        string
    82  	version    string
    83  	vendor     bool
    84  	disabled   bool
    85  	projectMod bool
    86  	owner      Module
    87  
    88  	mounts []Mount
    89  
    90  	configFilenames []string
    91  	cfg             config.Provider
    92  	config          Config
    93  
    94  	// Set if a Go module.
    95  	gomod *goModule
    96  }
    97  
    98  func (m *moduleAdapter) Cfg() config.Provider {
    99  	return m.cfg
   100  }
   101  
   102  func (m *moduleAdapter) Config() Config {
   103  	return m.config
   104  }
   105  
   106  func (m *moduleAdapter) ConfigFilenames() []string {
   107  	return m.configFilenames
   108  }
   109  
   110  func (m *moduleAdapter) Dir() string {
   111  	// This may point to the _vendor dir.
   112  	if !m.IsGoMod() || m.dir != "" {
   113  		return m.dir
   114  	}
   115  	return m.gomod.Dir
   116  }
   117  
   118  func (m *moduleAdapter) Disabled() bool {
   119  	return m.disabled
   120  }
   121  
   122  func (m *moduleAdapter) IsGoMod() bool {
   123  	return m.gomod != nil
   124  }
   125  
   126  func (m *moduleAdapter) Mounts() []Mount {
   127  	return m.mounts
   128  }
   129  
   130  func (m *moduleAdapter) Owner() Module {
   131  	return m.owner
   132  }
   133  
   134  func (m *moduleAdapter) Path() string {
   135  	if !m.IsGoMod() || m.path != "" {
   136  		return m.path
   137  	}
   138  	return m.gomod.Path
   139  }
   140  
   141  func (m *moduleAdapter) Replace() Module {
   142  	if m.IsGoMod() && !m.Vendor() && m.gomod.Replace != nil {
   143  		return &moduleAdapter{
   144  			gomod: m.gomod.Replace,
   145  			owner: m.owner,
   146  		}
   147  	}
   148  	return nil
   149  }
   150  
   151  func (m *moduleAdapter) Vendor() bool {
   152  	return m.vendor
   153  }
   154  
   155  func (m *moduleAdapter) Version() string {
   156  	if !m.IsGoMod() || m.version != "" {
   157  		return m.version
   158  	}
   159  	return m.gomod.Version
   160  }
   161  
   162  func (m *moduleAdapter) Time() time.Time {
   163  	if !m.IsGoMod() || m.gomod.Time == nil {
   164  		return time.Time{}
   165  	}
   166  
   167  	return *m.gomod.Time
   168  
   169  }
   170  
   171  func (m *moduleAdapter) Watch() bool {
   172  	if m.Owner() == nil {
   173  		// Main project
   174  		return true
   175  	}
   176  
   177  	if !m.IsGoMod() {
   178  		// Module inside /themes
   179  		return true
   180  	}
   181  
   182  	if m.Replace() != nil {
   183  		// Version is not set when replaced by a local folder.
   184  		return m.Replace().Version() == ""
   185  	}
   186  
   187  	return false
   188  }