diff --git a/CHANGELOG.md b/CHANGELOG.md index 18dd07e..b5c7b4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,15 @@ -# 1.2.0 (March 16th, 2021) +# 1.2.1 (April 28, 2021) + +## Fixes +* Fixed `PROXY` flag not working correctly in go 1.16 +* Fixed old executable not being removed after upgrading on windows + +## Enhancements +* `upgrade` command can now be executed with auto upgrades disabled +* Improved error messages on several commands +* Added upgrade command error message for homebrew installation + +# 1.2.0 (March 16, 2021) ## Fixes * Synced logs with terminal output in most commands. diff --git a/README.md b/README.md index bc915f5..529b9a1 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ To set up your `.edgerc` file, see [Get started with APIs](https://developer.aka Unless you installed Akamai CLI with Homebrew, you can enable automatic check for updates when you run Akamai CLI v0.3.0 or later for the first time. -If a new version is available, CLI prompts you to download it. Akamai CLI automatically checks the new version's `SHA256` signature to verify it is not corrupt. After the update, your original command executes using the new version. +When run for the first time, CLI asks you to enable automatic upgrades. If you do not agree, `last-upgrade-check=ignore` is set in the `.akamai-cli/config` file (this option will still allow you to perform manual upgrade as explained below). Otherwise, if a new version is available, CLI prompts you to download it. Akamai CLI automatically checks the new version's `SHA256` signature to verify it is not corrupt. After the update, your original command executes using the new version. For information on manual upgrade and the supported Homebrew command, see `akamai upgrade` in [Built-in commands](#built-in-commands). @@ -313,8 +313,3 @@ The package you install needs a `cli.json` file. This is where you specify the c ] } ``` - - - -## License -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fakamai%2Fcli.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fakamai%2Fcli?ref=badge_large) diff --git a/cli/app/run.go b/cli/app/run.go index dc62e81..9959d2d 100644 --- a/cli/app/run.go +++ b/cli/app/run.go @@ -2,8 +2,12 @@ package app import ( "context" + "errors" + "fmt" "os" "path/filepath" + "strings" + "syscall" "github.com/akamai/cli/pkg/app" "github.com/akamai/cli/pkg/commands" @@ -19,6 +23,13 @@ import ( func Run() int { ctx := context.Background() term := terminal.Color() + + var pathErr *os.PathError + if err := cleanupUpgrade(); err != nil && errors.As(err, &pathErr) && pathErr.Err != syscall.ENOENT { + term.WriteErrorf("Unable to remove old executable: %s", err.Error()) + return 7 + } + if err := os.Setenv("AKAMAI_CLI", "1"); err != nil { term.WriteErrorf("Unable to set AKAMAI_CLI: %s", err.Error()) return 1 @@ -76,6 +87,16 @@ func Run() int { return 0 } +func cleanupUpgrade() error { + oldFilename := os.Args[0] + if strings.HasSuffix(strings.ToLower(oldFilename), ".exe") { + oldFilename = fmt.Sprintf(".%s.old", oldFilename) + } else { + oldFilename = fmt.Sprintf(".%s.exe.old", oldFilename) + } + return os.Remove(oldFilename) +} + func checkUpgrade(ctx context.Context) { if len(os.Args) > 1 && os.Args[1] == "upgrade" { return diff --git a/go.mod b/go.mod index ed70fc0..04b346d 100644 --- a/go.mod +++ b/go.mod @@ -19,8 +19,10 @@ require ( github.com/stretchr/testify v1.6.1 github.com/tj/assert v0.0.3 github.com/urfave/cli/v2 v2.3.0 - golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 // indirect - golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061 + golang.org/x/mod v0.4.2 // indirect + golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 + golang.org/x/tools v0.1.0 // indirect gopkg.in/ini.v1 v1.62.0 // indirect gopkg.in/src-d/go-git.v4 v4.13.1 + honnef.co/go/tools v0.1.3 // indirect ) diff --git a/go.sum b/go.sum index 8367108..d6d70ab 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,6 @@ github.com/AlecAivazis/survey/v2 v2.2.7 h1:5NbxkF4RSKmpywYdcRgUmos1o+roJY8duCLZXbVjoig= github.com/AlecAivazis/survey/v2 v2.2.7/go.mod h1:9DYvHgXtiXm6nCn+jXnOXLKbH+Yo9u8fAS/SduGdoPk= +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= @@ -20,8 +21,6 @@ github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/briandowns/spinner v1.11.1 h1:OixPqDEcX3juo5AjQZAnFPbeUA0jvkp2qzB5gOZJ/L0= github.com/briandowns/spinner v1.11.1/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= -github.com/briandowns/spinner v1.12.0 h1:72O0PzqGJb6G3KgrcIOtL/JAGGZ5ptOMCn9cUHmqsmw= -github.com/briandowns/spinner v1.12.0/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A= @@ -68,6 +67,7 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= @@ -104,7 +104,6 @@ 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/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= @@ -132,21 +131,32 @@ github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/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/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -156,14 +166,29 @@ golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061 h1:DQmQoKxQWtyybCtX/3dIuDBcAhFszqq8YiNeS6sNu1c= golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 h1:rF3Ohx8DRyl8h2zw9qojyLHLhrJpEMgyPOImREEryf0= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/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/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a h1:mEQZbbaBjWyLNy0tmZmgEuQAR8XOQ3hL8GYi3J/NG64= golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= @@ -186,3 +211,5 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.1.3 h1:qTakTkI6ni6LFD5sBwwsdSO+AQqbSIxOauHTTQKZ/7o= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= diff --git a/pkg/app/cli.go b/pkg/app/cli.go index b814c91..16d1ac5 100644 --- a/pkg/app/cli.go +++ b/pkg/app/cli.go @@ -2,6 +2,7 @@ package app import ( "context" + "fmt" "os" "strings" "time" @@ -75,20 +76,15 @@ func CreateApp(ctx context.Context) *cli.App { app.Before = func(c *cli.Context) error { if c.IsSet("proxy") { proxy := c.String("proxy") + if !strings.HasPrefix(proxy, "http://") && !strings.HasPrefix(proxy, "https://") { + proxy = fmt.Sprintf("http://%s", proxy) + } if err := os.Setenv("HTTP_PROXY", proxy); err != nil { return err } - if err := os.Setenv("http_proxy", proxy); err != nil { + if err := os.Setenv("HTTPS_PROXY", proxy); err != nil { return err } - if strings.HasPrefix(proxy, "https") { - if err := os.Setenv("HTTPS_PROXY", proxy); err != nil { - return err - } - if err := os.Setenv("https_proxy", proxy); err != nil { - return err - } - } } if c.IsSet("daemon") { diff --git a/pkg/app/cli_test.go b/pkg/app/cli_test.go index e4e6113..70ce8fa 100644 --- a/pkg/app/cli_test.go +++ b/pkg/app/cli_test.go @@ -28,18 +28,61 @@ func TestCreateApp(t *testing.T) { assert.True(t, hasFlag(app, "proxy")) assert.True(t, hasFlag(app, "daemon")) assert.NotNil(t, app.Before) +} - set := flag.NewFlagSet("test", 0) - set.String("proxy", "", "") - cliCtx := cli.NewContext(app, set, nil) - require.NoError(t, cliCtx.Set("proxy", "https://test.akamai.com")) - err := app.Before(cliCtx) - require.NoError(t, err) - assert.NotNil(t, log.FromContext(cliCtx.Context)) - assert.Equal(t, "https://test.akamai.com", os.Getenv("HTTP_PROXY")) - assert.Equal(t, "https://test.akamai.com", os.Getenv("http_proxy")) - assert.Equal(t, "https://test.akamai.com", os.Getenv("HTTPS_PROXY")) - assert.Equal(t, "https://test.akamai.com", os.Getenv("https_proxy")) +func TestCreateAppProxy(t *testing.T) { + tests := map[string]struct { + proxyValue string + expectedEnvs map[string]string + }{ + "no proxy": { + expectedEnvs: map[string]string{ + "HTTP_PROXY": "", + "HTTPS_PROXY": "", + }, + }, + "proxy set without protocol": { + proxyValue: "test.akamai.com", + expectedEnvs: map[string]string{ + "HTTP_PROXY": "http://test.akamai.com", + "HTTPS_PROXY": "http://test.akamai.com", + }, + }, + "proxy set with http": { + proxyValue: "http://test.akamai.com", + expectedEnvs: map[string]string{ + "HTTP_PROXY": "http://test.akamai.com", + "HTTPS_PROXY": "http://test.akamai.com", + }, + }, + "proxy set with https": { + proxyValue: "https://test.akamai.com", + expectedEnvs: map[string]string{ + "HTTP_PROXY": "https://test.akamai.com", + "HTTPS_PROXY": "https://test.akamai.com", + }, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + term := terminal.Color() + ctx := terminal.Context(context.Background(), term) + app := CreateApp(ctx) + set := flag.NewFlagSet("test", 0) + set.String("proxy", "", "") + cliCtx := cli.NewContext(app, set, nil) + if test.proxyValue != "" { + require.NoError(t, cliCtx.Set("proxy", test.proxyValue)) + } + err := app.Before(cliCtx) + require.NoError(t, err) + assert.NotNil(t, log.FromContext(cliCtx.Context)) + for k, v := range test.expectedEnvs { + assert.Equal(t, v, os.Getenv(k)) + require.NoError(t, os.Unsetenv(k)) + } + }) + } } func hasFlag(app *cli.App, name string) bool { diff --git a/pkg/commands/command_upgrade_test.go b/pkg/commands/command_upgrade_test.go index a798bdb..934f21e 100644 --- a/pkg/commands/command_upgrade_test.go +++ b/pkg/commands/command_upgrade_test.go @@ -2,6 +2,13 @@ package commands import ( "fmt" + "net/http" + "net/http/httptest" + "os" + "regexp" + "strings" + "testing" + "github.com/akamai/cli/pkg/config" "github.com/akamai/cli/pkg/terminal" "github.com/akamai/cli/pkg/version" @@ -9,12 +16,6 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" - "net/http" - "net/http/httptest" - "os" - "regexp" - "strings" - "testing" ) func TestCmdUpgrade(t *testing.T) { @@ -55,6 +56,35 @@ func TestCmdUpgrade(t *testing.T) { }, expectedExitCode: 1, }, + "last upgrade check is set to ignore": { + args: []string{"cli.testKey", "testValue"}, + respLatestVersion: "10.0.0", + init: func(m *mocked) { + + m.term.On("Spinner").Return(m.term).Once() + m.term.On("Start", "Checking for upgrades...", []interface{}(nil)).Return().Once() + + // Checking if cli should be upgraded + m.term.On("IsTTY").Return(true).Once() + m.cfg.On("GetValue", "cli", "last-upgrade-check").Return("ignore", true).Once() + m.cfg.On("SetValue", "cli", "last-upgrade-check", mock.AnythingOfType("string")).Return().Once() + m.cfg.On("Save").Return(nil).Once() + + m.term.On("Spinner").Return(m.term).Once() + m.term.On("Stop", terminal.SpinnerStatusOK).Return().Once() + m.term.On("Confirm", fmt.Sprintf("New upgrade found: 10.0.0 (you are running: %s). Upgrade now? [Y/n]: ", version.Version), true).Return(true, nil).Once() + + // start upgrade + m.term.On("Spinner").Return(m.term).Once() + m.term.On("Start", "Upgrading Akamai CLI", []interface{}(nil)).Return().Once() + + m.term.On("Spinner").Return(m.term).Once() + m.term.On("OK").Return().Once() + + m.cfg.On("GetValue", "cli", "enable-cli-statistics").Return("false", true) + }, + expectedExitCode: 1, + }, "24 hours passed, upgrade": { args: []string{"cli.testKey", "testValue"}, respLatestVersion: "10.0.0", diff --git a/pkg/commands/upgrade.go b/pkg/commands/upgrade.go index c8641be..b38be36 100644 --- a/pkg/commands/upgrade.go +++ b/pkg/commands/upgrade.go @@ -21,8 +21,6 @@ import ( "context" "encoding/hex" "fmt" - "github.com/akamai/cli/pkg/log" - "github.com/urfave/cli/v2" "io/ioutil" "net/http" "os" @@ -32,6 +30,9 @@ import ( "text/template" "time" + "github.com/akamai/cli/pkg/log" + "github.com/urfave/cli/v2" + "github.com/akamai/cli/pkg/config" "github.com/akamai/cli/pkg/terminal" "github.com/akamai/cli/pkg/version" @@ -51,7 +52,7 @@ func CheckUpgradeVersion(ctx context.Context, force bool) string { data, _ := cfg.GetValue("cli", "last-upgrade-check") data = strings.TrimSpace(data) - if data == "ignore" { + if data == "ignore" && !force { return "" } @@ -85,16 +86,11 @@ func CheckUpgradeVersion(ctx context.Context, force bool) string { comp := version.Compare(version.Version, latestVersion) if comp == 1 { term.Spinner().Stop(terminal.SpinnerStatusOK) - answer, err := term.Confirm(fmt.Sprintf( + if answer, err := term.Confirm(fmt.Sprintf( "New upgrade found: %s (you are running: %s). Upgrade now? [Y/n]: ", color.BlueString(latestVersion), color.BlueString(version.Version), - ), true) - if err != nil { - return "" - } - - if !answer { + ), true); err != nil || !answer { return "" } return latestVersion @@ -211,13 +207,6 @@ func UpgradeCli(ctx context.Context, latestVersion string) bool { } selfPath := os.Args[0] - if err != nil { - term.Spinner().Fail() - errMsg := color.RedString("Unable to determine install location") - term.Writeln(errMsg) - logger.Error(errMsg) - return false - } err = update.Apply(resp.Body, update.Options{TargetPath: selfPath, Checksum: shasum}) if err != nil { diff --git a/pkg/commands/upgrade_noop.go b/pkg/commands/upgrade_noop.go index 5b200ec..96a6d66 100644 --- a/pkg/commands/upgrade_noop.go +++ b/pkg/commands/upgrade_noop.go @@ -18,6 +18,7 @@ package commands import ( "context" + "github.com/fatih/color" "github.com/urfave/cli/v2" ) @@ -34,5 +35,11 @@ func UpgradeCli(ctx context.Context, latestVersion string) bool { } func getUpgradeCommand() *cli.Command { - return nil + return &cli.Command{ + Name: "upgrade", + Description: "Upgrade Akamai CLI to the latest version", + Action: func(_ *cli.Context) error { + return cli.Exit(color.RedString("Upgrade command is not available for your installation. If you installed Akamai CLI with Homebrew, please run 'brew upgrade akamai' in order to perform upgrade."), 1) + }, + } } diff --git a/pkg/packages/golang.go b/pkg/packages/golang.go index 7316103..f7bd6a2 100644 --- a/pkg/packages/golang.go +++ b/pkg/packages/golang.go @@ -37,7 +37,7 @@ func (l *langManager) installGolang(ctx context.Context, dir, ver string, comman logger := log.FromContext(ctx) bin, err := l.commandExecutor.LookPath("go") if err != nil { - return fmt.Errorf("%w: %s", ErrRuntimeNotFound, "go") + return fmt.Errorf("%w: %s. Please verify if the executable is included in your PATH", ErrRuntimeNotFound, "go") } logger.Debugf("Go binary found: %s", bin) @@ -55,7 +55,7 @@ func (l *langManager) installGolang(ctx context.Context, dir, ver string, comman if version.Compare(ver, matches[1]) == -1 { logger.Debugf("Go Version found: %s", matches[1]) - return fmt.Errorf("%w: required: %s:%s, have: %s", ErrRuntimeMinimumVersionRequired, "go", ver, matches[1]) + return fmt.Errorf("%w: required: %s:%s, have: %s. Please upgrade your runtime", ErrRuntimeMinimumVersionRequired, "go", ver, matches[1]) } } @@ -129,7 +129,7 @@ func installGolangDepsGlide(logger log.Logger, cmdExecutor executor, dir string) func installGolangModules(logger log.Logger, cmdExecutor executor, dir string) error { bin, err := cmdExecutor.LookPath("go") if err != nil { - err = fmt.Errorf("%w: %s", ErrRuntimeNotFound, "go") + err = fmt.Errorf("%w: %s. Please verify if the executable is included in your PATH", ErrRuntimeNotFound, "go") logger.Debug(err.Error()) return err } diff --git a/pkg/packages/javascript.go b/pkg/packages/javascript.go index f904cfa..cdf5c32 100644 --- a/pkg/packages/javascript.go +++ b/pkg/packages/javascript.go @@ -34,7 +34,7 @@ func (l *langManager) installJavaScript(ctx context.Context, dir, ver string) er if err != nil { bin, err = l.commandExecutor.LookPath("nodejs") if err != nil { - return fmt.Errorf("%w: %s", ErrRuntimeNotFound, "Node.js") + return fmt.Errorf("%w: %s. Please verify if the executable is included in your PATH", ErrRuntimeNotFound, "Node.js") } } @@ -53,7 +53,7 @@ func (l *langManager) installJavaScript(ctx context.Context, dir, ver string) er if version.Compare(ver, matches[1]) == -1 { logger.Debugf("Node.js Version found: %s", matches[1]) - return fmt.Errorf("%w: required: %s:%s, have: %s", ErrRuntimeMinimumVersionRequired, "Node.js", ver, matches[1]) + return fmt.Errorf("%w: required: %s:%s, have: %s. Please upgrade your runtime", ErrRuntimeMinimumVersionRequired, "Node.js", ver, matches[1]) } } diff --git a/pkg/packages/php.go b/pkg/packages/php.go index 3f87e99..91bc18c 100644 --- a/pkg/packages/php.go +++ b/pkg/packages/php.go @@ -29,7 +29,7 @@ import ( func (l *langManager) installPHP(ctx context.Context, dir, cmdReq string) error { bin, err := l.commandExecutor.LookPath("php") if err != nil { - return fmt.Errorf("%w: %s", ErrRuntimeNotFound, "php") + return fmt.Errorf("%w: %s. Please verify if the executable is included in your PATH", ErrRuntimeNotFound, "php") } logger := log.FromContext(ctx) @@ -49,7 +49,7 @@ func (l *langManager) installPHP(ctx context.Context, dir, cmdReq string) error if version.Compare(cmdReq, matches[1]) == -1 { logger.Debugf("PHP Version found: %s", matches[1]) - return fmt.Errorf("%w: required: %s:%s, have: %s", ErrRuntimeMinimumVersionRequired, "php", cmdReq, matches[1]) + return fmt.Errorf("%w: required: %s:%s, have: %s. Please upgrade your runtime", ErrRuntimeMinimumVersionRequired, "php", cmdReq, matches[1]) } } diff --git a/pkg/packages/python.go b/pkg/packages/python.go index db3e6d2..204e925 100644 --- a/pkg/packages/python.go +++ b/pkg/packages/python.go @@ -54,7 +54,7 @@ func (l *langManager) installPython(ctx context.Context, dir, cmdReq string) err if version.Compare(cmdReq, matches[1]) == -1 { logger.Debugf("Python Version found: %s", matches[1]) - return fmt.Errorf("%w: required: %s:%s, have: %s", ErrRuntimeMinimumVersionRequired, "python", cmdReq, matches[1]) + return fmt.Errorf("%w: required: %s:%s, have: %s. Please upgrade your runtime", ErrRuntimeMinimumVersionRequired, "python", cmdReq, matches[1]) } } @@ -79,20 +79,20 @@ func findPythonBin(ctx context.Context, cmdExecutor executor, ver string) (strin if ver == "" || ver == "*" { bin, err = lookForBins(cmdExecutor, "python3", "python2", "python") if err != nil { - return "", fmt.Errorf("%w: %s", ErrRuntimeNotFound, "python") + return "", fmt.Errorf("%w: %s. Please verify if the executable is included in your PATH", ErrRuntimeNotFound, "python") } return bin, nil } if version.Compare("3.0.0", ver) != -1 { bin, err = lookForBins(cmdExecutor, "python3", "python") if err != nil { - return "", fmt.Errorf("%w: %s", ErrRuntimeNotFound, "python 3") + return "", fmt.Errorf("%w: %s. Please verify if the executable is included in your PATH", ErrRuntimeNotFound, "python 3") } return bin, nil } bin, err = lookForBins(cmdExecutor, "python2", "python", "python3") if err != nil { - return "", fmt.Errorf("%w: %s", ErrRuntimeNotFound, "python") + return "", fmt.Errorf("%w: %s. Please verify if the executable is included in your PATH", ErrRuntimeNotFound, "python") } return bin, nil } @@ -147,7 +147,7 @@ func installPythonDepsPip(ctx context.Context, cmdExecutor executor, bin, dir st if errors.As(err, &exitErr) { logger.Debugf("Unable execute package manager (PYTHONUSERBASE=%s %s): \n %s", dir, strings.Join(args, " "), exitErr.Stderr) } - return fmt.Errorf("%w: %s", ErrPackageManagerExec, "pip") + return fmt.Errorf("%w: %s. Please verify pip system dependencies (setuptools, python3-dev, gcc, libffi-dev, openssl-dev)", ErrPackageManagerExec, "pip") } return nil } diff --git a/pkg/packages/ruby.go b/pkg/packages/ruby.go index aad7b9a..cffd98c 100644 --- a/pkg/packages/ruby.go +++ b/pkg/packages/ruby.go @@ -32,7 +32,7 @@ func (l *langManager) installRuby(ctx context.Context, dir, cmdReq string) error bin, err := l.commandExecutor.LookPath("ruby") if err != nil { - return fmt.Errorf("%w: %s", ErrRuntimeNotFound, "ruby") + return fmt.Errorf("%w: %s. Please verify if the executable is included in your PATH", ErrRuntimeNotFound, "ruby") } logger.Debugf("Ruby binary found: %s", bin) @@ -50,7 +50,7 @@ func (l *langManager) installRuby(ctx context.Context, dir, cmdReq string) error if version.Compare(cmdReq, matches[1]) == -1 { logger.Debugf("Ruby Version found: %s", matches[1]) - return fmt.Errorf("%w: required: %s:%s, have: %s", ErrRuntimeMinimumVersionRequired, "ruby", cmdReq, matches[1]) + return fmt.Errorf("%w: required: %s:%s, have: %s. Please upgrade your runtime", ErrRuntimeMinimumVersionRequired, "ruby", cmdReq, matches[1]) } } diff --git a/pkg/version/version.go b/pkg/version/version.go index 84f94b6..5d9bbb3 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -4,7 +4,7 @@ import "github.com/Masterminds/semver" const ( // Version Application Version - Version = "1.2.0" + Version = "1.2.1" ) // Compare ...