github.com/gohugoio/hugo@v0.88.1/deploy/deployConfig.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 // +build !nodeploy 15 16 package deploy 17 18 import ( 19 "fmt" 20 "regexp" 21 22 "github.com/gobwas/glob" 23 "github.com/gohugoio/hugo/config" 24 hglob "github.com/gohugoio/hugo/hugofs/glob" 25 "github.com/gohugoio/hugo/media" 26 "github.com/mitchellh/mapstructure" 27 ) 28 29 const deploymentConfigKey = "deployment" 30 31 // deployConfig is the complete configuration for deployment. 32 type deployConfig struct { 33 Targets []*target 34 Matchers []*matcher 35 Order []string 36 37 ordering []*regexp.Regexp // compiled Order 38 mediaTypes media.Types 39 } 40 41 type target struct { 42 Name string 43 URL string 44 45 CloudFrontDistributionID string 46 47 // GoogleCloudCDNOrigin specifies the Google Cloud project and CDN origin to 48 // invalidate when deploying this target. It is specified as <project>/<origin>. 49 GoogleCloudCDNOrigin string 50 51 // Optional patterns of files to include/exclude for this target. 52 // Parsed using github.com/gobwas/glob. 53 Include string 54 Exclude string 55 56 // Parsed versions of Include/Exclude. 57 includeGlob glob.Glob 58 excludeGlob glob.Glob 59 } 60 61 func (tgt *target) parseIncludeExclude() error { 62 var err error 63 if tgt.Include != "" { 64 tgt.includeGlob, err = hglob.GetGlob(tgt.Include) 65 if err != nil { 66 return fmt.Errorf("invalid deployment.target.include %q: %v", tgt.Include, err) 67 } 68 } 69 if tgt.Exclude != "" { 70 tgt.excludeGlob, err = hglob.GetGlob(tgt.Exclude) 71 if err != nil { 72 return fmt.Errorf("invalid deployment.target.exclude %q: %v", tgt.Exclude, err) 73 } 74 } 75 return nil 76 } 77 78 // matcher represents configuration to be applied to files whose paths match 79 // a specified pattern. 80 type matcher struct { 81 // Pattern is the string pattern to match against paths. 82 // Matching is done against paths converted to use / as the path separator. 83 Pattern string 84 85 // CacheControl specifies caching attributes to use when serving the blob. 86 // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control 87 CacheControl string 88 89 // ContentEncoding specifies the encoding used for the blob's content, if any. 90 // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding 91 ContentEncoding string 92 93 // ContentType specifies the MIME type of the blob being written. 94 // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type 95 ContentType string 96 97 // Gzip determines whether the file should be gzipped before upload. 98 // If so, the ContentEncoding field will automatically be set to "gzip". 99 Gzip bool 100 101 // Force indicates that matching files should be re-uploaded. Useful when 102 // other route-determined metadata (e.g., ContentType) has changed. 103 Force bool 104 105 // re is Pattern compiled. 106 re *regexp.Regexp 107 } 108 109 func (m *matcher) Matches(path string) bool { 110 return m.re.MatchString(path) 111 } 112 113 // decode creates a config from a given Hugo configuration. 114 func decodeConfig(cfg config.Provider) (deployConfig, error) { 115 var ( 116 mediaTypesConfig []map[string]interface{} 117 dcfg deployConfig 118 ) 119 120 if !cfg.IsSet(deploymentConfigKey) { 121 return dcfg, nil 122 } 123 if err := mapstructure.WeakDecode(cfg.GetStringMap(deploymentConfigKey), &dcfg); err != nil { 124 return dcfg, err 125 } 126 for _, tgt := range dcfg.Targets { 127 if err := tgt.parseIncludeExclude(); err != nil { 128 return dcfg, err 129 } 130 } 131 var err error 132 for _, m := range dcfg.Matchers { 133 m.re, err = regexp.Compile(m.Pattern) 134 if err != nil { 135 return dcfg, fmt.Errorf("invalid deployment.matchers.pattern: %v", err) 136 } 137 } 138 for _, o := range dcfg.Order { 139 re, err := regexp.Compile(o) 140 if err != nil { 141 return dcfg, fmt.Errorf("invalid deployment.orderings.pattern: %v", err) 142 } 143 dcfg.ordering = append(dcfg.ordering, re) 144 } 145 146 if cfg.IsSet("mediaTypes") { 147 mediaTypesConfig = append(mediaTypesConfig, cfg.GetStringMap("mediaTypes")) 148 } 149 150 dcfg.mediaTypes, err = media.DecodeTypes(mediaTypesConfig...) 151 if err != nil { 152 return dcfg, err 153 } 154 return dcfg, nil 155 }