From 87ca0d0cbea19dd2c0aac44dc2731e6247a82ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Fri, 5 Feb 2016 18:41:40 +0100 Subject: [PATCH] Clean flags * Reduce the amount of global flags * Unexport all flag vars and commands vars * Some other minor flag cleaning --- commands/benchmark.go | 10 +- commands/check.go | 2 +- commands/hugo.go | 239 ++++++++++++++++++++++++------------------ commands/new.go | 22 ++-- commands/server.go | 22 ++-- 5 files changed, 171 insertions(+), 124 deletions(-) diff --git a/commands/benchmark.go b/commands/benchmark.go index 7e746535f..f2b7964c0 100644 --- a/commands/benchmark.go +++ b/commands/benchmark.go @@ -19,9 +19,11 @@ import ( "runtime/pprof" ) -var cpuProfilefile string -var memProfilefile string -var benchmarkTimes int +var ( + benchmarkTimes int + cpuProfilefile string + memProfilefile string +) var benchmarkCmd = &cobra.Command{ Use: "benchmark", @@ -31,7 +33,7 @@ creating a benchmark.`, } func init() { - initCoreCommonFlags(benchmarkCmd) + initHugoBuilderFlags(benchmarkCmd) benchmarkCmd.Flags().StringVar(&cpuProfilefile, "cpuprofile", "", "path/filename for the CPU profile file") benchmarkCmd.Flags().StringVar(&memProfilefile, "memprofile", "", "path/filename for the memory profile file") diff --git a/commands/check.go b/commands/check.go index 8d6350b93..e8d2e12ed 100644 --- a/commands/check.go +++ b/commands/check.go @@ -26,7 +26,7 @@ and will give feedback.`, } func init() { - initCoreCommonFlags(checkCmd) + initHugoBuilderFlags(checkCmd) checkCmd.RunE = check } diff --git a/commands/hugo.go b/commands/hugo.go index 5fa3dbec0..591101da1 100644 --- a/commands/hugo.go +++ b/commands/hugo.go @@ -27,6 +27,7 @@ import ( "time" "github.com/spf13/hugo/parser" + flag "github.com/spf13/pflag" "regexp" @@ -92,7 +93,7 @@ func isUserError(err error) bool { // HugoCmd is Hugo's root command. // Every other command attached to HugoCmd is a child command to it. -var HugoCmd = &cobra.Command{ +var hugoCmd = &cobra.Command{ Use: "hugo", Short: "hugo builds your site", Long: `hugo is the main command, used to build your Hugo site. @@ -106,7 +107,7 @@ Complete documentation is available at http://gohugo.io/.`, return err } - if BuildWatch { + if buildWatch { viper.Set("DisableLiveReload", true) watchConfig() } @@ -118,18 +119,37 @@ Complete documentation is available at http://gohugo.io/.`, var hugoCmdV *cobra.Command // Flags that are to be added to commands. -var BuildWatch, IgnoreCache, Draft, Future, UglyURLs, CanonifyURLs, Verbose, Logging, VerboseLog, DisableRSS, DisableSitemap, DisableRobotsTXT, PluralizeListTitles, PreserveTaxonomyNames, NoTimes, ForceSync, CleanDestination bool -var Source, CacheDir, Destination, Theme, BaseURL, CfgFile, LogFile, Editor string +var ( + canonifyURLs bool + cleanDestination bool + disableRobotsTXT bool + disableRSS bool + disableSitemap bool + draft bool + future bool + ignoreCache bool + logging bool + noTimes bool + pluralizeListTitles bool + preserveTaxonomyNames bool + uglyURLs bool + verbose bool + verboseLog bool + buildWatch bool +) + +var forceSync bool +var Source, CacheDir, Destination, Theme, BaseURL, CfgFile, LogFile string // Execute adds all child commands to the root command HugoCmd and sets flags appropriately. func Execute() { - HugoCmd.SetGlobalNormalizationFunc(helpers.NormalizeHugoFlags) + hugoCmd.SetGlobalNormalizationFunc(helpers.NormalizeHugoFlags) - HugoCmd.SilenceUsage = true + hugoCmd.SilenceUsage = true AddCommands() - if c, err := HugoCmd.ExecuteC(); err != nil { + if c, err := hugoCmd.ExecuteC(); err != nil { if isUserError(err) { c.Println("") c.Println(c.UsageString()) @@ -141,46 +161,34 @@ func Execute() { // AddCommands adds child commands to the root command HugoCmd. func AddCommands() { - HugoCmd.AddCommand(serverCmd) - HugoCmd.AddCommand(versionCmd) - HugoCmd.AddCommand(configCmd) - HugoCmd.AddCommand(checkCmd) - HugoCmd.AddCommand(benchmarkCmd) - HugoCmd.AddCommand(convertCmd) - HugoCmd.AddCommand(newCmd) - HugoCmd.AddCommand(listCmd) - HugoCmd.AddCommand(undraftCmd) - HugoCmd.AddCommand(importCmd) + hugoCmd.AddCommand(serverCmd) + hugoCmd.AddCommand(versionCmd) + hugoCmd.AddCommand(configCmd) + hugoCmd.AddCommand(checkCmd) + hugoCmd.AddCommand(benchmarkCmd) + hugoCmd.AddCommand(convertCmd) + hugoCmd.AddCommand(newCmd) + hugoCmd.AddCommand(listCmd) + hugoCmd.AddCommand(undraftCmd) + hugoCmd.AddCommand(importCmd) - HugoCmd.AddCommand(genCmd) + hugoCmd.AddCommand(genCmd) genCmd.AddCommand(genautocompleteCmd) genCmd.AddCommand(gendocCmd) genCmd.AddCommand(genmanCmd) } +// initHugoBuilderFlags initializes all common flags, typically used by the +// core build commands. +func initHugoBuilderFlags(cmd *cobra.Command) { + initCoreCommonFlags(cmd) + initHugoBuildCommonFlags(cmd) +} + // initCoreCommonFlags initializes common flags used by Hugo core commands // such as hugo itself, server, check, config and benchmark. func initCoreCommonFlags(cmd *cobra.Command) { - cmd.Flags().BoolVar(&CleanDestination, "cleanDestinationDir", false, "Remove files from destination not found in static directories") - cmd.Flags().BoolVarP(&Draft, "buildDrafts", "D", false, "include content marked as draft") - cmd.Flags().BoolVarP(&Future, "buildFuture", "F", false, "include content with publishdate in the future") - cmd.Flags().BoolVar(&DisableRSS, "disableRSS", false, "Do not build RSS files") - cmd.Flags().BoolVar(&DisableSitemap, "disableSitemap", false, "Do not build Sitemap file") - cmd.Flags().BoolVar(&DisableRobotsTXT, "disableRobotsTXT", false, "Do not build Robots TXT file") - cmd.Flags().StringVarP(&Source, "source", "s", "", "filesystem path to read files relative from") - cmd.Flags().StringVarP(&CacheDir, "cacheDir", "", "", "filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/") - cmd.Flags().BoolVarP(&IgnoreCache, "ignoreCache", "", false, "Ignores the cache directory for reading but still writes to it") - cmd.Flags().StringVarP(&Destination, "destination", "d", "", "filesystem path to write files to") - cmd.Flags().StringVarP(&Theme, "theme", "t", "", "theme to use (located in /themes/THEMENAME/)") - cmd.Flags().BoolVar(&UglyURLs, "uglyURLs", false, "if true, use /filename.html instead of /filename/") - cmd.Flags().BoolVar(&CanonifyURLs, "canonifyURLs", false, "if true, all relative URLs will be canonicalized using baseURL") - cmd.Flags().StringVarP(&BaseURL, "baseURL", "b", "", "hostname (and path) to the root, e.g. http://spf13.com/") cmd.Flags().StringVar(&CfgFile, "config", "", "config file (default is path/config.yaml|json|toml)") - cmd.Flags().StringVar(&Editor, "editor", "", "edit new content with this editor, if provided") - cmd.Flags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program") - cmd.Flags().BoolVar(&PluralizeListTitles, "pluralizeListTitles", true, "Pluralize titles in lists using inflect") - cmd.Flags().BoolVar(&PreserveTaxonomyNames, "preserveTaxonomyNames", false, `Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")`) - cmd.Flags().BoolVarP(&ForceSync, "forceSyncStatic", "", false, "Copy all files when static is changed.") // For bash-completion validConfigFilenames := []string{"json", "js", "yaml", "yml", "toml", "tml"} cmd.Flags().SetAnnotation("config", cobra.BashCompFilenameExt, validConfigFilenames) @@ -190,21 +198,45 @@ func initCoreCommonFlags(cmd *cobra.Command) { cmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"}) } +// initial flags related to the Hugo build +func initHugoBuildCommonFlags(cmd *cobra.Command) { + cmd.Flags().BoolVar(&cleanDestination, "cleanDestinationDir", false, "Remove files from destination not found in static directories") + cmd.Flags().BoolVarP(&draft, "buildDrafts", "D", false, "include content marked as draft") + cmd.Flags().BoolVarP(&future, "buildFuture", "F", false, "include content with publishdate in the future") + cmd.Flags().BoolVar(&disableRSS, "disableRSS", false, "Do not build RSS files") + cmd.Flags().BoolVar(&disableSitemap, "disableSitemap", false, "Do not build Sitemap file") + cmd.Flags().BoolVar(&disableRobotsTXT, "disableRobotsTXT", false, "Do not build Robots TXT file") + cmd.Flags().StringVarP(&Source, "source", "s", "", "filesystem path to read files relative from") + cmd.Flags().StringVarP(&CacheDir, "cacheDir", "", "", "filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/") + cmd.Flags().BoolVarP(&ignoreCache, "ignoreCache", "", false, "Ignores the cache directory for reading but still writes to it") + cmd.Flags().StringVarP(&Destination, "destination", "d", "", "filesystem path to write files to") + cmd.Flags().StringVarP(&Theme, "theme", "t", "", "theme to use (located in /themes/THEMENAME/)") + cmd.Flags().BoolVar(&uglyURLs, "uglyURLs", false, "if true, use /filename.html instead of /filename/") + cmd.Flags().BoolVar(&canonifyURLs, "canonifyURLs", false, "if true, all relative URLs will be canonicalized using baseURL") + cmd.Flags().StringVarP(&BaseURL, "baseURL", "b", "", "hostname (and path) to the root, e.g. http://spf13.com/") + + cmd.Flags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program") + cmd.Flags().BoolVar(&pluralizeListTitles, "pluralizeListTitles", true, "Pluralize titles in lists using inflect") + cmd.Flags().BoolVar(&preserveTaxonomyNames, "preserveTaxonomyNames", false, `Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")`) + cmd.Flags().BoolVarP(&forceSync, "forceSyncStatic", "", false, "Copy all files when static is changed.") + cmd.Flags().BoolVarP(&noTimes, "noTimes", "", false, "Don't sync modification time of files") + +} + // init initializes flags. func init() { - HugoCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") - HugoCmd.PersistentFlags().BoolVar(&Logging, "log", false, "Enable Logging") - HugoCmd.PersistentFlags().StringVar(&LogFile, "logFile", "", "Log File path (if set, logging enabled automatically)") - HugoCmd.PersistentFlags().BoolVar(&VerboseLog, "verboseLog", false, "verbose logging") + hugoCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output") + hugoCmd.PersistentFlags().BoolVar(&logging, "log", false, "Enable Logging") + hugoCmd.PersistentFlags().StringVar(&LogFile, "logFile", "", "Log File path (if set, logging enabled automatically)") + hugoCmd.PersistentFlags().BoolVar(&verboseLog, "verboseLog", false, "verbose logging") - initCoreCommonFlags(HugoCmd) + initHugoBuilderFlags(hugoCmd) - HugoCmd.Flags().BoolVarP(&BuildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed") - HugoCmd.Flags().BoolVarP(&NoTimes, "noTimes", "", false, "Don't sync modification time of files") - hugoCmdV = HugoCmd + hugoCmd.Flags().BoolVarP(&buildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed") + hugoCmdV = hugoCmd // For bash-completion - HugoCmd.PersistentFlags().SetAnnotation("logFile", cobra.BashCompFilenameExt, []string{}) + hugoCmd.PersistentFlags().SetAnnotation("logFile", cobra.BashCompFilenameExt, []string{}) } func LoadDefaultSettings() { @@ -278,57 +310,54 @@ func InitializeConfig(subCmdVs ...*cobra.Command) error { LoadDefaultSettings() - if hugoCmdV.PersistentFlags().Lookup("verbose").Changed { - viper.Set("Verbose", Verbose) - } - if hugoCmdV.PersistentFlags().Lookup("logFile").Changed { - viper.Set("LogFile", LogFile) - } - for _, cmdV := range append([]*cobra.Command{hugoCmdV}, subCmdVs...) { - if cmdV.Flags().Lookup("cleanDestinationDir").Changed { - viper.Set("cleanDestinationDir", CleanDestination) - } - if cmdV.Flags().Lookup("buildDrafts").Changed { - viper.Set("BuildDrafts", Draft) - } - if cmdV.Flags().Lookup("buildFuture").Changed { - viper.Set("BuildFuture", Future) - } - if cmdV.Flags().Lookup("uglyURLs").Changed { - viper.Set("UglyURLs", UglyURLs) - } - if cmdV.Flags().Lookup("canonifyURLs").Changed { - viper.Set("CanonifyURLs", CanonifyURLs) - } - if cmdV.Flags().Lookup("disableRSS").Changed { - viper.Set("DisableRSS", DisableRSS) - } - if cmdV.Flags().Lookup("disableSitemap").Changed { - viper.Set("DisableSitemap", DisableSitemap) - } - if cmdV.Flags().Lookup("disableRobotsTXT").Changed { - viper.Set("DisableRobotsTXT", DisableRobotsTXT) - } - if cmdV.Flags().Lookup("pluralizeListTitles").Changed { - viper.Set("PluralizeListTitles", PluralizeListTitles) - } - if cmdV.Flags().Lookup("preserveTaxonomyNames").Changed { - viper.Set("PreserveTaxonomyNames", PreserveTaxonomyNames) - } - if cmdV.Flags().Lookup("forceSyncStatic").Changed { - viper.Set("ForceSyncStatic", ForceSync) - } - if cmdV.Flags().Lookup("editor").Changed { - viper.Set("NewContentEditor", Editor) - } - if cmdV.Flags().Lookup("ignoreCache").Changed { - viper.Set("IgnoreCache", IgnoreCache) - } - } - if hugoCmdV.Flags().Lookup("noTimes").Changed { - viper.Set("NoTimes", NoTimes) + if flagChanged(cmdV.PersistentFlags(), "verbose") { + viper.Set("Verbose", verbose) + } + if flagChanged(cmdV.PersistentFlags(), "logFile") { + viper.Set("LogFile", LogFile) + } + if flagChanged(cmdV.Flags(), "cleanDestinationDir") { + viper.Set("cleanDestinationDir", cleanDestination) + } + if flagChanged(cmdV.Flags(), "buildDrafts") { + viper.Set("BuildDrafts", draft) + } + if flagChanged(cmdV.Flags(), "buildFuture") { + viper.Set("BuildFuture", future) + } + if flagChanged(cmdV.Flags(), "uglyURLs") { + viper.Set("UglyURLs", uglyURLs) + } + if flagChanged(cmdV.Flags(), "canonifyURLs") { + viper.Set("CanonifyURLs", canonifyURLs) + } + if flagChanged(cmdV.Flags(), "disableRSS") { + viper.Set("DisableRSS", disableRSS) + } + if flagChanged(cmdV.Flags(), "disableSitemap") { + viper.Set("DisableSitemap", disableSitemap) + } + if flagChanged(cmdV.Flags(), "disableRobotsTXT") { + viper.Set("DisableRobotsTXT", disableRobotsTXT) + } + if flagChanged(cmdV.Flags(), "pluralizeListTitles") { + viper.Set("PluralizeListTitles", pluralizeListTitles) + } + if flagChanged(cmdV.Flags(), "preserveTaxonomyNames") { + viper.Set("PreserveTaxonomyNames", preserveTaxonomyNames) + } + if flagChanged(cmdV.Flags(), "ignoreCache") { + viper.Set("IgnoreCache", ignoreCache) + } + if flagChanged(cmdV.Flags(), "forceSyncStatic") { + viper.Set("ForceSyncStatic", forceSync) + } + if flagChanged(cmdV.Flags(), "noTimes") { + viper.Set("NoTimes", noTimes) + } + } if BaseURL != "" { @@ -372,7 +401,7 @@ func InitializeConfig(subCmdVs ...*cobra.Command) error { viper.Set("CacheDir", helpers.GetTempDir("hugo_cache", hugofs.SourceFs)) } - if VerboseLog || Logging || (viper.IsSet("LogFile") && viper.GetString("LogFile") != "") { + if verboseLog || logging || (viper.IsSet("LogFile") && viper.GetString("LogFile") != "") { if viper.IsSet("LogFile") && viper.GetString("LogFile") != "" { jww.SetLogFile(viper.GetString("LogFile")) } else { @@ -386,7 +415,7 @@ func InitializeConfig(subCmdVs ...*cobra.Command) error { jww.SetStdoutThreshold(jww.LevelInfo) } - if VerboseLog { + if verboseLog { jww.SetLogThreshold(jww.LevelInfo) } @@ -409,6 +438,14 @@ func InitializeConfig(subCmdVs ...*cobra.Command) error { return nil } +func flagChanged(flags *flag.FlagSet, key string) bool { + flag := flags.Lookup(key) + if flag == nil { + return false + } + return flag.Changed +} + func watchConfig() { viper.WatchConfig() viper.OnConfigChange(func(e fsnotify.Event) { @@ -430,11 +467,11 @@ func build(watches ...bool) error { if len(watches) > 0 && watches[0] { watch = true } - if err := buildSite(BuildWatch || watch); err != nil { + if err := buildSite(buildWatch || watch); err != nil { return fmt.Errorf("Error building site: %s", err) } - if BuildWatch { + if buildWatch { jww.FEEDBACK.Println("Watching for changes in", helpers.AbsPathify(viper.GetString("ContentDir"))) jww.FEEDBACK.Println("Press Ctrl+C to stop") utils.CheckErr(NewWatcher(0)) @@ -787,7 +824,7 @@ func NewWatcher(port int) error { } } - if !BuildWatch && !viper.GetBool("DisableLiveReload") { + if !buildWatch && !viper.GetBool("DisableLiveReload") { // Will block forever trying to write to a channel that nobody is reading if livereload isn't initialized // force refresh when more than one file @@ -810,7 +847,7 @@ func NewWatcher(port int) error { rebuildSite(dynamicEvents) - if !BuildWatch && !viper.GetBool("DisableLiveReload") { + if !buildWatch && !viper.GetBool("DisableLiveReload") { // Will block forever trying to write to a channel that nobody is reading if livereload isn't initialized livereload.ForceRefresh() } diff --git a/commands/new.go b/commands/new.go index 8c2e4850f..73065fa94 100644 --- a/commands/new.go +++ b/commands/new.go @@ -30,11 +30,14 @@ import ( "github.com/spf13/viper" ) -var siteType string -var configFormat string -var contentType string -var contentFormat string -var contentFrontMatter string +var ( + configFormat string + contentEditor string + contentFormat string + contentFrontMatter string + contentType string + siteType string +) func init() { newSiteCmd.Flags().StringVarP(&configFormat, "format", "f", "toml", "config & frontmatter format") @@ -43,8 +46,11 @@ func init() { newCmd.Flags().StringVarP(&contentType, "kind", "k", "", "Content type to create") newCmd.PersistentFlags().StringVarP(&Source, "source", "s", "", "filesystem path to read files relative from") newCmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{}) + newCmd.Flags().StringVar(&contentEditor, "editor", "", "edit new content with this editor, if provided") + newCmd.AddCommand(newSiteCmd) newCmd.AddCommand(newThemeCmd) + } var newCmd = &cobra.Command{ @@ -85,10 +91,14 @@ func NewContent(cmd *cobra.Command, args []string) error { return err } - if cmd.Flags().Lookup("format").Changed { + if flagChanged(cmd.Flags(), "format") { viper.Set("MetaDataFormat", configFormat) } + if flagChanged(cmd.Flags(), "editor") { + viper.Set("NewContentEditor", contentEditor) + } + if len(args) < 1 { return newUserError("path needs to be provided") } diff --git a/commands/server.go b/commands/server.go index 875a98ba2..df75395d2 100644 --- a/commands/server.go +++ b/commands/server.go @@ -32,12 +32,14 @@ import ( "github.com/spf13/viper" ) -var serverPort int -var serverInterface string -var serverWatch bool -var serverAppend bool -var disableLiveReload bool -var renderToDisk bool +var ( + disableLiveReload bool + renderToDisk bool + serverAppend bool + serverInterface string + serverPort int + serverWatch bool +) //var serverCmdV *cobra.Command @@ -81,14 +83,14 @@ func (f noDirFile) Readdir(count int) ([]os.FileInfo, error) { } func init() { - initCoreCommonFlags(serverCmd) + initHugoBuilderFlags(serverCmd) + serverCmd.Flags().IntVarP(&serverPort, "port", "p", 1313, "port on which the server will listen") serverCmd.Flags().StringVarP(&serverInterface, "bind", "", "127.0.0.1", "interface to which the server will bind") serverCmd.Flags().BoolVarP(&serverWatch, "watch", "w", true, "watch filesystem for changes and recreate as needed") serverCmd.Flags().BoolVarP(&serverAppend, "appendPort", "", true, "append port to baseurl") serverCmd.Flags().BoolVar(&disableLiveReload, "disableLiveReload", false, "watch without enabling live browser reload on rebuild") serverCmd.Flags().BoolVar(&renderToDisk, "renderToDisk", false, "render to Destination path (default is render to memory & serve from there)") - serverCmd.Flags().BoolVarP(&NoTimes, "noTimes", "", false, "Don't sync modification time of files") serverCmd.Flags().String("memstats", "", "log memory usage to this file") serverCmd.Flags().Int("meminterval", 100, "interval to poll memory usage (requires --memstats)") serverCmd.RunE = server @@ -148,10 +150,6 @@ func server(cmd *cobra.Command, args []string) error { viper.Set("PublishDir", "/") } - if serverCmd.Flags().Lookup("noTimes").Changed { - viper.Set("NoTimes", NoTimes) - } - if err := build(serverWatch); err != nil { return err }