<commit_before>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// vespa config command
// author: bratseth

package cmd

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"github.com/vespa-engine/vespa/client/go/util"
	"github.com/vespa-engine/vespa/client/go/vespa"
)

const (
	configName = "config"
	configType = "yaml"
)

var flagToConfigBindings map[string]*cobra.Command = make(map[string]*cobra.Command)

func init() {
	rootCmd.AddCommand(configCmd)
	configCmd.AddCommand(setConfigCmd)
	configCmd.AddCommand(getConfigCmd)
}

var configCmd = &cobra.Command{
	Use:   "config",
	Short: "Configure persistent values for flags",
	Long: `Configure persistent values for flags.

This command allows setting a persistent value for a given flag. On future
invocations the flag can then be omitted as it is read from the config file
instead.

Configuration is written to $HOME/.vespa by default. This path can be
overridden by setting the VESPA_CLI_HOME environment variable.`,
	DisableAutoGenTag: true,
	Run: func(cmd *cobra.Command, args []string) {
		// Root command does nothing
		cmd.Help()
		exitFunc(1)
	},
}

var setConfigCmd = &cobra.Command{
	Use:               "set option-name value",
	Short:             "Set a configuration option.",
	Example:           "$ vespa config set target cloud",
	DisableAutoGenTag: true,
	Args:              cobra.ExactArgs(2),
	Run: func(cmd *cobra.Command, args []string) {
		cfg, err := LoadConfig()
		if err != nil {
			fatalErr(err, "Could not load config")
			return
		}
		if err := cfg.Set(args[0], args[1]); err != nil {
			fatalErr(err)
		} else {
			if err := cfg.Write(); err != nil {
				fatalErr(err)
			}
		}
	},
}

var getConfigCmd = &cobra.Command{
	Use:               "get option-name",
	Short:             "Get a configuration option",
	Example:           "$ vespa config get target",
	Args:              cobra.MaximumNArgs(1),
	DisableAutoGenTag: true,
	Run: func(cmd *cobra.Command, args []string) {
		cfg, err := LoadConfig()
		if err != nil {
			fatalErr(err, "Could not load config")
			return
		}

		if len(args) == 0 { // Print all values
			var flags []string
			for flag := range flagToConfigBindings {
				flags = append(flags, flag)
			}
			sort.Strings(flags)
			for _, flag := range flags {
				printOption(cfg, flag)
			}
		} else {
			printOption(cfg, args[0])
		}
	},
}

type Config struct {
	Home       string
	createDirs bool
}

func LoadConfig() (*Config, error) {
	home, err := vespaCliHome()
	if err != nil {
		return nil, err
	}
	c := &Config{Home: home, createDirs: true}
	if err := c.load(); err != nil {
		return nil, err
	}
	return c, nil
}

func (c *Config) Write() error {
	if err := os.MkdirAll(c.Home, 0700); err != nil {
		return err
	}
	configFile := filepath.Join(c.Home, configName+"."+configType)
	if !util.PathExists(configFile) {
		if _, err := os.Create(configFile); err != nil {
			return err
		}
	}
	return viper.WriteConfig()
}

func (c *Config) CertificatePath(app vespa.ApplicationID) (string, error) {
	if override, ok := os.LookupEnv("VESPA_CLI_DATA_PLANE_CERT_FILE"); ok {
		return override, nil
	}
	return c.applicationFilePath(app, "data-plane-public-cert.pem")
}

func (c *Config) PrivateKeyPath(app vespa.ApplicationID) (string, error) {
	if override, ok := os.LookupEnv("VESPA_CLI_DATA_PLANE_KEY_FILE"); ok {
		return override, nil
	}
	return c.applicationFilePath(app, "data-plane-private-key.pem")
}

func (c *Config) APIKeyPath(tenantName string) string {
	return filepath.Join(c.Home, tenantName+".api-key.pem")
}

func (c *Config) ReadAPIKey(tenantName string) ([]byte, error) {
	return ioutil.ReadFile(c.APIKeyPath(tenantName))
}

func (c *Config) AuthConfigPath() string {
	return filepath.Join(c.Home, "auth0.json")
}

func (c *Config) ReadSessionID(app vespa.ApplicationID) (int64, error) {
	sessionPath, err := c.applicationFilePath(app, "session_id")
	if err != nil {
		return 0, err
	}
	b, err := ioutil.ReadFile(sessionPath)
	if err != nil {
		return 0, err
	}
	return strconv.ParseInt(strings.TrimSpace(string(b)), 10, 64)
}

func (c *Config) WriteSessionID(app vespa.ApplicationID, sessionID int64) error {
	sessionPath, err := c.applicationFilePath(app, "session_id")
	if err != nil {
		return err
	}
	return ioutil.WriteFile(sessionPath, []byte(fmt.Sprintf("%d\n", sessionID)), 0600)
}

func (c *Config) applicationFilePath(app vespa.ApplicationID, name string) (string, error) {
	appDir := filepath.Join(c.Home, app.String())
	if c.createDirs {
		if err := os.MkdirAll(appDir, 0700); err != nil {
			return "", err
		}
	}
	return filepath.Join(appDir, name), nil<commit_msg>Rename file 'auth0.json' => 'auth.json'<commit_after>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// vespa config command
// author: bratseth

package cmd

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"github.com/vespa-engine/vespa/client/go/util"
	"github.com/vespa-engine/vespa/client/go/vespa"
)

const (
	configName = "config"
	configType = "yaml"
)

var flagToConfigBindings map[string]*cobra.Command = make(map[string]*cobra.Command)

func init() {
	rootCmd.AddCommand(configCmd)
	configCmd.AddCommand(setConfigCmd)
	configCmd.AddCommand(getConfigCmd)
}

var configCmd = &cobra.Command{
	Use:   "config",
	Short: "Configure persistent values for flags",
	Long: `Configure persistent values for flags.

This command allows setting a persistent value for a given flag. On future
invocations the flag can then be omitted as it is read from the config file
instead.

Configuration is written to $HOME/.vespa by default. This path can be
overridden by setting the VESPA_CLI_HOME environment variable.`,
	DisableAutoGenTag: true,
	Run: func(cmd *cobra.Command, args []string) {
		// Root command does nothing
		cmd.Help()
		exitFunc(1)
	},
}

var setConfigCmd = &cobra.Command{
	Use:               "set option-name value",
	Short:             "Set a configuration option.",
	Example:           "$ vespa config set target cloud",
	DisableAutoGenTag: true,
	Args:              cobra.ExactArgs(2),
	Run: func(cmd *cobra.Command, args []string) {
		cfg, err := LoadConfig()
		if err != nil {
			fatalErr(err, "Could not load config")
			return
		}
		if err := cfg.Set(args[0], args[1]); err != nil {
			fatalErr(err)
		} else {
			if err := cfg.Write(); err != nil {
				fatalErr(err)
			}
		}
	},
}

var getConfigCmd = &cobra.Command{
	Use:               "get option-name",
	Short:             "Get a configuration option",
	Example:           "$ vespa config get target",
	Args:              cobra.MaximumNArgs(1),
	DisableAutoGenTag: true,
	Run: func(cmd *cobra.Command, args []string) {
		cfg, err := LoadConfig()
		if err != nil {
			fatalErr(err, "Could not load config")
			return
		}

		if len(args) == 0 { // Print all values
			var flags []string
			for flag := range flagToConfigBindings {
				flags = append(flags, flag)
			}
			sort.Strings(flags)
			for _, flag := range flags {
				printOption(cfg, flag)
			}
		} else {
			printOption(cfg, args[0])
		}
	},
}

type Config struct {
	Home       string
	createDirs bool
}

func LoadConfig() (*Config, error) {
	home, err := vespaCliHome()
	if err != nil {
		return nil, err
	}
	c := &Config{Home: home, createDirs: true}
	if err := c.load(); err != nil {
		return nil, err
	}
	return c, nil
}

func (c *Config) Write() error {
	if err := os.MkdirAll(c.Home, 0700); err != nil {
		return err
	}
	configFile := filepath.Join(c.Home, configName+"."+configType)
	if !util.PathExists(configFile) {
		if _, err := os.Create(configFile); err != nil {
			return err
		}
	}
	return viper.WriteConfig()
}

func (c *Config) CertificatePath(app vespa.ApplicationID) (string, error) {
	if override, ok := os.LookupEnv("VESPA_CLI_DATA_PLANE_CERT_FILE"); ok {
		return override, nil
	}
	return c.applicationFilePath(app, "data-plane-public-cert.pem")
}

func (c *Config) PrivateKeyPath(app vespa.ApplicationID) (string, error) {
	if override, ok := os.LookupEnv("VESPA_CLI_DATA_PLANE_KEY_FILE"); ok {
		return override, nil
	}
	return c.applicationFilePath(app, "data-plane-private-key.pem")
}

func (c *Config) APIKeyPath(tenantName string) string {
	return filepath.Join(c.Home, tenantName+".api-key.pem")
}

func (c *Config) ReadAPIKey(tenantName string) ([]byte, error) {
	return ioutil.ReadFile(c.APIKeyPath(tenantName))
}

func (c *Config) AuthConfigPath() string {
	return filepath.Join(c.Home, "auth.json")
}

func (c *Config) ReadSessionID(app vespa.ApplicationID) (int64, error) {
	sessionPath, err := c.applicationFilePath(app, "session_id")
	if err != nil {
		return 0, err
	}
	b, err := ioutil.ReadFile(sessionPath)
	if err != nil {
		return 0, err
	}
	return strconv.ParseInt(strings.TrimSpace(string(b)), 10, 64)
}

func (c *Config) WriteSessionID(app vespa.ApplicationID, sessionID int64) error {
	sessionPath, err := c.applicationFilePath(app, "session_id")
	if err != nil {
		return err
	}
	return ioutil.WriteFile(sessionPath, []byte(fmt.Sprintf("%d\n", sessionID)), 0600)
}

func (c *Config) applicationFilePath(app vespa.ApplicationID, name string) (string, error) {
	appDir := filepath.Join(c.Home, app.String())
	if c.createDirs {
		if err := os.MkdirAll(appDir, 0700); err != nil {
			return "", err
		}
	}
	return filepath.Join(appDir, name), nil
{'fraction_non_alphanumeric': 0.13633021741413717, 'fraction_numerical': 0.00756223085810314, 'mean_word_length': 3.720872583044125, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '478359', 'n_tokens_mistral': 3604, 'n_tokens_neox': 3389, 'n_words': 898}