module.go (4004B)
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 }