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  }