1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00

Compare commits

..

No commits in common. "master" and "v0.34.0" have entirely different histories.

272 changed files with 1280 additions and 3098 deletions

View File

@ -1022,62 +1022,6 @@
"name": "Yuval Goldberg", "name": "Yuval Goldberg",
"avatar_url": "https://avatars0.githubusercontent.com/u/29873449?v=4", "avatar_url": "https://avatars0.githubusercontent.com/u/29873449?v=4",
"profile": "https://github.com/YuviGold", "profile": "https://github.com/YuviGold",
"contributions": []
},
{
"login": "dabcoder",
"name": "David Bouchare",
"avatar_url": "https://avatars3.githubusercontent.com/u/5034531?v=4",
"profile": "https://github.com/dabcoder",
"contributions": []
},
{
"login": "stone",
"name": "Fredrik Steen",
"avatar_url": "https://avatars3.githubusercontent.com/u/29077?v=4",
"profile": "https://github.com/stone",
"contributions": []
},
{
"login": "zye1996",
"name": "zye1996",
"avatar_url": "https://avatars2.githubusercontent.com/u/28901953?v=4",
"profile": "https://github.com/zye1996",
"contributions": []
},
{
"login": "pgaxatte",
"name": "Pierre Gaxatte",
"avatar_url": "https://avatars.githubusercontent.com/u/30696904?v=4",
"profile": "https://github.com/pgaxatte",
"contributions": []
},
{
"login": "xntrik",
"name": "Christian Frichot",
"avatar_url": "https://avatars.githubusercontent.com/u/678260?v=4",
"profile": "https://xntrik.wtf",
"contributions": []
},
{
"login": "LKaemmerling",
"name": "Lukas Kämmerling",
"avatar_url": "https://avatars.githubusercontent.com/u/4281581?v=4",
"profile": "https://lukas-kaemmerling.de",
"contributions": []
},
{
"login": "inetAnt",
"name": "Antoine Meillet",
"avatar_url": "https://avatars.githubusercontent.com/u/1765366?v=4",
"profile": "https://inetant.net/",
"contributions": []
},
{
"login": "cclauss",
"name": "Christian Clauss",
"avatar_url": "https://avatars.githubusercontent.com/u/3709715?v=4",
"profile": "https://www.patreon.com/cclauss",
"contributions": [ "contributions": [
] ]
} }

View File

@ -1,11 +0,0 @@
version: 2
updates:
- package-ecosystem: gomod
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
reviewers:
- senorprogrammer
assignees:
- senorprogrammer

View File

@ -13,10 +13,8 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v2 uses: golangci/golangci-lint-action@v1
with: with:
# Required: the version of golangci-lint is required and must be # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
# specified without patch version: we always use the latest patch version. version: v1.26
# https://github.com/golangci/golangci-lint/releases
version: v1.39
args: ./... args: ./...

View File

@ -1,30 +0,0 @@
name: goreleaser
on:
push:
tags:
- '*'
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.16
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GH_PAT }}

View File

@ -8,7 +8,7 @@ jobs:
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: check - name: check
uses: grandcolline/golang-github-actions@4356d0458ea4bfdb55fcb296437812acef970f9b uses: senorprogrammer/golang-github-actions@2614d7f
with: with:
run: imports run: imports
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
@ -19,7 +19,7 @@ jobs:
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: check - name: check
uses: grandcolline/golang-github-actions@4356d0458ea4bfdb55fcb296437812acef970f9b uses: senorprogrammer/golang-github-actions@2614d7f
with: with:
run: errcheck run: errcheck
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
@ -30,7 +30,7 @@ jobs:
#steps: #steps:
#- uses: actions/checkout@master #- uses: actions/checkout@master
#- name: check #- name: check
#uses: grandcolline/golang-github-actions@4356d04 #uses: senorprogrammer/golang-github-actions@2614d7f
#with: #with:
#run: lint #run: lint
#token: ${{ secrets.GITHUB_TOKEN }} #token: ${{ secrets.GITHUB_TOKEN }}
@ -41,7 +41,7 @@ jobs:
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: check - name: check
uses: grandcolline/golang-github-actions@4356d0458ea4bfdb55fcb296437812acef970f9b uses: senorprogrammer/golang-github-actions@2614d7f
with: with:
run: shadow run: shadow
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
@ -52,7 +52,7 @@ jobs:
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: check - name: check
uses: grandcolline/golang-github-actions@4356d0458ea4bfdb55fcb296437812acef970f9b uses: senorprogrammer/golang-github-actions@2614d7f
with: with:
run: staticcheck run: staticcheck
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
@ -63,7 +63,7 @@ jobs:
#steps: #steps:
#- uses: actions/checkout@master #- uses: actions/checkout@master
#- name: check #- name: check
#uses: grandcolline/golang-github-actions@4356d04 #uses: senorprogrammer/golang-github-actions@2614d7f
#with: #with:
#run: sec #run: sec
#token: ${{ secrets.GITHUB_TOKEN }} #token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,6 +1,3 @@
run:
timeout: 2m
linters: linters:
enable: enable:
- vet - vet

View File

@ -21,10 +21,10 @@ before:
- make install - make install
brews: brews:
- - github:
owner: wtfutil
name: homebrew-wtfutil
name: wtfutil name: wtfutil
homepage: 'https://wtfutil.com' homepage: 'https://wtfutil.com'
description: 'The personal information dashboard for your terminal.' description: 'The personal information dashboard for your terminal.'
tap:
owner: wtfutil
name: homebrew-wtfutil

View File

@ -1,7 +1,7 @@
language: go language: go
go: go:
- "1.16.x" - "1.15.x"
before_install: before_install:
# Make sure travis builds work for forks # Make sure travis builds work for forks

View File

@ -4,46 +4,6 @@
### ⚡️ Added ### ⚡️ Added
* Yahoo Finance module added, by [@inetAnt](https://github.com/inetAnt)
### 🐞 Fixed
* Fixed error closing the Jira module response body, [#1070](https://github.com/wtfutil/wtf/issues/1070) by [@senorprogrammer](https://github.com/senorprogrammer)
## v0.36.0
### ⚡️ Added
* HealthChecks module added, by [@stone](https://github.com/stone)
* Asana module added, by [@xntrik](https://github.com/xntrik)
* Kubernetes module now displays the Ready Replicas and Total Replicas count, by [@LKaemmerling](https://github.com/LKaemmerling)
* Now builds using Go 1.16, which provides support for Apple's M1 ARM hardware, by [@LKaemmerling](https://github.com/LKaemmerling)
### 🐞 Fixed
* Numerous dangling response bodies closed, by [@dabcoder](https://github.com/dabcoder)
* HackerNews read-on-response error fixed, by [@LKaemmerling](https://github.com/LKaemmerling)
* CircleCI read-on-response error fixed, by [@dabcoder](https://github.com/dabcoder)
## v0.35.0
### ⚡️ Added
* CircleCI module now supports `numberOfBuilds` setting defining how many builds to display, [#1020](https://github.com/wtfutil/wtf/issues/1020) by [@dabcoder](https://github.com/dabcoder)
* The <kbd>\\</kbd> key now opens module documentation in the browser for the currently-focused module, by [@senorprogrammer](https://github.com/senorprogrammer)
* Krisinformation module added, by [@stone](https://github.com/stone)
* Covid module has been added, by [@dabcoder](https://github.com/dabcoder)
* Support for a "Language" configuration key added. Supports any BCP 47 tag for identifying a langauge, by [@senorprogrammer](https://github.com/senorprogrammer)
### 🐞 Fixed
* CryptoLive prices update again, [#1041](https://github.com/wtfutil/wtf/issues/1041) by [@zye1996](https://github.com/zye1996)
## v0.34.0
2020-11-08
### ⚡️ Added
* DigitalOcean module now supports custom column definitions in the default layout. See [the docs](https://wtfutil.com/modules/digitalocean/) for details, [#986](https://github.com/wtfutil/wtf/issues/986) by [@senorprogrammer](https://github.com/senorprogrammer) * DigitalOcean module now supports custom column definitions in the default layout. See [the docs](https://wtfutil.com/modules/digitalocean/) for details, [#986](https://github.com/wtfutil/wtf/issues/986) by [@senorprogrammer](https://github.com/senorprogrammer)
* Finnhub stock quotes module added, [#930](https://github.com/wtfutil/wtf/issues/930) by [@applegreengrape](https://github.com/applegreengrape) * Finnhub stock quotes module added, [#930](https://github.com/wtfutil/wtf/issues/930) by [@applegreengrape](https://github.com/applegreengrape)
* Grafana Alerts module added, by [@schoentoon](https://github.com/schoentoon) * Grafana Alerts module added, by [@schoentoon](https://github.com/schoentoon)

View File

@ -1,4 +1,4 @@
FROM golang:1.16-alpine as build FROM golang:1.15-alpine as build
ARG version=master ARG version=master

View File

@ -1,4 +1,4 @@
FROM golang:1.16 as build FROM golang:1.15 as build
ARG version=master ARG version=master

View File

@ -1,8 +1,6 @@
*Mozilla Public License, version 2.0* Copyright 2018, Chris Cummer
1. Definitions Mozilla Public License, version 2.0 1. Definitions 1.1. “Contributor” means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software.
1.1. “Contributor” means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software.
1.2. “Contributor Version” means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributors Contribution. 1.2. “Contributor Version” means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributors Contribution.
@ -38,9 +36,7 @@ that the Covered Software was made available under the terms of version 1.1 or e
1.14. “You” (or “Your”) means an individual or a legal entity exercising rights under this License. For legal entities, “You” includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 1.14. “You” (or “Your”) means an individual or a legal entity exercising rights under this License. For legal entities, “You” includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license:
2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license:
under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and
@ -66,9 +62,7 @@ This License does not grant any rights in the trademarks, service marks, or logo
2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1.
3. Responsibilities 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients rights in the Source Code Form.
3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients rights in the Source Code Form.
3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then:
@ -82,37 +76,23 @@ You may distribute such Executable Form under the terms of this License, or subl
3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction.
4. Inability to Comply Due to Statute or Regulation 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.
If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice.
5. Termination
5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination.
6. Disclaimer of Warranty 6. Disclaimer of Warranty Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer.
Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such partys negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.
7. Limitation of Liability 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a partys ability to bring cross-claims or counter-claims.
Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such partys negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor.
8. Litigation 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number.
Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a partys ability to bring cross-claims or counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor.
10. Versions of the License
10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number.
10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward.
@ -120,14 +100,10 @@ This License represents the complete agreement concerning the subject matter her
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
You may add additional accurate notices of copyright ownership. You may add additional accurate notices of copyright ownership.
Exhibit B - “Incompatible With Secondary Licenses” Notice Exhibit B - “Incompatible With Secondary Licenses” Notice This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.
This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.

View File

@ -132,7 +132,7 @@ docker cp wtf_build:/usr/local/bin/wtfutil ~/.local/bin
docker rm wtf_build docker rm wtf_build
``` ```
**Note:** WTF is _only_ compatible with Go versions **1.16.0** or later (due to the use of Go modules and newer standard library functions). If you would like to use `gccgo` to compile, you _must_ use `gccgo-9` or later which introduces support for Go modules. **Note:** WTF is _only_ compatible with Go versions **1.15.0** or later (due to the use of Go modules and newer standard library functions). If you would like to use `gccgo` to compile, you _must_ use `gccgo-9` or later which introduces support for Go modules.
### Installing via Arch User Repository ### Installing via Arch User Repository
@ -176,8 +176,8 @@ Also, follow [on Twitter](https://twitter.com/wtfutil) for news and latest updat
See [https://wtfutil.com](https://wtfutil.com) for the definitive See [https://wtfutil.com](https://wtfutil.com) for the definitive
documentation. Here's some short-cuts: documentation. Here's some short-cuts:
* [Installation](https://wtfutil.com/quick_start/) * [Installation](https://wtfutil.com/getting_started/installation/)
* [Configuration](https://wtfutil.com/configuration/files/) * [Configuration](https://wtfutil.com/configuration/)
* [Module Documentation](https://wtfutil.com/modules/) * [Module Documentation](https://wtfutil.com/modules/)
## Modules ## Modules
@ -415,16 +415,6 @@ Dependency management in WTF is handled by [Go modules](https://github.com/golan
<td align="center"><a href="https://blog.sahilister.in/"><img src="https://avatars0.githubusercontent.com/u/52946452?v=4" width="48px;" alt=""/><br /><sub><b>Sahil Dhiman</b></sub></a><br /></td> <td align="center"><a href="https://blog.sahilister.in/"><img src="https://avatars0.githubusercontent.com/u/52946452?v=4" width="48px;" alt=""/><br /><sub><b>Sahil Dhiman</b></sub></a><br /></td>
<td align="center"><a href="https://pzoo.netlify.app/"><img src="https://avatars2.githubusercontent.com/u/17727004?v=4" width="48px;" alt=""/><br /><sub><b>Pingzhou &#124; 平舟</b></sub></a><br /></td> <td align="center"><a href="https://pzoo.netlify.app/"><img src="https://avatars2.githubusercontent.com/u/17727004?v=4" width="48px;" alt=""/><br /><sub><b>Pingzhou &#124; 平舟</b></sub></a><br /></td>
<td align="center"><a href="https://github.com/YuviGold"><img src="https://avatars0.githubusercontent.com/u/29873449?v=4" width="48px;" alt=""/><br /><sub><b>Yuval Goldberg</b></sub></a><br /></td> <td align="center"><a href="https://github.com/YuviGold"><img src="https://avatars0.githubusercontent.com/u/29873449?v=4" width="48px;" alt=""/><br /><sub><b>Yuval Goldberg</b></sub></a><br /></td>
<td align="center"><a href="https://github.com/dabcoder"><img src="https://avatars3.githubusercontent.com/u/5034531?v=4" width="48px;" alt=""/><br /><sub><b>David Bouchare</b></sub></a><br /></td>
<td align="center"><a href="https://github.com/stone"><img src="https://avatars3.githubusercontent.com/u/29077?v=4" width="48px;" alt=""/><br /><sub><b>Fredrik Steen</b></sub></a><br /></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/zye1996"><img src="https://avatars2.githubusercontent.com/u/28901953?v=4" width="48px;" alt=""/><br /><sub><b>zye1996</b></sub></a><br /></td>
<td align="center"><a href="https://github.com/pgaxatte"><img src="https://avatars.githubusercontent.com/u/30696904?v=4" width="48px;" alt=""/><br /><sub><b>Pierre Gaxatte</b></sub></a><br /></td>
<td align="center"><a href="https://xntrik.wtf"><img src="https://avatars.githubusercontent.com/u/678260?v=4" width="48px;" alt=""/><br /><sub><b>Christian Frichot</b></sub></a><br /></td>
<td align="center"><a href="https://lukas-kaemmerling.de"><img src="https://avatars.githubusercontent.com/u/4281581?v=4" width="48px;" alt=""/><br /><sub><b>Lukas Kämmerling</b></sub></a><br /></td>
<td align="center"><a href="https://inetant.net/"><img src="https://avatars.githubusercontent.com/u/1765366?v=4" width="48px;" alt=""/><br /><sub><b>Antoine Meillet</b></sub></a><br /></td>
<td align="center"><a href="https://www.patreon.com/cclauss"><img src="https://avatars.githubusercontent.com/u/3709715?v=4" width="48px;" alt=""/><br /><sub><b>Christian Clauss</b></sub></a><br /></td>
</tr> </tr>
</table> </table>

View File

@ -19,3 +19,4 @@ wtf:
height: 2 height: 2
width: 2 width: 2
refreshInterval: 30 refreshInterval: 30
updateInterval: 15

View File

@ -1,71 +0,0 @@
package app
import (
"errors"
"github.com/olebedev/config"
"github.com/rivo/tview"
)
// WtfAppManager handles the instances of WtfApp, ensuring that they're displayed as requested
type WtfAppManager struct {
WtfApps []*WtfApp
selected int
}
// NewAppManager creates and returns an instance of AppManager
func NewAppManager() WtfAppManager {
appMan := WtfAppManager{
WtfApps: []*WtfApp{},
}
return appMan
}
// MakeNewWtfApp creates and starts a new instance of WtfApp from a set of configuration params
func (appMan *WtfAppManager) MakeNewWtfApp(config *config.Config, configFilePath string) {
wtfApp := NewWtfApp(tview.NewApplication(), config, configFilePath)
appMan.Add(wtfApp)
wtfApp.Start()
}
// Add adds a WtfApp to the collection of apps that the AppManager manages.
// This app is then available for display onscreen.
func (appMan *WtfAppManager) Add(wtfApp *WtfApp) {
appMan.WtfApps = append(appMan.WtfApps, wtfApp)
}
// Current returns the currently-displaying instance of WtfApp
func (appMan *WtfAppManager) Current() (*WtfApp, error) {
if appMan.selected < 0 || appMan.selected >= len(appMan.WtfApps) {
return nil, errors.New("invalid app index selected")
}
return appMan.WtfApps[appMan.selected], nil
}
// Next cycles the WtfApps forward by one, making the next one in the list
// the current one. If there are none after the current one, it wraps around.
func (appMan *WtfAppManager) Next() (*WtfApp, error) {
appMan.selected++
if appMan.selected >= len(appMan.WtfApps) {
appMan.selected = 0
}
return appMan.Current()
}
// Prev cycles the WtfApps backwards by one, making the previous one in the
// list the current one. If there are none before the current one, it wraps around.
func (appMan *WtfAppManager) Prev() (*WtfApp, error) {
appMan.selected--
if appMan.selected < 0 {
appMan.selected = len(appMan.WtfApps) - 1
}
return appMan.Current()
}

View File

@ -84,14 +84,14 @@ func readGitHubAPIKey(cfg *config.Config) string {
func (wtfApp *WtfApp) contributorThankYouMessage() string { func (wtfApp *WtfApp) contributorThankYouMessage() string {
str := " On behalf of all the users of WTF, thank you for contributing to the source code." str := " On behalf of all the users of WTF, thank you for contributing to the source code."
str += fmt.Sprintf(" %s", aurora.Green("\n\n You rock.")) str += fmt.Sprintf(" %s", aurora.Green("You rock."))
return str return str
} }
func (wtfApp *WtfApp) sponsorThankYouMessage() string { func (wtfApp *WtfApp) sponsorThankYouMessage() string {
str := " Your sponsorship of WTF makes a difference. Thank you for sponsoring and supporting WTF." str := " Your sponsorship of WTF makes a difference. Thank you for sponsoring and supporting WTF."
str += fmt.Sprintf(" %s", aurora.Green("\n\n You're awesome.")) str += fmt.Sprintf(" %s", aurora.Green("You're awesome."))
return str return str
} }

View File

@ -9,7 +9,6 @@ import (
"github.com/wtfutil/wtf/wtf" "github.com/wtfutil/wtf/wtf"
) )
// FocusState is a custom type that differentiates focusable scopes
type FocusState int type FocusState int
const ( const (
@ -21,18 +20,17 @@ const (
// FocusTracker is used by the app to track which onscreen widget currently has focus, // FocusTracker is used by the app to track which onscreen widget currently has focus,
// and to move focus between widgets. // and to move focus between widgets.
type FocusTracker struct { type FocusTracker struct {
App *tview.Application
Idx int Idx int
IsFocused bool IsFocused bool
Widgets []wtf.Wtfable Widgets []wtf.Wtfable
config *config.Config config *config.Config
tviewApp *tview.Application
} }
// NewFocusTracker creates and returns an instance of FocusTracker func NewFocusTracker(app *tview.Application, widgets []wtf.Wtfable, config *config.Config) FocusTracker {
func NewFocusTracker(tviewApp *tview.Application, widgets []wtf.Wtfable, config *config.Config) FocusTracker {
focusTracker := FocusTracker{ focusTracker := FocusTracker{
tviewApp: tviewApp, App: app,
Idx: -1, Idx: -1,
IsFocused: false, IsFocused: false,
Widgets: widgets, Widgets: widgets,
@ -47,7 +45,6 @@ func NewFocusTracker(tviewApp *tview.Application, widgets []wtf.Wtfable, config
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
// FocusOn puts the focus on the item that belongs to the focus character passed in
func (tracker *FocusTracker) FocusOn(char string) bool { func (tracker *FocusTracker) FocusOn(char string) bool {
if !tracker.useNavShortcuts() { if !tracker.useNavShortcuts() {
return false return false
@ -111,7 +108,6 @@ func (tracker *FocusTracker) Prev() {
tracker.IsFocused = true tracker.IsFocused = true
} }
// Refocus forces the focus back to the currently-selected item
func (tracker *FocusTracker) Refocus() { func (tracker *FocusTracker) Refocus() {
tracker.focus(tracker.Idx) tracker.focus(tracker.Idx)
} }
@ -200,7 +196,7 @@ func (tracker *FocusTracker) focus(idx int) {
widget.CommonSettings().Colors.BorderTheme.Focused, widget.CommonSettings().Colors.BorderTheme.Focused,
), ),
) )
tracker.tviewApp.SetFocus(view) tracker.App.SetFocus(view)
} }
func (tracker *FocusTracker) focusables() []wtf.Wtfable { func (tracker *FocusTracker) focusables() []wtf.Wtfable {
@ -243,7 +239,7 @@ func (tracker *FocusTracker) focusState() FocusState {
} }
for _, widget := range tracker.Widgets { for _, widget := range tracker.Widgets {
if widget.TextView() == tracker.tviewApp.GetFocus() { if widget.TextView() == tracker.App.GetFocus() {
return widgetFocused return widgetFocused
} }
} }

View File

@ -9,7 +9,6 @@ import (
"github.com/wtfutil/wtf/wtf" "github.com/wtfutil/wtf/wtf"
) )
// ModuleValidator is responsible for validating the state of a module's configuration
type ModuleValidator struct{} type ModuleValidator struct{}
type widgetError struct { type widgetError struct {
@ -17,7 +16,6 @@ type widgetError struct {
validationErrors []cfg.Validatable validationErrors []cfg.Validatable
} }
// NewModuleValidator creates and returns an instance of ModuleValidator
func NewModuleValidator() *ModuleValidator { func NewModuleValidator() *ModuleValidator {
return &ModuleValidator{} return &ModuleValidator{}
} }

View File

@ -3,7 +3,6 @@ package app
import ( import (
"github.com/olebedev/config" "github.com/olebedev/config"
"github.com/rivo/tview" "github.com/rivo/tview"
"github.com/wtfutil/wtf/modules/asana"
"github.com/wtfutil/wtf/modules/azuredevops" "github.com/wtfutil/wtf/modules/azuredevops"
"github.com/wtfutil/wtf/modules/bamboohr" "github.com/wtfutil/wtf/modules/bamboohr"
"github.com/wtfutil/wtf/modules/bargraph" "github.com/wtfutil/wtf/modules/bargraph"
@ -14,7 +13,6 @@ import (
"github.com/wtfutil/wtf/modules/circleci" "github.com/wtfutil/wtf/modules/circleci"
"github.com/wtfutil/wtf/modules/clocks" "github.com/wtfutil/wtf/modules/clocks"
"github.com/wtfutil/wtf/modules/cmdrunner" "github.com/wtfutil/wtf/modules/cmdrunner"
"github.com/wtfutil/wtf/modules/covid"
"github.com/wtfutil/wtf/modules/cryptoexchanges/bittrex" "github.com/wtfutil/wtf/modules/cryptoexchanges/bittrex"
"github.com/wtfutil/wtf/modules/cryptoexchanges/blockfolio" "github.com/wtfutil/wtf/modules/cryptoexchanges/blockfolio"
"github.com/wtfutil/wtf/modules/cryptoexchanges/cryptolive" "github.com/wtfutil/wtf/modules/cryptoexchanges/cryptolive"
@ -25,6 +23,7 @@ import (
"github.com/wtfutil/wtf/modules/docker" "github.com/wtfutil/wtf/modules/docker"
"github.com/wtfutil/wtf/modules/exchangerates" "github.com/wtfutil/wtf/modules/exchangerates"
"github.com/wtfutil/wtf/modules/feedreader" "github.com/wtfutil/wtf/modules/feedreader"
"github.com/wtfutil/wtf/modules/finnhub"
"github.com/wtfutil/wtf/modules/football" "github.com/wtfutil/wtf/modules/football"
"github.com/wtfutil/wtf/modules/gcal" "github.com/wtfutil/wtf/modules/gcal"
"github.com/wtfutil/wtf/modules/gerrit" "github.com/wtfutil/wtf/modules/gerrit"
@ -37,13 +36,11 @@ import (
"github.com/wtfutil/wtf/modules/grafana" "github.com/wtfutil/wtf/modules/grafana"
"github.com/wtfutil/wtf/modules/gspreadsheets" "github.com/wtfutil/wtf/modules/gspreadsheets"
"github.com/wtfutil/wtf/modules/hackernews" "github.com/wtfutil/wtf/modules/hackernews"
"github.com/wtfutil/wtf/modules/healthchecks"
"github.com/wtfutil/wtf/modules/hibp" "github.com/wtfutil/wtf/modules/hibp"
"github.com/wtfutil/wtf/modules/ipaddresses/ipapi" "github.com/wtfutil/wtf/modules/ipaddresses/ipapi"
"github.com/wtfutil/wtf/modules/ipaddresses/ipinfo" "github.com/wtfutil/wtf/modules/ipaddresses/ipinfo"
"github.com/wtfutil/wtf/modules/jenkins" "github.com/wtfutil/wtf/modules/jenkins"
"github.com/wtfutil/wtf/modules/jira" "github.com/wtfutil/wtf/modules/jira"
"github.com/wtfutil/wtf/modules/krisinformation"
"github.com/wtfutil/wtf/modules/kubernetes" "github.com/wtfutil/wtf/modules/kubernetes"
"github.com/wtfutil/wtf/modules/logger" "github.com/wtfutil/wtf/modules/logger"
"github.com/wtfutil/wtf/modules/mercurial" "github.com/wtfutil/wtf/modules/mercurial"
@ -61,8 +58,6 @@ import (
"github.com/wtfutil/wtf/modules/spotify" "github.com/wtfutil/wtf/modules/spotify"
"github.com/wtfutil/wtf/modules/spotifyweb" "github.com/wtfutil/wtf/modules/spotifyweb"
"github.com/wtfutil/wtf/modules/status" "github.com/wtfutil/wtf/modules/status"
"github.com/wtfutil/wtf/modules/stocks/finnhub"
"github.com/wtfutil/wtf/modules/stocks/yfinance"
"github.com/wtfutil/wtf/modules/subreddit" "github.com/wtfutil/wtf/modules/subreddit"
"github.com/wtfutil/wtf/modules/textfile" "github.com/wtfutil/wtf/modules/textfile"
"github.com/wtfutil/wtf/modules/todo" "github.com/wtfutil/wtf/modules/todo"
@ -84,7 +79,7 @@ import (
// MakeWidget creates and returns instances of widgets // MakeWidget creates and returns instances of widgets
func MakeWidget( func MakeWidget(
tviewApp *tview.Application, app *tview.Application,
pages *tview.Pages, pages *tview.Pages,
moduleName string, moduleName string,
config *config.Config, config *config.Config,
@ -107,251 +102,236 @@ func MakeWidget(
switch moduleConfig.UString("type", moduleName) { switch moduleConfig.UString("type", moduleName) {
case "arpansagovau": case "arpansagovau":
settings := arpansagovau.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := arpansagovau.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = arpansagovau.NewWidget(tviewApp, settings) widget = arpansagovau.NewWidget(app, settings)
case "asana":
settings := asana.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = asana.NewWidget(tviewApp, pages, settings)
case "azuredevops": case "azuredevops":
settings := azuredevops.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := azuredevops.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = azuredevops.NewWidget(tviewApp, pages, settings) widget = azuredevops.NewWidget(app, pages, settings)
case "bamboohr": case "bamboohr":
settings := bamboohr.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := bamboohr.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = bamboohr.NewWidget(tviewApp, settings) widget = bamboohr.NewWidget(app, settings)
case "bargraph": case "bargraph":
settings := bargraph.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := bargraph.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = bargraph.NewWidget(tviewApp, settings) widget = bargraph.NewWidget(app, settings)
case "bittrex": case "bittrex":
settings := bittrex.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := bittrex.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = bittrex.NewWidget(tviewApp, settings) widget = bittrex.NewWidget(app, settings)
case "blockfolio": case "blockfolio":
settings := blockfolio.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := blockfolio.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = blockfolio.NewWidget(tviewApp, settings) widget = blockfolio.NewWidget(app, settings)
case "buildkite": case "buildkite":
settings := buildkite.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := buildkite.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = buildkite.NewWidget(tviewApp, pages, settings) widget = buildkite.NewWidget(app, pages, settings)
case "cdsFavorites": case "cdsFavorites":
settings := cdsfavorites.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := cdsfavorites.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = cdsfavorites.NewWidget(tviewApp, pages, settings) widget = cdsfavorites.NewWidget(app, pages, settings)
case "cdsQueue": case "cdsQueue":
settings := cdsqueue.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := cdsqueue.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = cdsqueue.NewWidget(tviewApp, pages, settings) widget = cdsqueue.NewWidget(app, pages, settings)
case "cdsStatus": case "cdsStatus":
settings := cdsstatus.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := cdsstatus.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = cdsstatus.NewWidget(tviewApp, pages, settings) widget = cdsstatus.NewWidget(app, pages, settings)
case "circleci": case "circleci":
settings := circleci.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := circleci.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = circleci.NewWidget(tviewApp, settings) widget = circleci.NewWidget(app, settings)
case "clocks": case "clocks":
settings := clocks.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := clocks.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = clocks.NewWidget(tviewApp, settings) widget = clocks.NewWidget(app, settings)
case "covid":
settings := covid.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = covid.NewWidget(tviewApp, settings)
case "cmdrunner": case "cmdrunner":
settings := cmdrunner.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := cmdrunner.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = cmdrunner.NewWidget(tviewApp, settings) widget = cmdrunner.NewWidget(app, settings)
case "cryptolive": case "cryptolive":
settings := cryptolive.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := cryptolive.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = cryptolive.NewWidget(tviewApp, settings) widget = cryptolive.NewWidget(app, settings)
case "datadog": case "datadog":
settings := datadog.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := datadog.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = datadog.NewWidget(tviewApp, pages, settings) widget = datadog.NewWidget(app, pages, settings)
case "devto": case "devto":
settings := devto.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := devto.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = devto.NewWidget(tviewApp, pages, settings) widget = devto.NewWidget(app, pages, settings)
case "digitalclock": case "digitalclock":
settings := digitalclock.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := digitalclock.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = digitalclock.NewWidget(tviewApp, settings) widget = digitalclock.NewWidget(app, settings)
case "digitalocean": case "digitalocean":
settings := digitalocean.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := digitalocean.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = digitalocean.NewWidget(tviewApp, pages, settings) widget = digitalocean.NewWidget(app, pages, settings)
case "docker": case "docker":
settings := docker.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := docker.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = docker.NewWidget(tviewApp, pages, settings) widget = docker.NewWidget(app, pages, settings)
case "feedreader": case "feedreader":
settings := feedreader.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := feedreader.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = feedreader.NewWidget(tviewApp, pages, settings) widget = feedreader.NewWidget(app, pages, settings)
case "football": case "football":
settings := football.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := football.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = football.NewWidget(tviewApp, pages, settings) widget = football.NewWidget(app, pages, settings)
case "gcal": case "gcal":
settings := gcal.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := gcal.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = gcal.NewWidget(tviewApp, settings) widget = gcal.NewWidget(app, settings)
case "gerrit": case "gerrit":
settings := gerrit.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := gerrit.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = gerrit.NewWidget(tviewApp, pages, settings) widget = gerrit.NewWidget(app, pages, settings)
case "git": case "git":
settings := git.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := git.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = git.NewWidget(tviewApp, pages, settings) widget = git.NewWidget(app, pages, settings)
case "github": case "github":
settings := github.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := github.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = github.NewWidget(tviewApp, pages, settings) widget = github.NewWidget(app, pages, settings)
case "gitlab": case "gitlab":
settings := gitlab.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := gitlab.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = gitlab.NewWidget(tviewApp, pages, settings) widget = gitlab.NewWidget(app, pages, settings)
case "gitlabtodo": case "gitlabtodo":
settings := gitlabtodo.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := gitlabtodo.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = gitlabtodo.NewWidget(tviewApp, pages, settings) widget = gitlabtodo.NewWidget(app, pages, settings)
case "gitter": case "gitter":
settings := gitter.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := gitter.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = gitter.NewWidget(tviewApp, pages, settings) widget = gitter.NewWidget(app, pages, settings)
case "googleanalytics": case "googleanalytics":
settings := googleanalytics.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := googleanalytics.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = googleanalytics.NewWidget(tviewApp, settings) widget = googleanalytics.NewWidget(app, settings)
case "gspreadsheets": case "gspreadsheets":
settings := gspreadsheets.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := gspreadsheets.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = gspreadsheets.NewWidget(tviewApp, settings) widget = gspreadsheets.NewWidget(app, settings)
case "grafana": case "grafana":
settings := grafana.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := grafana.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = grafana.NewWidget(tviewApp, pages, settings) widget = grafana.NewWidget(app, pages, settings)
case "hackernews": case "hackernews":
settings := hackernews.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := hackernews.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = hackernews.NewWidget(tviewApp, pages, settings) widget = hackernews.NewWidget(app, pages, settings)
case "healthchecks":
settings := healthchecks.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = healthchecks.NewWidget(tviewApp, pages, settings)
case "hibp": case "hibp":
settings := hibp.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := hibp.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = hibp.NewWidget(tviewApp, settings) widget = hibp.NewWidget(app, settings)
case "ipapi": case "ipapi":
settings := ipapi.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := ipapi.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = ipapi.NewWidget(tviewApp, settings) widget = ipapi.NewWidget(app, settings)
case "ipinfo": case "ipinfo":
settings := ipinfo.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := ipinfo.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = ipinfo.NewWidget(tviewApp, settings) widget = ipinfo.NewWidget(app, settings)
case "jenkins": case "jenkins":
settings := jenkins.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := jenkins.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = jenkins.NewWidget(tviewApp, pages, settings) widget = jenkins.NewWidget(app, pages, settings)
case "jira": case "jira":
settings := jira.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := jira.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = jira.NewWidget(tviewApp, pages, settings) widget = jira.NewWidget(app, pages, settings)
case "kubernetes": case "kubernetes":
settings := kubernetes.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := kubernetes.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = kubernetes.NewWidget(tviewApp, settings) widget = kubernetes.NewWidget(app, settings)
case "krisinformation":
settings := krisinformation.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = krisinformation.NewWidget(tviewApp, settings)
case "logger": case "logger":
settings := logger.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := logger.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = logger.NewWidget(tviewApp, settings) widget = logger.NewWidget(app, settings)
case "mercurial": case "mercurial":
settings := mercurial.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := mercurial.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = mercurial.NewWidget(tviewApp, pages, settings) widget = mercurial.NewWidget(app, pages, settings)
case "nbascore": case "nbascore":
settings := nbascore.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := nbascore.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = nbascore.NewWidget(tviewApp, pages, settings) widget = nbascore.NewWidget(app, pages, settings)
case "newrelic": case "newrelic":
settings := newrelic.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := newrelic.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = newrelic.NewWidget(tviewApp, pages, settings) widget = newrelic.NewWidget(app, pages, settings)
case "opsgenie": case "opsgenie":
settings := opsgenie.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := opsgenie.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = opsgenie.NewWidget(tviewApp, settings) widget = opsgenie.NewWidget(app, settings)
case "pagerduty": case "pagerduty":
settings := pagerduty.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := pagerduty.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = pagerduty.NewWidget(tviewApp, settings) widget = pagerduty.NewWidget(app, settings)
case "pihole": case "pihole":
settings := pihole.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := pihole.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = pihole.NewWidget(tviewApp, pages, settings) widget = pihole.NewWidget(app, pages, settings)
case "power": case "power":
settings := power.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := power.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = power.NewWidget(tviewApp, settings) widget = power.NewWidget(app, settings)
case "prettyweather": case "prettyweather":
settings := prettyweather.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := prettyweather.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = prettyweather.NewWidget(tviewApp, settings) widget = prettyweather.NewWidget(app, settings)
case "pocket": case "pocket":
settings := pocket.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := pocket.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = pocket.NewWidget(tviewApp, pages, settings) widget = pocket.NewWidget(app, pages, settings)
case "resourceusage": case "resourceusage":
settings := resourceusage.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := resourceusage.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = resourceusage.NewWidget(tviewApp, settings) widget = resourceusage.NewWidget(app, settings)
case "rollbar": case "rollbar":
settings := rollbar.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := rollbar.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = rollbar.NewWidget(tviewApp, pages, settings) widget = rollbar.NewWidget(app, pages, settings)
case "security": case "security":
settings := security.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := security.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = security.NewWidget(tviewApp, settings) widget = security.NewWidget(app, settings)
case "spacex": case "spacex":
settings := spacex.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := spacex.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = spacex.NewWidget(tviewApp, settings) widget = spacex.NewWidget(app, settings)
case "spotify": case "spotify":
settings := spotify.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := spotify.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = spotify.NewWidget(tviewApp, pages, settings) widget = spotify.NewWidget(app, pages, settings)
case "spotifyweb": case "spotifyweb":
settings := spotifyweb.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := spotifyweb.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = spotifyweb.NewWidget(tviewApp, pages, settings) widget = spotifyweb.NewWidget(app, pages, settings)
case "status": case "status":
settings := status.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := status.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = status.NewWidget(tviewApp, settings) widget = status.NewWidget(app, settings)
case "subreddit": case "subreddit":
settings := subreddit.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := subreddit.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = subreddit.NewWidget(tviewApp, pages, settings) widget = subreddit.NewWidget(app, pages, settings)
case "textfile": case "textfile":
settings := textfile.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := textfile.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = textfile.NewWidget(tviewApp, pages, settings) widget = textfile.NewWidget(app, pages, settings)
case "todo": case "todo":
settings := todo.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := todo.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = todo.NewWidget(tviewApp, pages, settings) widget = todo.NewWidget(app, pages, settings)
case "todo_plus": case "todo_plus":
settings := todo_plus.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := todo_plus.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = todo_plus.NewWidget(tviewApp, pages, settings) widget = todo_plus.NewWidget(app, pages, settings)
case "todoist": case "todoist":
settings := todo_plus.FromTodoist(moduleName, moduleConfig, config) settings := todo_plus.FromTodoist(moduleName, moduleConfig, config)
widget = todo_plus.NewWidget(tviewApp, pages, settings) widget = todo_plus.NewWidget(app, pages, settings)
case "transmission": case "transmission":
settings := transmission.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := transmission.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = transmission.NewWidget(tviewApp, pages, settings) widget = transmission.NewWidget(app, pages, settings)
case "travisci": case "travisci":
settings := travisci.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := travisci.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = travisci.NewWidget(tviewApp, pages, settings) widget = travisci.NewWidget(app, pages, settings)
case "trello": case "trello":
settings := todo_plus.FromTrello(moduleName, moduleConfig, config) settings := todo_plus.FromTrello(moduleName, moduleConfig, config)
widget = todo_plus.NewWidget(tviewApp, pages, settings) widget = todo_plus.NewWidget(app, pages, settings)
case "twitch": case "twitch":
settings := twitch.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := twitch.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = twitch.NewWidget(tviewApp, pages, settings) widget = twitch.NewWidget(app, pages, settings)
case "twitter": case "twitter":
settings := twitter.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := twitter.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = twitter.NewWidget(tviewApp, pages, settings) widget = twitter.NewWidget(app, pages, settings)
case "twitterstats": case "twitterstats":
settings := twitterstats.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := twitterstats.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = twitterstats.NewWidget(tviewApp, pages, settings) widget = twitterstats.NewWidget(app, pages, settings)
case "uptimerobot": case "uptimerobot":
settings := uptimerobot.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := uptimerobot.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = uptimerobot.NewWidget(tviewApp, pages, settings) widget = uptimerobot.NewWidget(app, pages, settings)
case "victorops": case "victorops":
settings := victorops.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := victorops.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = victorops.NewWidget(tviewApp, settings) widget = victorops.NewWidget(app, settings)
case "weather": case "weather":
settings := weather.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := weather.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = weather.NewWidget(tviewApp, pages, settings) widget = weather.NewWidget(app, pages, settings)
case "zendesk": case "zendesk":
settings := zendesk.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := zendesk.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = zendesk.NewWidget(tviewApp, pages, settings) widget = zendesk.NewWidget(app, pages, settings)
case "exchangerates": case "exchangerates":
settings := exchangerates.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := exchangerates.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = exchangerates.NewWidget(tviewApp, pages, settings) widget = exchangerates.NewWidget(app, pages, settings)
case "finnhub": case "finnhub":
settings := finnhub.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := finnhub.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = finnhub.NewWidget(tviewApp, settings) widget = finnhub.NewWidget(app, settings)
case "yfinance":
settings := yfinance.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = yfinance.NewWidget(tviewApp, settings)
default: default:
settings := unknown.NewSettingsFromYAML(moduleName, moduleConfig, config) settings := unknown.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = unknown.NewWidget(tviewApp, settings) widget = unknown.NewWidget(app, settings)
} }
return widget return widget
} }
// MakeWidgets creates and returns a collection of enabled widgets // MakeWidgets creates and returns a collection of enabled widgets
func MakeWidgets(tviewApp *tview.Application, pages *tview.Pages, config *config.Config) []wtf.Wtfable { func MakeWidgets(app *tview.Application, pages *tview.Pages, config *config.Config) []wtf.Wtfable {
widgets := []wtf.Wtfable{} widgets := []wtf.Wtfable{}
moduleNames, _ := config.Map("wtf.mods") moduleNames, _ := config.Map("wtf.mods")
for moduleName := range moduleNames { for moduleName := range moduleNames {
widget := MakeWidget(tviewApp, pages, moduleName, config) widget := MakeWidget(app, pages, moduleName, config)
if widget != nil { if widget != nil {
widgets = append(widgets, widget) widgets = append(widgets, widget)

View File

@ -1,14 +1,11 @@
package app package app
import ( import (
"fmt"
"log" "log"
"os"
"time" "time"
"github.com/gdamore/tcell" "github.com/gdamore/tcell"
_ "github.com/gdamore/tcell/terminfo/extended" _ "github.com/gdamore/tcell/terminfo/extended"
"github.com/logrusorgru/aurora"
"github.com/olebedev/config" "github.com/olebedev/config"
"github.com/radovskyb/watcher" "github.com/radovskyb/watcher"
"github.com/rivo/tview" "github.com/rivo/tview"
@ -21,42 +18,44 @@ import (
// WtfApp is the container for a collection of widgets that are all constructed from a single // WtfApp is the container for a collection of widgets that are all constructed from a single
// configuration file and displayed together // configuration file and displayed together
type WtfApp struct { type WtfApp struct {
TViewApp *tview.Application app *tview.Application
config *config.Config config *config.Config
configFilePath string configFilePath string
display *Display display *Display
focusTracker FocusTracker
ghUser *support.GitHubUser ghUser *support.GitHubUser
focusTracker FocusTracker
pages *tview.Pages pages *tview.Pages
validator *ModuleValidator validator *ModuleValidator
widgets []wtf.Wtfable widgets []wtf.Wtfable
} }
// NewWtfApp creates and returns an instance of WtfApp // NewWtfApp creates and returns an instance of WtfApp
func NewWtfApp(tviewApp *tview.Application, config *config.Config, configFilePath string) *WtfApp { func NewWtfApp(app *tview.Application, config *config.Config, configFilePath string) *WtfApp {
wtfApp := &WtfApp{ wtfApp := WtfApp{
TViewApp: tviewApp, app: app,
config: config, config: config,
configFilePath: configFilePath, configFilePath: configFilePath,
pages: tview.NewPages(), pages: tview.NewPages(),
} }
wtfApp.TViewApp.SetBeforeDrawFunc(func(s tcell.Screen) bool { wtfApp.app.SetBeforeDrawFunc(func(s tcell.Screen) bool {
s.Clear() s.Clear()
return false return false
}) })
wtfApp.widgets = MakeWidgets(wtfApp.TViewApp, wtfApp.pages, wtfApp.config) wtfApp.app.SetInputCapture(wtfApp.keyboardIntercept)
wtfApp.widgets = MakeWidgets(wtfApp.app, wtfApp.pages, wtfApp.config)
wtfApp.display = NewDisplay(wtfApp.widgets, wtfApp.config) wtfApp.display = NewDisplay(wtfApp.widgets, wtfApp.config)
wtfApp.focusTracker = NewFocusTracker(wtfApp.TViewApp, wtfApp.widgets, wtfApp.config) wtfApp.focusTracker = NewFocusTracker(wtfApp.app, wtfApp.widgets, wtfApp.config)
wtfApp.validator = NewModuleValidator()
githubAPIKey := readGitHubAPIKey(wtfApp.config) githubAPIKey := readGitHubAPIKey(wtfApp.config)
wtfApp.ghUser = support.NewGitHubUser(githubAPIKey) wtfApp.ghUser = support.NewGitHubUser(githubAPIKey)
wtfApp.validator = NewModuleValidator()
wtfApp.pages.AddPage("grid", wtfApp.display.Grid, true, true) wtfApp.pages.AddPage("grid", wtfApp.display.Grid, true, true)
wtfApp.app.SetRoot(wtfApp.pages, true)
wtfApp.validator.Validate(wtfApp.widgets) wtfApp.validator.Validate(wtfApp.widgets)
@ -67,28 +66,17 @@ func NewWtfApp(tviewApp *tview.Application, config *config.Config, configFilePat
), ),
) )
wtfApp.TViewApp.SetInputCapture(wtfApp.keyboardIntercept) return &wtfApp
wtfApp.TViewApp.SetRoot(wtfApp.pages, true)
return wtfApp
} }
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
// Run starts the underlying tview app
func (wtfApp *WtfApp) Run() {
if err := wtfApp.TViewApp.Run(); err != nil {
fmt.Printf("\n%s %v\n", aurora.Red("ERROR"), err)
os.Exit(1)
}
}
// Start initializes the app // Start initializes the app
func (wtfApp *WtfApp) Start() { func (wtfApp *WtfApp) Start() {
go wtfApp.scheduleWidgets() go wtfApp.scheduleWidgets()
go wtfApp.watchForConfigChanges() go wtfApp.watchForConfigChanges()
// FIXME: This should be moved to the AppManager
go func() { _ = wtfApp.ghUser.Load() }() go func() { _ = wtfApp.ghUser.Load() }()
} }
@ -110,16 +98,11 @@ func (wtfApp *WtfApp) keyboardIntercept(event *tcell.EventKey) *tcell.EventKey {
switch event.Key() { switch event.Key() {
case tcell.KeyCtrlC: case tcell.KeyCtrlC:
wtfApp.Stop() wtfApp.Stop()
wtfApp.TViewApp.Stop() wtfApp.app.Stop()
wtfApp.DisplayExitMessage() wtfApp.DisplayExitMessage()
case tcell.KeyCtrlR: case tcell.KeyCtrlR:
wtfApp.refreshAllWidgets() wtfApp.refreshAllWidgets()
return nil return nil
case tcell.KeyCtrlSpace:
// FIXME: This can't reside in the app, the app doesn't know about
// the AppManager. The AppManager needs to catch this one
fmt.Println("Next app")
return nil
case tcell.KeyTab: case tcell.KeyTab:
wtfApp.focusTracker.Next() wtfApp.focusTracker.Next()
case tcell.KeyBacktab: case tcell.KeyBacktab:
@ -171,7 +154,7 @@ func (wtfApp *WtfApp) watchForConfigChanges() {
wtfApp.Stop() wtfApp.Stop()
config := cfg.LoadWtfConfigFile(wtfApp.configFilePath) config := cfg.LoadWtfConfigFile(wtfApp.configFilePath)
newApp := NewWtfApp(wtfApp.TViewApp, config, wtfApp.configFilePath) newApp := NewWtfApp(wtfApp.app, config, wtfApp.configFilePath)
openURLUtil := utils.ToStrs(config.UList("wtf.openUrlUtil", []interface{}{})) openURLUtil := utils.ToStrs(config.UList("wtf.openUrlUtil", []interface{}{}))
utils.Init(config.UString("wtf.openFileUtil", "open"), openURLUtil) utils.Init(config.UString("wtf.openFileUtil", "open"), openURLUtil)

View File

@ -5,12 +5,6 @@ import (
"strings" "strings"
"github.com/olebedev/config" "github.com/olebedev/config"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
const (
defaultLanguageTag = "en-CA"
) )
type Module struct { type Module struct {
@ -29,32 +23,27 @@ type Sigils struct {
} }
} }
// Common defines a set of common configuration settings applicable to all modules
type Common struct { type Common struct {
Module Module
PositionSettings `help:"Defines where in the grid this modules widget will be displayed."` PositionSettings `help:"Defines where in the grid this modules widget will be displayed."`
Sigils Sigils
Colors ColorTheme Colors ColorTheme
Config *config.Config
DocPath string
Bordered bool `help:"Whether or not the module should be displayed with a border." values:"true, false" optional:"true" default:"true"` Bordered bool `help:"Whether or not the module should be displayed with a border." values:"true, false" optional:"true" default:"true"`
Enabled bool `help:"Whether or not this module is executed and if its data displayed onscreen." values:"true, false" optional:"true" default:"false"` Enabled bool `help:"Whether or not this module is executed and if its data displayed onscreen." values:"true, false" optional:"true" default:"false"`
Focusable bool `help:"Whether or not this module is focusable." values:"true, false" optional:"true" default:"false"` Focusable bool `help:"Whether or not this module is focusable." values:"true, false" optional:"true" default:"false"`
LanguageTag string `help:"The BCP 47 langauge tag to localize text to." values:"Any supported BCP 47 language tag." optional:"true" default:"en-CA"`
RefreshInterval int `help:"How often, in seconds, this module will update its data." values:"A positive integer, 0..n." optional:"true"` RefreshInterval int `help:"How often, in seconds, this module will update its data." values:"A positive integer, 0..n." optional:"true"`
Title string `help:"The title string to show when displaying this module" optional:"true"` Title string `help:"The title string to show when displaying this module" optional:"true"`
Config *config.Config
focusChar int `help:"Define one of the number keys as a short cut key to access the widget." optional:"true"` focusChar int `help:"Define one of the number keys as a short cut key to access the widget." optional:"true"`
} }
// NewCommonSettingsFromModule returns a common settings configuration tailed to the given module // NewCommonSettingsFromModule returns a common settings configuration tailed to the given module
func NewCommonSettingsFromModule(name, defaultTitle string, defaultFocusable bool, moduleConfig *config.Config, globalConfig *config.Config) *Common { func NewCommonSettingsFromModule(name, defaultTitle string, defaultFocusable bool, moduleConfig *config.Config, globalSettings *config.Config) *Common {
baseColors := NewDefaultColorTheme() baseColors := NewDefaultColorTheme()
colorsConfig, err := globalConfig.Get("wtf.colors") colorsConfig, err := globalSettings.Get("wtf.colors")
if err != nil && strings.Contains(err.Error(), "Nonexistent map") { if err != nil && strings.Contains(err.Error(), "Nonexistent map") {
// Create a default colors config to fill in for the missing one // Create a default colors config to fill in for the missing one
// This comes into play when the configuration file does not contain a `colors:` key, i.e: // This comes into play when the configuration file does not contain a `colors:` key, i.e:
@ -101,7 +90,6 @@ func NewCommonSettingsFromModule(name, defaultTitle string, defaultFocusable boo
Config: moduleConfig, Config: moduleConfig,
Enabled: moduleConfig.UBool("enabled", false), Enabled: moduleConfig.UBool("enabled", false),
Focusable: moduleConfig.UBool("focusable", defaultFocusable), Focusable: moduleConfig.UBool("focusable", defaultFocusable),
LanguageTag: globalConfig.UString("wtf.language", defaultLanguageTag),
RefreshInterval: moduleConfig.UInt("refreshInterval", 300), RefreshInterval: moduleConfig.UInt("refreshInterval", 300),
Title: moduleConfig.UString("title", defaultTitle), Title: moduleConfig.UString("title", defaultTitle),
@ -109,10 +97,11 @@ func NewCommonSettingsFromModule(name, defaultTitle string, defaultFocusable boo
} }
sigilsPath := "wtf.sigils" sigilsPath := "wtf.sigils"
common.Sigils.Checkbox.Checked = globalConfig.UString(sigilsPath+".checkbox.checked", "x")
common.Sigils.Checkbox.Unchecked = globalConfig.UString(sigilsPath+".checkbox.unchecked", " ") common.Sigils.Checkbox.Checked = globalSettings.UString(sigilsPath+".checkbox.checked", "x")
common.Sigils.Paging.Normal = globalConfig.UString(sigilsPath+".paging.normal", globalConfig.UString("wtf.paging.pageSigil", "*")) common.Sigils.Checkbox.Unchecked = globalSettings.UString(sigilsPath+".checkbox.unchecked", " ")
common.Sigils.Paging.Selected = globalConfig.UString(sigilsPath+".paging.select", globalConfig.UString("wtf.paging.selectedSigil", "_")) common.Sigils.Paging.Normal = globalSettings.UString(sigilsPath+".paging.normal", globalSettings.UString("wtf.paging.pageSigil", "*"))
common.Sigils.Paging.Selected = globalSettings.UString(sigilsPath+".paging.select", globalSettings.UString("wtf.paging.selectedSigil", "_"))
return &common return &common
} }
@ -149,20 +138,6 @@ func (common *Common) FocusChar() string {
return fmt.Sprint(common.focusChar) return fmt.Sprint(common.focusChar)
} }
// LocalizedPrinter returns a message.Printer instance localized to the BCP 47 language
// configuration value defined in 'wtf.language' config. If none exists, it defaults to
// 'en-CA'. Use this to format numbers, etc.
func (common *Common) LocalizedPrinter() (*message.Printer, error) {
langTag, err := language.Parse(common.LanguageTag)
if err != nil {
return nil, err
}
prntr := message.NewPrinter(langTag)
return prntr, nil
}
func (common *Common) RowColor(idx int) string { func (common *Common) RowColor(idx int) string {
if idx%2 == 0 { if idx%2 == 0 {
return common.Colors.RowTheme.EvenForeground return common.Colors.RowTheme.EvenForeground
@ -176,9 +151,7 @@ func (common *Common) RightAlignFormat(width int) string {
return fmt.Sprintf("%%%ds", width-borderOffset) return fmt.Sprintf("%%%ds", width-borderOffset)
} }
// PaginationMarker generates the pagination indicators that appear in the top-right corner func (common *Common) SigilStr(len, pos, width int) string {
// of multisource widgets
func (common *Common) PaginationMarker(len, pos, width int) string {
sigils := "" sigils := ""
if len > 1 { if len > 1 {
@ -192,15 +165,6 @@ func (common *Common) PaginationMarker(len, pos, width int) string {
return sigils return sigils
} }
// SetDocumentationPath is used to explicitly set the documentation path that should be opened
// when the key to open the documentation is pressed.
// Setting this is probably not necessary unless the module documentation is nested inside a
// documentation subdirectory in the /wtfutildocs repo, or the module here has a different
// name than the module's display name in the documentation (which ideally wouldn't be a thing).
func (common *Common) SetDocumentationPath(path string) {
common.DocPath = path
}
// Validations aggregates all the validations from all the sub-sections in Common into a // Validations aggregates all the validations from all the sub-sections in Common into a
// single array of validations // single array of validations
func (common *Common) Validations() []Validatable { func (common *Common) Validations() []Validatable {

View File

@ -144,7 +144,7 @@ func Test_RightAlignFormat(t *testing.T) {
} }
} }
func Test_PaginationMarker(t *testing.T) { func Test_SigilStr(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
len int len int
@ -184,7 +184,7 @@ func Test_PaginationMarker(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, testCfg.PaginationMarker(tt.len, tt.pos, tt.width)) assert.Equal(t, tt.expected, testCfg.SigilStr(tt.len, tt.pos, tt.width))
}) })
} }
} }

View File

@ -36,7 +36,7 @@ const defaultConfigFile = `wtf:
odd: "white" odd: "white"
enabled: true enabled: true
locations: locations:
Paris: "Europe/Paris" Avignon: "Europe/Paris"
Barcelona: "Europe/Madrid" Barcelona: "Europe/Madrid"
Dubai: "Asia/Dubai" Dubai: "Asia/Dubai"
position: position:
@ -58,7 +58,7 @@ const defaultConfigFile = `wtf:
left: 1 left: 1
width: 2 width: 2
height: 1 height: 1
refreshInterval: 14400 updateInterval: 14400
ipinfo: ipinfo:
colors: colors:
name: "lightblue" name: "lightblue"

View File

@ -40,6 +40,8 @@ func main() {
generateWidgetFile(data) generateWidgetFile(data)
generateSettingsFile(data) generateSettingsFile(data)
fmt.Println("Done")
} }
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */

View File

@ -9,14 +9,16 @@ import (
type Widget struct { type Widget struct {
view.TextWidget view.TextWidget
app *tview.Application
settings *Settings settings *Settings
} }
// NewWidget creates and returns an instance of Widget // NewWidget creates and returns an instance of Widget
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, settings.common), TextWidget: view.NewTextWidget(app, settings.common),
app: app,
settings: settings, settings: settings,
} }

9
go.mod
View File

@ -1,9 +1,8 @@
module github.com/wtfutil/wtf module github.com/wtfutil/wtf
go 1.16 go 1.15
require ( require (
bitbucket.org/mikehouston/asana-go v0.0.0-20201102222432-715318d0343a
code.cloudfoundry.org/bytefmt v0.0.0-20190819182555-854d396b647c code.cloudfoundry.org/bytefmt v0.0.0-20190819182555-854d396b647c
github.com/Azure/go-autorest v11.1.2+incompatible // indirect github.com/Azure/go-autorest v11.1.2+incompatible // indirect
github.com/Microsoft/go-winio v0.4.14 // indirect github.com/Microsoft/go-winio v0.4.14 // indirect
@ -26,12 +25,14 @@ require (
github.com/dustin/go-humanize v1.0.0 github.com/dustin/go-humanize v1.0.0
github.com/gdamore/tcell v1.4.0 github.com/gdamore/tcell v1.4.0
github.com/go-ole/go-ole v1.2.4 // indirect github.com/go-ole/go-ole v1.2.4 // indirect
github.com/go-openapi/strfmt v0.19.6 // indirect
github.com/godbus/dbus v4.1.0+incompatible // indirect github.com/godbus/dbus v4.1.0+incompatible // indirect
github.com/google/go-github/v32 v32.1.0 github.com/google/go-github/v32 v32.1.0
github.com/gophercloud/gophercloud v0.5.0 // indirect github.com/gophercloud/gophercloud v0.5.0 // indirect
github.com/hekmon/cunits v2.0.1+incompatible // indirect github.com/hekmon/cunits v2.0.1+incompatible // indirect
github.com/hekmon/transmissionrpc v0.0.0-20190525133028-1d589625bacd github.com/hekmon/transmissionrpc v0.0.0-20190525133028-1d589625bacd
github.com/jedib0t/go-pretty/v6 v6.1.0 github.com/imdario/mergo v0.3.8 // indirect
github.com/jedib0t/go-pretty v4.3.0+incompatible
github.com/jessevdk/go-flags v1.4.0 github.com/jessevdk/go-flags v1.4.0
github.com/lib/pq v1.2.0 // indirect github.com/lib/pq v1.2.0 // indirect
github.com/logrusorgru/aurora v0.0.0-20190803045625-94edacc10f9b github.com/logrusorgru/aurora v0.0.0-20190803045625-94edacc10f9b
@ -44,13 +45,11 @@ require (
github.com/onsi/gomega v1.9.0 // indirect github.com/onsi/gomega v1.9.0 // indirect
github.com/ovh/cds v0.0.0-20201014170613-39429542624d github.com/ovh/cds v0.0.0-20201014170613-39429542624d
github.com/pborman/uuid v1.2.0 // indirect github.com/pborman/uuid v1.2.0 // indirect
github.com/piquette/finance-go v1.0.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/pkg/profile v1.5.0 github.com/pkg/profile v1.5.0
github.com/radovskyb/watcher v1.0.7 github.com/radovskyb/watcher v1.0.7
github.com/rivo/tview v0.0.0-20200108161608-1316ea7a4b35 github.com/rivo/tview v0.0.0-20200108161608-1316ea7a4b35
github.com/shirou/gopsutil v2.20.9+incompatible github.com/shirou/gopsutil v2.20.9+incompatible
github.com/shopspring/decimal v1.2.0 // indirect
github.com/shurcooL/githubv4 v0.0.0-20200802174311-f27d2ca7f6d5 github.com/shurcooL/githubv4 v0.0.0-20200802174311-f27d2ca7f6d5
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f // indirect github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f // indirect
github.com/spf13/cobra v0.0.5 // indirect github.com/spf13/cobra v0.0.5 // indirect

124
go.sum
View File

@ -1,5 +1,3 @@
bitbucket.org/mikehouston/asana-go v0.0.0-20201102222432-715318d0343a h1:qH51iOpTres3x2kNb0f2R3ggMpbYCyCvaRrsvdndhvY=
bitbucket.org/mikehouston/asana-go v0.0.0-20201102222432-715318d0343a/go.mod h1:HcP4iCG6i6uVAyX2X7yKOsjbzLFiTfX0EMT20CYn5Ig=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@ -12,27 +10,34 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0 h1:WRz29PgAsVEyPSDHyk+0fpEkwEFyfhHn+JbksT6gIL4=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0 h1:RmDygqvj27Zf3fCQjQRtLyC7KwFcHkeJitcO0OoGOcA=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8= cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0 h1:xE3CPsOgttP4ACBePh79zTKALtXwn/Edhcr16R5hMWU=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0 h1:Lpy6hKgdcl7a3WGSfJIFmxmcdjSpP6OmBEfcOv1Y680=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0 h1:UDpwYIwla4jHGzZJaEJYx1tOejbgSoNqsAfHAUYe2r8=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
code.cloudfoundry.org/bytefmt v0.0.0-20190819182555-854d396b647c h1:2RuXx1+tSNWRjxhY0Bx52kjV2odJQ0a6MTbfTPhGAkg= code.cloudfoundry.org/bytefmt v0.0.0-20190819182555-854d396b647c h1:2RuXx1+tSNWRjxhY0Bx52kjV2odJQ0a6MTbfTPhGAkg=
code.cloudfoundry.org/bytefmt v0.0.0-20190819182555-854d396b647c/go.mod h1:wN/zk7mhREp/oviagqUXY3EwuHhWyOvAdsn5Y4CzOrc= code.cloudfoundry.org/bytefmt v0.0.0-20190819182555-854d396b647c/go.mod h1:wN/zk7mhREp/oviagqUXY3EwuHhWyOvAdsn5Y4CzOrc=
@ -45,8 +50,10 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX
github.com/Azure/go-autorest v11.1.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v11.1.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v11.1.2+incompatible h1:viZ3tV5l4gE2Sw0xrasFHytCGtzYCrT+um/rrSQ1BfA= github.com/Azure/go-autorest v11.1.2+incompatible h1:viZ3tV5l4gE2Sw0xrasFHytCGtzYCrT+um/rrSQ1BfA=
github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/Microsoft/go-winio v0.4.7/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.7/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
@ -59,9 +66,12 @@ github.com/PagerDuty/go-pagerduty v0.0.0-20191002190746-f60f4fc45222 h1:QBpFoUrM
github.com/PagerDuty/go-pagerduty v0.0.0-20191002190746-f60f4fc45222/go.mod h1:6hH58nzwYc9mw+TPyM1anW0ivbI0ti4lYc+ZBaKmWts= github.com/PagerDuty/go-pagerduty v0.0.0-20191002190746-f60f4fc45222/go.mod h1:6hH58nzwYc9mw+TPyM1anW0ivbI0ti4lYc+ZBaKmWts=
github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE= github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE=
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/SSSaaS/sssa-golang v0.0.0-20170502204618-d37d7782d752 h1:NMpC6M+PtNNDYpq7ozB7kINpv10L5yeli5GJpka2PX8=
github.com/SSSaaS/sssa-golang v0.0.0-20170502204618-d37d7782d752/go.mod h1:PbJ8S5YaSYAvDPTiEuUsBHQwTUlPs6VM+Av8Oi3v570= github.com/SSSaaS/sssa-golang v0.0.0-20170502204618-d37d7782d752/go.mod h1:PbJ8S5YaSYAvDPTiEuUsBHQwTUlPs6VM+Av8Oi3v570=
github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/sarama v1.27.0/go.mod h1:aCdj6ymI8uyPEux1JJ9gcaDT6cinjGhNCAhs54taSUo= github.com/Shopify/sarama v1.27.0/go.mod h1:aCdj6ymI8uyPEux1JJ9gcaDT6cinjGhNCAhs54taSUo=
github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
@ -93,8 +103,12 @@ github.com/aokoli/goutils v1.1.0/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g
github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs= github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.19.11 h1:tqaTGER6Byw3QvsjGW0p018U2UOqaJPeJuzoaF7jjoQ=
github.com/aws/aws-sdk-go v1.19.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.19.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 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/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@ -103,6 +117,7 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d h1:28xWzPQ9bdGxKAAwQpZipZZ9Xz8kQcgMPF9cZnvMeuI= github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d h1:28xWzPQ9bdGxKAAwQpZipZZ9Xz8kQcgMPF9cZnvMeuI=
github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d/go.mod h1:8g1Bgq9PbPpXIA3sdlWmWf2JpiWGJee/O4Q+ddYO6+k= github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d/go.mod h1:8g1Bgq9PbPpXIA3sdlWmWf2JpiWGJee/O4Q+ddYO6+k=
@ -120,16 +135,23 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWs
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 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=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@ -162,10 +184,13 @@ github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e/go.mod h1:
github.com/dsnet/compress v0.0.0-20171208185109-cc9eb1d7ad76/go.mod h1:KjxHHirfLaw19iGT70HvVjHQsL1vq1SRQB4yOsAfy2s= github.com/dsnet/compress v0.0.0-20171208185109-cc9eb1d7ad76/go.mod h1:KjxHHirfLaw19iGT70HvVjHQsL1vq1SRQB4yOsAfy2s=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q=
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@ -179,17 +204,19 @@ github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq
github.com/fsamin/go-dump v1.0.9 h1:3MAneAJLnGfKTJtFEAdgrD+QqqK2Hwj7EJUQMQZcDls= github.com/fsamin/go-dump v1.0.9 h1:3MAneAJLnGfKTJtFEAdgrD+QqqK2Hwj7EJUQMQZcDls=
github.com/fsamin/go-dump v1.0.9/go.mod h1:ZgKd2aOXAFFbbFuUgvQhu7mwTlI3d3qnTICMWdvAa9o= github.com/fsamin/go-dump v1.0.9/go.mod h1:ZgKd2aOXAFFbbFuUgvQhu7mwTlI3d3qnTICMWdvAa9o=
github.com/fsamin/go-repo v0.1.8/go.mod h1:JRLbo6sPXvAwwGs5RgifFk1pXiefeGf0hyHifEg1Vw4= github.com/fsamin/go-repo v0.1.8/go.mod h1:JRLbo6sPXvAwwGs5RgifFk1pXiefeGf0hyHifEg1Vw4=
github.com/fsamin/go-shredder v0.0.0-20180118184739-b2488aedb5be h1:UhjSvwE1gxUYfekK9BXZ/LL55we9Avg+2Pt0PIlMYCk=
github.com/fsamin/go-shredder v0.0.0-20180118184739-b2488aedb5be/go.mod h1:kuiNcf1lKxl4isIY6bHxbBatpLD43c2RKWIV/AGlhXY= github.com/fsamin/go-shredder v0.0.0-20180118184739-b2488aedb5be/go.mod h1:kuiNcf1lKxl4isIY6bHxbBatpLD43c2RKWIV/AGlhXY=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= 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/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fujiwara/shapeio v0.0.0-20170602072123-c073257dd745/go.mod h1:/WpqsrSkjgwEG2Es2qnZXbXwHDVbawpdlXJIjJMmnZs= github.com/fujiwara/shapeio v0.0.0-20170602072123-c073257dd745/go.mod h1:/WpqsrSkjgwEG2Es2qnZXbXwHDVbawpdlXJIjJMmnZs=
github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E=
github.com/gambol99/go-marathon v0.0.0-20170922093320-ec4a50170df7/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s= github.com/gambol99/go-marathon v0.0.0-20170922093320-ec4a50170df7/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell v1.3.0 h1:r35w0JBADPZCVQijYebl6YMWWtHRqVEGt7kL2eBADRM=
github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM= github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM=
github.com/gdamore/tcell v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU= github.com/gdamore/tcell v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU=
github.com/gdamore/tcell v1.4.0/go.mod h1:vxEiSDZdW3L+Uhjii9c3375IlDmR05bzxY404ZVSMo0= github.com/gdamore/tcell v1.4.0/go.mod h1:vxEiSDZdW3L+Uhjii9c3375IlDmR05bzxY404ZVSMo0=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
@ -204,9 +231,15 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY=
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/strfmt v0.19.6 h1:epWc+q5qSgsy7A7+/HYyxLF37vLEYdPSkNB9G8mRqjw=
github.com/go-openapi/strfmt v0.19.6/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4= github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4=
@ -233,6 +266,7 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
@ -242,6 +276,7 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@ -250,9 +285,11 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@ -262,7 +299,9 @@ github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASu
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@ -283,18 +322,24 @@ github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTV
github.com/gophercloud/gophercloud v0.0.0-20190504011306-6f9faf57fddc/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.0.0-20190504011306-6f9faf57fddc/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gophercloud/gophercloud v0.5.0 h1:uM4HalWpEdxORniBrzicAtpYNTk45p5QLLS7zwc1uAU= github.com/gophercloud/gophercloud v0.5.0 h1:uM4HalWpEdxORniBrzicAtpYNTk45p5QLLS7zwc1uAU=
github.com/gophercloud/gophercloud v0.5.0/go.mod h1:b1k/BkBA9smzYde6p6zYLIe5JNAEoJzUWaIRh+9A/j0= github.com/gophercloud/gophercloud v0.5.0/go.mod h1:b1k/BkBA9smzYde6p6zYLIe5JNAEoJzUWaIRh+9A/j0=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorhill/cronexpr v0.0.0-20161205141322-d520615e531a/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= github.com/gorhill/cronexpr v0.0.0-20161205141322-d520615e531a/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v0.0.0-20160816184729-a5775781a543/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/handlers v0.0.0-20160816184729-a5775781a543/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q=
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= 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 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= 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/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.6 h1:8p0pcgLlw2iuZVsdHdPaMUXFOA+6gDixcXbHEMzSyW8=
github.com/grpc-ecosystem/grpc-gateway v1.9.6/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.6/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -305,6 +350,7 @@ github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9
github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
@ -313,18 +359,21 @@ github.com/hashicorp/go-retryablehttp v0.6.4 h1:BbgctKO892xEyOXnGiaAwIoSq1QZ/SS4
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= 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/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q=
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hekmon/cunits v2.0.1+incompatible h1:yy/Wq5YvNtrweqfeRjvrvMdBMH6axBrlL8t7arLlm5A= github.com/hekmon/cunits v2.0.1+incompatible h1:yy/Wq5YvNtrweqfeRjvrvMdBMH6axBrlL8t7arLlm5A=
github.com/hekmon/cunits v2.0.1+incompatible/go.mod h1:0QdfIGGkucx1VgStMNiHOYn84t/Ru65b+D3z1QszVPc= github.com/hekmon/cunits v2.0.1+incompatible/go.mod h1:0QdfIGGkucx1VgStMNiHOYn84t/Ru65b+D3z1QszVPc=
@ -339,18 +388,20 @@ github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.0.0-20180119215619-163f41321a19/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.0.0-20180119215619-163f41321a19/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg= github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/itsjamie/gin-cors v0.0.0-20160420130702-97b4a9da7933/go.mod h1:AYdLvrSBFloDBNt7Y8xkQ6gmhCODGl8CPikjyIOnNzA= github.com/itsjamie/gin-cors v0.0.0-20160420130702-97b4a9da7933/go.mod h1:AYdLvrSBFloDBNt7Y8xkQ6gmhCODGl8CPikjyIOnNzA=
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
github.com/jedib0t/go-pretty/v6 v6.1.0 h1:NVS2PT3ZvzMb47DzS50cmsK6xkf8SSyLfroSSIG20JI= github.com/jedib0t/go-pretty v4.3.0+incompatible h1:CGs8AVhEKg/n9YbUenWmNStRW2PHJzaeDodcfvRAbIo=
github.com/jedib0t/go-pretty/v6 v6.1.0/go.mod h1:+nE9fyyHGil+PuISTCrp7avEdo6bqoMwqZnuiK2r2a0= github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jordan-wright/email v4.0.1-0.20200917010138-e1c00e156980+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= github.com/jordan-wright/email v4.0.1-0.20200917010138-e1c00e156980+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@ -358,12 +409,15 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/keybase/go-crypto v0.0.0-20181127160227-255a5089e85a h1:X/UFlwD2/UV0RCy+8ITi4DmxJwk83YUH7bXwkJIHHMo=
github.com/keybase/go-crypto v0.0.0-20181127160227-255a5089e85a/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= github.com/keybase/go-crypto v0.0.0-20181127160227-255a5089e85a/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
github.com/keybase/go-keychain v0.0.0-20190828020956-aa639f275ae1/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= github.com/keybase/go-keychain v0.0.0-20190828020956-aa639f275ae1/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc=
github.com/keybase/go.dbus v0.0.0-20190710215703-a33a09c8a604/go.mod h1:a8clEhrrGV/d76/f9r2I41BwANMihfZYV9C223vaxqE= github.com/keybase/go.dbus v0.0.0-20190710215703-a33a09c8a604/go.mod h1:a8clEhrrGV/d76/f9r2I41BwANMihfZYV9C223vaxqE=
@ -374,6 +428,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/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/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/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -394,6 +449,7 @@ github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 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 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20171120080333-32fa128f234d h1:bM4HYnlVXPgUKmzl7o3drEaVfOk+sTBiADAQOWjU+8I=
github.com/mailru/easyjson v0.0.0-20171120080333-32fa128f234d/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20171120080333-32fa128f234d/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/maruel/panicparse v1.3.0 h1:1Ep/RaYoSL1r5rTILHQQbyzHG8T4UP5ZbQTYTo4bdDc= github.com/maruel/panicparse v1.3.0 h1:1Ep/RaYoSL1r5rTILHQQbyzHG8T4UP5ZbQTYTo4bdDc=
github.com/maruel/panicparse v1.3.0/go.mod h1:vszMjr5QQ4F5FSRfraldcIA/BCw5xrdLL+zEcU2nRBs= github.com/maruel/panicparse v1.3.0/go.mod h1:vszMjr5QQ4F5FSRfraldcIA/BCw5xrdLL+zEcU2nRBs=
@ -408,9 +464,8 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.1/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.1/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4= github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
@ -424,15 +479,19 @@ github.com/microsoft/azure-devops-go-api/azuredevops v0.0.0-20191014190507-26902
github.com/microsoft/azure-devops-go-api/azuredevops v0.0.0-20191014190507-26902c1d4325/go.mod h1:PoGiBqKSQK1vIfQ+yVaFcGjDySHvym6FM1cNYnwzbrY= github.com/microsoft/azure-devops-go-api/azuredevops v0.0.0-20191014190507-26902c1d4325/go.mod h1:PoGiBqKSQK1vIfQ+yVaFcGjDySHvym6FM1cNYnwzbrY=
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75/go.mod h1:pBbZyGwC5i16IBkjVKoy/sznA8jPD/K9iedwe1ESE6w= github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75/go.mod h1:pBbZyGwC5i16IBkjVKoy/sznA8jPD/K9iedwe1ESE6w=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
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-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU=
github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mmcdole/gofeed v1.1.0 h1:T2WrGLVJRV04PY2qwhEJLHCt9JiCtBhb6SmC8ZvJH08= github.com/mmcdole/gofeed v1.1.0 h1:T2WrGLVJRV04PY2qwhEJLHCt9JiCtBhb6SmC8ZvJH08=
github.com/mmcdole/gofeed v1.1.0/go.mod h1:PPiVwgDXLlz2N83KB4TrIim2lyYM5Zn7ZWH9Pi4oHUk= github.com/mmcdole/gofeed v1.1.0/go.mod h1:PPiVwgDXLlz2N83KB4TrIim2lyYM5Zn7ZWH9Pi4oHUk=
@ -449,7 +508,9 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/mum4k/termdash v0.10.0/go.mod h1:l3tO+lJi9LZqXRq7cu7h5/8rDIK3AzelSuq2v/KncxI= github.com/mum4k/termdash v0.10.0/go.mod h1:l3tO+lJi9LZqXRq7cu7h5/8rDIK3AzelSuq2v/KncxI=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E=
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/ncw/swift v0.0.0-20171019114456-c95c6e5c2d1a h1:SAjW6pL/9NssyKM1Qvyy5/V4kR3z76qlTbaqJLixhP4=
github.com/ncw/swift v0.0.0-20171019114456-c95c6e5c2d1a/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/ncw/swift v0.0.0-20171019114456-c95c6e5c2d1a/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/nicklaw5/helix v0.7.0 h1:+E8YUqNewLFX0jSxlzKvDpyOs/v299ZZtp1aEqlonWk= github.com/nicklaw5/helix v0.7.0 h1:+E8YUqNewLFX0jSxlzKvDpyOs/v299ZZtp1aEqlonWk=
github.com/nicklaw5/helix v0.7.0/go.mod h1:nRcok4VLg8ONQYW/iXBZ24wcfiJjTlDbhgk0ZatOrUY= github.com/nicklaw5/helix v0.7.0/go.mod h1:nRcok4VLg8ONQYW/iXBZ24wcfiJjTlDbhgk0ZatOrUY=
@ -464,6 +525,7 @@ github.com/olebedev/config v0.0.0-20190528211619-364964f3a8e4/go.mod h1:RL5+WRxW
github.com/olekukonko/tablewriter v0.0.0-20160621093029-daf2955e742c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.0-20160621093029-daf2955e742c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8= github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/olivere/elastic v6.2.17+incompatible h1:g8tdYJgwHYh6LxfKp+YSgDmDVorZOm7+M8n1OkeQEWs=
github.com/olivere/elastic v6.2.17+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8= github.com/olivere/elastic v6.2.17+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 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/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -486,6 +548,7 @@ github.com/ovh/symmecrypt v0.4.4-0.20200925135645-1cb7e4ce37a0/go.mod h1:566sFU1
github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw= github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ= github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
@ -497,14 +560,11 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/piquette/finance-go v1.0.0 h1:0nHbZCbhAsUMUt18oTgy5bHQfPRGhcNA0EbpxNRsZAA=
github.com/piquette/finance-go v1.0.0/go.mod h1:H51NoGFnfu41Un/Fp0aAhS2lLRFBiiwHhMsV59bXAI0=
github.com/pkg/browser v0.0.0-20170505125900-c90ca0c84f15/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/browser v0.0.0-20170505125900-c90ca0c84f15/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pkg/profile v1.5.0 h1:042Buzk+NhDI+DeSAA62RwJL8VAuZUMQZUjCsRz1Mug= github.com/pkg/profile v1.5.0 h1:042Buzk+NhDI+DeSAA62RwJL8VAuZUMQZUjCsRz1Mug=
github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -549,13 +609,12 @@ github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rubenv/sql-migrate v0.0.0-20160620083229-6f4757563362/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY= github.com/rubenv/sql-migrate v0.0.0-20160620083229-6f4757563362/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= 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/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
@ -564,8 +623,6 @@ github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197/go.mod h1:0hh
github.com/shirou/gopsutil v0.0.0-20170406131756-e49a95f3d5f8/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v0.0.0-20170406131756-e49a95f3d5f8/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v2.20.9+incompatible h1:msXs2frUV+O/JLva9EDLpuJ84PrFsdCTCQex8PUdtkQ= github.com/shirou/gopsutil v2.20.9+incompatible h1:msXs2frUV+O/JLva9EDLpuJ84PrFsdCTCQex8PUdtkQ=
github.com/shirou/gopsutil v2.20.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v2.20.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/githubv4 v0.0.0-20200802174311-f27d2ca7f6d5 h1:CA6Mjshr+g5YHENwllpQNR0UaYO7VGKo6TzJLM64WJQ= github.com/shurcooL/githubv4 v0.0.0-20200802174311-f27d2ca7f6d5 h1:CA6Mjshr+g5YHENwllpQNR0UaYO7VGKo6TzJLM64WJQ=
github.com/shurcooL/githubv4 v0.0.0-20200802174311-f27d2ca7f6d5/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/githubv4 v0.0.0-20200802174311-f27d2ca7f6d5/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXkPI6mQ4o9DQ0+FKW41hTbunoXZCTqk= github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXkPI6mQ4o9DQ0+FKW41hTbunoXZCTqk=
@ -578,7 +635,9 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf
github.com/smartystreets/assertions v0.0.0-20170213163019-15adfb6b24e2/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20170213163019-15adfb6b24e2/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= 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 v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= 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/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.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
@ -601,9 +660,11 @@ github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
github.com/streadway/amqp v0.0.0-20180528204448-e5adc2ada8b8 h1:l6epF6yBwuejBfhGkM5m8VSNM/QAm7ApGyH35ehA7eQ=
github.com/streadway/amqp v0.0.0-20180528204448-e5adc2ada8b8/go.mod h1:1WNBiOZtZQLpVAyu0iTduoJL9hEsMloAK5XWrtW0xdY= github.com/streadway/amqp v0.0.0-20180528204448-e5adc2ada8b8/go.mod h1:1WNBiOZtZQLpVAyu0iTduoJL9hEsMloAK5XWrtW0xdY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@ -616,10 +677,15 @@ github.com/studio-b12/gowebdav v0.0.0-20200303150724-9380631c29a1/go.mod h1:gCcf
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5/go.mod h1:f1SCnEOt6sc3fOJfPQDRDzHOtSXuTtnz0ImG9kPRDV0= github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5/go.mod h1:f1SCnEOt6sc3fOJfPQDRDzHOtSXuTtnz0ImG9kPRDV0=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= 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/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ulikunitz/xz v0.5.4/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.4/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
@ -636,14 +702,17 @@ github.com/xanzy/go-gitlab v0.39.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfD
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= 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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yesnault/go-toml v0.0.0-20191205182532-f5ef6cee7945/go.mod h1:SsMrIuedaKvK8GekjwjVv8gMnHNAuvoINpKCARzdsEQ= github.com/yesnault/go-toml v0.0.0-20191205182532-f5ef6cee7945/go.mod h1:SsMrIuedaKvK8GekjwjVv8gMnHNAuvoINpKCARzdsEQ=
github.com/yuin/gluare v0.0.0-20170607022532-d7c94f1a80ed h1:I1vcLHWU9m30rA90rMrKPu0eD3NDA4FBlkB8WMaDyUw=
github.com/yuin/gluare v0.0.0-20170607022532-d7c94f1a80ed/go.mod h1:9w6KSdZh23UWqOywWsRLUcJUrUNjRh4Ql3z9uVgnSP4= github.com/yuin/gluare v0.0.0-20170607022532-d7c94f1a80ed/go.mod h1:9w6KSdZh23UWqOywWsRLUcJUrUNjRh4Ql3z9uVgnSP4=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/gopher-lua v0.0.0-20170901023928-8c2befcd3908 h1:D1Gc3nOtLEadaHIZD98eX2ABnEi0OW7UZGogFWERsFI=
github.com/yuin/gopher-lua v0.0.0-20170901023928-8c2befcd3908/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= github.com/yuin/gopher-lua v0.0.0-20170901023928-8c2befcd3908/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
@ -652,7 +721,10 @@ github.com/zmb3/spotify v0.0.0-20191010212056-e12fb981aacb/go.mod h1:pHsWAmY9PfX
github.com/zorkian/go-datadog-api v2.30.0+incompatible h1:R4ryGocppDqZZbnNc5EDR8xGWF/z/MxzWnqTUijDQes= github.com/zorkian/go-datadog-api v2.30.0+incompatible h1:R4ryGocppDqZZbnNc5EDR8xGWF/z/MxzWnqTUijDQes=
github.com/zorkian/go-datadog-api v2.30.0+incompatible/go.mod h1:PkXwHX9CUQa/FpB9ZwAD45N1uhCW4MT/Wj7m36PbKss= github.com/zorkian/go-datadog-api v2.30.0+incompatible/go.mod h1:PkXwHX9CUQa/FpB9ZwAD45N1uhCW4MT/Wj7m36PbKss=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.mongodb.org/mongo-driver v1.0.3 h1:GKoji1ld3tw2aC+GX1wbr/J2fX13yNacEYoJ8Nhr0yU=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
@ -660,8 +732,11 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@ -671,6 +746,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/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/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -695,6 +771,7 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
@ -703,6 +780,7 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
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.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -738,6 +816,7 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200528225125-3c3fba18258b/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
@ -746,6 +825,7 @@ golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAG
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
@ -758,7 +838,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/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-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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -802,6 +881,7 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642 h1:B6caxRw+hozq68X2MY7jEpZh/cr4/aHLv9xU8Kkadrw=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f h1:Fqb3ao1hUmOR3GkUOg/Y+BadLwykBIzs5q8Ez2SbHyc= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f h1:Fqb3ao1hUmOR3GkUOg/Y+BadLwykBIzs5q8Ez2SbHyc=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -810,6 +890,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 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/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@ -859,11 +940,13 @@ golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d h1:szSOL78iTCl0LF1AMjhSWJj8tIM0KixlUUnBtYXsmd8=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -884,6 +967,7 @@ google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.33.0 h1:+gL0XvACeMIvpwLZ5rQZzLn5cwOsgg8dIcfJ2SYfBVw= google.golang.org/api v0.33.0 h1:+gL0XvACeMIvpwLZ5rQZzLn5cwOsgg8dIcfJ2SYfBVw=
google.golang.org/api v0.33.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.33.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
@ -924,6 +1008,7 @@ google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1m
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c h1:Lq4llNryJoaVFRmvrIwC/ZHH7tNt4tUYIu8+se2aayY=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d h1:92D1fum1bJLKSdr11OJ+54YeCMCGYIygTA7R/YZxH5M= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d h1:92D1fum1bJLKSdr11OJ+54YeCMCGYIygTA7R/YZxH5M=
@ -941,6 +1026,7 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
@ -983,9 +1069,12 @@ gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mN
gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk= gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk=
gopkg.in/olivere/elastic.v6 v6.2.17 h1:ewcJ35+DJUA/OeZYP6I+oWoYWvcBlonuFJ8JU1/W4RY=
gopkg.in/olivere/elastic.v6 v6.2.17/go.mod h1:2cTT8Z+/LcArSWpCgvZqBgt3VOqXiy7v00w12Lz8bd4= gopkg.in/olivere/elastic.v6 v6.2.17/go.mod h1:2cTT8Z+/LcArSWpCgvZqBgt3VOqXiy7v00w12Lz8bd4=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/spacemonkeygo/httpsig.v0 v0.0.0-20170228231032-6732593ec966 h1:8kepDsMTleFJGPFjqiqahyFDI8s8zmx1CbCC3qUOh5c=
gopkg.in/spacemonkeygo/httpsig.v0 v0.0.0-20170228231032-6732593ec966/go.mod h1:KUilIqVZdvg7tsZSnGqOnw8jL2WVzcC0RHV/Av0km2U= gopkg.in/spacemonkeygo/httpsig.v0 v0.0.0-20170228231032-6732593ec966/go.mod h1:KUilIqVZdvg7tsZSnGqOnw8jL2WVzcC0RHV/Av0km2U=
gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
@ -995,6 +1084,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200601152816-913338de1bd2 h1:VEmvx0P+GVTgkNu2EdTN988YCZPcD3lo9AoczZpucwc= gopkg.in/yaml.v3 v3.0.0-20200601152816-913338de1bd2 h1:VEmvx0P+GVTgkNu2EdTN988YCZPcD3lo9AoczZpucwc=
gopkg.in/yaml.v3 v3.0.0-20200601152816-913338de1bd2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200601152816-913338de1bd2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

42
main.go
View File

@ -1,5 +1,10 @@
package main package main
// Generators
// To generate the skeleton for a new TextWidget use 'WTF_WIDGET_NAME=MySuperAwesomeWidget go generate -run=text
//go:generate -command text go run generator/textwidget.go
//go:generate text
import ( import (
"fmt" "fmt"
"log" "log"
@ -12,20 +17,34 @@ import (
_ "time/tzdata" _ "time/tzdata"
"github.com/logrusorgru/aurora" "github.com/logrusorgru/aurora"
"github.com/olebedev/config"
"github.com/pkg/profile" "github.com/pkg/profile"
"github.com/rivo/tview"
"github.com/wtfutil/wtf/app" "github.com/wtfutil/wtf/app"
"github.com/wtfutil/wtf/cfg" "github.com/wtfutil/wtf/cfg"
"github.com/wtfutil/wtf/flags" "github.com/wtfutil/wtf/flags"
"github.com/wtfutil/wtf/utils" "github.com/wtfutil/wtf/utils"
"github.com/wtfutil/wtf/wtf"
) )
var tviewApp *tview.Application
var ( var (
date = "dev" date = "dev"
version = "dev" version = "dev"
) )
/* -------------------- Functions -------------------- */
func setTerm(config *config.Config) {
term := config.UString("wtf.term", os.Getenv("TERM"))
err := os.Setenv("TERM", term)
if err != nil {
fmt.Printf("\n%s Failed to set $TERM to %s.\n", aurora.Red("ERROR"), aurora.Yellow(term))
os.Exit(1)
}
}
/* -------------------- Main -------------------- */ /* -------------------- Main -------------------- */
func main() { func main() {
@ -35,12 +54,11 @@ func main() {
flags := flags.NewFlags() flags := flags.NewFlags()
flags.Parse() flags.Parse()
hasCustom := flags.HasCustomConfig()
cfg.Initialize(hasCustom)
// Load the configuration file // Load the configuration file
cfg.Initialize(flags.HasCustomConfig())
config := cfg.LoadWtfConfigFile(flags.ConfigFilePath()) config := cfg.LoadWtfConfigFile(flags.ConfigFilePath())
wtf.SetTerminal(config)
flags.RenderIf(version, date, config) flags.RenderIf(version, date, config)
if flags.Profile { if flags.Profile {
@ -51,15 +69,15 @@ func main() {
openURLUtil := utils.ToStrs(config.UList("wtf.openUrlUtil", []interface{}{})) openURLUtil := utils.ToStrs(config.UList("wtf.openUrlUtil", []interface{}{}))
utils.Init(openFileUtil, openURLUtil) utils.Init(openFileUtil, openURLUtil)
/* Initialize the App Manager */ setTerm(config)
appMan := app.NewAppManager()
appMan.MakeNewWtfApp(config, flags.Config)
currentApp, err := appMan.Current() // Build the application
if err != nil { tviewApp = tview.NewApplication()
wtfApp := app.NewWtfApp(tviewApp, config, flags.Config)
wtfApp.Start()
if err := tviewApp.Run(); err != nil {
fmt.Printf("\n%s %v\n", aurora.Red("ERROR"), err) fmt.Printf("\n%s %v\n", aurora.Red("ERROR"), err)
os.Exit(1) os.Exit(1)
} }
currentApp.Run()
} }

View File

@ -1,280 +0,0 @@
package asana
import (
"fmt"
"strings"
"time"
asana "bitbucket.org/mikehouston/asana-go"
)
func fetchTasksFromProject(token, projectId, mode string) ([]*TaskItem, error) {
taskItems := []*TaskItem{}
uidToName := make(map[string]string)
client := asana.NewClientWithAccessToken(token)
uid, err := getCurrentUserId(client, mode)
if err != nil {
return nil, err
}
q := &asana.TaskQuery{
Project: projectId,
}
fetchedTasks, _, err := getTasksFromAsana(client, q)
if err != nil {
return nil, fmt.Errorf("error fetching tasks: %s", err)
}
processFetchedTasks(client, &fetchedTasks, &taskItems, &uidToName, mode, projectId, uid)
return taskItems, nil
}
func fetchTasksFromProjectSections(token, projectId string, sections []string, mode string) ([]*TaskItem, error) {
taskItems := []*TaskItem{}
uidToName := make(map[string]string)
client := asana.NewClientWithAccessToken(token)
uid, err := getCurrentUserId(client, mode)
if err != nil {
return nil, err
}
p := &asana.Project{
ID: projectId,
}
for _, section := range sections {
sectionId, err := findSection(client, p, section)
if err != nil {
return nil, fmt.Errorf("error fetching tasks: %s", err)
}
q := &asana.TaskQuery{
Section: sectionId,
}
fetchedTasks, _, err := getTasksFromAsana(client, q)
if err != nil {
return nil, fmt.Errorf("error fetching tasks: %s", err)
}
if len(fetchedTasks) > 0 {
taskItem := &TaskItem{
name: section,
taskType: TASK_SECTION,
}
taskItems = append(taskItems, taskItem)
}
processFetchedTasks(client, &fetchedTasks, &taskItems, &uidToName, mode, projectId, uid)
}
return taskItems, nil
}
func fetchTasksFromWorkspace(token, workspaceId, mode string) ([]*TaskItem, error) {
taskItems := []*TaskItem{}
uidToName := make(map[string]string)
client := asana.NewClientWithAccessToken(token)
uid, err := getCurrentUserId(client, mode)
if err != nil {
return nil, err
}
q := &asana.TaskQuery{
Workspace: workspaceId,
Assignee: "me",
}
fetchedTasks, _, err := getTasksFromAsana(client, q)
if err != nil {
return nil, fmt.Errorf("error fetching tasks: %s", err)
}
processFetchedTasks(client, &fetchedTasks, &taskItems, &uidToName, mode, workspaceId, uid)
return taskItems, nil
}
func toggleTaskCompletionById(token, taskId string) error {
client := asana.NewClientWithAccessToken(token)
t := &asana.Task{
ID: taskId,
}
err := t.Fetch(client)
if err != nil {
return fmt.Errorf("error fetching task: %s", err)
}
updateReq := &asana.UpdateTaskRequest{}
if *t.Completed {
f := false
updateReq.Completed = &f
} else {
t := true
updateReq.Completed = &t
}
err = t.Update(client, updateReq)
if err != nil {
return fmt.Errorf("error updating task: %s", err)
}
return nil
}
func processFetchedTasks(client *asana.Client, fetchedTasks *[]*asana.Task, taskItems *[]*TaskItem, uidToName *map[string]string, mode, projectId, uid string) {
for _, task := range *fetchedTasks {
switch {
case strings.HasSuffix(mode, "_all"):
if task.Assignee != nil {
// Check if we have already looked up this user
if assigneeName, ok := (*uidToName)[task.Assignee.ID]; ok {
task.Assignee.Name = assigneeName
} else {
// We haven't looked up this user before, perform the lookup now
assigneeName, err := getOtherUserEmail(client, task.Assignee.ID)
if err != nil {
task.Assignee.Name = "Error"
}
(*uidToName)[task.Assignee.ID] = assigneeName
task.Assignee.Name = assigneeName
}
} else {
task.Assignee = &asana.User{
Name: "Unassigned",
}
}
taskItem := buildTaskItem(task, projectId)
(*taskItems) = append((*taskItems), taskItem)
case !strings.HasSuffix(mode, "_all") && task.Assignee != nil && task.Assignee.ID == uid:
taskItem := buildTaskItem(task, projectId)
(*taskItems) = append((*taskItems), taskItem)
}
}
}
func buildTaskItem(task *asana.Task, projectId string) *TaskItem {
dueOnString := ""
if task.DueOn != nil {
dueOn := time.Time(*task.DueOn)
currentYear, _, _ := time.Now().Date()
if currentYear != dueOn.Year() {
dueOnString = dueOn.Format("Jan 2 2006")
} else {
dueOnString = dueOn.Format("Jan 2")
}
}
assignString := ""
if task.Assignee != nil {
assignString = task.Assignee.Name
}
taskItem := &TaskItem{
name: task.Name,
id: task.ID,
numSubtasks: task.NumSubtasks,
dueOn: dueOnString,
url: fmt.Sprintf("https://app.asana.com/0/%s/%s/f", projectId, task.ID),
taskType: TASK_TYPE,
completed: *task.Completed,
assignee: assignString,
}
return taskItem
}
func getOtherUserEmail(client *asana.Client, uid string) (string, error) {
if uid == "" {
return "", fmt.Errorf("missing uid")
}
u := &asana.User{
ID: uid,
}
err := u.Fetch(client, nil)
if err != nil {
return "", fmt.Errorf("error fetching user: %s", err)
}
return u.Email, nil
}
func getCurrentUserId(client *asana.Client, mode string) (string, error) {
if strings.HasSuffix(mode, "_all") {
return "", nil
}
u, err := client.CurrentUser()
if err != nil {
return "", fmt.Errorf("error getting current user: %s", err)
}
return u.ID, nil
}
func findSection(client *asana.Client, project *asana.Project, sectionName string) (string, error) {
sectionId := ""
sections, _, err := project.Sections(client, &asana.Options{
Limit: 100,
})
if err != nil {
return "", fmt.Errorf("error getting sections: %s", err)
}
for _, section := range sections {
if section.Name == sectionName {
sectionId = section.ID
break
}
}
if sectionId == "" {
return "", fmt.Errorf("we didn't find the section %s", sectionName)
}
return sectionId, nil
}
func getTasksFromAsana(client *asana.Client, q *asana.TaskQuery) ([]*asana.Task, bool, error) {
moreTasks := false
tasks, np, err := client.QueryTasks(q, &asana.Options{
Limit: 100,
Fields: []string{
"assignee",
"name",
"num_subtasks",
"due_on",
"completed",
},
})
if err != nil {
return nil, false, fmt.Errorf("error querying tasks: %s", err)
}
if np != nil {
moreTasks = true
}
return tasks, moreTasks, nil
}

View File

@ -1,20 +0,0 @@
package asana
import "github.com/gdamore/tcell"
func (widget *Widget) initializeKeyboardControls() {
widget.InitializeHelpTextKeyboardControl(widget.ShowHelp)
widget.InitializeRefreshKeyboardControl(widget.Refresh)
widget.SetKeyboardChar("j", widget.Next, "Select next task")
widget.SetKeyboardChar("k", widget.Prev, "Select previous task")
widget.SetKeyboardChar("q", widget.Unselect, "Unselect task")
widget.SetKeyboardChar("o", widget.openTask, "Open task in browser")
widget.SetKeyboardChar("x", widget.toggleTaskCompletion, "Toggles the task's completion state")
widget.SetKeyboardChar("?", widget.ShowHelp, "Shows help")
widget.SetKeyboardKey(tcell.KeyDown, widget.Next, "Select next task")
widget.SetKeyboardKey(tcell.KeyUp, widget.Prev, "Select previous task")
widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect, "Unselect task")
widget.SetKeyboardKey(tcell.KeyEnter, widget.openTask, "Open task in browser")
}

View File

@ -1,48 +0,0 @@
package asana
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
"github.com/wtfutil/wtf/utils"
)
const (
defaultFocusable = true
defaultTitle = "Asana"
)
type Settings struct {
*cfg.Common
projectId string `help:"The Asana Project ID. If the mode is 'project' or 'project_sections' this is required to known which Asana Project to pull your tasks from" values:"A valid Asana Project ID string" optional:"true"`
workspaceId string `help:"The Asana Workspace ID. If mode is 'workspace' this is required" values:"A valid Asana Workspace ID string" optional:"true"`
sections []string `help:"The Asana Section Labels to fetch from the Project. Required if the mode is 'project_sections'" values:"An array of Asana Section Label strings" optional:"true"`
allUsers bool `help:"Fetch tasks for all users, defaults to false" values:"bool" optional:"true"`
mode string `help:"What mode to query Asana, 'project', 'project_sections', 'workspace'" values:"A string with either 'project', 'project_sections' or 'workspace'"`
hideComplete bool `help:"Hide completed tasks, defaults to false" values:"bool" optional:"true"`
apiKey string `help:"Your Asana Personal Access Token. Leave this blank to use the WTF_ASANA_TOKEN environment variable." values:"Your Asana Personal Access Token as a string" optional:"true"`
token string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig,
globalConfig),
projectId: ymlConfig.UString("projectId", ""),
apiKey: ymlConfig.UString("apiKey", ""),
workspaceId: ymlConfig.UString("workspaceId", ""),
sections: utils.ToStrs(ymlConfig.UList("sections")),
allUsers: ymlConfig.UBool("allUsers", false),
mode: ymlConfig.UString("mode", ""),
hideComplete: ymlConfig.UBool("hideComplete", false),
}
return &settings
}

View File

@ -1,259 +0,0 @@
package asana
import (
"fmt"
"os"
"strings"
"sync"
"github.com/rivo/tview"
"github.com/wtfutil/wtf/utils"
"github.com/wtfutil/wtf/view"
)
type TaskType int
const (
TASK_TYPE TaskType = iota
TASK_SECTION
TASK_BREAK
)
type TaskItem struct {
name string
numSubtasks int32
dueOn string
id string
url string
taskType TaskType
completed bool
assignee string
}
type Widget struct {
view.ScrollableWidget
tasks []*TaskItem
mu sync.Mutex
err error
settings *Settings
tviewApp *tview.Application
}
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := &Widget{
ScrollableWidget: view.NewScrollableWidget(tviewApp, pages, settings.Common),
tviewApp: tviewApp,
settings: settings,
}
widget.SetRenderFunction(widget.Render)
widget.initializeKeyboardControls()
return widget
}
/* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() {
widget.tasks = nil
widget.err = nil
widget.SetItemCount(0)
widget.mu.Lock()
defer widget.mu.Unlock()
tasks, err := widget.Fetch(
widget.settings.workspaceId,
widget.settings.projectId,
widget.settings.mode,
widget.settings.sections,
widget.settings.allUsers,
)
if err != nil {
widget.err = err
} else {
widget.tasks = tasks
widget.SetItemCount(len(tasks))
}
widget.Render()
}
func (widget *Widget) Render() {
widget.Redraw(widget.content)
}
func (widget *Widget) Fetch(workspaceId, projectId, mode string, sections []string, allUsers bool) ([]*TaskItem, error) {
availableModes := map[string]interface{}{
"project": nil,
"project_sections": nil,
"workspace": nil,
}
if _, ok := availableModes[mode]; !ok {
return nil, fmt.Errorf("missing mode, or mode is invalid - please set to project, project_sections or workspace")
}
if widget.settings.apiKey != "" {
widget.settings.token = widget.settings.apiKey
} else {
widget.settings.token = os.Getenv("WTF_ASANA_TOKEN")
}
if widget.settings.token == "" {
return nil, fmt.Errorf("missing environment variable token or apikey config")
}
subMode := mode
if allUsers && mode != "workspace" {
subMode += "_all"
}
if projectId == "" && strings.HasPrefix(subMode, "project") {
return nil, fmt.Errorf("missing project id")
}
if workspaceId == "" && subMode == "workspace" {
return nil, fmt.Errorf("missing workspace id")
}
var tasks []*TaskItem
var err error
switch {
case strings.HasPrefix(subMode, "project_sections"):
tasks, err = fetchTasksFromProjectSections(widget.settings.token, projectId, sections, subMode)
case strings.HasPrefix(subMode, "project"):
tasks, err = fetchTasksFromProject(widget.settings.token, projectId, subMode)
case subMode == "workspace":
tasks, err = fetchTasksFromWorkspace(widget.settings.token, workspaceId, subMode)
default:
err = fmt.Errorf("no mode found")
}
if err != nil {
return nil, err
}
return tasks, nil
}
/* -------------------- Unexported Functions -------------------- */
func (widget *Widget) content() (string, string, bool) {
title := widget.CommonSettings().Title
if widget.err != nil {
return title, widget.err.Error(), true
}
data := widget.tasks
if len(data) == 0 {
return title, "No data", false
}
var str string
for idx, taskItem := range data {
switch {
case taskItem.taskType == TASK_TYPE:
if widget.settings.hideComplete && taskItem.completed {
continue
}
rowColor := widget.RowColor(idx)
completed := "[ []"
if taskItem.completed {
completed = "[x[]"
}
row := ""
if widget.settings.allUsers && taskItem.assignee != "" {
row = fmt.Sprintf(
"[%s] %s %s: %s",
rowColor,
completed,
taskItem.assignee,
taskItem.name,
)
} else {
row = fmt.Sprintf(
"[%s] %s %s",
rowColor,
completed,
taskItem.name,
)
}
if taskItem.numSubtasks > 0 {
row += fmt.Sprintf(" (%d)", taskItem.numSubtasks)
}
if taskItem.dueOn != "" {
row += fmt.Sprintf(" due: %s", taskItem.dueOn)
}
row += " [white]"
str += utils.HighlightableHelper(widget.View, row, idx, len(taskItem.name))
case taskItem.taskType == TASK_SECTION:
if idx > 1 {
row := "[white] "
str += utils.HighlightableHelper(widget.View, row, idx, len(taskItem.name))
}
row := fmt.Sprintf(
"[white] %s [white]",
taskItem.name,
)
str += utils.HighlightableHelper(widget.View, row, idx, len(taskItem.name))
row = "[white] "
str += utils.HighlightableHelper(widget.View, row, idx, len(taskItem.name))
}
}
return title, str, false
}
func (widget *Widget) openTask() {
sel := widget.GetSelected()
if sel >= 0 && widget.tasks != nil && sel < len(widget.tasks) {
task := widget.tasks[sel]
if task.taskType == TASK_TYPE && task.url != "" {
utils.OpenFile(task.url)
}
}
}
func (widget *Widget) toggleTaskCompletion() {
sel := widget.GetSelected()
if sel >= 0 && widget.tasks != nil && sel < len(widget.tasks) {
task := widget.tasks[sel]
if task.taskType == TASK_TYPE {
widget.mu.Lock()
err := toggleTaskCompletionById(widget.settings.token, task.id)
if err != nil {
widget.err = err
}
widget.mu.Unlock()
widget.Refresh()
}
}
}

View File

@ -14,7 +14,7 @@ const (
// Settings defines the configuration options for this module // Settings defines the configuration options for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
apiToken string `help:"Your Azure DevOps Access Token."` apiToken string `help:"Your Azure DevOps Access Token."`
labelColor string labelColor string
@ -26,7 +26,7 @@ type Settings struct {
// NewSettingsFromYAML creates and returns an instance of Settings with configuration options populated // NewSettingsFromYAML creates and returns an instance of Settings with configuration options populated
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocus, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocus, ymlConfig, globalConfig),
apiToken: ymlConfig.UString("apiToken", os.Getenv("WTF_AZURE_DEVOPS_API_TOKEN")), apiToken: ymlConfig.UString("apiToken", os.Getenv("WTF_AZURE_DEVOPS_API_TOKEN")),
labelColor: ymlConfig.UString("labelColor", "white"), labelColor: ymlConfig.UString("labelColor", "white"),

View File

@ -19,9 +19,9 @@ type Widget struct {
ctx context.Context ctx context.Context
} }
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, pages, settings.Common), TextWidget: view.NewTextWidget(app, settings.common),
settings: settings, settings: settings,
} }

View File

@ -13,7 +13,7 @@ const (
) )
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
apiKey string `help:"Your BambooHR API token."` apiKey string `help:"Your BambooHR API token."`
subdomain string `help:"Your BambooHR API subdomain name."` subdomain string `help:"Your BambooHR API subdomain name."`
@ -21,7 +21,7 @@ type Settings struct {
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_BAMBOO_HR_TOKEN"))), apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_BAMBOO_HR_TOKEN"))),
subdomain: ymlConfig.UString("subdomain", os.Getenv("WTF_BAMBOO_HR_SUBDOMAIN")), subdomain: ymlConfig.UString("subdomain", os.Getenv("WTF_BAMBOO_HR_SUBDOMAIN")),

View File

@ -19,9 +19,9 @@ type Widget struct {
items []Item items []Item
} }
func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, nil, settings.Common), TextWidget: view.NewTextWidget(app, settings.common),
settings: settings, settings: settings,
} }

View File

@ -11,12 +11,12 @@ const (
) )
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
} }
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
} }
return &settings return &settings

View File

@ -17,15 +17,15 @@ import (
type Widget struct { type Widget struct {
view.BarGraph view.BarGraph
tviewApp *tview.Application app *tview.Application
} }
// NewWidget Make new instance of widget // NewWidget Make new instance of widget
func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
BarGraph: view.NewBarGraph(tviewApp, "Sample Bar Graph", settings.Common), BarGraph: view.NewBarGraph(app, "Sample Bar Graph", settings.common),
tviewApp: tviewApp, app: app,
} }
widget.View.SetWrap(true) widget.View.SetWrap(true)
@ -69,7 +69,7 @@ func (widget *Widget) Refresh() {
widget.View.Clear() widget.View.Clear()
widget.tviewApp.QueueUpdateDraw(func() { widget.app.QueueUpdateDraw(func() {
display(widget) display(widget)
}) })

View File

@ -57,8 +57,6 @@ func (widget *Widget) recentBuilds(pipeline PipelineSettings) ([]Build, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode > 299 { if resp.StatusCode < 200 || resp.StatusCode > 299 {
return nil, fmt.Errorf(resp.Status) return nil, fmt.Errorf(resp.Status)
} }

View File

@ -1,6 +1,5 @@
package buildkite package buildkite
func (widget *Widget) initializeKeyboardControls() { func (widget *Widget) initializeKeyboardControls() {
widget.InitializeHelpTextKeyboardControl(widget.ShowHelp) widget.InitializeCommonControls(widget.Refresh)
widget.InitializeRefreshKeyboardControl(widget.Refresh)
} }

View File

@ -21,8 +21,7 @@ type PipelineSettings struct {
// Settings defines the configuration properties for this module // Settings defines the configuration properties for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
apiKey string `help:"Your Buildkite API Token"` apiKey string `help:"Your Buildkite API Token"`
orgSlug string `help:"Organization Slug"` orgSlug string `help:"Organization Slug"`
pipelines []PipelineSettings `help:"An array of pipelines to get data from"` pipelines []PipelineSettings `help:"An array of pipelines to get data from"`
@ -31,8 +30,7 @@ type Settings struct {
// NewSettingsFromYAML creates a new settings instance from a YAML config block // NewSettingsFromYAML creates a new settings instance from a YAML config block
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
apiKey: ymlConfig.UString("apiKey", os.Getenv("WTF_BUILDKITE_TOKEN")), apiKey: ymlConfig.UString("apiKey", os.Getenv("WTF_BUILDKITE_TOKEN")),
orgSlug: ymlConfig.UString("organizationSlug"), orgSlug: ymlConfig.UString("organizationSlug"),
pipelines: buildPipelineSettings(ymlConfig), pipelines: buildPipelineSettings(ymlConfig),

View File

@ -7,7 +7,12 @@ import (
"github.com/wtfutil/wtf/view" "github.com/wtfutil/wtf/view"
) )
const HelpText = `
Keyboard commands for Buildkite:
`
type Widget struct { type Widget struct {
view.KeyboardWidget
view.TextWidget view.TextWidget
settings *Settings settings *Settings
@ -15,14 +20,17 @@ type Widget struct {
err error err error
} }
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, pages, settings.Common), KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
TextWidget: view.NewTextWidget(app, settings.common),
settings: settings, settings: settings,
} }
widget.initializeKeyboardControls() widget.initializeKeyboardControls()
widget.View.SetInputCapture(widget.InputCapture)
widget.View.SetScrollable(true) widget.View.SetScrollable(true)
widget.KeyboardWidget.SetView(widget.View)
return &widget return &widget
} }

View File

@ -25,7 +25,7 @@ func (widget *Widget) content() (string, string, bool) {
} }
_, _, width, _ := widget.View.GetRect() _, _, width, _ := widget.View.GetRect()
str := widget.settings.PaginationMarker(len(widget.workflows), widget.Idx, width) + "\n" str := widget.settings.common.SigilStr(len(widget.workflows), widget.Idx, width) + "\n"
title := fmt.Sprintf("%s - %s", widget.CommonSettings().Title, widget.title(workflow)) title := fmt.Sprintf("%s - %s", widget.CommonSettings().Title, widget.title(workflow))
str += widget.displayWorkflowRuns(workflow) str += widget.displayWorkflowRuns(workflow)
@ -36,7 +36,7 @@ func (widget *Widget) content() (string, string, bool) {
func (widget *Widget) title(workflow *sdk.Workflow) string { func (widget *Widget) title(workflow *sdk.Workflow) string {
return fmt.Sprintf( return fmt.Sprintf(
"[%s]%s/%s[white]", "[%s]%s/%s[white]",
widget.settings.Colors.TextTheme.Title, widget.settings.common.Colors.TextTheme.Title,
workflow.ProjectKey, workflow.Name, workflow.ProjectKey, workflow.Name,
) )
} }

View File

@ -5,8 +5,7 @@ import (
) )
func (widget *Widget) initializeKeyboardControls() { func (widget *Widget) initializeKeyboardControls() {
widget.InitializeHelpTextKeyboardControl(widget.ShowHelp) widget.InitializeCommonControls(widget.Refresh)
widget.InitializeRefreshKeyboardControl(widget.Refresh)
widget.SetKeyboardChar("j", widget.Next, "Select next workflow") widget.SetKeyboardChar("j", widget.Next, "Select next workflow")
widget.SetKeyboardChar("k", widget.Prev, "Select previous workflow") widget.SetKeyboardChar("k", widget.Prev, "Select previous workflow")

View File

@ -15,8 +15,7 @@ const (
// Settings defines the configuration properties for this module // Settings defines the configuration properties for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
token string `help:"Your CDS API token."` token string `help:"Your CDS API token."`
apiURL string `help:"Your CDS API URL."` apiURL string `help:"Your CDS API URL."`
uiURL string uiURL string
@ -26,14 +25,10 @@ type Settings struct {
// NewSettingsFromYAML creates a new settings instance from a YAML config block // NewSettingsFromYAML creates a new settings instance from a YAML config block
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
token: ymlConfig.UString("token", ymlConfig.UString("token", os.Getenv("CDS_TOKEN"))), token: ymlConfig.UString("token", ymlConfig.UString("token", os.Getenv("CDS_TOKEN"))),
apiURL: ymlConfig.UString("apiURL", os.Getenv("CDS_API_URL")), apiURL: ymlConfig.UString("apiURL", os.Getenv("CDS_API_URL")),
hideTags: utils.ToStrs(ymlConfig.UList("hideTags")), hideTags: utils.ToStrs(ymlConfig.UList("hideTags")),
} }
settings.SetDocumentationPath("cds/favorites")
return &settings return &settings
} }

View File

@ -14,6 +14,7 @@ import (
// Widget define wtf widget to register widget later // Widget define wtf widget to register widget later
type Widget struct { type Widget struct {
view.MultiSourceWidget view.MultiSourceWidget
view.KeyboardWidget
view.TextWidget view.TextWidget
workflows []sdk.Workflow workflows []sdk.Workflow
@ -27,19 +28,22 @@ type Widget struct {
} }
// NewWidget creates a new instance of the widget // NewWidget creates a new instance of the widget
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
MultiSourceWidget: view.NewMultiSourceWidget(settings.Common, "workflow", "workflows"), KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
TextWidget: view.NewTextWidget(tviewApp, pages, settings.Common), MultiSourceWidget: view.NewMultiSourceWidget(settings.common, "workflow", "workflows"),
TextWidget: view.NewTextWidget(app, settings.common),
settings: settings, settings: settings,
} }
widget.initializeKeyboardControls() widget.initializeKeyboardControls()
widget.View.SetRegions(true) widget.View.SetRegions(true)
widget.View.SetInputCapture(widget.InputCapture)
widget.SetDisplayFunction(widget.display) widget.SetDisplayFunction(widget.display)
widget.Unselect() widget.Unselect()
widget.KeyboardWidget.SetView(widget.View)
widget.client = cdsclient.New(cdsclient.Config{ widget.client = cdsclient.New(cdsclient.Config{
Host: settings.apiURL, Host: settings.apiURL,
@ -106,6 +110,11 @@ func (widget *Widget) Refresh() {
widget.display() widget.display()
} }
// HelpText displays the widgets controls
func (widget *Widget) HelpText() string {
return widget.KeyboardWidget.HelpText()
}
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */
func (widget *Widget) buildWorkflowsCollection() []sdk.Workflow { func (widget *Widget) buildWorkflowsCollection() []sdk.Workflow {

View File

@ -23,7 +23,7 @@ func (widget *Widget) content() (string, string, bool) {
filter := widget.currentFilter() filter := widget.currentFilter()
_, _, width, _ := widget.View.GetRect() _, _, width, _ := widget.View.GetRect()
str := widget.settings.PaginationMarker(len(widget.filters), widget.Idx, width) + "\n" str := widget.settings.common.SigilStr(len(widget.filters), widget.Idx, width) + "\n"
str += widget.displayQueue(filter) str += widget.displayQueue(filter)
title := fmt.Sprintf("%s - %s", widget.CommonSettings().Title, widget.title(filter)) title := fmt.Sprintf("%s - %s", widget.CommonSettings().Title, widget.title(filter))
@ -34,7 +34,7 @@ func (widget *Widget) content() (string, string, bool) {
func (widget *Widget) title(filter string) string { func (widget *Widget) title(filter string) string {
return fmt.Sprintf( return fmt.Sprintf(
"[%s]%d - %s[white]", "[%s]%d - %s[white]",
widget.settings.Colors.TextTheme.Title, widget.settings.common.Colors.TextTheme.Title,
widget.maxItems, widget.maxItems,
filter, filter,
) )

View File

@ -5,8 +5,7 @@ import (
) )
func (widget *Widget) initializeKeyboardControls() { func (widget *Widget) initializeKeyboardControls() {
widget.InitializeHelpTextKeyboardControl(widget.ShowHelp) widget.InitializeCommonControls(widget.Refresh)
widget.InitializeRefreshKeyboardControl(widget.Refresh)
widget.SetKeyboardChar("j", widget.Next, "Select next workflow") widget.SetKeyboardChar("j", widget.Next, "Select next workflow")
widget.SetKeyboardChar("k", widget.Prev, "Select previous workflow") widget.SetKeyboardChar("k", widget.Prev, "Select previous workflow")

View File

@ -14,8 +14,7 @@ const (
// Settings defines the configuration properties for this module // Settings defines the configuration properties for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
token string `help:"Your CDS API token."` token string `help:"Your CDS API token."`
apiURL string `help:"Your CDS API URL."` apiURL string `help:"Your CDS API URL."`
uiURL string uiURL string
@ -24,13 +23,9 @@ type Settings struct {
// NewSettingsFromYAML creates a new settings instance from a YAML config block // NewSettingsFromYAML creates a new settings instance from a YAML config block
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
token: ymlConfig.UString("token", ymlConfig.UString("token", os.Getenv("CDS_TOKEN"))), token: ymlConfig.UString("token", ymlConfig.UString("token", os.Getenv("CDS_TOKEN"))),
apiURL: ymlConfig.UString("apiURL", os.Getenv("CDS_API_URL")), apiURL: ymlConfig.UString("apiURL", os.Getenv("CDS_API_URL")),
} }
settings.SetDocumentationPath("cds/queue")
return &settings return &settings
} }

View File

@ -14,6 +14,7 @@ import (
// Widget define wtf widget to register widget later // Widget define wtf widget to register widget later
type Widget struct { type Widget struct {
view.MultiSourceWidget view.MultiSourceWidget
view.KeyboardWidget
view.TextWidget view.TextWidget
filters []string filters []string
@ -27,21 +28,25 @@ type Widget struct {
} }
// NewWidget creates a new instance of the widget // NewWidget creates a new instance of the widget
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
MultiSourceWidget: view.NewMultiSourceWidget(settings.Common, "workflow", "workflows"), KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
TextWidget: view.NewTextWidget(tviewApp, pages, settings.Common), MultiSourceWidget: view.NewMultiSourceWidget(settings.common, "workflow", "workflows"),
TextWidget: view.NewTextWidget(app, settings.common),
settings: settings, settings: settings,
} }
widget.initializeKeyboardControls() widget.initializeKeyboardControls()
widget.View.SetRegions(true) widget.View.SetRegions(true)
widget.View.SetInputCapture(widget.InputCapture)
widget.SetDisplayFunction(widget.display) widget.SetDisplayFunction(widget.display)
widget.Unselect() widget.Unselect()
widget.filters = []string{sdk.StatusWaiting, sdk.StatusBuilding} widget.filters = []string{sdk.StatusWaiting, sdk.StatusBuilding}
widget.KeyboardWidget.SetView(widget.View)
widget.client = cdsclient.New(cdsclient.Config{ widget.client = cdsclient.New(cdsclient.Config{
Host: settings.apiURL, Host: settings.apiURL,
BuitinConsumerAuthenticationToken: settings.token, BuitinConsumerAuthenticationToken: settings.token,
@ -106,6 +111,11 @@ func (widget *Widget) Refresh() {
widget.display() widget.display()
} }
// HelpText displays the widgets controls
func (widget *Widget) HelpText() string {
return widget.KeyboardWidget.HelpText()
}
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */
func (widget *Widget) currentFilter() string { func (widget *Widget) currentFilter() string {

View File

@ -5,8 +5,7 @@ import (
) )
func (widget *Widget) initializeKeyboardControls() { func (widget *Widget) initializeKeyboardControls() {
widget.InitializeHelpTextKeyboardControl(widget.ShowHelp) widget.InitializeCommonControls(widget.Refresh)
widget.InitializeRefreshKeyboardControl(widget.Refresh)
widget.SetKeyboardChar("j", widget.Next, "Select next line") widget.SetKeyboardChar("j", widget.Next, "Select next line")
widget.SetKeyboardChar("k", widget.Prev, "Select previous line") widget.SetKeyboardChar("k", widget.Prev, "Select previous line")

View File

@ -14,8 +14,7 @@ const (
// Settings defines the configuration properties for this module // Settings defines the configuration properties for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
token string `help:"Your CDS API token."` token string `help:"Your CDS API token."`
apiURL string `help:"Your CDS API URL."` apiURL string `help:"Your CDS API URL."`
uiURL string uiURL string
@ -24,13 +23,9 @@ type Settings struct {
// NewSettingsFromYAML creates a new settings instance from a YAML config block // NewSettingsFromYAML creates a new settings instance from a YAML config block
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
token: ymlConfig.UString("token", ymlConfig.UString("token", os.Getenv("CDS_TOKEN"))), token: ymlConfig.UString("token", ymlConfig.UString("token", os.Getenv("CDS_TOKEN"))),
apiURL: ymlConfig.UString("apiURL", os.Getenv("CDS_API_URL")), apiURL: ymlConfig.UString("apiURL", os.Getenv("CDS_API_URL")),
} }
settings.SetDocumentationPath("cds/status")
return &settings return &settings
} }

View File

@ -14,6 +14,7 @@ import (
// Widget define wtf widget to register widget later // Widget define wtf widget to register widget later
type Widget struct { type Widget struct {
view.MultiSourceWidget view.MultiSourceWidget
view.KeyboardWidget
view.TextWidget view.TextWidget
filters []string filters []string
@ -27,21 +28,25 @@ type Widget struct {
} }
// NewWidget creates a new instance of the widget // NewWidget creates a new instance of the widget
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
MultiSourceWidget: view.NewMultiSourceWidget(settings.Common, "workflow", "workflows"), KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
TextWidget: view.NewTextWidget(tviewApp, pages, settings.Common), MultiSourceWidget: view.NewMultiSourceWidget(settings.common, "workflow", "workflows"),
TextWidget: view.NewTextWidget(app, settings.common),
settings: settings, settings: settings,
} }
widget.initializeKeyboardControls() widget.initializeKeyboardControls()
widget.View.SetRegions(true) widget.View.SetRegions(true)
widget.View.SetInputCapture(widget.InputCapture)
widget.SetDisplayFunction(widget.display) widget.SetDisplayFunction(widget.display)
widget.Unselect() widget.Unselect()
widget.filters = []string{sdk.StatusWaiting, sdk.StatusBuilding} widget.filters = []string{sdk.StatusWaiting, sdk.StatusBuilding}
widget.KeyboardWidget.SetView(widget.View)
widget.client = cdsclient.New(cdsclient.Config{ widget.client = cdsclient.New(cdsclient.Config{
Host: settings.apiURL, Host: settings.apiURL,
BuitinConsumerAuthenticationToken: settings.token, BuitinConsumerAuthenticationToken: settings.token,
@ -106,6 +111,11 @@ func (widget *Widget) Refresh() {
widget.display() widget.display()
} }
// HelpText displays the widgets controls
func (widget *Widget) HelpText() string {
return widget.KeyboardWidget.HelpText()
}
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */
func (widget *Widget) openWorkflow() { func (widget *Widget) openWorkflow() {

View File

@ -1,9 +1,7 @@
package circleci package circleci
import ( import (
"bytes"
"fmt" "fmt"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
@ -30,7 +28,7 @@ func (client *Client) BuildsFor() ([]*Build, error) {
return builds, err return builds, err
} }
err = utils.ParseJSON(&builds, bytes.NewReader(resp)) err = utils.ParseJSON(&builds, resp.Body)
if err != nil { if err != nil {
return builds, err return builds, err
} }
@ -44,7 +42,7 @@ var (
circleAPIURL = &url.URL{Scheme: "https", Host: "circleci.com", Path: "/api/v1/"} circleAPIURL = &url.URL{Scheme: "https", Host: "circleci.com", Path: "/api/v1/"}
) )
func (client *Client) circleRequest(path string) ([]byte, error) { func (client *Client) circleRequest(path string) (*http.Response, error) {
params := url.Values{} params := url.Values{}
params.Add("circle-token", client.apiKey) params.Add("circle-token", client.apiKey)
@ -63,15 +61,9 @@ func (client *Client) circleRequest(path string) ([]byte, error) {
return nil, err return nil, err
} }
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode > 299 { if resp.StatusCode < 200 || resp.StatusCode > 299 {
return nil, fmt.Errorf(resp.Status) return nil, fmt.Errorf(resp.Status)
} }
body, err := ioutil.ReadAll(resp.Body) return resp, nil
if err != nil {
return nil, err
}
return body, nil
} }

View File

@ -13,19 +13,17 @@ const (
) )
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
apiKey string `help:"Your CircleCI API token."` apiKey string `help:"Your CircleCI API token."`
numberOfBuilds int `help:"The number of build, 10 by default"`
} }
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_CIRCLE_API_KEY"))), apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_CIRCLE_API_KEY"))),
numberOfBuilds: ymlConfig.UInt("numberOfBuilds", 10),
} }
cfg.ModuleSecret(name, globalConfig, &settings.apiKey).Load() cfg.ModuleSecret(name, globalConfig, &settings.apiKey).Load()

View File

@ -14,9 +14,9 @@ type Widget struct {
settings *Settings settings *Settings
} }
func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, nil, settings.Common), TextWidget: view.NewTextWidget(app, settings.common),
Client: NewClient(settings.apiKey), Client: NewClient(settings.apiKey),
settings: settings, settings: settings,
@ -48,7 +48,7 @@ func (widget *Widget) content() (string, string, bool) {
str = err.Error() str = err.Error()
} else { } else {
for idx, build := range builds { for idx, build := range builds {
if idx > widget.settings.numberOfBuilds { if idx > 10 {
break break
} }

View File

@ -13,7 +13,7 @@ const (
// Settings defines the configuration properties for this module // Settings defines the configuration properties for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
dateFormat string `help:"The format of the date string for all clocks." values:"Any valid Go date layout which is handled by Time.Format. Defaults to Jan 2."` dateFormat string `help:"The format of the date string for all clocks." values:"Any valid Go date layout which is handled by Time.Format. Defaults to Jan 2."`
timeFormat string `help:"The format of the time string for all clocks." values:"Any valid Go time layout which is handled by Time.Format. Defaults to 15:04 MST."` timeFormat string `help:"The format of the time string for all clocks." values:"Any valid Go time layout which is handled by Time.Format. Defaults to 15:04 MST."`
@ -24,7 +24,7 @@ type Settings struct {
// NewSettingsFromYAML creates a new settings instance from a YAML config block // NewSettingsFromYAML creates a new settings instance from a YAML config block
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
dateFormat: ymlConfig.UString("dateFormat", utils.SimpleDateFormat), dateFormat: ymlConfig.UString("dateFormat", utils.SimpleDateFormat),
timeFormat: ymlConfig.UString("timeFormat", utils.SimpleTimeFormat), timeFormat: ymlConfig.UString("timeFormat", utils.SimpleTimeFormat),

View File

@ -8,16 +8,18 @@ import (
type Widget struct { type Widget struct {
view.TextWidget view.TextWidget
app *tview.Application
clockColl ClockCollection clockColl ClockCollection
dateFormat string dateFormat string
timeFormat string timeFormat string
settings *Settings settings *Settings
} }
func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, nil, settings.Common), TextWidget: view.NewTextWidget(app, settings.common),
app: app,
settings: settings, settings: settings,
dateFormat: settings.dateFormat, dateFormat: settings.dateFormat,
timeFormat: settings.timeFormat, timeFormat: settings.timeFormat,
@ -32,8 +34,10 @@ func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget {
// Refresh updates the onscreen contents of the widget // Refresh updates the onscreen contents of the widget
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
widget.app.QueueUpdateDraw(func() {
sortedClocks := widget.clockColl.Sorted(widget.settings.sort) sortedClocks := widget.clockColl.Sorted(widget.settings.sort)
widget.display(sortedClocks, widget.dateFormat, widget.timeFormat) widget.display(sortedClocks, widget.dateFormat, widget.timeFormat)
})
} }
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */

View File

@ -13,7 +13,7 @@ const (
// Settings for the cmdrunner widget // Settings for the cmdrunner widget
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
args []string `help:"The arguments to the command, with each item as an element in an array. Example: for curl -I cisco.com, the arguments array would be ['-I', 'cisco.com']."` args []string `help:"The arguments to the command, with each item as an element in an array. Example: for curl -I cisco.com, the arguments array would be ['-I', 'cisco.com']."`
cmd string `help:"The terminal command to be run, withouth the arguments. Ie: ping, whoami, curl."` cmd string `help:"The terminal command to be run, withouth the arguments. Ie: ping, whoami, curl."`
@ -29,7 +29,7 @@ type Settings struct {
// NewSettingsFromYAML loads the cmdrunner portion of the WTF config // NewSettingsFromYAML loads the cmdrunner portion of the WTF config
func NewSettingsFromYAML(name string, moduleConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, moduleConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, moduleConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, moduleConfig, globalConfig),
args: utils.ToStrs(moduleConfig.UList("args")), args: utils.ToStrs(moduleConfig.UList("args")),
cmd: moduleConfig.UString("cmd"), cmd: moduleConfig.UString("cmd"),

View File

@ -27,9 +27,9 @@ type Widget struct {
} }
// NewWidget creates a new instance of the widget // NewWidget creates a new instance of the widget
func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, nil, settings.Common), TextWidget: view.NewTextWidget(app, settings.common),
settings: settings, settings: settings,
buffer: &bytes.Buffer{}, buffer: &bytes.Buffer{},

View File

@ -1,14 +0,0 @@
package covid
// Cases holds the latest cases
type Cases struct {
Latest Latest `json:"latest"`
}
// Latest holds the number of global confirmed cases and deaths due to Covid
type Latest struct {
Confirmed int `json:"confirmed"`
Deaths int `json:"deaths"`
// Not currently used but holds information about the country
Locations []interface{} `json:"locations,omitempty"`
}

View File

@ -1,24 +0,0 @@
package covid
import (
"encoding/json"
"testing"
)
func Test_CasesInclude(t *testing.T) {
// The api does not seem to return the correct recovered numbers
responseBody := `{"latest":{"confirmed":3093619,"deaths":73018,"recovered":0},"locations":[]}`
latestData := Cases{}
_ = json.Unmarshal([]byte(responseBody), &latestData)
expectedConfirmed := 3093619
expectedDeaths := 73018
actualConfirmed := latestData.Latest.Confirmed
actualDeaths := latestData.Latest.Deaths
if expectedConfirmed != actualConfirmed {
t.Errorf("\nexpected: %v\n got: %v", expectedConfirmed, actualConfirmed)
}
if expectedDeaths != actualDeaths {
t.Errorf("\nexpected: %v\n got: %v", expectedDeaths, actualDeaths)
}
}

View File

@ -1,58 +0,0 @@
package covid
import (
"fmt"
"net/http"
"github.com/wtfutil/wtf/utils"
)
const covidTrackerAPIURL = "https://coronavirus-tracker-api.herokuapp.com/v2/"
// LatestCases queries the /latest endpoint, does not take any query parameters
func LatestCases() (*Cases, error) {
latestURL := covidTrackerAPIURL + "latest"
resp, err := http.Get(latestURL)
if resp.StatusCode != 200 {
return nil, fmt.Errorf(resp.Status)
}
if err != nil {
return nil, err
}
defer func() { _ = resp.Body.Close() }()
var latestGlobalCases Cases
err = utils.ParseJSON(&latestGlobalCases, resp.Body)
if err != nil {
return nil, err
}
return &latestGlobalCases, nil
}
// LatestCountryCases queries the /locations endpoint, takes a query parameter: the country code
func (widget *Widget) LatestCountryCases(countries []interface{}) ([]*Cases, error) {
countriesCovidData := []*Cases{}
for _, name := range countries {
countryURL := covidTrackerAPIURL + "locations?source=jhu&country_code=" + name.(string)
resp, err := http.Get(countryURL)
if resp.StatusCode != 200 {
return nil, fmt.Errorf(resp.Status)
}
if err != nil {
return nil, err
}
defer func() { _ = resp.Body.Close() }()
var latestCountryCases Cases
err = utils.ParseJSON(&latestCountryCases, resp.Body)
if err != nil {
return nil, err
}
// add stats for each country to the slice
countriesCovidData = append(countriesCovidData, &latestCountryCases)
}
return countriesCovidData, nil
}

View File

@ -1,31 +0,0 @@
package covid
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const (
defaultFocusable = false
defaultTitle = "Covid tracker"
)
// Settings is the struct for this module's settings
type Settings struct {
*cfg.Common
countries []interface{} `help:"Countries (codes) from which to retrieve stats."`
}
// NewSettingsFromYAML returns the settings from the config yaml file
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
// List of countries to retrieve stats from
countries: ymlConfig.UList("countries"),
}
return &settings
}

View File

@ -1,86 +0,0 @@
package covid
import (
"fmt"
"github.com/rivo/tview"
"github.com/wtfutil/wtf/view"
)
// Widget is the struct that defines this module widget
type Widget struct {
view.TextWidget
settings *Settings
err error
}
// NewWidget creates a new widget for this module
func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := &Widget{
TextWidget: view.NewTextWidget(app, nil, settings.Common),
settings: settings,
}
widget.View.SetScrollable(true)
return widget
}
// Refresh checks if this module widget is disabled
func (widget *Widget) Refresh() {
if widget.Disabled() {
return
}
widget.Redraw(widget.content)
}
// Render renders this module widget
func (widget *Widget) Render() {
widget.Redraw(widget.content)
}
// Display stats based on the user's locale
func (widget *Widget) displayStats(cases int) string {
prntr, err := widget.settings.LocalizedPrinter()
if err != nil {
return err.Error()
}
return prntr.Sprintf("%d", cases)
}
func (widget *Widget) content() (string, string, bool) {
title := defaultTitle
if widget.CommonSettings().Title != "" {
title = widget.CommonSettings().Title
}
cases, err := LatestCases()
var covidStats string
if err != nil {
widget.err = err
} else {
// Display global stats
covidStats = fmt.Sprintf("[%s]Global[white]\n", widget.settings.Colors.Subheading)
covidStats += fmt.Sprintf("%s: %s\n", "Confirmed", widget.displayStats(cases.Latest.Confirmed))
covidStats += fmt.Sprintf("%s: %s\n", "Deaths", widget.displayStats(cases.Latest.Deaths))
}
// Retrieve country stats if country codes are set in the config
if len(widget.settings.countries) > 0 {
countryCases, err := widget.LatestCountryCases(widget.settings.countries)
if err != nil {
widget.err = err
} else {
for i, name := range countryCases {
covidStats += fmt.Sprintf("[%s]Country[white]: %s\n", widget.settings.Colors.Subheading, widget.settings.countries[i])
covidStats += fmt.Sprintf("%s: %s\n", "Confirmed", widget.displayStats(name.Latest.Confirmed))
covidStats += fmt.Sprintf("%s: %s\n", "Deaths", widget.displayStats(name.Latest.Deaths))
}
}
}
return title, covidStats, true
}

View File

@ -32,16 +32,15 @@ type summary struct {
} }
type Settings struct { type Settings struct {
*cfg.Common
colors colors
common *cfg.Common
summary summary
} }
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
} }
settings.colors.base.name = ymlConfig.UString("colors.base.name") settings.colors.base.name = ymlConfig.UString("colors.base.name")
@ -63,7 +62,5 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
settings.summary.currencies[key] = currency settings.summary.currencies[key] = currency
} }
settings.SetDocumentationPath("cryptocurrencies/bittrex")
return &settings return &settings
} }

View File

@ -29,9 +29,9 @@ type Widget struct {
} }
// NewWidget Make new instance of widget // NewWidget Make new instance of widget
func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, nil, settings.Common), TextWidget: view.NewTextWidget(app, settings.common),
settings: settings, settings: settings,
summaryList: summaryList{}, summaryList: summaryList{},

View File

@ -17,9 +17,8 @@ type colors struct {
} }
type Settings struct { type Settings struct {
*cfg.Common
colors colors
common *cfg.Common
deviceToken string deviceToken string
displayHoldings bool displayHoldings bool
@ -28,13 +27,11 @@ type Settings struct {
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
deviceToken: ymlConfig.UString("device_token"), deviceToken: ymlConfig.UString("device_token"),
displayHoldings: ymlConfig.UBool("displayHoldings", true), displayHoldings: ymlConfig.UBool("displayHoldings", true),
} }
settings.SetDocumentationPath("cryptocurrencies/blockfolio")
return &settings return &settings
} }

View File

@ -18,9 +18,9 @@ type Widget struct {
settings *Settings settings *Settings
} }
func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, nil, settings.Common), TextWidget: view.NewTextWidget(app, settings.common),
device_token: settings.deviceToken, device_token: settings.deviceToken,
settings: settings, settings: settings,

View File

@ -38,16 +38,15 @@ type currency struct {
} }
type Settings struct { type Settings struct {
*cfg.Common
colors colors
common *cfg.Common
currencies map[string]*currency currencies map[string]*currency
} }
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
} }
settings.colors.from.name = ymlConfig.UString("colors.from.name") settings.colors.from.name = ymlConfig.UString("colors.from.name")

View File

@ -137,7 +137,7 @@ func makeRequest(currency *fromCurrency) *http.Request {
tsyms += fmt.Sprintf("%s,", to.name) tsyms += fmt.Sprintf("%s,", to.name)
} }
url := fmt.Sprintf("%s?fsym=%s&tsyms=%s", baseURL, currency.name, tsyms) url := fmt.Sprintf("%s?fsym=%s&tsyms=%s", baseURL, currency.name, "")
request, _ := http.NewRequest("GET", url, nil) request, _ := http.NewRequest("GET", url, nil)
return request return request

View File

@ -35,9 +35,8 @@ type colors struct {
} }
type Settings struct { type Settings struct {
*cfg.Common
colors colors
common *cfg.Common
currencies map[string]interface{} currencies map[string]interface{}
top map[string]interface{} top map[string]interface{}
@ -51,7 +50,7 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
top, _ := ymlConfig.Map("top") top, _ := ymlConfig.Map("top")
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
currencies: currencies, currencies: currencies,
top: top, top: top,
@ -73,7 +72,5 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
settings.colors.top.to.field = ymlConfig.UString("colors.top.to.field") settings.colors.top.to.field = ymlConfig.UString("colors.top.to.field")
settings.colors.top.to.value = ymlConfig.UString("colors.top.to.value") settings.colors.top.to.value = ymlConfig.UString("colors.top.to.value")
settings.SetDocumentationPath("cryptocurrencies/cryptolive")
return &settings return &settings
} }

View File

@ -39,16 +39,15 @@ type currency struct {
} }
type Settings struct { type Settings struct {
*cfg.Common
colors colors
common *cfg.Common
top map[string]*currency top map[string]*currency
} }
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
} }
settings.colors.from.name = ymlConfig.UString("colors.from.name") settings.colors.from.name = ymlConfig.UString("colors.from.name")

View File

@ -20,9 +20,9 @@ type Widget struct {
} }
// NewWidget Make new instance of widget // NewWidget Make new instance of widget
func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, nil, settings.Common), TextWidget: view.NewTextWidget(app, settings.common),
priceWidget: price.NewWidget(settings.priceSettings), priceWidget: price.NewWidget(settings.priceSettings),
toplistWidget: toplist.NewWidget(settings.toplistSettings), toplistWidget: toplist.NewWidget(settings.toplistSettings),

View File

@ -5,7 +5,7 @@ import (
datadog "github.com/zorkian/go-datadog-api" datadog "github.com/zorkian/go-datadog-api"
) )
// Monitors returns a list of Datadog monitors // Monitors returns a list of newrelic monitors
func (widget *Widget) Monitors() ([]datadog.Monitor, error) { func (widget *Widget) Monitors() ([]datadog.Monitor, error) {
client := datadog.NewClient( client := datadog.NewClient(
widget.settings.apiKey, widget.settings.apiKey,

View File

@ -5,8 +5,7 @@ import (
) )
func (widget *Widget) initializeKeyboardControls() { func (widget *Widget) initializeKeyboardControls() {
widget.InitializeHelpTextKeyboardControl(widget.ShowHelp) widget.InitializeCommonControls(widget.Refresh)
widget.InitializeRefreshKeyboardControl(widget.Refresh)
widget.SetKeyboardChar("j", widget.Next, "Select next item") widget.SetKeyboardChar("j", widget.Next, "Select next item")
widget.SetKeyboardChar("k", widget.Prev, "Select previous item") widget.SetKeyboardChar("k", widget.Prev, "Select previous item")

View File

@ -13,7 +13,7 @@ const (
) )
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
apiKey string `help:"Your Datadog API key."` apiKey string `help:"Your Datadog API key."`
applicationKey string `help:"Your Datadog Application key."` applicationKey string `help:"Your Datadog Application key."`
@ -23,7 +23,7 @@ type Settings struct {
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_DATADOG_API_KEY"))), apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_DATADOG_API_KEY"))),
applicationKey: ymlConfig.UString("applicationKey", os.Getenv("WTF_DATADOG_APPLICATION_KEY")), applicationKey: ymlConfig.UString("applicationKey", os.Getenv("WTF_DATADOG_APPLICATION_KEY")),

View File

@ -10,6 +10,7 @@ import (
) )
type Widget struct { type Widget struct {
view.KeyboardWidget
view.ScrollableWidget view.ScrollableWidget
monitors []datadog.Monitor monitors []datadog.Monitor
@ -17,15 +18,19 @@ type Widget struct {
err error err error
} }
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
ScrollableWidget: view.NewScrollableWidget(tviewApp, pages, settings.Common), KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
ScrollableWidget: view.NewScrollableWidget(app, settings.common),
settings: settings, settings: settings,
} }
widget.SetRenderFunction(widget.Render) widget.SetRenderFunction(widget.Render)
widget.initializeKeyboardControls() widget.initializeKeyboardControls()
widget.View.SetInputCapture(widget.InputCapture)
widget.KeyboardWidget.SetView(widget.View)
return &widget return &widget
} }
@ -61,6 +66,10 @@ func (widget *Widget) Render() {
widget.Redraw(widget.content) widget.Redraw(widget.content)
} }
func (widget *Widget) HelpText() string {
return widget.KeyboardWidget.HelpText()
}
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */
func (widget *Widget) content() (string, string, bool) { func (widget *Widget) content() (string, string, bool) {
@ -78,7 +87,7 @@ func (widget *Widget) content() (string, string, bool) {
" %s\n", " %s\n",
fmt.Sprintf( fmt.Sprintf(
"[%s]Triggered Monitors[white]", "[%s]Triggered Monitors[white]",
widget.settings.Colors.Subheading, widget.settings.common.Colors.Subheading,
), ),
) )
for idx, triggeredMonitor := range triggeredMonitors { for idx, triggeredMonitor := range triggeredMonitors {

View File

@ -3,8 +3,7 @@ package devto
import "github.com/gdamore/tcell" import "github.com/gdamore/tcell"
func (widget *Widget) initializeKeyboardControls() { func (widget *Widget) initializeKeyboardControls() {
widget.InitializeHelpTextKeyboardControl(widget.ShowHelp) widget.InitializeCommonControls(widget.Refresh)
widget.InitializeRefreshKeyboardControl(widget.Refresh)
widget.SetKeyboardChar("d", widget.Next, "Select next item") widget.SetKeyboardChar("d", widget.Next, "Select next item")
widget.SetKeyboardChar("a", widget.Prev, "Select previous item") widget.SetKeyboardChar("a", widget.Prev, "Select previous item")

View File

@ -13,7 +13,7 @@ const (
// Settings defines the configuration options for this module // Settings defines the configuration options for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
numberOfArticles int `help:"Number of stories to show. Default is 10" optional:"true"` numberOfArticles int `help:"Number of stories to show. Default is 10" optional:"true"`
contentTag string `help:"List articles from a specific tag. Default is empty" optional:"true"` contentTag string `help:"List articles from a specific tag. Default is empty" optional:"true"`
@ -24,8 +24,7 @@ type Settings struct {
// NewSettingsFromYAML creates and returns an instance of Settings with configuration options populated // NewSettingsFromYAML creates and returns an instance of Settings with configuration options populated
func NewSettingsFromYAML(name string, yamlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, yamlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, yamlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, yamlConfig, globalConfig),
numberOfArticles: yamlConfig.UInt("numberOfArticles", 10), numberOfArticles: yamlConfig.UInt("numberOfArticles", 10),
contentTag: yamlConfig.UString("contentTag", ""), contentTag: yamlConfig.UString("contentTag", ""),
contentUsername: yamlConfig.UString("contentUsername", ""), contentUsername: yamlConfig.UString("contentUsername", ""),

View File

@ -12,16 +12,17 @@ import (
) )
type Widget struct { type Widget struct {
view.KeyboardWidget
view.ScrollableWidget view.ScrollableWidget
articles []devto.ListedArticle articles []devto.ListedArticle
settings *Settings settings *Settings
err error err error
} }
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := &Widget{ widget := &Widget{
ScrollableWidget: view.NewScrollableWidget(tviewApp, pages, settings.Common), KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
ScrollableWidget: view.NewScrollableWidget(app, settings.common),
settings: settings, settings: settings,
} }
@ -29,6 +30,9 @@ func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settin
widget.SetRenderFunction(widget.Render) widget.SetRenderFunction(widget.Render)
widget.View.SetScrollable(true) widget.View.SetScrollable(true)
widget.initializeKeyboardControls() widget.initializeKeyboardControls()
widget.View.SetInputCapture(widget.InputCapture)
widget.KeyboardWidget.SetView(widget.View)
return widget return widget
} }

View File

@ -12,7 +12,7 @@ const (
// Settings defines the configuration properties for this module // Settings defines the configuration properties for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
color string `help:"The color of the clock."` color string `help:"The color of the clock."`
font string `help:"The font of the clock." values:"bigfont or digitalfont"` font string `help:"The font of the clock." values:"bigfont or digitalfont"`
@ -23,7 +23,7 @@ type Settings struct {
// NewSettingsFromYAML creates a new settings instance from a YAML config block // NewSettingsFromYAML creates a new settings instance from a YAML config block
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
color: ymlConfig.UString("color"), color: ymlConfig.UString("color"),
font: ymlConfig.UString("font"), font: ymlConfig.UString("font"),

View File

@ -9,14 +9,16 @@ import (
type Widget struct { type Widget struct {
view.TextWidget view.TextWidget
app *tview.Application
settings *Settings settings *Settings
} }
// NewWidget creates a new widget using settings // NewWidget creates a new widget using settings
func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, nil, settings.Common), TextWidget: view.NewTextWidget(app, settings.common),
app: app,
settings: settings, settings: settings,
} }

View File

@ -20,7 +20,7 @@ func (widget *Widget) content() (string, string, bool) {
return title, " no columns defined", false return title, " no columns defined", false
} }
str := fmt.Sprintf(" [::b][%s]", widget.settings.Colors.Subheading) str := fmt.Sprintf(" [::b][%s]", widget.settings.common.Colors.Subheading)
for _, colName := range columnSet { for _, colName := range columnSet {
truncName := utils.Truncate(colName, maxColWidth, false) truncName := utils.Truncate(colName, maxColWidth, false)

View File

@ -3,8 +3,7 @@ package digitalocean
import "github.com/gdamore/tcell" import "github.com/gdamore/tcell"
func (widget *Widget) initializeKeyboardControls() { func (widget *Widget) initializeKeyboardControls() {
widget.InitializeHelpTextKeyboardControl(widget.ShowHelp) widget.InitializeCommonControls(widget.Refresh)
widget.InitializeRefreshKeyboardControl(widget.Refresh)
widget.SetKeyboardChar("?", widget.showInfo, "Show info about the selected droplet") widget.SetKeyboardChar("?", widget.showInfo, "Show info about the selected droplet")

View File

@ -24,7 +24,7 @@ var defaultColumns = []interface{}{
// Settings defines the configuration properties for this module // Settings defines the configuration properties for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
apiKey string `help:"Your DigitalOcean API key."` apiKey string `help:"Your DigitalOcean API key."`
columns []string `help:"A list of the droplet properties to display."` columns []string `help:"A list of the droplet properties to display."`
@ -35,7 +35,7 @@ type Settings struct {
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_DIGITALOCEAN_API_KEY"))), apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_DIGITALOCEAN_API_KEY"))),
columns: utils.ToStrs(ymlConfig.UList("columns", defaultColumns)), columns: utils.ToStrs(ymlConfig.UList("columns", defaultColumns)),

View File

@ -30,6 +30,7 @@ func (t *tokenSource) Token() (*oauth2.Token, error) {
// Widget is the container for droplet data // Widget is the container for droplet data
type Widget struct { type Widget struct {
view.KeyboardWidget
view.ScrollableWidget view.ScrollableWidget
app *tview.Application app *tview.Application
@ -42,19 +43,22 @@ type Widget struct {
} }
// NewWidget creates a new instance of a widget // NewWidget creates a new instance of a widget
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
ScrollableWidget: view.NewScrollableWidget(tviewApp, pages, settings.Common), KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
ScrollableWidget: view.NewScrollableWidget(app, settings.common),
app: tviewApp, app: app,
pages: pages, pages: pages,
settings: settings, settings: settings,
} }
widget.initializeKeyboardControls() widget.initializeKeyboardControls()
widget.View.SetInputCapture(widget.InputCapture)
widget.View.SetScrollable(true) widget.View.SetScrollable(true)
widget.KeyboardWidget.SetView(widget.View)
widget.SetRenderFunction(widget.display) widget.SetRenderFunction(widget.display)
widget.createClient() widget.createClient()
@ -75,6 +79,11 @@ func (widget *Widget) Fetch() error {
return err return err
} }
// HelpText returns the help text for this widget
func (widget *Widget) HelpText() string {
return widget.KeyboardWidget.HelpText()
}
// Next selects the next item in the list // Next selects the next item in the list
func (widget *Widget) Next() { func (widget *Widget) Next() {
widget.ScrollableWidget.Next() widget.ScrollableWidget.Next()

View File

@ -41,13 +41,13 @@ func (widget *Widget) getSystemInfo() string {
}{ }{
{ {
name: "name:", name: "name:",
value: fmt.Sprintf("[%s]%s", widget.settings.Colors.RowTheme.EvenForeground, info.Name), value: fmt.Sprintf("[%s]%s", widget.settings.common.Colors.RowTheme.EvenForeground, info.Name),
}, { }, {
name: "version:", name: "version:",
value: fmt.Sprintf("[%s]%s", widget.settings.Colors.RowTheme.EvenForeground, info.ServerVersion), value: fmt.Sprintf("[%s]%s", widget.settings.common.Colors.RowTheme.EvenForeground, info.ServerVersion),
}, { }, {
name: "root:", name: "root:",
value: fmt.Sprintf("[%s]%s", widget.settings.Colors.RowTheme.EvenForeground, info.DockerRootDir), value: fmt.Sprintf("[%s]%s", widget.settings.common.Colors.RowTheme.EvenForeground, info.DockerRootDir),
}, },
{ {
name: "containers:", name: "containers:",
@ -57,15 +57,15 @@ func (widget *Widget) getSystemInfo() string {
}, },
{ {
name: "images:", name: "images:",
value: fmt.Sprintf("[%s]%d", widget.settings.Colors.RowTheme.EvenForeground, info.Images), value: fmt.Sprintf("[%s]%d", widget.settings.common.Colors.RowTheme.EvenForeground, info.Images),
}, },
{ {
name: "volumes:", name: "volumes:",
value: fmt.Sprintf("[%s]%v", widget.settings.Colors.RowTheme.EvenForeground, len(diskUsage.Volumes)), value: fmt.Sprintf("[%s]%v", widget.settings.common.Colors.RowTheme.EvenForeground, len(diskUsage.Volumes)),
}, },
{ {
name: "memory limit:", name: "memory limit:",
value: fmt.Sprintf("[%s]%s", widget.settings.Colors.RowTheme.EvenForeground, humanize.Bytes(uint64(info.MemTotal))), value: fmt.Sprintf("[%s]%s", widget.settings.common.Colors.RowTheme.EvenForeground, humanize.Bytes(uint64(info.MemTotal))),
}, },
{ {
name: "disk usage:", name: "disk usage:",
@ -76,19 +76,19 @@ func (widget *Widget) getSystemInfo() string {
[%s]* [::b]total: [%s]%s[::-] [%s]* [::b]total: [%s]%s[::-]
`, `,
widget.settings.labelColor, widget.settings.labelColor,
widget.settings.Colors.RowTheme.EvenForeground, widget.settings.common.Colors.RowTheme.EvenForeground,
humanize.Bytes(uint64(duContainer)), humanize.Bytes(uint64(duContainer)),
widget.settings.labelColor, widget.settings.labelColor,
widget.settings.Colors.RowTheme.EvenForeground, widget.settings.common.Colors.RowTheme.EvenForeground,
humanize.Bytes(uint64(duImg)), humanize.Bytes(uint64(duImg)),
widget.settings.labelColor, widget.settings.labelColor,
widget.settings.Colors.RowTheme.EvenForeground, widget.settings.common.Colors.RowTheme.EvenForeground,
humanize.Bytes(uint64(duVol)), humanize.Bytes(uint64(duVol)),
widget.settings.labelColor, widget.settings.labelColor,
widget.settings.Colors.RowTheme.EvenForeground, widget.settings.common.Colors.RowTheme.EvenForeground,
humanize.Bytes(uint64(duContainer+duImg+duVol))), humanize.Bytes(uint64(duContainer+duImg+duVol))),
}, },
} }

View File

@ -12,15 +12,14 @@ const (
// Settings defines the configuration options for this module // Settings defines the configuration options for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
labelColor string labelColor string
} }
// NewSettingsFromYAML creates and returns an instance of Settings with configuration options populated // NewSettingsFromYAML creates and returns an instance of Settings with configuration options populated
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
labelColor: ymlConfig.UString("labelColor", "white"), labelColor: ymlConfig.UString("labelColor", "white"),
} }

View File

@ -16,9 +16,9 @@ type Widget struct {
displayBuffer string displayBuffer string
} }
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(tviewApp, pages, settings.Common), TextWidget: view.NewTextWidget(app, settings.common),
settings: settings, settings: settings,
} }
@ -56,11 +56,11 @@ func (widget *Widget) refreshDisplayBuffer() {
widget.displayBuffer = "" widget.displayBuffer = ""
widget.displayBuffer += fmt.Sprintf("[%s] System[white]\n", widget.settings.Colors.Subheading) widget.displayBuffer += fmt.Sprintf("[%s] System[white]\n", widget.settings.common.Colors.Subheading)
widget.displayBuffer += widget.getSystemInfo() widget.displayBuffer += widget.getSystemInfo()
widget.displayBuffer += "\n" widget.displayBuffer += "\n"
widget.displayBuffer += fmt.Sprintf("[%s] Containers[white]\n", widget.settings.Colors.Subheading) widget.displayBuffer += fmt.Sprintf("[%s] Containers[white]\n", widget.settings.common.Colors.Subheading)
widget.displayBuffer += widget.getContainerStates() widget.displayBuffer += widget.getContainerStates()
} }

View File

@ -13,7 +13,7 @@ const (
// Settings defines the configuration properties for this module // Settings defines the configuration properties for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
precision int `help:"How many decimal places to display." optional:"true"` precision int `help:"How many decimal places to display." optional:"true"`
@ -24,7 +24,7 @@ type Settings struct {
// NewSettingsFromYAML creates a new settings instance from a YAML config block // NewSettingsFromYAML creates a new settings instance from a YAML config block
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
precision: ymlConfig.UInt("precision", 7), precision: ymlConfig.UInt("precision", 7),

View File

@ -18,9 +18,9 @@ type Widget struct {
err error err error
} }
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
ScrollableWidget: view.NewScrollableWidget(tviewApp, pages, settings.Common), ScrollableWidget: view.NewScrollableWidget(app, settings.common),
settings: settings, settings: settings,
} }

View File

@ -3,8 +3,7 @@ package feedreader
import "github.com/gdamore/tcell" import "github.com/gdamore/tcell"
func (widget *Widget) initializeKeyboardControls() { func (widget *Widget) initializeKeyboardControls() {
widget.InitializeHelpTextKeyboardControl(widget.ShowHelp) widget.InitializeCommonControls(widget.Refresh)
widget.InitializeRefreshKeyboardControl(widget.Refresh)
widget.SetKeyboardChar("j", widget.Next, "Select next item") widget.SetKeyboardChar("j", widget.Next, "Select next item")
widget.SetKeyboardChar("k", widget.Prev, "Select previous item") widget.SetKeyboardChar("k", widget.Prev, "Select previous item")

View File

@ -13,7 +13,7 @@ const (
// Settings defines the configuration properties for this module // Settings defines the configuration properties for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
feeds []string `help:"An array of RSS and Atom feed URLs"` feeds []string `help:"An array of RSS and Atom feed URLs"`
feedLimit int `help:"The maximum number of stories to display for each feed"` feedLimit int `help:"The maximum number of stories to display for each feed"`
@ -22,7 +22,7 @@ type Settings struct {
// NewSettingsFromYAML creates a new settings instance from a YAML config block // NewSettingsFromYAML creates a new settings instance from a YAML config block
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := &Settings{ settings := &Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
feeds: utils.ToStrs(ymlConfig.UList("feeds")), feeds: utils.ToStrs(ymlConfig.UList("feeds")),
feedLimit: ymlConfig.UInt("feedLimit", -1), feedLimit: ymlConfig.UInt("feedLimit", -1),

View File

@ -28,6 +28,7 @@ type FeedItem struct {
// Widget is the container for RSS and Atom data // Widget is the container for RSS and Atom data
type Widget struct { type Widget struct {
view.KeyboardWidget
view.ScrollableWidget view.ScrollableWidget
stories []*FeedItem stories []*FeedItem
@ -63,9 +64,10 @@ func getShowText(feedItem *FeedItem, showType ShowType) string {
} }
// NewWidget creates a new instance of a widget // NewWidget creates a new instance of a widget
func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settings) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := &Widget{ widget := &Widget{
ScrollableWidget: view.NewScrollableWidget(tviewApp, pages, settings.Common), KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
ScrollableWidget: view.NewScrollableWidget(app, settings.common),
parser: gofeed.NewParser(), parser: gofeed.NewParser(),
settings: settings, settings: settings,
@ -74,6 +76,9 @@ func NewWidget(tviewApp *tview.Application, pages *tview.Pages, settings *Settin
widget.SetRenderFunction(widget.Render) widget.SetRenderFunction(widget.Render)
widget.initializeKeyboardControls() widget.initializeKeyboardControls()
widget.View.SetInputCapture(widget.InputCapture)
widget.KeyboardWidget.SetView(widget.View)
return widget return widget
} }
@ -165,7 +170,7 @@ func (widget *Widget) content() (string, string, bool) {
// Grays out viewed items in the list, while preserving background highlighting when selected // Grays out viewed items in the list, while preserving background highlighting when selected
rowColor = "gray" rowColor = "gray"
if idx == widget.Selected { if idx == widget.Selected {
rowColor = fmt.Sprintf("gray:%s", widget.settings.Colors.RowTheme.HighlightedBackground) rowColor = fmt.Sprintf("gray:%s", widget.settings.common.Colors.RowTheme.HighlightedBackground)
} }
} }

View File

@ -70,7 +70,6 @@ func (client *Client) finnhubRequest(symbol string) (*http.Response, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode > 299 { if resp.StatusCode < 200 || resp.StatusCode > 299 {
return nil, fmt.Errorf(resp.Status) return nil, fmt.Errorf(resp.Status)

View File

@ -0,0 +1,25 @@
package finnhub
import (
"fmt"
"testing"
)
func TestFinnhubClient(t *testing.T) {
testClient := &Client{
symbols: []string{
"AAPL",
"MSFT",
},
apiKey: "",
}
r, err := testClient.Getquote()
if err != nil {
fmt.Println(err)
}
fmt.Println(r[0].Stock, r[0].C)
fmt.Println(r[1].Stock, r[1].C)
}

View File

@ -15,8 +15,7 @@ const (
// Settings defines the configuration properties for this module // Settings defines the configuration properties for this module
type Settings struct { type Settings struct {
*cfg.Common common *cfg.Common
apiKey string `help:"Your finnhub API token."` apiKey string `help:"Your finnhub API token."`
symbols []string `help:"An array of stocks symbols (i.e. AAPL, MSFT)"` symbols []string `help:"An array of stocks symbols (i.e. AAPL, MSFT)"`
} }
@ -25,7 +24,7 @@ type Settings struct {
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{ settings := Settings{
Common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_FINNHUB_API_KEY"))), apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_FINNHUB_API_KEY"))),
symbols: utils.ToStrs(ymlConfig.UList("symbols")), symbols: utils.ToStrs(ymlConfig.UList("symbols")),

View File

@ -3,7 +3,7 @@ package finnhub
import ( import (
"fmt" "fmt"
"github.com/jedib0t/go-pretty/v6/table" "github.com/jedib0t/go-pretty/table"
"github.com/rivo/tview" "github.com/rivo/tview"
"github.com/wtfutil/wtf/view" "github.com/wtfutil/wtf/view"
) )
@ -17,10 +17,10 @@ type Widget struct {
} }
// NewWidget .. // NewWidget ..
func NewWidget(tviewApp *tview.Application, settings *Settings) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: view.NewTextWidget(app, settings.common),
Client: NewClient(settings.symbols, settings.apiKey), Client: NewClient(settings.symbols, settings.apiKey),
TextWidget: view.NewTextWidget(tviewApp, nil, settings.Common),
settings: settings, settings: settings,
} }

Some files were not shown because too many files have changed in this diff Show More