Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support of '-' to go back to previous profile as well as if name given switch to that name direcly #12

Merged
merged 7 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
module gcps
module github.com/naman2706/gcps

go 1.17

require github.com/AlecAivazis/survey/v2 v2.3.4
require (
github.com/AlecAivazis/survey/v2 v2.3.4 // indirect
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/withmandala/go-log v0.1.0 // indirect
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)

require (
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/manifoldco/promptui v0.9.0
github.com/mattn/go-colorable v0.1.2 // indirect
github.com/mattn/go-isatty v0.0.8 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
github.com/stretchr/testify v1.7.1
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect
golang.org/x/text v0.3.3 // indirect
golang.org/x/text v0.3.6 // indirect
)
16 changes: 16 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ github.com/AlecAivazis/survey/v2 v2.3.4 h1:pchTU9rsLUSvWEl2Aq9Pv3k0IE2fkqtGxazsk
github.com/AlecAivazis/survey/v2 v2.3.4/go.mod h1:hrV6Y/kQCLhIZXGcriDCUBtB3wnN7156gMXJ3+b23xM=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -11,6 +15,8 @@ github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
Expand All @@ -22,13 +28,23 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/withmandala/go-log v0.1.0 h1:wINmTEe7BQ6zEA8sE7lSsYeaxCLluK6RFjF/IB5tzkA=
github.com/withmandala/go-log v0.1.0/go.mod h1:/V9xQUTW74VjYm3u2Liv/bIUGLWoL9z2GlHwtscp4vg=
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 h1:S25/rfnfsMVgORT4/J61MJ7rdyseOZOyvLIrZEZ7s6s=
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
Expand Down
110 changes: 64 additions & 46 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,71 +1,89 @@
package main

import (
"encoding/json"
"fmt"
"log"
"os"
"os/exec"

"github.com/AlecAivazis/survey/v2"
"github.com/naman2706/gcps/pkg/cmd"
"github.com/naman2706/gcps/pkg/file"
"github.com/naman2706/gcps/pkg/gcp"
)

// to unmarshal gcloud configurations json
type List struct {
Name string `json:"name"`
IsActive bool `json:"is_active"`
}

func main() {
// seleted profile by user
// validation
if _, err := exec.LookPath("gcloud"); err != nil {
fmt.Println("gcloud command not found")
fmt.Println("Refer to this guide for help to setting up a gcloud")
fmt.Println("https://cloud.google.com/sdk/docs/install")
return
}

// store seleted profile
var seletedProfile string
// to set activated profile as default
var activeProfile string
// list of profiles
profileList := []string{}

// run cmd to get list of profiles
out, err := exec.Command("gcloud", "config", "configurations", "list", "--format=json").Output()
list, err := gcp.GetProfileList()
if err != nil {
log.Fatal(err)
log.Fatalf("Error getting profile list: %v", err)
}

// temporary list of profiles
l := []List{}

// unmarshal to get the desired value
if err := json.Unmarshal(out, &l); err != nil {
log.Fatal(err)
}
if len(os.Args) > 1 {
if os.Args[1] == "--help" {
fmt.Println("usage: gcps [arguments] or flags")
fmt.Print("\t Switch google cloud profile\n\n")
fmt.Println("\t Arguments:")
fmt.Println("\t\t[name]\tswitch profile to given name.")
fmt.Print("\t Flags:\n")
fmt.Println("\t\t-\tswitch to previous profile.")
fmt.Print("\t\t--help\tto get help about gcps.\n\n")
return
} else if os.Args[1] == "-" {
lastProfile, err := file.ReadLastProfile()
if err != nil {
log.Fatalf("Error while reading file: %v", err)
} else if lastProfile == "" {
fmt.Println("No previous profile found. Please select profile from below")
} else {
seletedProfile = lastProfile
}
} else {
isContain := gcp.ContainsProfile(list, os.Args[1])
if isContain {
seletedProfile = os.Args[1]
} else {
log.Printf("Given profile %s is invalide please select from below!\n", os.Args[1])
}

for _, e := range l {
if e.IsActive {
activeProfile = e.Name
}
profileList = append(profileList, e.Name)
}

// survey
p := []*survey.Question{
{
Name: "profiles",
Prompt: &survey.Select{
Message: "Select Profile:",
Options: profileList,
Default: activeProfile,
},
Validate: survey.Required,
},
if len(seletedProfile) == 0 {
seletedProfile, err = cmd.GetProfileFromUser(list)
if err != nil {
log.Fatalf("Error while setting up cli: %v", err)
}
}

// ask
err = survey.Ask(p, &seletedProfile)
if err != nil {
log.Fatal(err)
activeProfile := gcp.GetActiveProfile(list)
if activeProfile == "" {
err := file.WriteLastProfile(seletedProfile)
if err != nil {
log.Fatalf("Error while writing last activate profile: %v", err)
}
} else if activeProfile == seletedProfile {
fmt.Printf("Activate profile %s. No need to switch again\n", seletedProfile)
return
} else {
err := file.WriteLastProfile(activeProfile)
if err != nil {
log.Fatalf("Error while writing last activate profile: %v", err)
}
}

// set the given profile
if err := exec.Command("gcloud", "config", "configurations", "activate", seletedProfile).Run(); err != nil {
log.Fatal(err)
if err := gcp.SetProfile(seletedProfile); err != nil {
log.Fatalf("Error setting up the profile: %v", err)
}

log.Printf("Switched profile to %s successfully!!", seletedProfile)
fmt.Printf("Switched profile to %s successfully!!\n", seletedProfile)
}
32 changes: 32 additions & 0 deletions pkg/cmd/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package cmd

import (
"strings"

"github.com/manifoldco/promptui"
"github.com/naman2706/gcps/pkg/types"
)

func GetProfileFromUser(list []types.List) (string, error) {
templates := &promptui.SelectTemplates{
Label: "{{ . }}?",
Active: "\U0001f449 {{ .Name | cyan }} ({{ .IsActive | red }})",
Inactive: " {{ .Name | cyan }} ({{ .IsActive | red }})",
Selected: "\u2705 {{ .Name | green }}",
}

prompt := promptui.Select{
Label: "Select Profile",
Items: list,
Size: 10,
Templates: templates,
HideHelp: true,
}

_, result, err := prompt.Run()
if err != nil {
return "", err
}

return strings.Split(strings.Trim(result, "{}"), " ")[0], nil
}
49 changes: 49 additions & 0 deletions pkg/file/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package file

import (
"errors"
"io/ioutil"
"os"
"path/filepath"
)

func HomeDir() string {
home := os.Getenv("HOME")
if home == "" {
home = os.Getenv("USERPROFILE") // windows
}
return home
}

func PrevProfileFile() (string, error) {
home := HomeDir()
if home == "" {
return "", errors.New("HOME or USERPROFILE environment variable not set")
}
return filepath.Join(home, ".gcps"), nil
}

func WriteLastProfile(value string) error {
path, err := PrevProfileFile()
if err != nil {
return err
}
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0750); err != nil {
return err
}
return ioutil.WriteFile(path, []byte(value), 0600)
}

func ReadLastProfile() (string, error) {
path, err := PrevProfileFile()
if err != nil {
return "", err
}
b, err := ioutil.ReadFile(filepath.Clean(path))
if os.IsNotExist(err) {
return "", nil
}
filepath.Clean(path)
return string(b), err
}
54 changes: 54 additions & 0 deletions pkg/gcp/gcp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package gcp

import (
"encoding/json"
"os/exec"

"github.com/naman2706/gcps/pkg/types"
)

// get list of profile
func GetProfileList() ([]types.List, error) {
// run cmd to get list of profiles
out, err := exec.Command("gcloud", "config", "configurations", "list", "--format=json").Output()
if err != nil {
return []types.List{}, err
}

// list of profiles
list := []types.List{}

// unmarshal to get the desired value
if err := json.Unmarshal(out, &list); err != nil {
return []types.List{}, err
}

return list, nil
}

// set the given profile
func SetProfile(profile string) error {
if err := exec.Command("gcloud", "config", "configurations", "activate", profile).Run(); err != nil {
return err
}
return nil
}

// Check if the given profile exists in given array
func ContainsProfile(arr []types.List, profile string) bool {
for _, n := range arr {
if n.Name == profile {
return true
}
}
return false
}

func GetActiveProfile(list []types.List) string {
for _, n := range list {
if n.IsActive {
return n.Name
}
}
return ""
}
Loading