From 92bf1f1b12b72687e4f9725a72667e9b9812a7fb Mon Sep 17 00:00:00 2001 From: Andre Marcelo-Tanner Date: Thu, 27 Sep 2018 17:33:51 +0800 Subject: [PATCH 1/5] make LINODE_DEBUG env var optional --- main.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 0aa6a04..1ab1807 100644 --- a/main.go +++ b/main.go @@ -26,7 +26,10 @@ func main() { } linodeClient := linodego.NewClient(oauth2Client) - linodeClient.SetDebug(true) + + if _, ok := os.LookupEnv("LINODE_DEBUG"); ok { + linodeClient.SetDebug(true) + } res, err := linodeClient.GetInstance(context.Background(), 4090913) if err != nil { From 4f14b5848b368dbc844995c6de2b4d376c332bdd Mon Sep 17 00:00:00 2001 From: Andre Marcelo-Tanner Date: Sat, 29 Sep 2018 11:26:30 +0800 Subject: [PATCH 2/5] Adding initial Cobra/Viper code and moving client to internal package --- cmd/root.go | 84 +++++++++++++++++++++++++++++++++++++++ go.mod | 9 +++++ go.sum | 50 +++++++++++++++++++++++ internal/client/client.go | 41 +++++++++++++++++++ main.go | 48 ++++++++-------------- 5 files changed, 200 insertions(+), 32 deletions(-) create mode 100644 cmd/root.go create mode 100644 internal/client/client.go diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..10cd490 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,84 @@ +// Copyright © 2018 Andre Marcelo-Tanner +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var cfgFile string + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "ligo", + Short: "Linode CLI", + Long: `Linode CLI tools written in GOLANG`, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func init() { + cobra.OnInitialize(initConfig) + + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is .linodecli.yaml)") + + // Cobra also supports local flags, which will only run + // when this action is called directly. + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} + +// initConfig reads in config file and ENV variables if set. +func initConfig() { + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find current directory + currentDir, err := os.Getwd() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Search config in currentDir with name ".galleoncli" (without extension). + viper.AddConfigPath(currentDir) + viper.SetConfigName(".linodecli") + } + + viper.AutomaticEnv() // read in environment variables that match + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + fmt.Println("Using config file:", viper.ConfigFileUsed()) + } + +} diff --git a/go.mod b/go.mod index 2ef4824..be49485 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,16 @@ module github.com/kzap/ligo require ( + github.com/BurntSushi/toml v0.3.1 // indirect + github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/linode/linodego v0.5.2-0.20180916222121-15d4ab6c221b + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/cobra v0.0.3 + github.com/spf13/viper v1.2.1 + github.com/stretchr/testify v1.2.2 // indirect golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be + golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect + google.golang.org/appengine v1.2.0 // indirect gopkg.in/resty.v1 v1.9.1 // indirect ) diff --git a/go.sum b/go.sum index 489bc44..11aca7b 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,58 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31 h1:Dzuw9GtbmllUqEcoHfScT9YpKFUssSiZ5PgZkIGf/YQ= +github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/linode/linodego v0.5.2-0.20180916222121-15d4ab6c221b h1:1oeOtCnxd4Fi9qWnUr0v/k1XURvWdEPGDyJLbHg4b6o= github.com/linode/linodego v0.5.2-0.20180916222121-15d4ab6c221b/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= +github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I= +github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg= +github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.2 h1:Fy0orTDgHdbnzHcsOgfCN4LtHf0ec3wwtiwJqwvf3Gc= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.2.1 h1:bIcUwXqLseLF3BDAZduuNfekWG87ibtFxi59Bq+oI9M= +github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/net v0.0.0-20180611182652-db08ff08e862 h1:JZi6BqOZ+iSgmLWe6llhGrNnEnK+YB/MRkStwnEfbqM= golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225 h1:kNX+jCowfMYzvlSvJu5pQWEmyWFrBXJ3PBy10xKMXK8= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992 h1:BH3eQWeGbwRU2+wxxuuPOdFBmaiBH81O8BugSjHeTFg= +golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +google.golang.org/appengine v1.2.0 h1:S0iUepdCWODXRvtE+gcRDd15L+k+k1AiHlMiMjefH24= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/resty.v1 v1.9.1 h1:Lq4EIBZ5e2J4ZWp22W2hVOYc0X1qwDDki/nNVchRbdw= gopkg.in/resty.v1 v1.9.1/go.mod h1:vo52Hzryw9PnPHcJfPsBiFW62XhNx5OczbV9y+IMpgc= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/client/client.go b/internal/client/client.go new file mode 100644 index 0000000..0cc96b7 --- /dev/null +++ b/internal/client/client.go @@ -0,0 +1,41 @@ +// Package client initializes the Linode Client and provides related helpers. +package client + +import ( + "context" + "fmt" + + "github.com/linode/linodego" + "golang.org/x/oauth2" + + "log" + "net/http" + "os" +) + +// NewClient creates a new Linode Client using the given LINODE_TOKEN +func NewClient() { + apiKey, ok := os.LookupEnv("LINODE_TOKEN") + if !ok { + log.Fatal("Could not find LINODE_TOKEN, please assert it is set.") + } + tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: apiKey}) + + oauth2Client := &http.Client{ + Transport: &oauth2.Transport{ + Source: tokenSource, + }, + } + + linodeClient := linodego.NewClient(oauth2Client) + + if _, ok := os.LookupEnv("LINODE_DEBUG"); ok { + linodeClient.SetDebug(true) + } + + res, err := linodeClient.GetInstance(context.Background(), 4090913) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%v", res) +} diff --git a/main.go b/main.go index 1ab1807..ce9c69e 100644 --- a/main.go +++ b/main.go @@ -1,39 +1,23 @@ +// Copyright © 2018 Andre Marcelo-Tanner +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( - "context" - "fmt" - - "github.com/linode/linodego" - "golang.org/x/oauth2" - - "log" - "net/http" - "os" + "github.com/kzap/ligo/cmd" ) func main() { - apiKey, ok := os.LookupEnv("LINODE_TOKEN") - if !ok { - log.Fatal("Could not find LINODE_TOKEN, please assert it is set.") - } - tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: apiKey}) - - oauth2Client := &http.Client{ - Transport: &oauth2.Transport{ - Source: tokenSource, - }, - } - - linodeClient := linodego.NewClient(oauth2Client) - - if _, ok := os.LookupEnv("LINODE_DEBUG"); ok { - linodeClient.SetDebug(true) - } - - res, err := linodeClient.GetInstance(context.Background(), 4090913) - if err != nil { - log.Fatal(err) - } - fmt.Printf("%v", res) + cmd.Execute() } From f268fa242e6e95b2f3075e4442f1a37e6a753aff Mon Sep 17 00:00:00 2001 From: Andre Marcelo-Tanner Date: Sun, 30 Sep 2018 08:59:41 +0800 Subject: [PATCH 3/5] updating dir structure so main.go is in a per app directory --- internal/client/client.go => client.go | 2 +- cmd/{ => ligo/cmd}/root.go | 0 main.go => cmd/ligo/main.go | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename internal/client/client.go => client.go (98%) rename cmd/{ => ligo/cmd}/root.go (100%) rename main.go => cmd/ligo/main.go (94%) diff --git a/internal/client/client.go b/client.go similarity index 98% rename from internal/client/client.go rename to client.go index 0cc96b7..7a4a789 100644 --- a/internal/client/client.go +++ b/client.go @@ -1,5 +1,5 @@ // Package client initializes the Linode Client and provides related helpers. -package client +package ligo import ( "context" diff --git a/cmd/root.go b/cmd/ligo/cmd/root.go similarity index 100% rename from cmd/root.go rename to cmd/ligo/cmd/root.go diff --git a/main.go b/cmd/ligo/main.go similarity index 94% rename from main.go rename to cmd/ligo/main.go index ce9c69e..b5977be 100644 --- a/main.go +++ b/cmd/ligo/main.go @@ -15,7 +15,7 @@ package main import ( - "github.com/kzap/ligo/cmd" + "github.com/kzap/ligo/cmd/ligo/cmd" ) func main() { From a0833af9677323017929ca5ea81a69bb9dd7a1fb Mon Sep 17 00:00:00 2001 From: Andre Marcelo-Tanner Date: Sun, 30 Sep 2018 09:00:07 +0800 Subject: [PATCH 4/5] add GoReleaser config file --- .gitignore | 2 +- .goreleaser.yml | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 .goreleaser.yml diff --git a/.gitignore b/.gitignore index c4cdbf9..17407a7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ *.dll *.so *.dylib -ligo +dist/ # Test binary, build with `go test -c` *.test diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..6dbaebc --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,24 @@ +# This is an example goreleaser.yaml file with some sane defaults. +# Make sure to check the documentation at http://goreleaser.com +builds: +- + env: + - CGO_ENABLED=0 + main: ./cmd/ligo/main.go +archive: + replacements: + darwin: Darwin + linux: Linux + windows: Windows + 386: i386 + amd64: x86_64 +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ .Tag }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' From f4e7dbdd8f3e0669580e25c0f8121b35564df451 Mon Sep 17 00:00:00 2001 From: Andre Marcelo-Tanner Date: Sun, 30 Sep 2018 09:02:23 +0800 Subject: [PATCH 5/5] Add CHANGELOG file --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..0cf3c8b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ + +0.0.1 / 2018-09-30 +================== + + * add GoReleaser config file + * updating dir structure so main.go is in a per app directory + * Adding initial Cobra/Viper code and moving client to internal package + * make LINODE_DEBUG env var optional + * Working WIP using Linode Go SDK