aboutsummaryrefslogtreecommitdiffhomepage
path: root/deploy/deployconfig/deployConfig.go
diff options
context:
space:
mode:
Diffstat (limited to 'deploy/deployconfig/deployConfig.go')
-rw-r--r--deploy/deployconfig/deployConfig.go174
1 files changed, 174 insertions, 0 deletions
diff --git a/deploy/deployconfig/deployConfig.go b/deploy/deployconfig/deployConfig.go
new file mode 100644
index 000000000..b5b8973b2
--- /dev/null
+++ b/deploy/deployconfig/deployConfig.go
@@ -0,0 +1,174 @@
+// Copyright 2024 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 deployconfig
+
+import (
+ "errors"
+ "fmt"
+ "regexp"
+
+ "github.com/gobwas/glob"
+ "github.com/gohugoio/hugo/config"
+ hglob "github.com/gohugoio/hugo/hugofs/glob"
+ "github.com/mitchellh/mapstructure"
+)
+
+const DeploymentConfigKey = "deployment"
+
+// DeployConfig is the complete configuration for deployment.
+type DeployConfig struct {
+ Targets []*Target
+ Matchers []*Matcher
+ Order []string
+
+ // Usually set via flags.
+ // Target deployment Name; defaults to the first one.
+ Target string
+ // Show a confirm prompt before deploying.
+ Confirm bool
+ // DryRun will try the deployment without any remote changes.
+ DryRun bool
+ // Force will re-upload all files.
+ Force bool
+ // Invalidate the CDN cache listed in the deployment target.
+ InvalidateCDN bool
+ // MaxDeletes is the maximum number of files to delete.
+ MaxDeletes int
+ // Number of concurrent workers to use when uploading files.
+ Workers int
+
+ Ordering []*regexp.Regexp `json:"-"` // compiled Order
+}
+
+type Target struct {
+ Name string
+ URL string
+
+ CloudFrontDistributionID string
+
+ // GoogleCloudCDNOrigin specifies the Google Cloud project and CDN origin to
+ // invalidate when deploying this target. It is specified as <project>/<origin>.
+ GoogleCloudCDNOrigin string
+
+ // Optional patterns of files to include/exclude for this target.
+ // Parsed using github.com/gobwas/glob.
+ Include string
+ Exclude string
+
+ // Parsed versions of Include/Exclude.
+ IncludeGlob glob.Glob `json:"-"`
+ ExcludeGlob glob.Glob `json:"-"`
+}
+
+func (tgt *Target) ParseIncludeExclude() error {
+ var err error
+ if tgt.Include != "" {
+ tgt.IncludeGlob, err = hglob.GetGlob(tgt.Include)
+ if err != nil {
+ return fmt.Errorf("invalid deployment.target.include %q: %v", tgt.Include, err)
+ }
+ }
+ if tgt.Exclude != "" {
+ tgt.ExcludeGlob, err = hglob.GetGlob(tgt.Exclude)
+ if err != nil {
+ return fmt.Errorf("invalid deployment.target.exclude %q: %v", tgt.Exclude, err)
+ }
+ }
+ return nil
+}
+
+// Matcher represents configuration to be applied to files whose paths match
+// a specified pattern.
+type Matcher struct {
+ // Pattern is the string pattern to match against paths.
+ // Matching is done against paths converted to use / as the path separator.
+ Pattern string
+
+ // CacheControl specifies caching attributes to use when serving the blob.
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
+ CacheControl string
+
+ // ContentEncoding specifies the encoding used for the blob's content, if any.
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
+ ContentEncoding string
+
+ // ContentType specifies the MIME type of the blob being written.
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
+ ContentType string
+
+ // Gzip determines whether the file should be gzipped before upload.
+ // If so, the ContentEncoding field will automatically be set to "gzip".
+ Gzip bool
+
+ // Force indicates that matching files should be re-uploaded. Useful when
+ // other route-determined metadata (e.g., ContentType) has changed.
+ Force bool
+
+ // Re is Pattern compiled.
+ Re *regexp.Regexp `json:"-"`
+}
+
+func (m *Matcher) Matches(path string) bool {
+ return m.Re.MatchString(path)
+}
+
+var DefaultConfig = DeployConfig{
+ Workers: 10,
+ InvalidateCDN: true,
+ MaxDeletes: 256,
+}
+
+// DecodeConfig creates a config from a given Hugo configuration.
+func DecodeConfig(cfg config.Provider) (DeployConfig, error) {
+ dcfg := DefaultConfig
+
+ if !cfg.IsSet(DeploymentConfigKey) {
+ return dcfg, nil
+ }
+ if err := mapstructure.WeakDecode(cfg.GetStringMap(DeploymentConfigKey), &dcfg); err != nil {
+ return dcfg, err
+ }
+
+ if dcfg.Workers <= 0 {
+ dcfg.Workers = 10
+ }
+
+ for _, tgt := range dcfg.Targets {
+ if *tgt == (Target{}) {
+ return dcfg, errors.New("empty deployment target")
+ }
+ if err := tgt.ParseIncludeExclude(); err != nil {
+ return dcfg, err
+ }
+ }
+ var err error
+ for _, m := range dcfg.Matchers {
+ if *m == (Matcher{}) {
+ return dcfg, errors.New("empty deployment matcher")
+ }
+ m.Re, err = regexp.Compile(m.Pattern)
+ if err != nil {
+ return dcfg, fmt.Errorf("invalid deployment.matchers.pattern: %v", err)
+ }
+ }
+ for _, o := range dcfg.Order {
+ re, err := regexp.Compile(o)
+ if err != nil {
+ return dcfg, fmt.Errorf("invalid deployment.orderings.pattern: %v", err)
+ }
+ dcfg.Ordering = append(dcfg.Ordering, re)
+ }
+
+ return dcfg, nil
+}