add config command for toggling update checker (#589)

* add odo utils config command for enable/disable parameters

- add config command
- create a new field 'config' in odoconfig file
  for storing odo specific configurations

* update CLI structure in Readme.md
This commit is contained in:
Syam.G.Krishnan
2018-09-04 22:13:54 +05:30
committed by Charlie Drage
parent 8ced49f7ae
commit 2bb2dca872
8 changed files with 292 additions and 17 deletions

View File

@@ -119,7 +119,6 @@ $ curl nodejs-myproject.192.168.42.147.nip.io
Multiple component types are currently supported, like nodejs, perl, php, python, ruby, etc.
## CLI Structure
```sh
odo --verbose : Odo (Openshift Do)
app --short : Perform application operations
@@ -166,10 +165,14 @@ odo --verbose : Odo (Openshift Do)
create --application --component --port : Create a URL for a component
delete --component --force : Delete a URL
list --application --component : List URLs
utils : Utilities for completion and terminal commands
utils : Utilities for completion, terminal commands and modifying Odo configurations
completion : Output shell completion code
config : Modifies configuration settings
set : Set a value in odo config file
view : View current configuration values
terminal : Add Odo terminal support to your development environment
version : Print the client version information
watch : Watch for changes, update component on change
```
*_autogenerated_

93
cmd/config.go Normal file
View File

@@ -0,0 +1,93 @@
package cmd
import (
"fmt"
"os"
"strconv"
"strings"
"text/tabwriter"
"github.com/pkg/errors"
"github.com/redhat-developer/odo/pkg/config"
"github.com/spf13/cobra"
)
// configurationCmd represents the app command
var configurationCmd = &cobra.Command{
Use: "config",
Short: "Modifies configuration settings",
Long: `Modifies Odo specific configuration settings within the config file.
Available Parameters:
UpdateNotification - Controls if an update notification is shown or not (true or false)`,
Example: fmt.Sprintf("%s\n%s\n",
configurationViewCmd.Example,
configurationSetCmd.Example),
Aliases: []string{"configuration"},
// 'odo utils config' is the same as 'odo utils config --help'
Args: func(cmd *cobra.Command, args []string) error {
if len(args) >= 1 && args[0] != "view" && args[0] != "set" {
return fmt.Errorf("Unknown command, use set or view")
}
return nil
}, Run: func(cmd *cobra.Command, args []string) {
if len(args) > 0 && args[0] == "set" {
configurationSetCmd.Run(cmd, args)
} else if len(args) > 0 && args[0] == "view" {
configurationViewCmd.Run(cmd, args)
} else {
cmd.Help()
}
},
}
var configurationSetCmd = &cobra.Command{
Use: "set",
Short: "Set a value in odo config file",
Long: `Set an individual value in the Odo configuration file
Available Parameters:
UpdateNotification - Controls if an update notification is shown or not (true or false)`,
Example: `
# Set a configuration value
odo utils config set UpdateNotification false
`,
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return fmt.Errorf("Please provide a parameter name and value")
} else if len(args) > 2 {
return fmt.Errorf("Only one value per parameter is allowed")
} else {
return nil
}
}, RunE: func(cmd *cobra.Command, args []string) error {
cfg, err := config.New()
if err != nil {
return errors.Wrapf(err, "unable to set configuration")
}
value, err := strconv.ParseBool(args[1])
if err != nil {
return errors.Wrapf(err, "unable to set configuration")
}
return cfg.SetConfiguration(strings.ToLower(args[0]), value)
},
}
var configurationViewCmd = &cobra.Command{
Use: "view",
Short: "View current configuration values",
Long: "View current configuration values",
Example: `
# For viewing the current configuration
odo utils config view`,
Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
cfg, err := config.New()
if err != nil {
fmt.Println(err, ": unable to view configuration")
}
w := tabwriter.NewWriter(os.Stdout, 5, 2, 2, ' ', tabwriter.TabIndent)
fmt.Fprintln(w, "PARAMETER", "\t", "CURRENT_VALUE")
fmt.Fprintln(w, "UpdateNotification", "\t", cfg.GetUpdateNotification())
w.Flush()
},
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/golang/glog"
"github.com/pkg/errors"
"github.com/redhat-developer/odo/pkg/config"
"github.com/redhat-developer/odo/pkg/notify"
"github.com/redhat-developer/odo/pkg/occlient"
"github.com/spf13/cobra"
@@ -99,17 +100,27 @@ Find more information at https://github.com/redhat-developer/odo`,
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
updateInfo := make(chan string)
go getLatestReleaseInfo(updateInfo)
checkError(rootCmd.Execute(), "")
select {
case message := <-updateInfo:
fmt.Println(message)
default:
glog.V(4).Info("Could not get the latest release information in time. Never mind, exiting gracefully :)")
// checking the value of updatenotification in config
// before proceeding with fetching the latest version
cfg, err := config.New()
if err != nil {
fmt.Println("unable to fetch configuration from Odo config file.")
}
if cfg.GetUpdateNotification() == true {
updateInfo := make(chan string)
go getLatestReleaseInfo(updateInfo)
checkError(rootCmd.Execute(), "")
select {
case message := <-updateInfo:
fmt.Println(message)
default:
glog.V(4).Info("Could not get the latest release information in time. Never mind, exiting gracefully :)")
}
} else {
checkError(rootCmd.Execute(), "")
}
}
func init() {

View File

@@ -9,17 +9,24 @@ import (
// utilsCmd represents the utils command
var utilsCmd = &cobra.Command{
Use: "utils",
Short: "Utilities for completion and terminal commands",
Long: `Utilities for completion and terminal commands`,
Example: fmt.Sprintf("%s\n%s",
Short: "Utilities for completion, terminal commands and modifying Odo configurations",
Long: `Utilities for completion, terminal commands and modifying Odo configurations`,
Example: fmt.Sprintf("%s\n%s\n%s%s",
completionCmd.Example,
terminalCmd.Example),
terminalCmd.Example,
configurationSetCmd.Example,
configurationViewCmd.Example),
}
func init() {
utilsCmd.Annotations = map[string]string{"command": "utility"}
utilsCmd.SetUsageTemplate(cmdUsageTemplate)
configurationCmd.AddCommand(configurationViewCmd)
configurationCmd.AddCommand(configurationSetCmd)
configurationCmd.SetUsageTemplate(cmdUsageTemplate)
utilsCmd.AddCommand(configurationCmd)
utilsCmd.AddCommand(completionCmd)
utilsCmd.AddCommand(terminalCmd)
rootCmd.AddCommand(utilsCmd)

View File

@@ -16,6 +16,12 @@ const (
configFileName = "odo"
)
// OdoSettings holds all odo specific configurations
type OdoSettings struct {
// Controls if an update notification is shown or not
UpdateNotification *bool `json:"updatenotification,omitempty"`
}
// ApplicationInfo holds all important information about one application
type ApplicationInfo struct {
// name of the application
@@ -29,6 +35,9 @@ type ApplicationInfo struct {
}
type Config struct {
// odo specific configuration settings
OdoSettings OdoSettings `json:"settings"`
// remember active applications and components per project
// when project or applications is switched we can go back to last active app/component
@@ -112,6 +121,30 @@ func (c *ConfigInfo) writeToFile() error {
return nil
}
// SetConfiguration modifies Odo configurations in the config file
// as of now only being used for updatenotification
func (c *ConfigInfo) SetConfiguration(parameter string, value bool) error {
switch parameter {
case "updatenotification":
c.OdoSettings.UpdateNotification = &value
default:
return errors.Errorf("unknown parameter :'%s' is not a parameter in odo config", parameter)
}
err := c.writeToFile()
if err != nil {
return errors.Wrapf(err, "unable to set %s", parameter)
}
return nil
}
// GetupdateNotification returns the value of UpdateNotification from config
func (c *ConfigInfo) GetUpdateNotification() bool {
if c.OdoSettings.UpdateNotification == nil {
return true
}
return *c.OdoSettings.UpdateNotification
}
// SetActiveComponent sets active component for given project and application.
// application must exist
func (c *ConfigInfo) SetActiveComponent(component string, application string, project string) error {

View File

@@ -923,6 +923,126 @@ func TestDeleteApplication(t *testing.T) {
}
}
func TestSetConfiguration(t *testing.T) {
tempConfigFile, err := ioutil.TempFile("", "odoconfig")
if err != nil {
t.Fatal(err)
}
defer tempConfigFile.Close()
os.Setenv(configEnvName, tempConfigFile.Name())
trueValue := true
falseValue := false
tests := []struct {
name string
parameter string
existingConfig Config
want bool
}{
{
name: "updatenotification set nil to true",
parameter: "updatenotification",
existingConfig: Config{},
want: true,
},
{
name: "updatenotification set true to false",
parameter: "updatenotification",
existingConfig: Config{
OdoSettings: OdoSettings{
UpdateNotification: &trueValue,
},
},
want: false,
},
{
name: "updatenotification set false to true",
parameter: "updatenotification",
existingConfig: Config{
OdoSettings: OdoSettings{
UpdateNotification: &falseValue,
},
},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg, err := New()
if err != nil {
t.Error(err)
}
cfg.Config = tt.existingConfig
cfg.SetConfiguration(tt.parameter, tt.want)
// validating the value after executing Serconfiguration
if *cfg.OdoSettings.UpdateNotification != tt.want {
t.Errorf("unexpeced value after execution of SetConfiguration expected \ngot: %t \nexpected: %t\n", *cfg.OdoSettings.UpdateNotification, tt.want)
}
})
}
}
func TestGetupdateNotification(t *testing.T) {
tempConfigFile, err := ioutil.TempFile("", "odoconfig")
if err != nil {
t.Fatal(err)
}
defer tempConfigFile.Close()
os.Setenv(configEnvName, tempConfigFile.Name())
trueValue := true
falseValue := false
tests := []struct {
name string
existingConfig Config
want bool
}{
{
name: "updatenotification nil",
existingConfig: Config{},
want: true,
},
{
name: "updatenotification true",
existingConfig: Config{
OdoSettings: OdoSettings{
UpdateNotification: &trueValue,
},
},
want: true,
},
{
name: "updatenotification false",
existingConfig: Config{
OdoSettings: OdoSettings{
UpdateNotification: &falseValue,
},
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := ConfigInfo{
Config: tt.existingConfig,
}
output := cfg.GetUpdateNotification()
if output != tt.want {
t.Errorf("GetUpdateNotification returned unexpeced value expected \ngot: %t \nexpected: %t\n", output, tt.want)
}
})
}
}
//
//func TestGet(t *testing.T) {
//

Binary file not shown.

View File

@@ -127,6 +127,14 @@ var _ = Describe("odoe2e", func() {
})
})
Context("odo utils config", func() {
It("should get true for updatenotification by defult", func() {
config := runCmd("odo utils config view")
Expect(config).To(ContainSubstring("true"))
Expect(config).To(ContainSubstring("UpdateNotification"))
})
})
Context("creating component without an application", func() {
It("should create the component in default application", func() {
runCmd("odo create php testcmp")