func/cmd/config.go

176 lines
3.9 KiB
Go

package cmd
import (
"fmt"
"github.com/AlecAivazis/survey/v2"
"github.com/ory/viper"
"github.com/spf13/cobra"
"knative.dev/func/pkg/config"
fn "knative.dev/func/pkg/functions"
)
type functionLoader interface {
Load(path string) (fn.Function, error)
}
type functionSaver interface {
Save(f fn.Function) error
}
type functionLoaderSaver interface {
functionLoader
functionSaver
}
type standardLoaderSaver struct{}
func (s standardLoaderSaver) Load(path string) (fn.Function, error) {
f, err := fn.NewFunction(path)
if err != nil {
return fn.Function{}, fmt.Errorf("failed to create new function (path: %q): %w", path, err)
}
if !f.Initialized() {
return fn.Function{}, fn.NewErrNotInitialized(f.Root)
}
return f, nil
}
func (s standardLoaderSaver) Save(f fn.Function) error {
return f.Write()
}
var defaultLoaderSaver standardLoaderSaver
func NewConfigCmd(loadSaver functionLoaderSaver, newClient ClientFactory) *cobra.Command {
cmd := &cobra.Command{
Use: "config",
Short: "Configure a function",
Long: `Configure a function
Interactive prompt that allows configuration of Git configuration, Volume mounts, Environment
variables, and Labels for a function project present in the current directory
or from the directory specified with --path.
`,
SuggestFor: []string{"cfg", "cofnig"},
PreRunE: bindEnv("path", "verbose"),
RunE: runConfigCmd,
}
cfg, err := config.NewDefault()
if err != nil {
fmt.Fprintf(cmd.OutOrStdout(), "error loading config at '%v'. %v\n", config.File(), err)
}
addPathFlag(cmd)
addVerboseFlag(cmd, cfg.Verbose)
cmd.AddCommand(NewConfigGitCmd(newClient))
cmd.AddCommand(NewConfigLabelsCmd(loadSaver))
cmd.AddCommand(NewConfigEnvsCmd(loadSaver))
cmd.AddCommand(NewConfigVolumesCmd())
return cmd
}
func runConfigCmd(cmd *cobra.Command, args []string) (err error) {
function, err := initConfigCommand(defaultLoaderSaver)
if err != nil {
return
}
var qs = []*survey.Question{
{
Name: "selectedConfig",
Prompt: &survey.Select{
Message: "What do you want to configure?",
Options: []string{"Git", "Environment variables", "Volumes", "Labels"},
Default: "Git",
},
},
{
Name: "selectedOperation",
Prompt: &survey.Select{
Message: "What operation do you want to perform?",
Options: []string{"Add", "Remove", "List"},
Default: "List",
},
},
}
answers := struct {
SelectedConfig string
SelectedOperation string
}{}
err = survey.Ask(qs, &answers)
if err != nil {
return
}
switch answers.SelectedOperation {
case "Add":
switch answers.SelectedConfig {
case "Volumes":
err = runAddVolumesPrompt(cmd.Context(), function)
case "Environment variables":
err = runAddEnvsPrompt(cmd.Context(), function)
case "Labels":
err = runAddLabelsPrompt(cmd.Context(), function, defaultLoaderSaver)
case "Git":
err = runConfigGitSetCmd(cmd, NewClient)
}
case "Remove":
switch answers.SelectedConfig {
case "Volumes":
err = runRemoveVolumesPrompt(function)
case "Environment variables":
err = runRemoveEnvsPrompt(function)
case "Labels":
err = runRemoveLabelsPrompt(function, defaultLoaderSaver)
case "Git":
err = runConfigGitRemoveCmd(cmd, NewClient)
}
case "List":
switch answers.SelectedConfig {
case "Volumes":
listVolumes(function)
case "Environment variables":
err = listEnvs(function, cmd.OutOrStdout(), Human)
case "Labels":
listLabels(function)
case "Git":
err = runConfigGitCmd(cmd, NewClient)
}
}
return
}
// CLI Configuration (parameters)
// ------------------------------
type configCmdConfig struct {
Path string
Verbose bool
}
func newConfigCmdConfig() configCmdConfig {
return configCmdConfig{
Path: viper.GetString("path"),
Verbose: viper.GetBool("verbose"),
}
}
func initConfigCommand(loader functionLoader) (fn.Function, error) {
config := newConfigCmdConfig()
function, err := loader.Load(config.Path)
if err != nil {
return fn.Function{}, err
}
return function, nil
}