From 358304b9e2b1d1991a19832e2de03f398db8e177 Mon Sep 17 00:00:00 2001 From: "warren.veerasingam" Date: Tue, 12 Jan 2021 18:28:26 +0800 Subject: [PATCH 1/7] latest version2 --- go.mod | 1 + go.sum | 4 + go.sum538389371.tmp | 222 +++++++++++++++++++++++++++++++++++++++++++ lib/latest.go | 7 ++ lib/list_versions.go | 48 ++++++++++ main.go | 120 +++++++++++++++++------ 6 files changed, 375 insertions(+), 27 deletions(-) create mode 100644 go.sum538389371.tmp create mode 100644 lib/latest.go diff --git a/go.mod b/go.mod index 99932fc4..284be9c0 100644 --- a/go.mod +++ b/go.mod @@ -20,4 +20,5 @@ require ( github.com/spf13/afero v1.2.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/viper v1.4.0 + gopkg.in/alecthomas/kingpin.v2 v2.2.6 ) diff --git a/go.sum b/go.sum index b7f5d836..71a0e53a 100644 --- a/go.sum +++ b/go.sum @@ -7,7 +7,9 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= @@ -112,6 +114,7 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30 h1:BHT1/DKsYDGkUgQ2jmMaozVcdk+sVfz0+1ZJq4zkWgw= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +github.com/pborman/getopt v1.1.0 h1:eJ3aFZroQqq0bWmraivjQNt6Dmm5M0h2JcDW38/Azb0= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= @@ -205,6 +208,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= diff --git a/go.sum538389371.tmp b/go.sum538389371.tmp new file mode 100644 index 00000000..1f319460 --- /dev/null +++ b/go.sum538389371.tmp @@ -0,0 +1,222 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= +github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= +github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bsm/go-vlq v0.0.0-20150828105119-ec6e8d4f5f4e/go.mod h1:N+BjUcTjSxc2mtRGSCPsat1kze3CUtvJN3/jTXlp29k= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20171208011716-f6d7a1f6fbf3 h1:T7Bw4H6z3WAZ2khw+gfKdYmbKHyy5xiHtk9IHfZqm7g= +github.com/chzyer/readline v0.0.0-20171208011716-f6d7a1f6fbf3/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= +github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +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/hashicorp/hcl2 v0.0.0-20190821123243-0c888d1241f6 h1:JImQpEeUQ+0DPFMaWzLA0GdUNPaUlCXLpfiqkSZBUfc= +github.com/hashicorp/hcl2 v0.0.0-20190821123243-0c888d1241f6/go.mod h1:Cxv+IJLuBiEhQ7pBYGEuORa0nr4U994pE8mYLuFd7v0= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= +github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kiranjthomas/terraform-config-inspect v0.0.0-20191120205521-a1d709eb2824 h1:2W0nCRf6KE5PGakYzkMTiOCGKTZR1HGxd8zxdqbLqgc= +github.com/kiranjthomas/terraform-config-inspect v0.0.0-20191120205521-a1d709eb2824/go.mod h1:1Yap3+TRKI7BuRH6I8lbmjr+hMN7/GBxqBFhI2f2fmw= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lunixbochs/vtclean v0.0.0-20170504063817-d14193dfc626 h1:33Ys8SnkRfz5ojdG853pyT/2Iqbk95PVm+QrC5XvI70= +github.com/lunixbochs/vtclean v0.0.0-20170504063817-d14193dfc626/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/manifoldco/promptui v0.2.2-0.20180308161052-c0c0d3afc6a0 h1:m+7Wac/EstF4dyXS4Il4eNK1GM/yMI0jgylBB6Ztg0c= +github.com/manifoldco/promptui v0.2.2-0.20180308161052-c0c0d3afc6a0/go.mod h1:zoCNXiJnyM03LlBgTsWv8mq28s7aTC71UgKasqRJHww= +github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30 h1:BHT1/DKsYDGkUgQ2jmMaozVcdk+sVfz0+1ZJq4zkWgw= +github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +github.com/pborman/getopt v1.1.0 h1:eJ3aFZroQqq0bWmraivjQNt6Dmm5M0h2JcDW38/Azb0= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/zclconf/go-cty v1.0.0 h1:EWtv3gKe2wPLIB9hQRQJa7k/059oIfAqcEkCNnaVckk= +github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180514143608-7c87d13f8e83/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 h1:vsphBvatvfbhlb4PO1BYSr9dzugGxJ/SQHoNufZJq1w= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099 h1:XJP7lxbSxWLOMNdBE4B/STaqVy6L73o0knwj2vIlxnw= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= diff --git a/lib/latest.go b/lib/latest.go new file mode 100644 index 00000000..f40c65d6 --- /dev/null +++ b/lib/latest.go @@ -0,0 +1,7 @@ +package lib + +import "fmt" + +func GetLatest() { + fmt.Println("0") +} diff --git a/lib/list_versions.go b/lib/list_versions.go index c7ca1fb2..5b5656a2 100644 --- a/lib/list_versions.go +++ b/lib/list_versions.go @@ -1,6 +1,7 @@ package lib import ( + "fmt" "io/ioutil" "log" "net/http" @@ -57,6 +58,53 @@ func GetTFList(hashiURL string, listAll bool) ([]string, error) { } +//GetTFLatest : Get the latest terraform version given the hashicorp url +func GetTFLatest(hashiURL string, listAll bool, version string) (string, error) { + + /* Get list of terraform versions from hashicorp releases */ + resp, errURL := http.Get(hashiURL) + if errURL != nil { + log.Printf("Error getting url: %v", errURL) + return "nil", errURL + } + defer resp.Body.Close() + + body, errBody := ioutil.ReadAll(resp.Body) + if errBody != nil { + log.Printf("Error reading body: %v", errBody) + return "", errBody + } + + bodyString := string(body) + result := strings.Split(bodyString, "\n") + + var semver string + if version == "-" { + // Getting versions from body; should return match /X.X.X/ where X is a number + // Follow https://semver.org/spec/v2.0.0.html + semver = `\/(\d+\.\d+\.\d+)\/` + } else if listAll == true { + // Getting versions from body; should return match /X.X.X-@/ where X is a number,@ is a word character between a-z or A-Z + // Follow https://semver.org/spec/v1.0.0-beta.html + // Check regular expression at https://rubular.com/r/ju3PxbaSBALpJB + semver = fmt.Sprintf(`\/(%s{1}\.\d+\-[a-zA-z]+\d*)?\/`, version) + } else if listAll == false { + semver = fmt.Sprintf(`\/(%s{1}\.\d+)\/`, version) + } + r, _ := regexp.Compile(semver) + for i := range result { + if r.MatchString(result[i]) { + str := r.FindString(result[i]) + trimstr := strings.Trim(str, "/") //remove "/" from /X.X.X/ + fmt.Println(trimstr) + return trimstr, nil + } + } + + return "", nil + +} + //VersionExist : check if requested version exist func VersionExist(val interface{}, array interface{}) (exists bool) { diff --git a/main.go b/main.go index b89d46b0..895c4304 100644 --- a/main.go +++ b/main.go @@ -30,36 +30,73 @@ import ( "github.com/Masterminds/semver" "github.com/kiranjthomas/terraform-config-inspect/tfconfig" "github.com/mitchellh/go-homedir" + "github.com/pborman/getopt" + "gopkg.in/alecthomas/kingpin.v2" // "github.com/hashicorp/terraform-config-inspect/tfconfig" "github.com/manifoldco/promptui" - "github.com/pborman/getopt" + //"github.com/pborman/getopt" "github.com/spf13/viper" lib "github.com/warrensbox/terraform-switcher/lib" ) +var ( + custBinPath *string + listAllFlag *bool + latest *string + versionFlag *bool + helpFlag *bool + arg *string +) + const ( - hashiURL = "https://releases.hashicorp.com/terraform/" - defaultBin = "/usr/local/bin/terraform" //default bin installation dir - tfvFilename = ".terraform-version" - rcFilename = ".tfswitchrc" - tomlFilename = ".tfswitch.toml" + hashiURL = "https://releases.hashicorp.com/terraform/" + defaultBin = "/usr/local/bin/terraform" //default bin installation dir + tfvFilename = ".terraform-version" + rcFilename = ".tfswitchrc" + tomlFilename = ".tfswitch.toml" + defaultlatest = "" ) +func init() { + const ( + custBinPathDesc = "Custom binary path. For example: /Users/username/bin/terraform" + listAllFlagDesc = "List all versions of terraform - including beta and rc" + latestDesc = "Get latest explicit version. For example: tfswitch --latest 0.13 will download 0.13.5 (latest). tfswitch --latest will download the most latest stable release" + argDesc = "Pass version required" + helpDesc = "Displays help message" + ) + + custBinPath = kingpin.Flag("bin", custBinPathDesc).Default(defaultBin).Short('b').String() + listAllFlag = kingpin.Flag("list-all", listAllFlagDesc).Short('l').Bool() + versionFlag = kingpin.Flag("version", listAllFlagDesc).Short('v').Bool() + //helpFlag = kingpin.Flag("h", helpDesc).Short('h').Bool() + latest = kingpin.Flag("latest", latestDesc).Default(defaultlatest).Short('a').String() + arg = kingpin.Arg("arg", "Supply terraform version as an argument. For example: tfswtich 0.14.0").String() +} + var version = "0.9.0\n" func main() { - custBinPath := getopt.StringLong("bin", 'b', defaultBin, "Custom binary path. For example: /Users/username/bin/terraform") - listAllFlag := getopt.BoolLong("list-all", 'l', "List all versions of terraform - including beta and rc") - versionFlag := getopt.BoolLong("version", 'v', "Displays the version of tfswitch") - helpFlag := getopt.BoolLong("help", 'h', "Displays help message") - _ = versionFlag - - getopt.Parse() - args := getopt.Args() + // custBinPath := getopt.StringLong("bin", 'b', defaultBin, "Custom binary path. For example: /Users/username/bin/terraform") + // listAllFlag := getopt.BoolLong("list-all", 'l', "List all versions of terraform - including beta and rc") + // latest := getopt.StringLong("latest", 'a', defaultlatest, "Custom binary path. For example: tfswitch --latest 0.13 will download 0.13.5 (latest). tfswitch --latest will download the most latest stable release") + // versionFlag := getopt.BoolLong("version", 'v', "Displays the version of tfswitch") + // helpFlag := getopt.BoolLong("help", 'h', "Displays help message") + // _ = versionFlag + + kingpin.CommandLine.Interspersed(false) + kingpin.Parse() + + //os.Exit(0) + /* check if arg is provided; set bool = true */ + argProvided := false + if *arg != "" { + argProvided = true + } dir, err := os.Getwd() //get current directory if err != nil { @@ -82,9 +119,9 @@ func main() { case *versionFlag: //if *versionFlag { fmt.Printf("\nVersion: %v\n", version) - case *helpFlag: - //} else if *helpFlag { - usageMessage() + // case *helpFlag: + // //} else if *helpFlag { + // usageMessage() /* Checks if the .tfswitch.toml file exist in home or current directory * This block checks to see if the tfswitch toml file is provided in the current path. * If the .tfswitch.toml file exist, it has a higher precedence than the .tfswitchrc file @@ -106,17 +143,17 @@ func main() { case *listAllFlag: listAll := true //set list all true - all versions including beta and rc will be displayed installOption(listAll, &binPath) - case len(args) == 1: - installVersion(args[0], &binPath) - case fileExists(curr_rcfile) && len(args) == 0: + case *arg != "": + installVersion(*arg, &binPath) + case fileExists(curr_rcfile) && argProvided: readingFileMsg(rcFilename) tfversion := retrieveFileContents(curr_rcfile) installVersion(tfversion, &binPath) - case fileExists(curr_tfvfile) && len(args) == 0: + case fileExists(curr_tfvfile) && argProvided: readingFileMsg(tfvFilename) tfversion := retrieveFileContents(curr_tfvfile) installVersion(tfversion, &binPath) - case checkTFModuleFileExist(dir) && len(args) == 0: + case checkTFModuleFileExist(dir) && argProvided: installTFProvidedModule(dir, &binPath) case version != "": installVersion(version, &binPath) @@ -129,24 +166,28 @@ func main() { case *listAllFlag: installWithListAll(custBinPath) + case *latest != "": + fmt.Println(*latest) + installLatestVersion(*latest, custBinPath) + /* version provided on command line as arg */ - case len(args) == 1: - installVersion(args[0], custBinPath) + case argProvided: + installVersion(*arg, custBinPath) /* provide an tfswitchrc file */ - case fileExists(curr_rcfile) && len(args) == 0: + case fileExists(curr_rcfile) && argProvided: readingFileMsg(rcFilename) tfversion := retrieveFileContents(curr_rcfile) installVersion(tfversion, custBinPath) /* if .terraform-version file found */ - case fileExists(curr_tfvfile) && len(args) == 0: + case fileExists(curr_tfvfile) && argProvided: readingFileMsg(tfvFilename) tfversion := retrieveFileContents(curr_tfvfile) installVersion(tfversion, custBinPath) /* if versions.tf file found */ - case checkTFModuleFileExist(dir) && len(args) == 0: + case checkTFModuleFileExist(dir) && argProvided: installTFProvidedModule(dir, custBinPath) // if no arg is provided @@ -164,6 +205,31 @@ func installWithListAll(custBinPath *string) { installOption(listAll, custBinPath) } +// install latest with provided version as argument +func installLatestVersion(arg string, custBinPath *string) { + // if lib.ValidVersionFormat(arg) { + requestedVersion := arg + listAll := true + fmt.Println(requestedVersion) + os.Exit(0) + //set list all true - all versions including beta and rc will be displayed + tfversion, _ := lib.GetTFLatest(hashiURL, listAll, requestedVersion) //get list of versions + //exist := lib.VersionExist(requestedVersion, tflist) //check if version exist before downloading it + fmt.Println(tfversion) + os.Exit(0) + // if exist { + lib.Install(tfversion, *custBinPath) + // } else { + fmt.Println("The provided terraform version does not exist. Try `tfswitch -l` to see all available versions.") + // } + + // } else { + // printInvalidTFVersion() + // fmt.Println("Args must be a valid terraform version") + // usageMessage() + // } +} + // install with provided version as argument func installVersion(arg string, custBinPath *string) { if lib.ValidVersionFormat(arg) { From 32f7569a0538e140bdcee22cb99907877a3ad7fc Mon Sep 17 00:00:00 2001 From: "warren.veerasingam" Date: Wed, 13 Jan 2021 14:14:54 +0800 Subject: [PATCH 2/7] added option to download latest version --- lib/list_versions.go | 107 +++++++++++++++----------- main.go | 176 +++++++++++++++++++------------------------ 2 files changed, 143 insertions(+), 140 deletions(-) diff --git a/lib/list_versions.go b/lib/list_versions.go index 5b5656a2..0dce9ca5 100644 --- a/lib/list_versions.go +++ b/lib/list_versions.go @@ -17,33 +17,18 @@ type tfVersionList struct { //GetTFList : Get the list of available terraform version given the hashicorp url func GetTFList(hashiURL string, listAll bool) ([]string, error) { - /* Get list of terraform versions from hashicorp releases */ - resp, errURL := http.Get(hashiURL) - if errURL != nil { - log.Printf("Error getting url: %v", errURL) - return nil, errURL + result, error := GetTFURLBody(hashiURL) + if error != nil { + return nil, error } - defer resp.Body.Close() - - body, errBody := ioutil.ReadAll(resp.Body) - if errBody != nil { - log.Printf("Error reading body: %v", errBody) - return nil, errBody - } - - bodyString := string(body) - result := strings.Split(bodyString, "\n") var tfVersionList tfVersionList for i := range result { // Getting versions from body; should return match /X.X.X/ where X is a number - // Follow https://semver.org/spec/v2.0.0.html r, _ := regexp.Compile(`\/(\d+\.\d+\.\d+)\/`) if listAll { // Getting versions from body; should return match /X.X.X-@/ where X is a number,@ is a word character between a-z or A-Z - // Follow https://semver.org/spec/v1.0.0-beta.html - // Check regular expression at https://rubular.com/r/ju3PxbaSBALpJB r, _ = regexp.Compile(`\/(\d+\.\d+\.\d+)(-[a-zA-z]+\d*)?\/`) } @@ -58,37 +43,39 @@ func GetTFList(hashiURL string, listAll bool) ([]string, error) { } -//GetTFLatest : Get the latest terraform version given the hashicorp url -func GetTFLatest(hashiURL string, listAll bool, version string) (string, error) { +//GetTFLatestImplicit : Get the latest terraform version given the hashicorp url +func GetTFLatest(hashiURL string) (string, error) { - /* Get list of terraform versions from hashicorp releases */ - resp, errURL := http.Get(hashiURL) - if errURL != nil { - log.Printf("Error getting url: %v", errURL) - return "nil", errURL + result, error := GetTFURLBody(hashiURL) + if error != nil { + return "", error } - defer resp.Body.Close() - - body, errBody := ioutil.ReadAll(resp.Body) - if errBody != nil { - log.Printf("Error reading body: %v", errBody) - return "", errBody + // Getting versions from body; should return match /X.X.X/ where X is a number + semver := `\/(\d+\.\d+\.\d+)\/` + r, _ := regexp.Compile(semver) + for i := range result { + if r.MatchString(result[i]) { + str := r.FindString(result[i]) + trimstr := strings.Trim(str, "/") //remove "/" from /X.X.X/ + return trimstr, nil + } } - bodyString := string(body) - result := strings.Split(bodyString, "\n") + return "", nil +} +//GetTFLatestImplicit : Get the latest terraform version given the hashicorp url +func GetTFLatestImplicit(hashiURL string, preRelease bool, version string) (string, error) { + + result, error := GetTFURLBody(hashiURL) + if error != nil { + return "", error + } var semver string - if version == "-" { - // Getting versions from body; should return match /X.X.X/ where X is a number - // Follow https://semver.org/spec/v2.0.0.html - semver = `\/(\d+\.\d+\.\d+)\/` - } else if listAll == true { + if preRelease == true { // Getting versions from body; should return match /X.X.X-@/ where X is a number,@ is a word character between a-z or A-Z - // Follow https://semver.org/spec/v1.0.0-beta.html - // Check regular expression at https://rubular.com/r/ju3PxbaSBALpJB semver = fmt.Sprintf(`\/(%s{1}\.\d+\-[a-zA-z]+\d*)?\/`, version) - } else if listAll == false { + } else if preRelease == false { semver = fmt.Sprintf(`\/(%s{1}\.\d+)\/`, version) } r, _ := regexp.Compile(semver) @@ -96,7 +83,6 @@ func GetTFLatest(hashiURL string, listAll bool, version string) (string, error) if r.MatchString(result[i]) { str := r.FindString(result[i]) trimstr := strings.Trim(str, "/") //remove "/" from /X.X.X/ - fmt.Println(trimstr) return trimstr, nil } } @@ -105,6 +91,28 @@ func GetTFLatest(hashiURL string, listAll bool, version string) (string, error) } +//GetTFURLBody : Get list of terraform versions from hashicorp releases +func GetTFURLBody(hashiURL string) ([]string, error) { + + resp, errURL := http.Get(hashiURL) + if errURL != nil { + log.Printf("Error getting url: %v", errURL) + return nil, errURL + } + defer resp.Body.Close() + + body, errBody := ioutil.ReadAll(resp.Body) + if errBody != nil { + log.Printf("Error reading body: %v", errBody) + return nil, errBody + } + + bodyString := string(body) + result := strings.Split(bodyString, "\n") + + return result, nil +} + //VersionExist : check if requested version exist func VersionExist(val interface{}, array interface{}) (exists bool) { @@ -161,3 +169,18 @@ func ValidVersionFormat(version string) bool { return semverRegex.MatchString(version) } + +// ValidMinorVersionFormat : returns valid MINOR version format +/* For example: 0.1 = valid +// For example: a.1.2 = invalid +// For example: 0.1.2 = invalid +*/ +func ValidMinorVersionFormat(version string) bool { + + // Getting versions from body; should return match /X.X.X-@/ where X is a number,@ is a word character between a-z or A-Z + // Follow https://semver.org/spec/v1.0.0-beta.html + // Check regular expression at https://rubular.com/r/ju3PxbaSBALpJB + semverRegex := regexp.MustCompile(`^(\d+\.\d+)`) + + return semverRegex.MatchString(version) +} diff --git a/main.go b/main.go index 895c4304..e04c5f4b 100644 --- a/main.go +++ b/main.go @@ -30,73 +30,39 @@ import ( "github.com/Masterminds/semver" "github.com/kiranjthomas/terraform-config-inspect/tfconfig" "github.com/mitchellh/go-homedir" - "github.com/pborman/getopt" - "gopkg.in/alecthomas/kingpin.v2" // "github.com/hashicorp/terraform-config-inspect/tfconfig" "github.com/manifoldco/promptui" - //"github.com/pborman/getopt" + "github.com/pborman/getopt" "github.com/spf13/viper" lib "github.com/warrensbox/terraform-switcher/lib" ) -var ( - custBinPath *string - listAllFlag *bool - latest *string - versionFlag *bool - helpFlag *bool - arg *string -) - const ( hashiURL = "https://releases.hashicorp.com/terraform/" defaultBin = "/usr/local/bin/terraform" //default bin installation dir + defaultLatest = "" tfvFilename = ".terraform-version" rcFilename = ".tfswitchrc" tomlFilename = ".tfswitch.toml" - defaultlatest = "" ) -func init() { - const ( - custBinPathDesc = "Custom binary path. For example: /Users/username/bin/terraform" - listAllFlagDesc = "List all versions of terraform - including beta and rc" - latestDesc = "Get latest explicit version. For example: tfswitch --latest 0.13 will download 0.13.5 (latest). tfswitch --latest will download the most latest stable release" - argDesc = "Pass version required" - helpDesc = "Displays help message" - ) - - custBinPath = kingpin.Flag("bin", custBinPathDesc).Default(defaultBin).Short('b').String() - listAllFlag = kingpin.Flag("list-all", listAllFlagDesc).Short('l').Bool() - versionFlag = kingpin.Flag("version", listAllFlagDesc).Short('v').Bool() - //helpFlag = kingpin.Flag("h", helpDesc).Short('h').Bool() - latest = kingpin.Flag("latest", latestDesc).Default(defaultlatest).Short('a').String() - arg = kingpin.Arg("arg", "Supply terraform version as an argument. For example: tfswtich 0.14.0").String() -} - var version = "0.9.0\n" func main() { - - // custBinPath := getopt.StringLong("bin", 'b', defaultBin, "Custom binary path. For example: /Users/username/bin/terraform") - // listAllFlag := getopt.BoolLong("list-all", 'l', "List all versions of terraform - including beta and rc") - // latest := getopt.StringLong("latest", 'a', defaultlatest, "Custom binary path. For example: tfswitch --latest 0.13 will download 0.13.5 (latest). tfswitch --latest will download the most latest stable release") - // versionFlag := getopt.BoolLong("version", 'v', "Displays the version of tfswitch") - // helpFlag := getopt.BoolLong("help", 'h', "Displays help message") - // _ = versionFlag - - kingpin.CommandLine.Interspersed(false) - kingpin.Parse() - - //os.Exit(0) - /* check if arg is provided; set bool = true */ - argProvided := false - if *arg != "" { - argProvided = true - } + custBinPath := getopt.StringLong("bin", 'b', defaultBin, "Custom binary path. Ex: /Users/username/bin/terraform") + listAllFlag := getopt.BoolLong("list-all", 'l', "List all versions of terraform - including beta and rc") + latestPre := getopt.StringLong("latest-pre", 'p', defaultLatest, "Latest pre-release implicit version. Ex: tfswitch --latest-pre 0.13 downloads 0.13.0-rc1 (latest)") + latestStable := getopt.StringLong("latest-stable", 's', defaultLatest, "Latest implicit version. Ex: tfswitch --latest 0.13 downloads 0.13.5 (latest)") + latestFlag := getopt.BoolLong("latest", 'u', "Get latest stable version") + versionFlag := getopt.BoolLong("version", 'v', "Displays the version of tfswitch") + helpFlag := getopt.BoolLong("help", 'h', "Displays help message") + _ = versionFlag + + getopt.Parse() + args := getopt.Args() dir, err := os.Getwd() //get current directory if err != nil { @@ -110,18 +76,18 @@ func main() { os.Exit(1) } - curr_tfvfile := dir + fmt.Sprintf("/%s", tfvFilename) //settings for .terraform-version file in current directory (tfenv compatible) - curr_rcfile := dir + fmt.Sprintf("/%s", rcFilename) //settings for .tfswitchrc file in current directory (backward compatible purpose) - curr_tomlconfigfile := dir + fmt.Sprintf("/%s", tomlFilename) //settings for .tfswitch.toml file in current directory (option to specify bin directory) - home_tomlconfigfile := homedir + fmt.Sprintf("/%s", tomlFilename) //settings for .tfswitch.toml file in home directory (option to specify bin directory) + TFVersionFile := dir + fmt.Sprintf("/%s", tfvFilename) //settings for .terraform-version file in current directory (tfenv compatible) + RCFile := dir + fmt.Sprintf("/%s", rcFilename) //settings for .tfswitchrc file in current directory (backward compatible purpose) + TOMLConfigFile := dir + fmt.Sprintf("/%s", tomlFilename) //settings for .tfswitch.toml file in current directory (option to specify bin directory) + HomeTOMLConfigFile := homedir + fmt.Sprintf("/%s", tomlFilename) //settings for .tfswitch.toml file in home directory (option to specify bin directory) switch { case *versionFlag: //if *versionFlag { fmt.Printf("\nVersion: %v\n", version) - // case *helpFlag: - // //} else if *helpFlag { - // usageMessage() + case *helpFlag: + //} else if *helpFlag { + usageMessage() /* Checks if the .tfswitch.toml file exist in home or current directory * This block checks to see if the tfswitch toml file is provided in the current path. * If the .tfswitch.toml file exist, it has a higher precedence than the .tfswitchrc file @@ -129,11 +95,11 @@ func main() { * If you provide a custom binary path with the -b option, this will override the bin value in the toml file * If you provide a version on the command line, this will override the version value in the toml file */ - case fileExists(curr_tomlconfigfile) || fileExists(home_tomlconfigfile): + case fileExists(TOMLConfigFile) || fileExists(HomeTOMLConfigFile): version := "" binPath := *custBinPath - if fileExists(curr_tomlconfigfile) { //read from toml from current directory + if fileExists(TOMLConfigFile) { //read from toml from current directory version, binPath = getParamsTOML(binPath, dir) } else { // else read from toml from home directory version, binPath = getParamsTOML(binPath, homedir) @@ -143,17 +109,25 @@ func main() { case *listAllFlag: listAll := true //set list all true - all versions including beta and rc will be displayed installOption(listAll, &binPath) - case *arg != "": - installVersion(*arg, &binPath) - case fileExists(curr_rcfile) && argProvided: + case *latestPre != "": + preRelease := true + installLatestImplicitVersion(*latestPre, custBinPath, preRelease) + case *latestStable != "": + preRelease := false + installLatestImplicitVersion(*latestStable, custBinPath, preRelease) + case *latestFlag: + installLatestVersion(custBinPath) + case len(args) == 1: + installVersion(args[0], &binPath) + case fileExists(RCFile) && len(args) == 0: readingFileMsg(rcFilename) - tfversion := retrieveFileContents(curr_rcfile) + tfversion := retrieveFileContents(RCFile) installVersion(tfversion, &binPath) - case fileExists(curr_tfvfile) && argProvided: + case fileExists(TFVersionFile) && len(args) == 0: readingFileMsg(tfvFilename) - tfversion := retrieveFileContents(curr_tfvfile) + tfversion := retrieveFileContents(TFVersionFile) installVersion(tfversion, &binPath) - case checkTFModuleFileExist(dir) && argProvided: + case checkTFModuleFileExist(dir) && len(args) == 0: installTFProvidedModule(dir, &binPath) case version != "": installVersion(version, &binPath) @@ -162,32 +136,42 @@ func main() { installOption(listAll, &binPath) } - /* list all versions, //show all terraform version including betas and RCs*/ + /* show all terraform version including betas and RCs*/ case *listAllFlag: installWithListAll(custBinPath) - case *latest != "": - fmt.Println(*latest) - installLatestVersion(*latest, custBinPath) + /* latest pre-release implicit version. Ex: tfswitch --latest-pre 0.13 downloads 0.13.0-rc1 (latest) */ + case *latestPre != "": + preRelease := true + installLatestImplicitVersion(*latestPre, custBinPath, preRelease) + + /* latest implicit version. Ex: tfswitch --latest 0.13 downloads 0.13.5 (latest) */ + case *latestStable != "": + preRelease := false + installLatestImplicitVersion(*latestStable, custBinPath, preRelease) + + /* latest stable version */ + case *latestFlag: + installLatestVersion(custBinPath) /* version provided on command line as arg */ - case argProvided: - installVersion(*arg, custBinPath) + case len(args) == 1: + installVersion(args[0], custBinPath) /* provide an tfswitchrc file */ - case fileExists(curr_rcfile) && argProvided: + case fileExists(RCFile) && len(args) == 0: readingFileMsg(rcFilename) - tfversion := retrieveFileContents(curr_rcfile) + tfversion := retrieveFileContents(RCFile) installVersion(tfversion, custBinPath) /* if .terraform-version file found */ - case fileExists(curr_tfvfile) && argProvided: + case fileExists(TFVersionFile) && len(args) == 0: readingFileMsg(tfvFilename) - tfversion := retrieveFileContents(curr_tfvfile) + tfversion := retrieveFileContents(TFVersionFile) installVersion(tfversion, custBinPath) /* if versions.tf file found */ - case checkTFModuleFileExist(dir) && argProvided: + case checkTFModuleFileExist(dir) && len(args) == 0: installTFProvidedModule(dir, custBinPath) // if no arg is provided @@ -205,29 +189,20 @@ func installWithListAll(custBinPath *string) { installOption(listAll, custBinPath) } -// install latest with provided version as argument -func installLatestVersion(arg string, custBinPath *string) { - // if lib.ValidVersionFormat(arg) { - requestedVersion := arg - listAll := true - fmt.Println(requestedVersion) - os.Exit(0) - //set list all true - all versions including beta and rc will be displayed - tfversion, _ := lib.GetTFLatest(hashiURL, listAll, requestedVersion) //get list of versions - //exist := lib.VersionExist(requestedVersion, tflist) //check if version exist before downloading it - fmt.Println(tfversion) - os.Exit(0) - // if exist { +// install latest stable tf version +func installLatestVersion(custBinPath *string) { + tfversion, _ := lib.GetTFLatest(hashiURL) lib.Install(tfversion, *custBinPath) - // } else { - fmt.Println("The provided terraform version does not exist. Try `tfswitch -l` to see all available versions.") - // } - - // } else { - // printInvalidTFVersion() - // fmt.Println("Args must be a valid terraform version") - // usageMessage() - // } +} + +// install latest - argument (version) must be provided +func installLatestImplicitVersion(requestedVersion string, custBinPath *string, preRelease bool) { + if lib.ValidMinorVersionFormat(requestedVersion) { + tfversion, _ := lib.GetTFLatestImplicit(hashiURL, preRelease, requestedVersion) + lib.Install(tfversion, *custBinPath) + } else { + printInvalidMinorTFVersion() + } } // install with provided version as argument @@ -253,7 +228,12 @@ func installVersion(arg string, custBinPath *string) { // Print invalid TF version func printInvalidTFVersion() { - fmt.Println("Invalid terraform version format. Format should be #.#.# or #.#.#-@# where # is numbers and @ is word characters. For example, 0.11.7 and 0.11.9-beta1 are valid versions") + fmt.Println("Invalid terraform version format. Format should be #.#.# or #.#.#-@# where # are numbers and @ are word characters. For example, 0.11.7 and 0.11.9-beta1 are valid versions") +} + +// Print invalid TF version +func printInvalidMinorTFVersion() { + fmt.Println("Invalid minor terraform version format. Format should be #.# where # are numbers. For example, 0.11 is valid versions") } //retrive file content of regular file @@ -361,7 +341,7 @@ func installOption(listAll bool, custBinPath *string) { os.Exit(0) } -// installation when +// install when tf file is provided func installTFProvidedModule(dir string, custBinPath *string) { tfversion := "" module, _ := tfconfig.LoadModule(dir) From 1d0690d572aea257c894e28753609fb198603397 Mon Sep 17 00:00:00 2001 From: "warren.veerasingam" Date: Wed, 13 Jan 2021 14:22:27 +0800 Subject: [PATCH 3/7] enchance code --- lib/list_versions.go | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/list_versions.go b/lib/list_versions.go index 0dce9ca5..bccf2d9e 100644 --- a/lib/list_versions.go +++ b/lib/list_versions.go @@ -15,7 +15,7 @@ type tfVersionList struct { } //GetTFList : Get the list of available terraform version given the hashicorp url -func GetTFList(hashiURL string, listAll bool) ([]string, error) { +func GetTFList(hashiURL string, preRelease bool) ([]string, error) { result, error := GetTFURLBody(hashiURL) if error != nil { @@ -23,15 +23,16 @@ func GetTFList(hashiURL string, listAll bool) ([]string, error) { } var tfVersionList tfVersionList - - for i := range result { + var semver string + if preRelease == true { + // Getting versions from body; should return match /X.X.X-@/ where X is a number,@ is a word character between a-z or A-Z + semver = `\/(\d+\.\d+\.\d+)(-[a-zA-z]+\d*)?\/` + } else if preRelease == false { // Getting versions from body; should return match /X.X.X/ where X is a number - r, _ := regexp.Compile(`\/(\d+\.\d+\.\d+)\/`) - if listAll { - // Getting versions from body; should return match /X.X.X-@/ where X is a number,@ is a word character between a-z or A-Z - r, _ = regexp.Compile(`\/(\d+\.\d+\.\d+)(-[a-zA-z]+\d*)?\/`) - } - + semver = `\/(\d+\.\d+\.\d+)\/` + } + r, _ := regexp.Compile(semver) + for i := range result { if r.MatchString(result[i]) { str := r.FindString(result[i]) trimstr := strings.Trim(str, "/") //remove "/" from /X.X.X/ @@ -43,7 +44,7 @@ func GetTFList(hashiURL string, listAll bool) ([]string, error) { } -//GetTFLatestImplicit : Get the latest terraform version given the hashicorp url +//GetTFLatest : Get the latest terraform version given the hashicorp url func GetTFLatest(hashiURL string) (string, error) { result, error := GetTFURLBody(hashiURL) @@ -64,7 +65,7 @@ func GetTFLatest(hashiURL string) (string, error) { return "", nil } -//GetTFLatestImplicit : Get the latest terraform version given the hashicorp url +//GetTFLatestImplicit : Get the latest implicit terraform version given the hashicorp url func GetTFLatestImplicit(hashiURL string, preRelease bool, version string) (string, error) { result, error := GetTFURLBody(hashiURL) @@ -177,9 +178,7 @@ func ValidVersionFormat(version string) bool { */ func ValidMinorVersionFormat(version string) bool { - // Getting versions from body; should return match /X.X.X-@/ where X is a number,@ is a word character between a-z or A-Z - // Follow https://semver.org/spec/v1.0.0-beta.html - // Check regular expression at https://rubular.com/r/ju3PxbaSBALpJB + // Getting versions from body; should return match /X.X./ where X is a number semverRegex := regexp.MustCompile(`^(\d+\.\d+)`) return semverRegex.MatchString(version) From 696af4ed826a892db3c33d093056e400ecaa6802 Mon Sep 17 00:00:00 2001 From: "warren.veerasingam" Date: Wed, 13 Jan 2021 14:23:30 +0800 Subject: [PATCH 4/7] remove kingpin --- go.mod | 1 - go.sum | 2 -- go.sum538389371.tmp | 1 - vendor/github.com/manifoldco/promptui/Gopkg.lock | 6 ------ vendor/github.com/spf13/viper/go.sum | 1 - 5 files changed, 11 deletions(-) diff --git a/go.mod b/go.mod index 284be9c0..99932fc4 100644 --- a/go.mod +++ b/go.mod @@ -20,5 +20,4 @@ require ( github.com/spf13/afero v1.2.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/viper v1.4.0 - gopkg.in/alecthomas/kingpin.v2 v2.2.6 ) diff --git a/go.sum b/go.sum index 71a0e53a..23a0393b 100644 --- a/go.sum +++ b/go.sum @@ -208,8 +208,6 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/go.sum538389371.tmp b/go.sum538389371.tmp index 1f319460..9129b877 100644 --- a/go.sum538389371.tmp +++ b/go.sum538389371.tmp @@ -206,7 +206,6 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/manifoldco/promptui/Gopkg.lock b/vendor/github.com/manifoldco/promptui/Gopkg.lock index 3c03227c..4ecebf2a 100644 --- a/vendor/github.com/manifoldco/promptui/Gopkg.lock +++ b/vendor/github.com/manifoldco/promptui/Gopkg.lock @@ -103,12 +103,6 @@ packages = ["go/ast/astutil","go/buildutil","go/gcexportdata","go/gcimporter15","go/loader","go/types/typeutil"] revision = "9bd2f442688b66c5289262d70f537c2ecf81d7de" -[[projects]] - branch = "v3-unstable" - name = "gopkg.in/alecthomas/kingpin.v3-unstable" - packages = ["."] - revision = "63abe20a23e29e80bbef8089bd3dee3ac25e5306" - [[projects]] branch = "v2" name = "gopkg.in/yaml.v2" diff --git a/vendor/github.com/spf13/viper/go.sum b/vendor/github.com/spf13/viper/go.sum index 97afaffe..f07eee0b 100644 --- a/vendor/github.com/spf13/viper/go.sum +++ b/vendor/github.com/spf13/viper/go.sum @@ -165,7 +165,6 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= From 4e8657214177921ea3ed0f16f1b14da9fa0f052f Mon Sep 17 00:00:00 2001 From: "warren.veerasingam" Date: Wed, 13 Jan 2021 16:41:15 +0800 Subject: [PATCH 5/7] update regex --- lib/latest.go | 7 ------- lib/list_versions.go | 2 +- main.go | 4 ++-- version | 2 +- 4 files changed, 4 insertions(+), 11 deletions(-) delete mode 100644 lib/latest.go diff --git a/lib/latest.go b/lib/latest.go deleted file mode 100644 index f40c65d6..00000000 --- a/lib/latest.go +++ /dev/null @@ -1,7 +0,0 @@ -package lib - -import "fmt" - -func GetLatest() { - fmt.Println("0") -} diff --git a/lib/list_versions.go b/lib/list_versions.go index bccf2d9e..7f2c43e2 100644 --- a/lib/list_versions.go +++ b/lib/list_versions.go @@ -179,7 +179,7 @@ func ValidVersionFormat(version string) bool { func ValidMinorVersionFormat(version string) bool { // Getting versions from body; should return match /X.X./ where X is a number - semverRegex := regexp.MustCompile(`^(\d+\.\d+)`) + semverRegex := regexp.MustCompile(`^(\d+\.\d+)$`) return semverRegex.MatchString(version) } diff --git a/main.go b/main.go index e04c5f4b..8e62439d 100644 --- a/main.go +++ b/main.go @@ -49,7 +49,7 @@ const ( tomlFilename = ".tfswitch.toml" ) -var version = "0.9.0\n" +var version = "0.10.0\n" func main() { custBinPath := getopt.StringLong("bin", 'b', defaultBin, "Custom binary path. Ex: /Users/username/bin/terraform") @@ -233,7 +233,7 @@ func printInvalidTFVersion() { // Print invalid TF version func printInvalidMinorTFVersion() { - fmt.Println("Invalid minor terraform version format. Format should be #.# where # are numbers. For example, 0.11 is valid versions") + fmt.Println("Invalid minor terraform version format. Format should be #.# where # are numbers. For example, 0.11 is valid version") } //retrive file content of regular file diff --git a/version b/version index 512833fc..b7d9be54 100644 --- a/version +++ b/version @@ -1 +1 @@ -RELEASE_VERSION=0.9 \ No newline at end of file +RELEASE_VERSION=0.10 \ No newline at end of file From 69c438d3ee1880793fac1444615c74b7b5d620ae Mon Sep 17 00:00:00 2001 From: "warren.veerasingam" Date: Wed, 13 Jan 2021 16:54:54 +0800 Subject: [PATCH 6/7] update readme --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index c6d795bd..3706c75c 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,18 @@ The most recently selected versions are presented at the top of the dropdown. 2. For example, `tfswitch -l` or `tfswitch --list-all` to see all versions. 3. Hit **Enter** to select the desired version. +### Install latest version only +1. Install the latest stable version only. +2. Run `tfswitch -u` or `tfswitch --latest` to see all versions. +3. Hit **Enter** to install. +### Install latest implicit version for stable releases +1. Install the latest implicit stable version. +2. Ex: `tfswitch -s 0.13` or `tfswitch --latest-stable 0.13` downloads 0.13.6 (latest) version. +3. Hit **Enter** to install. +### Install latest implicit version for beta, alpha and release candidates(rc) +1. Install the latest implicit pre-release version. +2. Ex: `tfswitch -p 0.13` or `tfswitch --latest-pre 0.13` downloads 0.13.0-rc1 (latest) version. +3. Hit **Enter** to install. ### Use version.tf file If a .tf file with the terraform constrain is included in the current directory, it should automatically download or switch to that terraform version. For example, the following should automatically switch terraform to the lastest version: ```ruby From 92e0612c9d6fd70b7597d04c17ac5f6074dde4e9 Mon Sep 17 00:00:00 2001 From: "warren.veerasingam" Date: Wed, 13 Jan 2021 17:05:22 +0800 Subject: [PATCH 7/7] added quickstart --- go.sum | 1 + www/docs/Quick-Start.md | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/go.sum b/go.sum index 23a0393b..99faf702 100644 --- a/go.sum +++ b/go.sum @@ -208,6 +208,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/www/docs/Quick-Start.md b/www/docs/Quick-Start.md index 3669fd00..7da3ecc4 100644 --- a/www/docs/Quick-Start.md +++ b/www/docs/Quick-Start.md @@ -22,7 +22,18 @@ The most recently selected versions are presented at the top of the dropdown. 1. Display all versions including beta, alpha and release candidates(rc). 2. For example, `tfswitch -l` or `tfswitch --list-all` to see all versions. 3. Hit **Enter** to select the desired version. - +### Install latest version only +1. Install the latest stable version only. +2. Run `tfswitch -u` or `tfswitch --latest` to see all versions. +3. Hit **Enter** to install. +### Install latest implicit version for stable releases +1. Install the latest implicit stable version. +2. Ex: `tfswitch -s 0.13` or `tfswitch --latest-stable 0.13` downloads 0.13.6 (latest) version. +3. Hit **Enter** to install. +### Install latest implicit version for beta, alpha and release candidates(rc) +1. Install the latest implicit pre-release version. +2. Ex: `tfswitch -p 0.13` or `tfswitch --latest-pre 0.13` downloads 0.13.0-rc1 (latest) version. +3. Hit **Enter** to install. ### Use version.tf file If a .tf file with the terraform constrain is included in the current directory, it should automatically download or switch to that terraform version. For example, the following should automatically switch terraform to the lastest version: ```