github.com/shohhei1126/hugo@v0.42.2-0.20180623210752-3d5928889ad7/commands/commands.go (about) 1 // Copyright 2017 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 commands 15 16 import ( 17 "github.com/gohugoio/hugo/config" 18 "github.com/gohugoio/hugo/helpers" 19 "github.com/spf13/cobra" 20 21 "github.com/spf13/nitro" 22 ) 23 24 type commandsBuilder struct { 25 hugoBuilderCommon 26 27 commands []cmder 28 } 29 30 func newCommandsBuilder() *commandsBuilder { 31 return &commandsBuilder{} 32 } 33 34 func (b *commandsBuilder) addCommands(commands ...cmder) *commandsBuilder { 35 b.commands = append(b.commands, commands...) 36 return b 37 } 38 39 func (b *commandsBuilder) addAll() *commandsBuilder { 40 b.addCommands( 41 b.newServerCmd(), 42 newVersionCmd(), 43 newEnvCmd(), 44 newConfigCmd(), 45 newCheckCmd(), 46 b.newBenchmarkCmd(), 47 newConvertCmd(), 48 newNewCmd(), 49 newListCmd(), 50 newImportCmd(), 51 newGenCmd(), 52 createReleaser(), 53 ) 54 55 return b 56 } 57 58 func (b *commandsBuilder) build() *hugoCmd { 59 h := b.newHugoCmd() 60 addCommands(h.getCommand(), b.commands...) 61 return h 62 } 63 64 func addCommands(root *cobra.Command, commands ...cmder) { 65 for _, command := range commands { 66 cmd := command.getCommand() 67 if cmd == nil { 68 continue 69 } 70 root.AddCommand(cmd) 71 } 72 } 73 74 type baseCmd struct { 75 cmd *cobra.Command 76 } 77 78 var _ commandsBuilderGetter = (*baseBuilderCmd)(nil) 79 80 // Used in tests. 81 type commandsBuilderGetter interface { 82 getCmmandsBuilder() *commandsBuilder 83 } 84 type baseBuilderCmd struct { 85 *baseCmd 86 *commandsBuilder 87 } 88 89 func (b *baseBuilderCmd) getCmmandsBuilder() *commandsBuilder { 90 return b.commandsBuilder 91 } 92 93 func (c *baseCmd) getCommand() *cobra.Command { 94 return c.cmd 95 } 96 97 func newBaseCmd(cmd *cobra.Command) *baseCmd { 98 return &baseCmd{cmd: cmd} 99 } 100 101 func (b *commandsBuilder) newBuilderCmd(cmd *cobra.Command) *baseBuilderCmd { 102 bcmd := &baseBuilderCmd{commandsBuilder: b, baseCmd: &baseCmd{cmd: cmd}} 103 bcmd.hugoBuilderCommon.handleFlags(cmd) 104 return bcmd 105 } 106 107 func (c *baseCmd) flagsToConfig(cfg config.Provider) { 108 initializeFlags(c.cmd, cfg) 109 } 110 111 type hugoCmd struct { 112 *baseBuilderCmd 113 114 // Need to get the sites once built. 115 c *commandeer 116 } 117 118 var _ cmder = (*nilCommand)(nil) 119 120 type nilCommand struct { 121 } 122 123 func (c *nilCommand) getCommand() *cobra.Command { 124 return nil 125 } 126 127 func (c *nilCommand) flagsToConfig(cfg config.Provider) { 128 129 } 130 131 func (b *commandsBuilder) newHugoCmd() *hugoCmd { 132 cc := &hugoCmd{} 133 134 cc.baseBuilderCmd = b.newBuilderCmd(&cobra.Command{ 135 Use: "hugo", 136 Short: "hugo builds your site", 137 Long: `hugo is the main command, used to build your Hugo site. 138 139 Hugo is a Fast and Flexible Static Site Generator 140 built with love by spf13 and friends in Go. 141 142 Complete documentation is available at http://gohugo.io/.`, 143 RunE: func(cmd *cobra.Command, args []string) error { 144 cfgInit := func(c *commandeer) error { 145 if cc.buildWatch { 146 c.Set("disableLiveReload", true) 147 } 148 return nil 149 } 150 151 c, err := initializeConfig(true, cc.buildWatch, &cc.hugoBuilderCommon, cc, cfgInit) 152 if err != nil { 153 return err 154 } 155 cc.c = c 156 157 return c.build() 158 }, 159 }) 160 161 cc.cmd.PersistentFlags().StringVar(&cc.cfgFile, "config", "", "config file (default is path/config.yaml|json|toml)") 162 cc.cmd.PersistentFlags().BoolVar(&cc.quiet, "quiet", false, "build in quiet mode") 163 164 // Set bash-completion 165 validConfigFilenames := []string{"json", "js", "yaml", "yml", "toml", "tml"} 166 _ = cc.cmd.PersistentFlags().SetAnnotation("config", cobra.BashCompFilenameExt, validConfigFilenames) 167 168 cc.cmd.PersistentFlags().BoolVarP(&cc.verbose, "verbose", "v", false, "verbose output") 169 cc.cmd.PersistentFlags().BoolVarP(&cc.debug, "debug", "", false, "debug output") 170 cc.cmd.PersistentFlags().BoolVar(&cc.logging, "log", false, "enable Logging") 171 cc.cmd.PersistentFlags().StringVar(&cc.logFile, "logFile", "", "log File path (if set, logging enabled automatically)") 172 cc.cmd.PersistentFlags().BoolVar(&cc.verboseLog, "verboseLog", false, "verbose logging") 173 174 cc.cmd.Flags().BoolVarP(&cc.buildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed") 175 176 cc.cmd.Flags().Bool("renderToMemory", false, "render to memory (only useful for benchmark testing)") 177 178 // Set bash-completion 179 _ = cc.cmd.PersistentFlags().SetAnnotation("logFile", cobra.BashCompFilenameExt, []string{}) 180 181 cc.cmd.SetGlobalNormalizationFunc(helpers.NormalizeHugoFlags) 182 cc.cmd.SilenceUsage = true 183 184 return cc 185 } 186 187 type hugoBuilderCommon struct { 188 source string 189 baseURL string 190 191 buildWatch bool 192 193 gc bool 194 195 // TODO(bep) var vs string 196 logging bool 197 verbose bool 198 verboseLog bool 199 debug bool 200 quiet bool 201 202 cfgFile string 203 logFile string 204 } 205 206 func (cc *hugoBuilderCommon) handleFlags(cmd *cobra.Command) { 207 cmd.Flags().Bool("cleanDestinationDir", false, "remove files from destination not found in static directories") 208 cmd.Flags().BoolP("buildDrafts", "D", false, "include content marked as draft") 209 cmd.Flags().BoolP("buildFuture", "F", false, "include content with publishdate in the future") 210 cmd.Flags().BoolP("buildExpired", "E", false, "include expired content") 211 cmd.Flags().StringVarP(&cc.source, "source", "s", "", "filesystem path to read files relative from") 212 cmd.Flags().StringP("contentDir", "c", "", "filesystem path to content directory") 213 cmd.Flags().StringP("layoutDir", "l", "", "filesystem path to layout directory") 214 cmd.Flags().StringP("cacheDir", "", "", "filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/") 215 cmd.Flags().BoolP("ignoreCache", "", false, "ignores the cache directory") 216 cmd.Flags().StringP("destination", "d", "", "filesystem path to write files to") 217 cmd.Flags().StringP("theme", "t", "", "theme to use (located in /themes/THEMENAME/)") 218 cmd.Flags().StringP("themesDir", "", "", "filesystem path to themes directory") 219 cmd.Flags().Bool("uglyURLs", false, "(deprecated) if true, use /filename.html instead of /filename/") 220 cmd.Flags().Bool("canonifyURLs", false, "(deprecated) if true, all relative URLs will be canonicalized using baseURL") 221 cmd.Flags().StringVarP(&cc.baseURL, "baseURL", "b", "", "hostname (and path) to the root, e.g. http://spf13.com/") 222 cmd.Flags().Bool("enableGitInfo", false, "add Git revision, date and author info to the pages") 223 cmd.Flags().BoolVar(&cc.gc, "gc", false, "enable to run some cleanup tasks (remove unused cache files) after the build") 224 225 cmd.Flags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program") 226 cmd.Flags().Bool("templateMetrics", false, "display metrics about template executions") 227 cmd.Flags().Bool("templateMetricsHints", false, "calculate some improvement hints when combined with --templateMetrics") 228 cmd.Flags().Bool("pluralizeListTitles", true, "(deprecated) pluralize titles in lists using inflect") 229 cmd.Flags().Bool("preserveTaxonomyNames", false, `(deprecated) preserve taxonomy names as written ("GĂ©rard Depardieu" vs "gerard-depardieu")`) 230 cmd.Flags().BoolP("forceSyncStatic", "", false, "copy all files when static is changed.") 231 cmd.Flags().BoolP("noTimes", "", false, "don't sync modification time of files") 232 cmd.Flags().BoolP("noChmod", "", false, "don't sync permission mode of files") 233 cmd.Flags().BoolP("i18n-warnings", "", false, "print missing translations") 234 235 cmd.Flags().StringSlice("disableKinds", []string{}, "disable different kind of pages (home, RSS etc.)") 236 237 // Set bash-completion. 238 // Each flag must first be defined before using the SetAnnotation() call. 239 _ = cmd.Flags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{}) 240 _ = cmd.Flags().SetAnnotation("cacheDir", cobra.BashCompSubdirsInDir, []string{}) 241 _ = cmd.Flags().SetAnnotation("destination", cobra.BashCompSubdirsInDir, []string{}) 242 _ = cmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"}) 243 }