github.com/criteo/command-launcher@v0.0.0-20230407142452-fb616f546e98/cmd/config.go (about)

     1  package cmd
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"sort"
     7  	"strings"
     8  
     9  	"github.com/criteo/command-launcher/internal/config"
    10  	"github.com/criteo/command-launcher/internal/context"
    11  	log "github.com/sirupsen/logrus"
    12  	"github.com/spf13/cobra"
    13  	"github.com/spf13/viper"
    14  )
    15  
    16  type ConfigFlags struct {
    17  	Json bool
    18  }
    19  
    20  var (
    21  	configFlags = ConfigFlags{}
    22  )
    23  
    24  func AddConfigCmd(rootCmd *cobra.Command, appCtx context.LauncherContext) {
    25  	configCmd := &cobra.Command{
    26  		Use:   "config",
    27  		Short: "Manage configurations",
    28  		Long: fmt.Sprintf(`Manage the command launcher configurations
    29  
    30    Example:
    31      get configuration
    32      %s config [key]
    33  
    34      set configuration
    35      %s config [key] [value]
    36  	`, appCtx.AppName(), appCtx.AppName()),
    37  		Run: func(cmd *cobra.Command, args []string) {
    38  			// list all configs
    39  			if len(args) == 0 {
    40  				settings := viper.AllSettings()
    41  				printSettings(settings, configFlags.Json)
    42  			}
    43  
    44  			// get configuration with key
    45  			if len(args) == 1 {
    46  				if viper.Get(args[0]) == nil {
    47  					return
    48  				}
    49  				if configFlags.Json {
    50  					printSettings(map[string]interface{}{
    51  						args[0]: viper.Get(args[0]),
    52  					}, true)
    53  				} else {
    54  					fmt.Println(viper.Get(args[0]))
    55  				}
    56  
    57  			}
    58  
    59  			// set configuration with key
    60  			if len(args) == 2 {
    61  				if err := config.SetSettingValue(args[0], args[1]); err != nil {
    62  					fmt.Println(err)
    63  					return
    64  				}
    65  				if err := viper.WriteConfig(); err != nil {
    66  					log.Error("cannot write the default configuration: ", err)
    67  					return
    68  				}
    69  			}
    70  		},
    71  		ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
    72  			if len(args) > 0 {
    73  				return []string{}, cobra.ShellCompDirectiveNoFileComp
    74  			}
    75  
    76  			lowerKeys := []string{}
    77  			for _, k := range config.SettingKeys {
    78  				lowerKeys = append(lowerKeys, strings.ToLower(k))
    79  			}
    80  
    81  			return lowerKeys, cobra.ShellCompDirectiveNoFileComp
    82  		},
    83  	}
    84  
    85  	configCmd.Flags().BoolVarP(&configFlags.Json, "json", "", false, "output in JSON format")
    86  	rootCmd.AddCommand(configCmd)
    87  }
    88  
    89  // get printable settings in alphabet order
    90  func printableSettingsInOrder(settings map[string]interface{}) []string {
    91  	sorted := []string{}
    92  	keys := []string{}
    93  	for k := range settings {
    94  		keys = append(keys, k)
    95  	}
    96  
    97  	sort.Strings(keys)
    98  	for _, k := range keys {
    99  		if k == strings.ToLower(config.EXTRA_REMOTES_KEY) {
   100  			remotes, _ := config.Remotes()
   101  			for _, remote := range remotes {
   102  				key := fmt.Sprintf("extra_remotes.%s.remote_base_url", remote.Name)
   103  				sorted = append(sorted, fmt.Sprintf("%-40v: %v", key, remote.RemoteBaseUrl))
   104  				key = fmt.Sprintf("extra_remotes.%s.repository_dir", remote.Name)
   105  				sorted = append(sorted, fmt.Sprintf("%-40v: %v", key, remote.RepositoryDir))
   106  				key = fmt.Sprintf("extra_remotes.%s.sync_policy", remote.Name)
   107  				sorted = append(sorted, fmt.Sprintf("%-40v: %v", key, remote.SyncPolicy))
   108  			}
   109  		} else {
   110  			sorted = append(sorted, fmt.Sprintf("%-40v: %v", k, settings[k]))
   111  		}
   112  	}
   113  
   114  	return sorted
   115  }
   116  
   117  func printSettings(settings map[string]interface{}, jsonFormat bool) {
   118  	if jsonFormat {
   119  		printInJson(settings)
   120  	} else {
   121  		printInPlainText(settings)
   122  	}
   123  }
   124  
   125  func printInJson(settings map[string]interface{}) {
   126  	val, err := json.MarshalIndent(settings, "", "    ")
   127  	if err != nil {
   128  		fmt.Println(err)
   129  	} else {
   130  		fmt.Println(string(val))
   131  	}
   132  }
   133  
   134  func printInPlainText(settings map[string]interface{}) {
   135  	printableSettings := printableSettingsInOrder(settings)
   136  	for _, line := range printableSettings {
   137  		fmt.Println(line)
   138  	}
   139  }