Skip to content

Commit

Permalink
Merge pull request #83 from rm-Umar/umar/settings
Browse files Browse the repository at this point in the history
added global cache
  • Loading branch information
UmanShahzad authored Dec 8, 2021
2 parents fe3df87 + 61d60bb commit 05602e8
Show file tree
Hide file tree
Showing 11 changed files with 274 additions and 103 deletions.
88 changes: 88 additions & 0 deletions ipinfo/cmd_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package main

import (
"fmt"
"strings"

"github.com/ipinfo/cli/lib/complete"
"github.com/ipinfo/cli/lib/complete/predict"
"github.com/spf13/pflag"
)

var completionsConfig = &complete.Command{
Flags: map[string]complete.Predictor{
"-h": predict.Nothing,
"--help": predict.Nothing,
},
}

func printHelpConfig() {
fmt.Printf(
`Usage: %s config [<key>=<value>...]
Description:
Change the configurations.
Examples:
$ %[1]s config cache=disable
$ %[1]s config token=testtoken cache=enable
Options:
--help, -h
show help.
Configurations:
cache=<enable | disable>
Control whether the cache is enabled or disabled.
token=<tok>
Save a token for use when querying the API.
(Token will not be validated).
`, progBase)
}

func cmdConfig() error {
var fHelp bool

pflag.BoolVarP(&fHelp, "help", "h", false, "show help.")
pflag.Parse()

// get args for config and parsing it.
args := pflag.Args()[1:]
if fHelp || len(args) < 1 {
printHelpConfig()
return nil
}
for _, arg := range args {
configStr := strings.Split(arg, "=")
key := strings.ToLower(configStr[0])
if len(configStr) != 2 {
if key == "cache" || key == "token" {
return fmt.Errorf("err: no value provided for key %s", key)
}
return fmt.Errorf("err: invalid key argument %s", key)
}
switch key {
case "cache":
val := strings.ToLower(configStr[1])
switch val {
case "enable":
gConfig.CacheEnabled = true
case "disable":
gConfig.CacheEnabled = false
default:
return fmt.Errorf("err: invalid value %s; cache must be 'enabled' or disabled", val)
}
case "token":
gConfig.Token = configStr[1]
default:
return fmt.Errorf("err: invalid key argument %s", configStr[0])
}
}

// save config in bulk.
if err := SaveConfig(gConfig); err != nil {
return err
}

return nil
}
1 change: 1 addition & 0 deletions ipinfo/cmd_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Commands:
range2ip convert IP ranges to individual IPs within those ranges.
randip Generates random IPs.
cache manage the cache.
config manage the config.
login save an API token session.
logout delete your current API token session.
completion install or output shell auto-completion script.
Expand Down
3 changes: 2 additions & 1 deletion ipinfo/cmd_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ func cmdLogin() error {
}

// save token to file.
if err := saveToken(tok); err != nil {
gConfig.Token = tok
if err := SaveConfig(gConfig); err != nil {
return err
}

Expand Down
9 changes: 7 additions & 2 deletions ipinfo/cmd_logout.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,17 @@ func cmdLogout() error {
return nil
}

// delete but don't return an error; just log it.
if err := deleteToken(); err != nil {
// checks if not logged in.
if gConfig.Token == "" {
fmt.Println("not logged in")
return nil
}

gConfig.Token = ""
if err := SaveConfig(gConfig); err != nil {
return err
}

fmt.Println("logged out")

return nil
Expand Down
1 change: 1 addition & 0 deletions ipinfo/completions.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var completions = &complete.Command{
"cache": completionsCache,
"login": completionsLogin,
"logout": completionsLogout,
"config": completionsConfig,
"completion": completionsCompletion,
"version": completionsVersion,
},
Expand Down
162 changes: 162 additions & 0 deletions ipinfo/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package main

import (
"encoding/json"
"io/ioutil"
"os"
"path/filepath"

"github.com/ipinfo/cli/lib"
)

// global config.
var gConfig Config

type Config struct {
CacheEnabled bool `json:"cache_enabled"`
Token string `json:"token"`
}

// gets the global config directory, creating it if necessary.
func getConfigDir() (string, error) {
cdir, err := os.UserConfigDir()
if err != nil {
return "", err
}

confDir := filepath.Join(cdir, "ipinfo")
if err := os.MkdirAll(confDir, 0700); err != nil {
return "", err
}

return confDir, nil
}

// returns the path to the config file.
func ConfigPath() (string, error) {
confDir, err := getConfigDir()
if err != nil {
return "", err
}

return filepath.Join(confDir, "config.json"), nil
}

// returns the path to the token file.
//
// might be deleted in future release as `token` file is deprecated.
func TokenPath() (string, error) {
confDir, err := getConfigDir()
if err != nil {
return "", err
}

return filepath.Join(confDir, "token"), nil
}

func InitConfig() error {
configpath, err := ConfigPath()
if err != nil {
return err
}

// create default config if none yet.
if !lib.FileExists(configpath) {
gConfig = NewConfig()

tokenpath, err := TokenPath()
if err != nil {
return err
}

// if token exists, migrate it to the config file.
if lib.FileExists(tokenpath) {
token, err := ReadTokenFile()
if err != nil {
return err
}
gConfig.Token = token

// remove the existing token file
if err := os.Remove(tokenpath); err != nil {
return err
}
}
} else {
config, err := ReadConfig()
if err != nil {
return err
}
gConfig = config
}

if err := SaveConfig(gConfig); err != nil {
return err
}

return nil
}

// returns a new, default config.
func NewConfig() Config {
return Config{
CacheEnabled: true,
Token: "",
}
}

// reads `token` file for migration of token to config file.
//
// might be deleted in future release as `token` file is deprecated.
func ReadTokenFile() (string, error) {
path, err := TokenPath()
if err != nil {
return "", err
}

token, err := ioutil.ReadFile(path)
if err != nil {
return "", err
}

return string(token), nil
}

// save the config to file.
func SaveConfig(config Config) error {
configPath, err := ConfigPath()
if err != nil {
return err
}

jsonData, err := json.Marshal(config)
if err != nil {
return err
}

if err := ioutil.WriteFile(configPath, jsonData, 0644); err != nil {
return err
}

return nil
}

// returns the values of config file.
func ReadConfig() (Config, error) {
configPath, err := ConfigPath()
if err != nil {
return Config{}, err
}

data, err := ioutil.ReadFile(configPath)
if err != nil {
return Config{}, err
}

var config Config
if err := json.Unmarshal(data, &config); err != nil {
return Config{}, err
}

return config, nil
}
9 changes: 9 additions & 0 deletions ipinfo/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

import "fmt"

func init() {
if err := InitConfig(); err != nil {
fmt.Println("warn: error in creating config file.")
}
}
5 changes: 2 additions & 3 deletions ipinfo/ipinfo_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ func prepareIpinfoClient(tok string) *ipinfo.Client {

// get token from persistent store.
if tok == "" {
tok, _ = restoreToken()
tok = gConfig.Token
}

// attempt to init cache; don't force require it, though.
var cache *ipinfo.Cache
if !fNoCache {
if gConfig.CacheEnabled && !fNoCache {
boltdbCache, err := NewBoltdbCache()
if err != nil {
fmt.Printf("warn: cache will not be used: %v", err)
Expand Down
2 changes: 2 additions & 0 deletions ipinfo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ func main() {
err = cmdRandIP()
case cmd == "cache":
err = cmdCache()
case cmd == "config":
err = cmdConfig()
case cmd == "login":
err = cmdLogin()
case cmd == "logout":
Expand Down
21 changes: 0 additions & 21 deletions ipinfo/utils_config.go

This file was deleted.

Loading

0 comments on commit 05602e8

Please sign in to comment.