summaryrefslogtreecommitdiffstats
path: root/commands/helpers.go
diff options
context:
space:
mode:
Diffstat (limited to 'commands/helpers.go')
-rw-r--r--commands/helpers.go131
1 files changed, 94 insertions, 37 deletions
diff --git a/commands/helpers.go b/commands/helpers.go
index 71f686953..c342ce2c7 100644
--- a/commands/helpers.go
+++ b/commands/helpers.go
@@ -1,4 +1,4 @@
-// Copyright 2018 The Hugo Authors. All rights reserved.
+// Copyright 2023 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.
@@ -11,16 +11,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Package commands defines and implements command-line commands and flags
-// used by Hugo. Commands and flags are implemented using Cobra.
package commands
import (
+ "bytes"
+ "errors"
"fmt"
- "regexp"
+ "log"
+ "os"
+ "path/filepath"
+ "strings"
+ "github.com/bep/simplecobra"
"github.com/gohugoio/hugo/config"
- "github.com/spf13/cobra"
+ "github.com/gohugoio/hugo/helpers"
+ "github.com/spf13/afero"
+ "github.com/spf13/pflag"
)
const (
@@ -30,50 +36,101 @@ const (
showCursor = ansiEsc + "[?25h"
)
-type flagsToConfigHandler interface {
- flagsToConfig(cfg config.Provider)
+func newUserError(a ...any) *simplecobra.CommandError {
+ return &simplecobra.CommandError{Err: errors.New(fmt.Sprint(a...))}
}
-type cmder interface {
- flagsToConfigHandler
- getCommand() *cobra.Command
-}
+func setValueFromFlag(flags *pflag.FlagSet, key string, cfg config.Provider, targetKey string, force bool) {
+ key = strings.TrimSpace(key)
+ if (force && flags.Lookup(key) != nil) || flags.Changed(key) {
+ f := flags.Lookup(key)
+ configKey := key
+ if targetKey != "" {
+ configKey = targetKey
+ }
+ // Gotta love this API.
+ switch f.Value.Type() {
+ case "bool":
+ bv, _ := flags.GetBool(key)
+ cfg.Set(configKey, bv)
+ case "string":
+ cfg.Set(configKey, f.Value.String())
+ case "stringSlice":
+ bv, _ := flags.GetStringSlice(key)
+ cfg.Set(configKey, bv)
+ case "int":
+ iv, _ := flags.GetInt(key)
+ cfg.Set(configKey, iv)
+ default:
+ panic(fmt.Sprintf("update switch with %s", f.Value.Type()))
+ }
-// commandError is an error used to signal different error situations in command handling.
-type commandError struct {
- s string
- userError bool
+ }
}
-func (c commandError) Error() string {
- return c.s
+func flagsToCfg(cd *simplecobra.Commandeer, cfg config.Provider) config.Provider {
+ return flagsToCfgWithAdditionalConfigBase(cd, cfg, "")
}
-func (c commandError) isUserError() bool {
- return c.userError
-}
+func flagsToCfgWithAdditionalConfigBase(cd *simplecobra.Commandeer, cfg config.Provider, additionalConfigBase string) config.Provider {
+ if cfg == nil {
+ cfg = config.New()
+ }
-func newUserError(a ...any) commandError {
- return commandError{s: fmt.Sprintln(a...), userError: true}
-}
+ // Flags with a different name in the config.
+ keyMap := map[string]string{
+ "minify": "minifyOutput",
+ "destination": "publishDir",
+ "printI18nWarnings": "logI18nWarnings",
+ "printPathWarnings": "logPathWarnings",
+ "editor": "newContentEditor",
+ }
-func newSystemError(a ...any) commandError {
- return commandError{s: fmt.Sprintln(a...), userError: false}
-}
+ // Flags that we for some reason don't want to expose in the site config.
+ internalKeySet := map[string]bool{
+ "quiet": true,
+ "verbose": true,
+ "watch": true,
+ "disableLiveReload": true,
+ "liveReloadPort": true,
+ "renderToMemory": true,
+ "clock": true,
+ }
-func newSystemErrorF(format string, a ...any) commandError {
- return commandError{s: fmt.Sprintf(format, a...), userError: false}
-}
+ cmd := cd.CobraCommand
+ flags := cmd.Flags()
-// Catch some of the obvious user errors from Cobra.
-// We don't want to show the usage message for every error.
-// The below may be to generic. Time will show.
-var userErrorRegexp = regexp.MustCompile("unknown flag")
+ flags.VisitAll(func(f *pflag.Flag) {
+ if f.Changed {
+ targetKey := f.Name
+ if internalKeySet[targetKey] {
+ targetKey = "internal." + targetKey
+ } else if mapped, ok := keyMap[targetKey]; ok {
+ targetKey = mapped
+ }
+ setValueFromFlag(flags, f.Name, cfg, targetKey, false)
+ if additionalConfigBase != "" {
+ setValueFromFlag(flags, f.Name, cfg, additionalConfigBase+"."+targetKey, true)
+ }
+ }
+ })
-func isUserError(err error) bool {
- if cErr, ok := err.(commandError); ok && cErr.isUserError() {
- return true
+ return cfg
+
+}
+
+func mkdir(x ...string) {
+ p := filepath.Join(x...)
+ err := os.MkdirAll(p, 0777) // before umask
+ if err != nil {
+ log.Fatal(err)
}
+}
- return userErrorRegexp.MatchString(err.Error())
+func touchFile(fs afero.Fs, filename string) {
+ mkdir(filepath.Dir(filename))
+ err := helpers.WriteToDisk(filename, bytes.NewReader([]byte{}), fs)
+ if err != nil {
+ log.Fatal(err)
+ }
}