mirror of
https://github.com/Threnklyn/jira.git
synced 2026-06-13 16:13:34 +02:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e841270b83 | |||
| 2ededeeaf7 | |||
| 00cba793ad | |||
| fb43753c31 | |||
| 5085a14494 | |||
| 5da04c1f86 | |||
| 052e038d73 | |||
| a7f1323f34 | |||
| 8d27b736ca | |||
| c3c008e53d | |||
| 608e586d1c | |||
| 2c552ac530 | |||
| 1d269183c3 | |||
| e0e1e5b941 | |||
| 941824d7f8 | |||
| c585244f3e | |||
| 29b95a52cb | |||
| f556375242 | |||
| 86b963bdb5 | |||
| 036ebb4bf7 | |||
| 7d481fe965 | |||
| 4709bbbe38 | |||
| 1c79a80389 | |||
| 6a879959be | |||
| d46f9495e7 | |||
| e6faee1573 | |||
| c4be59cae3 | |||
| 9cc91f7108 | |||
| da8ee59ebb | |||
| 4386b9c541 | |||
| aa876cd588 | |||
| 9453179251 | |||
| 4d79af4f5e | |||
| 2cb6bbb10d | |||
| 1106558703 | |||
| 6e027657c2 | |||
| d87ca7a55d | |||
| 1b854da23b | |||
| 6719e926f0 | |||
| b68c44384f | |||
| 000b82fa19 | |||
| 07854d6be5 |
@@ -2,3 +2,4 @@ jira
|
|||||||
schemas/*.json
|
schemas/*.json
|
||||||
t/.gnupg/random_seed
|
t/.gnupg/random_seed
|
||||||
t/issue.props
|
t/issue.props
|
||||||
|
dist
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
config:
|
||||||
|
stop: true
|
||||||
|
password-source: pass
|
||||||
|
endpoint: https://go-jira.atlassian.net
|
||||||
|
user: admin
|
||||||
|
|
||||||
|
queries:
|
||||||
|
todo: |
|
||||||
|
resolution = unresolved {{if .project}}AND project = '{{.project}}'{{end}} AND status = 'To Do'
|
||||||
|
open: |
|
||||||
|
resolution = unresolved {{if .project}}AND project = '{{.project}}'{{end}} AND status = 'Open'
|
||||||
@@ -1,5 +1,92 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 1.0.6 - 2017-09-13
|
||||||
|
|
||||||
|
* tweaks for templates in named queries to work better [Cory Bennett] [[00cba79](https://github.com/Netflix-Skunkworks/go-jira/commit/00cba79)]
|
||||||
|
* [[#99](https://github.com/Netflix-Skunkworks/go-jira/issues/99)] add support for named queries to be stored in configs [Cory Bennett] [[fb43753](https://github.com/Netflix-Skunkworks/go-jira/commit/fb43753)]
|
||||||
|
* [[#98](https://github.com/Netflix-Skunkworks/go-jira/issues/98)] add `--status` option for JQL filter on status with `list` command [Cory Bennett] [[5da04c1](https://github.com/Netflix-Skunkworks/go-jira/commit/5da04c1)]
|
||||||
|
|
||||||
|
## 1.0.5 - 2017-09-11
|
||||||
|
|
||||||
|
* use --gjq for GJson Query to filter json response data [Cory Bennett] [[608e586](https://github.com/Netflix-Skunkworks/go-jira/commit/608e586)]
|
||||||
|
* fix field tag syntax [Cory Bennett] [[2c552ac](https://github.com/Netflix-Skunkworks/go-jira/commit/2c552ac)]
|
||||||
|
* add '{{jira}}' template macro to refer to path of currently running jira command [Cory Bennett] [[941824d](https://github.com/Netflix-Skunkworks/go-jira/commit/941824d)]
|
||||||
|
|
||||||
|
## 1.0.4 - 2017-09-08
|
||||||
|
|
||||||
|
* update deps for kingpeon update use os.exec instead of syscall.exec for windows [Cory Bennett] [[86b963b](https://github.com/Netflix-Skunkworks/go-jira/commit/86b963b)]
|
||||||
|
|
||||||
|
## 1.0.3 - 2017-09-06
|
||||||
|
|
||||||
|
* [[#66](https://github.com/Netflix-Skunkworks/go-jira/issues/66)] add --started option to `jira worklog add` to change the start time for worklog [Cory Bennett] [[e6faee1](https://github.com/Netflix-Skunkworks/go-jira/commit/e6faee1)]
|
||||||
|
* [[#45](https://github.com/Netflix-Skunkworks/go-jira/issues/45)] automatically add comment to issue even if transition does not support comment updates during transtion [Cory Bennett] [[c4be59c](https://github.com/Netflix-Skunkworks/go-jira/commit/c4be59c)]
|
||||||
|
|
||||||
|
## 1.0.2 - 2017-09-06
|
||||||
|
|
||||||
|
* update dependencies [Cory Bennett] [[aa876cd](https://github.com/Netflix-Skunkworks/go-jira/commit/aa876cd)]
|
||||||
|
* update for github.com/AlecAivazis/survey => gopkg.in/AlecAivazis/survey.v1 package [Cory Bennett] [[9453179](https://github.com/Netflix-Skunkworks/go-jira/commit/9453179)]
|
||||||
|
* use stdout to determin output terminal size [Cory Bennett] [[4d79af4](https://github.com/Netflix-Skunkworks/go-jira/commit/4d79af4)]
|
||||||
|
|
||||||
|
## 1.0.1 - 2017-09-06
|
||||||
|
|
||||||
|
* [[#13](https://github.com/Netflix-Skunkworks/go-jira/issues/13)] change default input syntax to not require escaping for special characters [Cory Bennett] [[1106558](https://github.com/Netflix-Skunkworks/go-jira/commit/1106558)]
|
||||||
|
|
||||||
|
## 1.0.0 - 2017-09-05
|
||||||
|
|
||||||
|
* fix build for windows [Cory Bennett] [[1b854da](https://github.com/Netflix-Skunkworks/go-jira/commit/1b854da)]
|
||||||
|
* change the default log output format [Cory Bennett] [[f1b8c64](https://github.com/Netflix-Skunkworks/go-jira/commit/f1b8c64)]
|
||||||
|
* tweak auto-login so it does not print the standard `jira login` command output [Cory Bennett] [[49f6cdc](https://github.com/Netflix-Skunkworks/go-jira/commit/49f6cdc)]
|
||||||
|
* add --quiet global option [Cory Bennett] [[c226077](https://github.com/Netflix-Skunkworks/go-jira/commit/c226077)]
|
||||||
|
* refactor to allow for --insecure and --unixproxy arguments [Cory Bennett] [[c0358eb](https://github.com/Netflix-Skunkworks/go-jira/commit/c0358eb)]
|
||||||
|
* handle html response on expired cookies (require X-Ausername header to always be present) [Cory Bennett] [[21920c5](https://github.com/Netflix-Skunkworks/go-jira/commit/21920c5)]
|
||||||
|
* allow login prompt to be interrupted [Cory Bennett] [[7ab6c22](https://github.com/Netflix-Skunkworks/go-jira/commit/7ab6c22)]
|
||||||
|
* fmt -> log typo [Cory Bennett] [[bccf09f](https://github.com/Netflix-Skunkworks/go-jira/commit/bccf09f)]
|
||||||
|
* make ~/.jira.d directory if not already present [Cory Bennett] [[e72479c](https://github.com/Netflix-Skunkworks/go-jira/commit/e72479c)]
|
||||||
|
* fix go vet [Cory Bennett] [[e04b506](https://github.com/Netflix-Skunkworks/go-jira/commit/e04b506)]
|
||||||
|
* fix tests [Cory Bennett] [[ba35f55](https://github.com/Netflix-Skunkworks/go-jira/commit/ba35f55)]
|
||||||
|
* add OK printf [Cory Bennett] [[dc02181](https://github.com/Netflix-Skunkworks/go-jira/commit/dc02181)]
|
||||||
|
* change --method to use -M for backwards compat [Cory Bennett] [[b120c0b](https://github.com/Netflix-Skunkworks/go-jira/commit/b120c0b)]
|
||||||
|
* add resolution to dup'd issues when necessary [Cory Bennett] [[2638396](https://github.com/Netflix-Skunkworks/go-jira/commit/2638396)]
|
||||||
|
* call correct function for `labels remove|set` commands [Cory Bennett] [[ad1a62a](https://github.com/Netflix-Skunkworks/go-jira/commit/ad1a62a)]
|
||||||
|
* data argument is optional (for GET and DELETE requests) [Cory Bennett] [[4b60313](https://github.com/Netflix-Skunkworks/go-jira/commit/4b60313)]
|
||||||
|
* fix usage, overrides not serialized correctly [Cory Bennett] [[84119a2](https://github.com/Netflix-Skunkworks/go-jira/commit/84119a2)]
|
||||||
|
* fix `jira ISSUE-123` command line parsing [Cory Bennett] [[fa4ac25](https://github.com/Netflix-Skunkworks/go-jira/commit/fa4ac25)]
|
||||||
|
* add logger object to jiracmd [Cory Bennett] [[aed952b](https://github.com/Netflix-Skunkworks/go-jira/commit/aed952b)]
|
||||||
|
* refactor for GlobalOptions and CommonOptions [Cory Bennett] [[979da1f](https://github.com/Netflix-Skunkworks/go-jira/commit/979da1f)]
|
||||||
|
* move commands from jiracli package to jiracmd package [Cory Bennett] [[0a5510b](https://github.com/Netflix-Skunkworks/go-jira/commit/0a5510b)]
|
||||||
|
* use jiracli.Error object to disambiguate between kingpin errors and cli errors [Cory Bennett] [[fb1bfeb](https://github.com/Netflix-Skunkworks/go-jira/commit/fb1bfeb)]
|
||||||
|
* fix stray newline for list table template [Cory Bennett] [[36c26c5](https://github.com/Netflix-Skunkworks/go-jira/commit/36c26c5)]
|
||||||
|
* fix dynamic table output when not on tty [Cory Bennett] [[3942f6f](https://github.com/Netflix-Skunkworks/go-jira/commit/3942f6f)]
|
||||||
|
* when using --verbose set the JIRA_DEBUG environment variable so custom-commands can auto enable verbose output [Cory Bennett] [[da9a2b2](https://github.com/Netflix-Skunkworks/go-jira/commit/da9a2b2)]
|
||||||
|
* make `jira ISSUE-123` usage call `jira view ISSUE-123` [Cory Bennett] [[ec0858b](https://github.com/Netflix-Skunkworks/go-jira/commit/ec0858b)]
|
||||||
|
* integrate kingpeon library to allow for custom commands via configuration [Cory Bennett] [[301a61f](https://github.com/Netflix-Skunkworks/go-jira/commit/301a61f)]
|
||||||
|
* use terminal width to adjust list table output [Cory Bennett] [[2a081dd](https://github.com/Netflix-Skunkworks/go-jira/commit/2a081dd)]
|
||||||
|
* set yaml/json tags for option structs [Cory Bennett] [[f52d2c4](https://github.com/Netflix-Skunkworks/go-jira/commit/f52d2c4)]
|
||||||
|
* update generated data files [Cory Bennett] [[c89f11d](https://github.com/Netflix-Skunkworks/go-jira/commit/c89f11d)]
|
||||||
|
* automatically login when anonymous user detected [Cory Bennett] [[21add54](https://github.com/Netflix-Skunkworks/go-jira/commit/21add54)]
|
||||||
|
* refactor trivial objects in favor of arguments to static functions [Cory Bennett] [[1f345ce](https://github.com/Netflix-Skunkworks/go-jira/commit/1f345ce)]
|
||||||
|
* set JIRA_OPERATION when parsing configs. Use figtree config types for options to make defaulting work [Cory Bennett] [[5716a7c](https://github.com/Netflix-Skunkworks/go-jira/commit/5716a7c)]
|
||||||
|
* add better handing for usage error [Cory Bennett] [[b235dcc](https://github.com/Netflix-Skunkworks/go-jira/commit/b235dcc)]
|
||||||
|
* adding `request` command, removing dead code [Cory Bennett] [[56b1c9d](https://github.com/Netflix-Skunkworks/go-jira/commit/56b1c9d)]
|
||||||
|
* adding Do required for request language [Cory Bennett] [[a1c2849](https://github.com/Netflix-Skunkworks/go-jira/commit/a1c2849)]
|
||||||
|
* add `browse` command and implement -b option for most operations [Cory Bennett] [[a91b9d5](https://github.com/Netflix-Skunkworks/go-jira/commit/a91b9d5)]
|
||||||
|
* fix IssueAssign [Cory Bennett] [[f32cc70](https://github.com/Netflix-Skunkworks/go-jira/commit/f32cc70)]
|
||||||
|
* merge in update for upstream changes [#104](https://github.com/Netflix-Skunkworks/go-jira/issues/104) [Cory Bennett] [[19d8686](https://github.com/Netflix-Skunkworks/go-jira/commit/19d8686)]
|
||||||
|
* add `export-templates` command [Cory Bennett] [[abaad56](https://github.com/Netflix-Skunkworks/go-jira/commit/abaad56)]
|
||||||
|
* add `issuetypes` command [Cory Bennett] [[da39323](https://github.com/Netflix-Skunkworks/go-jira/commit/da39323)]
|
||||||
|
* add `components` command [Cory Bennett] [[0bd3ca2](https://github.com/Netflix-Skunkworks/go-jira/commit/0bd3ca2)]
|
||||||
|
* add `component add` command [Cory Bennett] [[cc90610](https://github.com/Netflix-Skunkworks/go-jira/commit/cc90610)]
|
||||||
|
* add `take`, `unassign` and `assign|give` commands [Cory Bennett] [[959524a](https://github.com/Netflix-Skunkworks/go-jira/commit/959524a)]
|
||||||
|
* adding `labels [add|set|remove]` commands [Cory Bennett] [[9161861](https://github.com/Netflix-Skunkworks/go-jira/commit/9161861)]
|
||||||
|
* add `comment` command [Cory Bennett] [[f0b08c5](https://github.com/Netflix-Skunkworks/go-jira/commit/f0b08c5)]
|
||||||
|
* add `watch` command [Cory Bennett] [[ec0ac3c](https://github.com/Netflix-Skunkworks/go-jira/commit/ec0ac3c)]
|
||||||
|
* add `rank ISSUE after|before ISSUE` command [Cory Bennett] [[8b863d2](https://github.com/Netflix-Skunkworks/go-jira/commit/8b863d2)]
|
||||||
|
* add `vote` command [Cory Bennett] [[a08c92f](https://github.com/Netflix-Skunkworks/go-jira/commit/a08c92f)]
|
||||||
|
* add `issuelinktypes` command [Cory Bennett] [[37f81a4](https://github.com/Netflix-Skunkworks/go-jira/commit/37f81a4)]
|
||||||
|
* add `issuelink` command [Cory Bennett] [[aacc9f4](https://github.com/Netflix-Skunkworks/go-jira/commit/aacc9f4)]
|
||||||
|
* fix closing duplicate issue on `dup` command [Cory Bennett] [[fc696c3](https://github.com/Netflix-Skunkworks/go-jira/commit/fc696c3)]
|
||||||
|
* rewrite checkpoint [Cory Bennett] [[36632a5](https://github.com/Netflix-Skunkworks/go-jira/commit/36632a5)]
|
||||||
|
|
||||||
## 0.1.14 - 2017-05-10
|
## 0.1.14 - 2017-05-10
|
||||||
|
|
||||||
* fix unsafe casting for --quiet flag [Cory Bennett] [[6f29f43](https://github.com/Netflix-Skunkworks/go-jira/commit/6f29f43)]
|
* fix unsafe casting for --quiet flag [Cory Bennett] [[6f29f43](https://github.com/Netflix-Skunkworks/go-jira/commit/6f29f43)]
|
||||||
|
|||||||
Generated
+165
@@ -0,0 +1,165 @@
|
|||||||
|
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||||
|
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/alecthomas/template"
|
||||||
|
packages = [".","parse"]
|
||||||
|
revision = "a0175ee3bccc567396460bf5acd36800cb10c49c"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/alecthomas/units"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/cheekybits/genny"
|
||||||
|
packages = ["generic"]
|
||||||
|
revision = "9127e812e1e9e501ce899a18121d316ecb52e4ba"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/coryb/figtree"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "c7d8fbf1d7746b5864b8262fabffec813b5a43fa"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/coryb/kingpeon"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "64b561ae2d0f895b94719c486bed798f4236a4b3"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/coryb/oreo"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "95687d61c95ee1522c1140e2af59b0c1846abfc1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/fatih/camelcase"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "f6a740d52f961c60348ebb109adde9f4635d7540"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/guelfey/go.dbus"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "f6a3a2366cc39b8479cadc499d3c735fb10fbdda"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/jinzhu/copier"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "32e0d0db1dcd4373fb9eb0f9d727b1fe1a723e54"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/kballard/go-shellquote"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "cd60e84ee657ff3dc51de0b4f55dd299a3e136f2"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/mattn/go-colorable"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "ad5389df28cdac544c99bd7b9161a0b5b6ca9d1b"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/mattn/go-isatty"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "fc9e8d8ef48496124e79ae0df75490096eccf6fe"
|
||||||
|
version = "v0.0.2"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/mgutz/ansi"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "9520e82c474b0a04dd04f8a40959027271bab992"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/pkg/browser"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "c90ca0c84f15f81c982e32665bffd8d7aac8f097"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/pkg/errors"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||||
|
version = "v0.8.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/sethgrid/pester"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "a86a2d88f4dc3c7dbf3a6a6bbbfb095690b834b6"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/theckman/go-flock"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "6de226b0d5f040ed85b88c82c381709b98277f3d"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/tidwall/gjson"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "be96719f990978a867f52c48f29d43f6b591da28"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/tidwall/match"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "173748da739a410c5b0b813b956f89ff94730b4c"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/tmc/keyring"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "06e6283d50adc5f8fcdb3cdf33ee1244d4400ae1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/crypto"
|
||||||
|
packages = ["ssh/terminal"]
|
||||||
|
revision = "9ba3862cf6a5452ae579de98f9364dd2e544844c"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/sys"
|
||||||
|
packages = ["unix","windows"]
|
||||||
|
revision = "a5054c7c1385fd50d9394475365355a87a7873ec"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "gopkg.in/AlecAivazis/survey.v1"
|
||||||
|
packages = [".","core","terminal"]
|
||||||
|
revision = "9d910423e24aa6d7c7950160658c295e0734c7e0"
|
||||||
|
version = "1.3.1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "gopkg.in/alecthomas/kingpin.v2"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "1087e65c9441605df944fb12c33f0fe7072d18ca"
|
||||||
|
version = "v2.2.5"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "v2"
|
||||||
|
name = "gopkg.in/coryb/yaml.v2"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "fb7cb9628c6e3bdd76c29fb91798d51a09832470"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "gopkg.in/op/go-logging.v1"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "b2cb9fa56473e98db8caba80237377e83fe44db5"
|
||||||
|
version = "v1"
|
||||||
|
|
||||||
|
[solve-meta]
|
||||||
|
analyzer-name = "dep"
|
||||||
|
analyzer-version = 1
|
||||||
|
inputs-digest = "1f4b97fcf898a5ef03af5e222686a09328b393e71797d21bf0c37b74d1e74a8e"
|
||||||
|
solver-name = "gps-cdcl"
|
||||||
|
solver-version = 1
|
||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
|
||||||
|
# Gopkg.toml example
|
||||||
|
#
|
||||||
|
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||||
|
# for detailed Gopkg.toml documentation.
|
||||||
|
#
|
||||||
|
# required = ["github.com/user/thing/cmd/thing"]
|
||||||
|
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project"
|
||||||
|
# version = "1.0.0"
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project2"
|
||||||
|
# branch = "dev"
|
||||||
|
# source = "github.com/myfork/project2"
|
||||||
|
#
|
||||||
|
# [[override]]
|
||||||
|
# name = "github.com/x/y"
|
||||||
|
# version = "2.4.0"
|
||||||
|
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/coryb/figtree"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/coryb/kingpeon"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/coryb/oreo"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/jinzhu/copier"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/kballard/go-shellquote"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/mgutz/ansi"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/pkg/browser"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/pkg/errors"
|
||||||
|
version = "0.8.0"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/savaki/jq"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/tmc/keyring"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "golang.org/x/crypto"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "gopkg.in/AlecAivazis/survey.v1"
|
||||||
|
version = "1.3.1"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "gopkg.in/alecthomas/kingpin.v2"
|
||||||
|
version = "2.2.5"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "gopkg.in/coryb/yaml.v2"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "gopkg.in/op/go-logging.v1"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/tidwall/gjson"
|
||||||
@@ -1,19 +1,3 @@
|
|||||||
PLATFORMS= \
|
|
||||||
freebsd/amd64 \
|
|
||||||
linux/386 \
|
|
||||||
linux/amd64 \
|
|
||||||
windows/386 \
|
|
||||||
windows/amd64 \
|
|
||||||
darwin/amd64 \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
# freebsd-386 \
|
|
||||||
# freebsd-arm \
|
|
||||||
# linux-arm \
|
|
||||||
# openbsd-386 \
|
|
||||||
# openbsd-amd64 \
|
|
||||||
# darwin-386
|
|
||||||
|
|
||||||
NAME=jira
|
NAME=jira
|
||||||
|
|
||||||
OS=$(shell uname -s)
|
OS=$(shell uname -s)
|
||||||
@@ -33,21 +17,10 @@ DIST=$(CWD)$(SEP)dist
|
|||||||
GOBIN ?= $(CWD)
|
GOBIN ?= $(CWD)
|
||||||
|
|
||||||
CURVER ?= $(patsubst v%,%,$(shell [ -d .git ] && git describe --abbrev=0 --tags || grep ^\#\# CHANGELOG.md | awk '{print $$2; exit}'))
|
CURVER ?= $(patsubst v%,%,$(shell [ -d .git ] && git describe --abbrev=0 --tags || grep ^\#\# CHANGELOG.md | awk '{print $$2; exit}'))
|
||||||
LDFLAGS:=-X jira.VERSION=$(CURVER) -w
|
LDFLAGS:= -w
|
||||||
|
|
||||||
# use make DEBUG=1 and you can get a debuggable golang binary
|
|
||||||
# see https://github.com/mailgun/godebug
|
|
||||||
ifneq ($(DEBUG),)
|
|
||||||
GOBUILD=go get -v github.com/mailgun/godebug &&
|
|
||||||
else
|
|
||||||
GOBUILD=go build -gcflags="-e -complete" -v -ldflags "$(LDFLAGS) -s"
|
|
||||||
endif
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
$(GOBUILD) -o '$(BIN)' cmd/jira/main.go
|
go build -gcflags="-e" -v -ldflags "$(LDFLAGS) -s" -o '$(BIN)' cmd/jira/main.go
|
||||||
|
|
||||||
debug:
|
|
||||||
go build -v -o '$(BIN)' cmd/jira/main.go
|
|
||||||
|
|
||||||
vet:
|
vet:
|
||||||
@go vet .
|
@go vet .
|
||||||
@@ -64,33 +37,11 @@ lint:
|
|||||||
@golint ./jiradata
|
@golint ./jiradata
|
||||||
@golint ./cmd/jira
|
@golint ./cmd/jira
|
||||||
|
|
||||||
cross-setup:
|
|
||||||
for p in $(PLATFORMS); do \
|
|
||||||
echo Building for $$p"; \
|
|
||||||
cd $(GOROOT)/src && sudo GOROOT_BOOTSTRAP=$(GOROOT) GOOS=$${p/-*/} GOARCH=$${p/*-/} bash ./make.bash --no-clean; \
|
|
||||||
done
|
|
||||||
|
|
||||||
all:
|
all:
|
||||||
git push --tags
|
go get -u github.com/karalabe/xgo
|
||||||
rm -rf src
|
|
||||||
${MAKE} src/gopkg.in/Netflix-Skunkworks/go-jira.v0
|
|
||||||
docker pull karalabe/xgo-latest
|
|
||||||
rm -rf dist
|
rm -rf dist
|
||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
docker run --rm -e EXT_GOPATH=/gopath -v $$(pwd):/gopath -e TARGETS="$(PLATFORMS)" -v $$(pwd)/dist:/build karalabe/xgo-latest gopkg.in/Netflix-Skunkworks/go-jira.v0/main
|
xgo --targets="freebsd/amd64,linux/386,linux/amd64,windows/386,windows/amd64,darwin/amd64" -dest ./dist -ldflags="-w -s" ./cmd/jira
|
||||||
cd $(DIST) && for x in main-*; do mv $$x jira-$$(echo $$x | cut -c 6-); done
|
|
||||||
|
|
||||||
# all:
|
|
||||||
# rm -rf $(DIST); \
|
|
||||||
# mkdir -p $(DIST); \
|
|
||||||
# for p in $(PLATFORMS); do \
|
|
||||||
# echo "Building for $$p"; \
|
|
||||||
# ${MAKE} build GOOS=$${p/-*/} GOARCH=$${p/*-/} BIN=$(DIST)/$(NAME)-$$p; \
|
|
||||||
# done
|
|
||||||
# for x in $(DIST)/jira-windows-*; do mv $$x $$x.exe; done
|
|
||||||
|
|
||||||
fmt:
|
|
||||||
gofmt -s -w main/*.go *.go
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
${MAKE} GOBIN=$$HOME/bin build
|
${MAKE} GOBIN=$$HOME/bin build
|
||||||
@@ -99,7 +50,7 @@ NEWVER ?= $(shell echo $(CURVER) | awk -F. '{print $$1"."$$2"."$$3+1}')
|
|||||||
TODAY := $(shell date +%Y-%m-%d)
|
TODAY := $(shell date +%Y-%m-%d)
|
||||||
|
|
||||||
changes:
|
changes:
|
||||||
@git log --pretty=format:"* %s [%cn] [%h]" --no-merges ^v$(CURVER) HEAD main/*.go *.go | grep -vE 'gofmt|go fmt'
|
@git log --pretty=format:"* %s [%cn] [%h]" --no-merges ^v$(CURVER) HEAD *.go jiracli/*.go jiradata/*.go jiracmd/*.go cmd/*/*.go *.lock | grep -vE 'gofmt|go fmt|version bump'
|
||||||
|
|
||||||
update-changelog:
|
update-changelog:
|
||||||
@echo "# Changelog" > CHANGELOG.md.new; \
|
@echo "# Changelog" > CHANGELOG.md.new; \
|
||||||
@@ -110,22 +61,24 @@ update-changelog:
|
|||||||
perl -pe 's{\[([a-f0-9]+)\]}{[[$$1](https://github.com/Netflix-Skunkworks/go-jira/commit/$$1)]}g' | \
|
perl -pe 's{\[([a-f0-9]+)\]}{[[$$1](https://github.com/Netflix-Skunkworks/go-jira/commit/$$1)]}g' | \
|
||||||
perl -pe 's{\#(\d+)}{[#$$1](https://github.com/Netflix-Skunkworks/go-jira/issues/$$1)}g' >> CHANGELOG.md.new; \
|
perl -pe 's{\#(\d+)}{[#$$1](https://github.com/Netflix-Skunkworks/go-jira/issues/$$1)}g' >> CHANGELOG.md.new; \
|
||||||
tail -n +2 CHANGELOG.md >> CHANGELOG.md.new; \
|
tail -n +2 CHANGELOG.md >> CHANGELOG.md.new; \
|
||||||
|
perl -pi -e 's{VERSION = "$(CURVER)"}{VERSION = "$(NEWVER)"}' jira.go; \
|
||||||
mv CHANGELOG.md.new CHANGELOG.md; \
|
mv CHANGELOG.md.new CHANGELOG.md; \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
release:
|
||||||
git commit -m "Updated Changelog" CHANGELOG.md; \
|
git commit -m "Updated Changelog" CHANGELOG.md; \
|
||||||
|
git commit -m "version bump" jira.go
|
||||||
git tag v$(NEWVER)
|
git tag v$(NEWVER)
|
||||||
|
git push --tags
|
||||||
|
|
||||||
version:
|
version:
|
||||||
@echo $(CURVER)
|
@echo $(CURVER)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf pkg dist bin src ./$(NAME)
|
rm -rf ./$(NAME)
|
||||||
|
|
||||||
export GNUPGHOME=$(CWD)/t/.gnupg
|
|
||||||
export PASSWORD_STORE_DIR=$(CWD)/t/.password-store
|
|
||||||
export JIRACLOUD=1
|
|
||||||
|
|
||||||
prove:
|
prove:
|
||||||
chmod -R g-rwx,o-rwx $(GNUPGHOME)
|
chmod -R g-rwx,o-rwx $(CWD)/t/.gnupg
|
||||||
OSHT_VERBOSE=1 prove -v
|
OSHT_VERBOSE=1 prove -v
|
||||||
|
|
||||||
generate:
|
generate:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[](https://gitter.im/go-jira-cli/help?utm_source=badge&utm_medium=badge&utm_content=badge)
|
[](https://gitter.im/go-jira-cli/help?utm_source=badge&utm_medium=badge&utm_content=badge)
|
||||||
[](https://travis-ci.org/Netflix-Skunkworks/go-jira)
|
[](https://travis-ci.org/Netflix-Skunkworks/go-jira)
|
||||||
[](https://godoc.org/gopkg.in/Netflix-Skunkworks/go-jira.v1)
|
[](https://godoc.org/gopkg.in/Netflix-Skunkworks/go-jira.v1)
|
||||||
|
[](https://opensource.org/licenses/Apache-2.0)
|
||||||
|
|
||||||
# go-jira
|
# go-jira
|
||||||
simple command line client for Atlassian's Jira service written in Go
|
simple command line client for Atlassian's Jira service written in Go
|
||||||
@@ -56,7 +56,7 @@ custom-commands:
|
|||||||
- name: mine
|
- name: mine
|
||||||
help: display issues assigned to me
|
help: display issues assigned to me
|
||||||
script: |-
|
script: |-
|
||||||
jira list --query "resolution = unresolved and assignee=currentuser() ORDER BY created"
|
{{jira}} list --query "resolution = unresolved and assignee=currentuser() ORDER BY created"
|
||||||
```
|
```
|
||||||
Then the next time you run `jira help` you will see your usage:
|
Then the next time you run `jira help` you will see your usage:
|
||||||
```
|
```
|
||||||
@@ -267,25 +267,27 @@ custom-commands:
|
|||||||
|
|
||||||
* `jira mine` for listing issues assigned to you
|
* `jira mine` for listing issues assigned to you
|
||||||
```
|
```
|
||||||
|
custom-commands:
|
||||||
- name: mine
|
- name: mine
|
||||||
help: display issues assigned to me
|
help: display issues assigned to me
|
||||||
script: |-
|
script: |-
|
||||||
if [ -n "$JIRA_PROJECT" ]; then
|
if [ -n "$JIRA_PROJECT" ]; then
|
||||||
# if `project: ...` configured just list the issues for current project
|
# if `project: ...` configured just list the issues for current project
|
||||||
jira list --template table --query "resolution = unresolved and assignee=currentuser() and project = $JIRA_PROJECT ORDER BY priority asc, created"
|
{{jira}} list --template table --query "resolution = unresolved and assignee=currentuser() and project = $JIRA_PROJECT ORDER BY priority asc, created"
|
||||||
else
|
else
|
||||||
# otherwise list issues for all project
|
# otherwise list issues for all project
|
||||||
jira list --template table --query "resolution = unresolved and assignee=currentuser() ORDER BY priority asc, created"
|
{{jira}} list --template table --query "resolution = unresolved and assignee=currentuser() ORDER BY priority asc, created"
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
* `jira sprint` for listing issues in your current sprint
|
* `jira sprint` for listing issues in your current sprint
|
||||||
```
|
```
|
||||||
|
custom-commands:
|
||||||
- name: sprint
|
- name: sprint
|
||||||
help: display issues for active sprint
|
help: display issues for active sprint
|
||||||
script: |-
|
script: |-
|
||||||
if [ -n "$JIRA_PROJECT" ]; then
|
if [ -n "$JIRA_PROJECT" ]; then
|
||||||
# if `project: ...` configured just list the issues for current project
|
# if `project: ...` configured just list the issues for current project
|
||||||
jira list --template table --query "sprint in openSprints() and type != epic and resolution = unresolved and project=$JIRA_PROJECT ORDER BY rank asc, created"
|
{{jira}} list --template table --query "sprint in openSprints() and type != epic and resolution = unresolved and project=$JIRA_PROJECT ORDER BY rank asc, created"
|
||||||
else
|
else
|
||||||
# otherwise list issues for all project
|
# otherwise list issues for all project
|
||||||
echo "\"project: ...\" configuration missing from .jira.d/config.yml"
|
echo "\"project: ...\" configuration missing from .jira.d/config.yml"
|
||||||
|
|||||||
+16
-1
@@ -3,10 +3,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/coryb/figtree"
|
"github.com/coryb/figtree"
|
||||||
"github.com/coryb/kingpeon"
|
"github.com/coryb/kingpeon"
|
||||||
@@ -307,9 +310,21 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(data.CustomCommands) > 0 {
|
if len(data.CustomCommands) > 0 {
|
||||||
|
runner := syscall.Exec
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
runner = func(binary string, cmd []string, env []string) error {
|
||||||
|
command := exec.Command(binary, cmd[1:]...)
|
||||||
|
command.Stdin = os.Stdin
|
||||||
|
command.Stdout = os.Stdout
|
||||||
|
command.Stderr = os.Stderr
|
||||||
|
command.Env = env
|
||||||
|
return command.Run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tmp := map[string]interface{}{}
|
tmp := map[string]interface{}{}
|
||||||
fig.LoadAllConfigs("config.yml", &tmp)
|
fig.LoadAllConfigs("config.yml", &tmp)
|
||||||
kingpeon.RegisterDynamicCommands(app, data.CustomCommands, jiracli.TemplateProcessor())
|
kingpeon.RegisterDynamicCommandsWithRunner(runner, app, data.CustomCommands, jiracli.TemplateProcessor())
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Terminate(func(status int) {
|
app.Terminate(func(status int) {
|
||||||
|
|||||||
Generated
-65
@@ -1,65 +0,0 @@
|
|||||||
hash: 3e4ada7ae3922b18b3492a45f1f31cdaaf68fa708327ce9b4f9730c3f0b3ca90
|
|
||||||
updated: 2017-08-30T18:15:39.909557691-07:00
|
|
||||||
imports:
|
|
||||||
- name: github.com/AlecAivazis/survey
|
|
||||||
version: 73fd4d7829877a72e03dbb42f84ed383fbbc5fa0
|
|
||||||
subpackages:
|
|
||||||
- core
|
|
||||||
- terminal
|
|
||||||
- name: github.com/alecthomas/template
|
|
||||||
version: a0175ee3bccc567396460bf5acd36800cb10c49c
|
|
||||||
subpackages:
|
|
||||||
- parse
|
|
||||||
- name: github.com/alecthomas/units
|
|
||||||
version: 2efee857e7cfd4f3d0138cc3cbb1b4966962b93a
|
|
||||||
- name: github.com/cheekybits/genny
|
|
||||||
version: 9127e812e1e9e501ce899a18121d316ecb52e4ba
|
|
||||||
subpackages:
|
|
||||||
- generic
|
|
||||||
- name: github.com/coryb/figtree
|
|
||||||
version: 48d3afc6118a0c353dc7d41ff77a3e0b75e14c07
|
|
||||||
- name: github.com/coryb/kingpeon
|
|
||||||
version: 3ca9749293339b932167921f92ce7a55207ad34e
|
|
||||||
- name: github.com/coryb/oreo
|
|
||||||
version: 95687d61c95ee1522c1140e2af59b0c1846abfc1
|
|
||||||
- name: github.com/fatih/camelcase
|
|
||||||
version: f6a740d52f961c60348ebb109adde9f4635d7540
|
|
||||||
- name: github.com/guelfey/go.dbus
|
|
||||||
version: f6a3a2366cc39b8479cadc499d3c735fb10fbdda
|
|
||||||
- name: github.com/jinzhu/copier
|
|
||||||
version: 8bfca8a02a0ce12119cdc4974143c834ca589257
|
|
||||||
- name: github.com/kballard/go-shellquote
|
|
||||||
version: d8ec1a69a250a17bb0e419c386eac1f3711dc142
|
|
||||||
- name: github.com/mattn/go-isatty
|
|
||||||
version: 57fdcb988a5c543893cc61bce354a6e24ab70022
|
|
||||||
- name: github.com/mgutz/ansi
|
|
||||||
version: c286dcecd19ff979eeb73ea444e479b903f2cfcb
|
|
||||||
- name: github.com/pkg/browser
|
|
||||||
version: c90ca0c84f15f81c982e32665bffd8d7aac8f097
|
|
||||||
- name: github.com/pkg/errors
|
|
||||||
version: 645ef00459ed84a119197bfb8d8205042c6df63d
|
|
||||||
- name: github.com/sethgrid/pester
|
|
||||||
version: 8053687f99650573b28fb75cddf3f295082704d7
|
|
||||||
- name: github.com/theckman/go-flock
|
|
||||||
version: 6de226b0d5f040ed85b88c82c381709b98277f3d
|
|
||||||
- name: github.com/tmc/keyring
|
|
||||||
version: 39227cc0349f1b69956c23aa1f679eefd17ebae0
|
|
||||||
- name: golang.org/x/crypto
|
|
||||||
version: 7f7c0c2d75ebb4e32a21396ce36e87b6dadc91c9
|
|
||||||
subpackages:
|
|
||||||
- ssh/terminal
|
|
||||||
- name: golang.org/x/sys
|
|
||||||
version: e24f485414aeafb646f6fca458b0bf869c0880a1
|
|
||||||
subpackages:
|
|
||||||
- unix
|
|
||||||
- name: gopkg.in/alecthomas/kingpin.v2
|
|
||||||
version: 1087e65c9441605df944fb12c33f0fe7072d18ca
|
|
||||||
- name: gopkg.in/coryb/yaml.v2
|
|
||||||
version: fb7cb9628c6e3bdd76c29fb91798d51a09832470
|
|
||||||
- name: gopkg.in/op/go-logging.v1
|
|
||||||
version: b2cb9fa56473e98db8caba80237377e83fe44db5
|
|
||||||
testImports:
|
|
||||||
- name: github.com/stretchr/testify
|
|
||||||
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
|
|
||||||
subpackages:
|
|
||||||
- assert
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
package: gopkg.in/Netflix-Skunkworks/go-jira.v1
|
|
||||||
import:
|
|
||||||
- package: github.com/coryb/figtree
|
|
||||||
- package: github.com/coryb/oreo
|
|
||||||
- package: github.com/mgutz/ansi
|
|
||||||
- package: github.com/pkg/errors
|
|
||||||
version: ^0.8.0
|
|
||||||
- package: github.com/sethgrid/pester
|
|
||||||
- package: github.com/theckman/go-flock
|
|
||||||
- package: gopkg.in/alecthomas/kingpin.v2
|
|
||||||
version: ^2.2.4
|
|
||||||
- package: gopkg.in/op/go-logging.v1
|
|
||||||
version: ^1.0.0
|
|
||||||
- package: github.com/AlecAivazis/survey
|
|
||||||
version: ^1.2.4
|
|
||||||
- package: github.com/tmc/keyring
|
|
||||||
- package: github.com/kballard/go-shellquote
|
|
||||||
- package: github.com/jinzhu/copier
|
|
||||||
- package: github.com/pkg/browser
|
|
||||||
- package: github.com/coryb/kingpeon
|
|
||||||
- package: golang.org/x/crypto
|
|
||||||
subpackages:
|
|
||||||
- ssh/terminal
|
|
||||||
testImport:
|
|
||||||
- package: github.com/stretchr/testify
|
|
||||||
version: ^1.1.4
|
|
||||||
subpackages:
|
|
||||||
- assert
|
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
var log = logging.MustGetLogger("jira")
|
var log = logging.MustGetLogger("jira")
|
||||||
|
|
||||||
const VERSION = "1.0.0"
|
const VERSION = "1.0.6"
|
||||||
|
|
||||||
type Jira struct {
|
type Jira struct {
|
||||||
Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"`
|
Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"`
|
||||||
|
|||||||
+19
-1
@@ -12,11 +12,12 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
"github.com/coryb/figtree"
|
"github.com/coryb/figtree"
|
||||||
"github.com/coryb/oreo"
|
"github.com/coryb/oreo"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
shellquote "github.com/kballard/go-shellquote"
|
shellquote "github.com/kballard/go-shellquote"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
"gopkg.in/AlecAivazis/survey.v1"
|
||||||
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
||||||
yaml "gopkg.in/coryb/yaml.v2"
|
yaml "gopkg.in/coryb/yaml.v2"
|
||||||
logging "gopkg.in/op/go-logging.v1"
|
logging "gopkg.in/op/go-logging.v1"
|
||||||
@@ -40,6 +41,7 @@ type GlobalOptions struct {
|
|||||||
type CommonOptions struct {
|
type CommonOptions struct {
|
||||||
Browse figtree.BoolOption `yaml:"browse,omitempty" json:"browse,omitempty"`
|
Browse figtree.BoolOption `yaml:"browse,omitempty" json:"browse,omitempty"`
|
||||||
Editor figtree.StringOption `yaml:"editor,omitempty" json:"editor,omitempty"`
|
Editor figtree.StringOption `yaml:"editor,omitempty" json:"editor,omitempty"`
|
||||||
|
GJsonQuery figtree.StringOption `yaml:"gjq,omitempty" json:"gjq,omitempty"`
|
||||||
SkipEditing figtree.BoolOption `yaml:"noedit,omitempty" json:"noedit,omitempty"`
|
SkipEditing figtree.BoolOption `yaml:"noedit,omitempty" json:"noedit,omitempty"`
|
||||||
Template figtree.StringOption `yaml:"template,omitempty" json:"template,omitempty"`
|
Template figtree.StringOption `yaml:"template,omitempty" json:"template,omitempty"`
|
||||||
}
|
}
|
||||||
@@ -169,6 +171,22 @@ func TemplateUsage(cmd *kingpin.CmdClause, opts *CommonOptions) {
|
|||||||
cmd.Flag("template", "Template to use for output").Short('t').SetValue(&opts.Template)
|
cmd.Flag("template", "Template to use for output").Short('t').SetValue(&opts.Template)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GJsonQueryUsage(cmd *kingpin.CmdClause, opts *CommonOptions) {
|
||||||
|
cmd.Flag("gjq", "GJSON Query to filter output, see https://goo.gl/iaYwJ5").SetValue(&opts.GJsonQuery)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *CommonOptions) PrintTemplate(data interface{}) error {
|
||||||
|
if o.GJsonQuery.Value != "" {
|
||||||
|
buf := bytes.NewBufferString("")
|
||||||
|
RunTemplate("json", data, buf)
|
||||||
|
results := gjson.GetBytes(buf.Bytes(), o.GJsonQuery.Value)
|
||||||
|
_, err := os.Stdout.Write([]byte(results.String()))
|
||||||
|
os.Stdout.Write([]byte{'\n'})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return RunTemplate(o.Template.Value, data, nil)
|
||||||
|
}
|
||||||
|
|
||||||
func (o *CommonOptions) editFile(fileName string) (changes bool, err error) {
|
func (o *CommonOptions) editFile(fileName string) (changes bool, err error) {
|
||||||
var editor string
|
var editor string
|
||||||
for _, ed := range []string{o.Editor.Value, os.Getenv("JIRA_EDITOR"), os.Getenv("EDITOR"), "vim"} {
|
for _, ed := range []string{o.Editor.Value, os.Getenv("JIRA_EDITOR"), os.Getenv("EDITOR"), "vim"} {
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey"
|
"gopkg.in/AlecAivazis/survey.v1"
|
||||||
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
|
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+79
-40
@@ -11,12 +11,13 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
yaml "gopkg.in/coryb/yaml.v2"
|
||||||
|
|
||||||
|
"github.com/coryb/figtree"
|
||||||
"github.com/mgutz/ansi"
|
"github.com/mgutz/ansi"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
yaml "gopkg.in/coryb/yaml.v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func findTemplate(name string) ([]byte, error) {
|
func findTemplate(name string) ([]byte, error) {
|
||||||
@@ -61,6 +62,9 @@ func tmpTemplate(templateName string, data interface{}) (string, error) {
|
|||||||
|
|
||||||
func TemplateProcessor() *template.Template {
|
func TemplateProcessor() *template.Template {
|
||||||
funcs := map[string]interface{}{
|
funcs := map[string]interface{}{
|
||||||
|
"jira": func() string {
|
||||||
|
return os.Args[0]
|
||||||
|
},
|
||||||
"toJson": func(content interface{}) (string, error) {
|
"toJson": func(content interface{}) (string, error) {
|
||||||
bytes, err := json.MarshalIndent(content, "", " ")
|
bytes, err := json.MarshalIndent(content, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -69,7 +73,7 @@ func TemplateProcessor() *template.Template {
|
|||||||
return string(bytes), nil
|
return string(bytes), nil
|
||||||
},
|
},
|
||||||
"termWidth": func() int {
|
"termWidth": func() int {
|
||||||
w, _, err := terminal.GetSize(syscall.Stdout)
|
w, _, err := terminal.GetSize(int(os.Stdout.Fd()))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
@@ -155,6 +159,48 @@ func TemplateProcessor() *template.Template {
|
|||||||
return template.New("gojira").Funcs(funcs)
|
return template.New("gojira").Funcs(funcs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConfigTemplate(fig *figtree.FigTree, template, command string, opts interface{}) (string, error) {
|
||||||
|
tmp, err := translateOptions(opts)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
fig.LoadAllConfigs(command+".yml", tmp)
|
||||||
|
fig.LoadAllConfigs("config.yml", tmp)
|
||||||
|
|
||||||
|
tmpl, err := TemplateProcessor().Parse(template)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
buf := bytes.NewBufferString("")
|
||||||
|
if err := tmpl.Execute(buf, &tmp); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func translateOptions(opts interface{}) (interface{}, error) {
|
||||||
|
// HACK HACK HACK: convert data formats to json for backwards compatibilty with templates
|
||||||
|
jsonData, err := json.Marshal(opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func(mapType, iface reflect.Type) {
|
||||||
|
yaml.DefaultMapType = mapType
|
||||||
|
yaml.IfaceType = iface
|
||||||
|
}(yaml.DefaultMapType, yaml.IfaceType)
|
||||||
|
|
||||||
|
yaml.DefaultMapType = reflect.TypeOf(map[string]interface{}{})
|
||||||
|
yaml.IfaceType = yaml.DefaultMapType.Elem()
|
||||||
|
|
||||||
|
var rawData map[string]interface{}
|
||||||
|
if err := yaml.Unmarshal(jsonData, &rawData); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &rawData, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func RunTemplate(templateName string, data interface{}, out io.Writer) error {
|
func RunTemplate(templateName string, data interface{}, out io.Writer) error {
|
||||||
|
|
||||||
templateContent, err := getTemplate(templateName)
|
templateContent, err := getTemplate(templateName)
|
||||||
@@ -166,22 +212,9 @@ func RunTemplate(templateName string, data interface{}, out io.Writer) error {
|
|||||||
out = os.Stdout
|
out = os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK HACK HACK: convert data formats to json for backwards compatibilty with templates
|
rawData, err := translateOptions(data)
|
||||||
var rawData interface{}
|
if err != nil {
|
||||||
if jsonData, err := json.Marshal(data); err != nil {
|
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
defer func(mapType, iface reflect.Type) {
|
|
||||||
yaml.DefaultMapType = mapType
|
|
||||||
yaml.IfaceType = iface
|
|
||||||
}(yaml.DefaultMapType, yaml.IfaceType)
|
|
||||||
|
|
||||||
yaml.DefaultMapType = reflect.TypeOf(map[string]interface{}{})
|
|
||||||
yaml.IfaceType = yaml.DefaultMapType.Elem()
|
|
||||||
|
|
||||||
if err := yaml.Unmarshal(jsonData, &rawData); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := TemplateProcessor().Parse(templateContent)
|
tmpl, err := TemplateProcessor().Parse(templateContent)
|
||||||
@@ -195,25 +228,26 @@ func RunTemplate(templateName string, data interface{}, out io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var AllTemplates = map[string]string{
|
var AllTemplates = map[string]string{
|
||||||
"component-add": defaultComponentAddTemplate,
|
|
||||||
"debug": defaultDebugTemplate,
|
|
||||||
"fields": defaultDebugTemplate,
|
|
||||||
"editmeta": defaultDebugTemplate,
|
|
||||||
"transmeta": defaultDebugTemplate,
|
|
||||||
"createmeta": defaultDebugTemplate,
|
|
||||||
"issuelinktypes": defaultDebugTemplate,
|
|
||||||
"list": defaultListTemplate,
|
|
||||||
"table": defaultTableTemplate,
|
|
||||||
"view": defaultViewTemplate,
|
|
||||||
"edit": defaultEditTemplate,
|
|
||||||
"transitions": defaultTransitionsTemplate,
|
|
||||||
"components": defaultComponentsTemplate,
|
|
||||||
"issuetypes": defaultIssuetypesTemplate,
|
|
||||||
"create": defaultCreateTemplate,
|
|
||||||
"subtask": defaultSubtaskTemplate,
|
|
||||||
"comment": defaultCommentTemplate,
|
"comment": defaultCommentTemplate,
|
||||||
"transition": defaultTransitionTemplate,
|
"component-add": defaultComponentAddTemplate,
|
||||||
|
"components": defaultComponentsTemplate,
|
||||||
|
"create": defaultCreateTemplate,
|
||||||
|
"createmeta": defaultDebugTemplate,
|
||||||
|
"debug": defaultDebugTemplate,
|
||||||
|
"edit": defaultEditTemplate,
|
||||||
|
"editmeta": defaultDebugTemplate,
|
||||||
|
"fields": defaultDebugTemplate,
|
||||||
|
"issuelinktypes": defaultDebugTemplate,
|
||||||
|
"issuetypes": defaultIssuetypesTemplate,
|
||||||
|
"json": defaultDebugTemplate,
|
||||||
|
"list": defaultListTemplate,
|
||||||
"request": defaultDebugTemplate,
|
"request": defaultDebugTemplate,
|
||||||
|
"subtask": defaultSubtaskTemplate,
|
||||||
|
"table": defaultTableTemplate,
|
||||||
|
"transition": defaultTransitionTemplate,
|
||||||
|
"transitions": defaultTransitionsTemplate,
|
||||||
|
"transmeta": defaultDebugTemplate,
|
||||||
|
"view": defaultViewTemplate,
|
||||||
"worklog": defaultWorklogTemplate,
|
"worklog": defaultWorklogTemplate,
|
||||||
"worklogs": defaultWorklogsTemplate,
|
"worklogs": defaultWorklogsTemplate,
|
||||||
}
|
}
|
||||||
@@ -286,7 +320,8 @@ update:
|
|||||||
body: |~
|
body: |~
|
||||||
{{ or .overrides.comment "" | indent 10 }}
|
{{ or .overrides.comment "" | indent 10 }}
|
||||||
fields:
|
fields:
|
||||||
summary: {{ or .overrides.summary .fields.summary }}
|
summary: >-
|
||||||
|
{{ or .overrides.summary .fields.summary }}
|
||||||
{{- if and .meta.fields.components .meta.fields.components.allowedValues }}
|
{{- if and .meta.fields.components .meta.fields.components.allowedValues }}
|
||||||
components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{if .overrides.components }}{{ range (split "," .overrides.components)}}
|
components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{if .overrides.components }}{{ range (split "," .overrides.components)}}
|
||||||
- name: {{.}}{{end}}{{else}}{{ range .fields.components }}
|
- name: {{.}}{{end}}{{else}}{{ range .fields.components }}
|
||||||
@@ -335,7 +370,8 @@ fields:
|
|||||||
key: {{ or .overrides.project "" }}
|
key: {{ or .overrides.project "" }}
|
||||||
issuetype:
|
issuetype:
|
||||||
name: {{ or .overrides.issuetype "" }}
|
name: {{ or .overrides.issuetype "" }}
|
||||||
summary: {{ or .overrides.summary "" }}{{if .meta.fields.priority.allowedValues}}
|
summary: >-
|
||||||
|
{{ or .overrides.summary "" }}{{if .meta.fields.priority.allowedValues}}
|
||||||
priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
|
priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
|
||||||
name: {{ or .overrides.priority ""}}{{end}}{{if .meta.fields.components.allowedValues}}
|
name: {{ or .overrides.priority ""}}{{end}}{{if .meta.fields.components.allowedValues}}
|
||||||
components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{ range split "," (or .overrides.components "")}}
|
components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{ range split "," (or .overrides.components "")}}
|
||||||
@@ -355,7 +391,8 @@ const defaultSubtaskTemplate = `{{/* create subtask template */ -}}
|
|||||||
fields:
|
fields:
|
||||||
project:
|
project:
|
||||||
key: {{ .parent.fields.project.key }}
|
key: {{ .parent.fields.project.key }}
|
||||||
summary: {{ or .overrides.summary "" }}{{if .meta.fields.priority.allowedValues}}
|
summary: >-
|
||||||
|
{{ or .overrides.summary "" }}{{if .meta.fields.priority.allowedValues}}
|
||||||
priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
|
priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
|
||||||
name: {{ or .overrides.priority ""}}{{end}}{{if .meta.fields.components.allowedValues}}
|
name: {{ or .overrides.priority ""}}{{end}}{{if .meta.fields.components.allowedValues}}
|
||||||
components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{ range split "," (or .overrides.components "")}}
|
components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{ range split "," (or .overrides.components "")}}
|
||||||
@@ -429,7 +466,8 @@ fields:
|
|||||||
name: {{if .overrides.resolution}}{{.overrides.resolution}}{{else if .fields.resolution}}{{.fields.resolution.name}}{{else}}{{or .overrides.defaultResolution "Fixed"}}{{end}}
|
name: {{if .overrides.resolution}}{{.overrides.resolution}}{{else if .fields.resolution}}{{.fields.resolution.name}}{{else}}{{or .overrides.defaultResolution "Fixed"}}{{end}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{if .meta.fields.summary}}
|
{{if .meta.fields.summary}}
|
||||||
summary: {{or .overrides.summary .fields.summary}}
|
summary: >-
|
||||||
|
{{or .overrides.summary .fields.summary}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{if .meta.fields.versions.allowedValues}}
|
{{if .meta.fields.versions.allowedValues}}
|
||||||
versions: # Values: {{ range .meta.fields.versions.allowedValues }}{{.name}}, {{end}}{{if .overrides.versions}}{{ range (split "," .overrides.versions)}}
|
versions: # Values: {{ range .meta.fields.versions.allowedValues }}{{.name}}, {{end}}{{if .overrides.versions}}{{ range (split "," .overrides.versions)}}
|
||||||
@@ -446,12 +484,13 @@ const defaultWorklogTemplate = `{{/* worklog template */ -}}
|
|||||||
comment: |~
|
comment: |~
|
||||||
{{ or .comment "" }}
|
{{ or .comment "" }}
|
||||||
timeSpent: {{ or .timeSpent "" }}
|
timeSpent: {{ or .timeSpent "" }}
|
||||||
started:
|
started: {{ or .started "" }}
|
||||||
`
|
`
|
||||||
|
|
||||||
const defaultWorklogsTemplate = `{{/* worklogs template */ -}}
|
const defaultWorklogsTemplate = `{{/* worklogs template */ -}}
|
||||||
{{ range .worklogs }}- # {{.author.name}}, {{.created | age}} ago
|
{{ range .worklogs }}- # {{.author.name}}, {{.created | age}} ago
|
||||||
comment: {{ or .comment "" }}
|
comment: {{ or .comment "" }}
|
||||||
|
started: {{ .started }}
|
||||||
timeSpent: {{ .timeSpent }}
|
timeSpent: {{ .timeSpent }}
|
||||||
|
|
||||||
{{end}}`
|
{{end}}`
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ func CmdComponentsRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
|
|
||||||
func CmdComponentsUsage(cmd *kingpin.CmdClause, opts *ComponentsOptions) error {
|
func CmdComponentsUsage(cmd *kingpin.CmdClause, opts *ComponentsOptions) error {
|
||||||
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
|
||||||
cmd.Flag("project", "project to list components").Short('p').StringVar(&opts.Project)
|
cmd.Flag("project", "project to list components").Short('p').StringVar(&opts.Project)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -51,5 +52,5 @@ func CmdComponents(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Compone
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return jiracli.RunTemplate(opts.Template.Value, data, nil)
|
return opts.PrintTemplate(data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ func CmdCreateMetaRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
|
|
||||||
func CmdCreateMetaUsage(cmd *kingpin.CmdClause, opts *CreateMetaOptions) error {
|
func CmdCreateMetaUsage(cmd *kingpin.CmdClause, opts *CreateMetaOptions) error {
|
||||||
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
|
||||||
cmd.Flag("project", "project to fetch create metadata").Short('p').StringVar(&opts.Project)
|
cmd.Flag("project", "project to fetch create metadata").Short('p').StringVar(&opts.Project)
|
||||||
cmd.Flag("issuetype", "issuetype in project to fetch create metadata").Short('i').StringVar(&opts.IssueType)
|
cmd.Flag("issuetype", "issuetype in project to fetch create metadata").Short('i').StringVar(&opts.IssueType)
|
||||||
return nil
|
return nil
|
||||||
@@ -49,5 +50,5 @@ func CmdCreateMeta(o *oreo.Client, globals *jiracli.GlobalOptions, opts *CreateM
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return jiracli.RunTemplate(opts.Template.Value, createMeta, nil)
|
return opts.PrintTemplate(createMeta)
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-2
@@ -18,6 +18,7 @@ type EditOptions struct {
|
|||||||
jira.SearchOptions `yaml:",inline" json:",inline" figtree:",inline"`
|
jira.SearchOptions `yaml:",inline" json:",inline" figtree:",inline"`
|
||||||
Overrides map[string]string `yaml:"overrides,omitempty" json:"overrides,omitempty"`
|
Overrides map[string]string `yaml:"overrides,omitempty" json:"overrides,omitempty"`
|
||||||
Issue string `yaml:"issue,omitempty" json:"issue,omitempty"`
|
Issue string `yaml:"issue,omitempty" json:"issue,omitempty"`
|
||||||
|
Queries map[string]string `yaml:"queries,omitempty" json:"queries,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func CmdEditRegistry() *jiracli.CommandRegistryEntry {
|
func CmdEditRegistry() *jiracli.CommandRegistryEntry {
|
||||||
@@ -32,7 +33,7 @@ func CmdEditRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
"Edit issue details",
|
"Edit issue details",
|
||||||
func(fig *figtree.FigTree, cmd *kingpin.CmdClause) error {
|
func(fig *figtree.FigTree, cmd *kingpin.CmdClause) error {
|
||||||
jiracli.LoadConfigs(cmd, fig, &opts)
|
jiracli.LoadConfigs(cmd, fig, &opts)
|
||||||
return CmdEditUsage(cmd, &opts)
|
return CmdEditUsage(cmd, &opts, fig)
|
||||||
},
|
},
|
||||||
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
|
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
|
||||||
return CmdEdit(o, globals, &opts)
|
return CmdEdit(o, globals, &opts)
|
||||||
@@ -40,11 +41,20 @@ func CmdEditRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CmdEditUsage(cmd *kingpin.CmdClause, opts *EditOptions) error {
|
func CmdEditUsage(cmd *kingpin.CmdClause, opts *EditOptions, fig *figtree.FigTree) error {
|
||||||
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
|
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
|
||||||
jiracli.EditorUsage(cmd, &opts.CommonOptions)
|
jiracli.EditorUsage(cmd, &opts.CommonOptions)
|
||||||
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
||||||
cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing)
|
cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing)
|
||||||
|
cmd.Flag("named-query", "The name of a query in the `queries` configuration").Short('n').PreAction(func(ctx *kingpin.ParseContext) error {
|
||||||
|
name := jiracli.FlagValue(ctx, "named-query")
|
||||||
|
if query, ok := opts.Queries[name]; ok && query != "" {
|
||||||
|
var err error
|
||||||
|
opts.Query, err = jiracli.ConfigTemplate(fig, query, cmd.FullCommand(), opts)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fmt.Errorf("A valid named-query %q not found in `queries` configuration", name)
|
||||||
|
}).String()
|
||||||
cmd.Flag("query", "Jira Query Language (JQL) expression for the search to edit multiple issues").Short('q').StringVar(&opts.Query)
|
cmd.Flag("query", "Jira Query Language (JQL) expression for the search to edit multiple issues").Short('q').StringVar(&opts.Query)
|
||||||
cmd.Flag("comment", "Comment message for issue").Short('m').PreAction(func(ctx *kingpin.ParseContext) error {
|
cmd.Flag("comment", "Comment message for issue").Short('m').PreAction(func(ctx *kingpin.ParseContext) error {
|
||||||
opts.Overrides["comment"] = jiracli.FlagValue(ctx, "comment")
|
opts.Overrides["comment"] = jiracli.FlagValue(ctx, "comment")
|
||||||
|
|||||||
+2
-1
@@ -36,6 +36,7 @@ func CmdEditMetaRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
func CmdEditMetaUsage(cmd *kingpin.CmdClause, opts *EditMetaOptions) error {
|
func CmdEditMetaUsage(cmd *kingpin.CmdClause, opts *EditMetaOptions) error {
|
||||||
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
|
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
|
||||||
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
|
||||||
cmd.Arg("ISSUE", "edit metadata for issue id").Required().StringVar(&opts.Issue)
|
cmd.Arg("ISSUE", "edit metadata for issue id").Required().StringVar(&opts.Issue)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -46,7 +47,7 @@ func CmdEditMeta(o *oreo.Client, globals *jiracli.GlobalOptions, opts *EditMetaO
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := jiracli.RunTemplate(opts.Template.Value, editMeta, nil); err != nil {
|
if err := opts.PrintTemplate(editMeta); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if opts.Browse.Value {
|
if opts.Browse.Value {
|
||||||
|
|||||||
+2
-1
@@ -17,6 +17,7 @@ func CmdFieldsRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
func(fig *figtree.FigTree, cmd *kingpin.CmdClause) error {
|
func(fig *figtree.FigTree, cmd *kingpin.CmdClause) error {
|
||||||
jiracli.LoadConfigs(cmd, fig, &opts)
|
jiracli.LoadConfigs(cmd, fig, &opts)
|
||||||
jiracli.TemplateUsage(cmd, &opts)
|
jiracli.TemplateUsage(cmd, &opts)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, &opts)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
|
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
|
||||||
@@ -31,5 +32,5 @@ func CmdFields(o *oreo.Client, globals *jiracli.GlobalOptions, opts *jiracli.Com
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return jiracli.RunTemplate(opts.Template.Value, data, nil)
|
return opts.PrintTemplate(data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ func CmdIssueLinkTypesRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
|
|
||||||
func CmdIssueLinkTypesUsage(cmd *kingpin.CmdClause, opts *jiracli.CommonOptions) error {
|
func CmdIssueLinkTypesUsage(cmd *kingpin.CmdClause, opts *jiracli.CommonOptions) error {
|
||||||
jiracli.TemplateUsage(cmd, opts)
|
jiracli.TemplateUsage(cmd, opts)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, opts)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,5 +37,5 @@ func CmdIssueLinkTypes(o *oreo.Client, globals *jiracli.GlobalOptions, opts *jir
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return jiracli.RunTemplate(opts.Template.Value, data, nil)
|
return opts.PrintTemplate(data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ func CmdIssueTypesRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
|
|
||||||
func CmdIssueTypesUsage(cmd *kingpin.CmdClause, opts *IssueTypesOptions) error {
|
func CmdIssueTypesUsage(cmd *kingpin.CmdClause, opts *IssueTypesOptions) error {
|
||||||
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
|
||||||
cmd.Flag("project", "project to list issueTypes").Short('p').StringVar(&opts.Project)
|
cmd.Flag("project", "project to list issueTypes").Short('p').StringVar(&opts.Project)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -51,5 +52,5 @@ func CmdIssueTypes(o *oreo.Client, globals *jiracli.GlobalOptions, opts *IssueTy
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return jiracli.RunTemplate(opts.Template.Value, data, nil)
|
return opts.PrintTemplate(data)
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-3
@@ -1,6 +1,8 @@
|
|||||||
package jiracmd
|
package jiracmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/coryb/figtree"
|
"github.com/coryb/figtree"
|
||||||
"github.com/coryb/oreo"
|
"github.com/coryb/oreo"
|
||||||
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
|
"gopkg.in/Netflix-Skunkworks/go-jira.v1"
|
||||||
@@ -11,6 +13,7 @@ import (
|
|||||||
type ListOptions struct {
|
type ListOptions struct {
|
||||||
jiracli.CommonOptions `yaml:",inline" json:",inline" figtree:",inline"`
|
jiracli.CommonOptions `yaml:",inline" json:",inline" figtree:",inline"`
|
||||||
jira.SearchOptions `yaml:",inline" json:",inline" figtree:",inline"`
|
jira.SearchOptions `yaml:",inline" json:",inline" figtree:",inline"`
|
||||||
|
Queries map[string]string `yaml:"queries,omitempty" json:"queries,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func CmdListRegistry() *jiracli.CommandRegistryEntry {
|
func CmdListRegistry() *jiracli.CommandRegistryEntry {
|
||||||
@@ -33,7 +36,7 @@ func CmdListRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
if opts.Sort == "" {
|
if opts.Sort == "" {
|
||||||
opts.Sort = "priority asc, key"
|
opts.Sort = "priority asc, key"
|
||||||
}
|
}
|
||||||
return CmdListUsage(cmd, &opts)
|
return CmdListUsage(cmd, &opts, fig)
|
||||||
},
|
},
|
||||||
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
|
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
|
||||||
return CmdList(o, globals, &opts)
|
return CmdList(o, globals, &opts)
|
||||||
@@ -41,16 +44,27 @@ func CmdListRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CmdListUsage(cmd *kingpin.CmdClause, opts *ListOptions) error {
|
func CmdListUsage(cmd *kingpin.CmdClause, opts *ListOptions, fig *figtree.FigTree) error {
|
||||||
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
|
||||||
cmd.Flag("assignee", "User assigned the issue").Short('a').StringVar(&opts.Assignee)
|
cmd.Flag("assignee", "User assigned the issue").Short('a').StringVar(&opts.Assignee)
|
||||||
cmd.Flag("component", "Component to search for").Short('c').StringVar(&opts.Component)
|
cmd.Flag("component", "Component to search for").Short('c').StringVar(&opts.Component)
|
||||||
cmd.Flag("issuetype", "Issue type to search for").Short('i').StringVar(&opts.IssueType)
|
cmd.Flag("issuetype", "Issue type to search for").Short('i').StringVar(&opts.IssueType)
|
||||||
cmd.Flag("limit", "Maximum number of results to return in search").Short('l').IntVar(&opts.MaxResults)
|
cmd.Flag("limit", "Maximum number of results to return in search").Short('l').IntVar(&opts.MaxResults)
|
||||||
cmd.Flag("project", "Project to search for").Short('p').StringVar(&opts.Project)
|
cmd.Flag("project", "Project to search for").Short('p').StringVar(&opts.Project)
|
||||||
|
cmd.Flag("named-query", "The name of a query in the `queries` configuration").Short('n').PreAction(func(ctx *kingpin.ParseContext) error {
|
||||||
|
name := jiracli.FlagValue(ctx, "named-query")
|
||||||
|
if query, ok := opts.Queries[name]; ok && query != "" {
|
||||||
|
var err error
|
||||||
|
opts.Query, err = jiracli.ConfigTemplate(fig, query, cmd.FullCommand(), opts)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fmt.Errorf("A valid named-query %q not found in `queries` configuration", name)
|
||||||
|
}).String()
|
||||||
cmd.Flag("query", "Jira Query Language (JQL) expression for the search").Short('q').StringVar(&opts.Query)
|
cmd.Flag("query", "Jira Query Language (JQL) expression for the search").Short('q').StringVar(&opts.Query)
|
||||||
cmd.Flag("queryfields", "Fields that are used in \"list\" template").Short('f').StringVar(&opts.QueryFields)
|
cmd.Flag("queryfields", "Fields that are used in \"list\" template").Short('f').StringVar(&opts.QueryFields)
|
||||||
cmd.Flag("reporter", "Reporter to search for").Short('r').StringVar(&opts.Reporter)
|
cmd.Flag("reporter", "Reporter to search for").Short('r').StringVar(&opts.Reporter)
|
||||||
|
cmd.Flag("status", "Filter on issue status").Short('S').StringVar(&opts.Status)
|
||||||
cmd.Flag("sort", "Sort order to return").Short('s').StringVar(&opts.Sort)
|
cmd.Flag("sort", "Sort order to return").Short('s').StringVar(&opts.Sort)
|
||||||
cmd.Flag("watcher", "Watcher to search for").Short('w').StringVar(&opts.Watcher)
|
cmd.Flag("watcher", "Watcher to search for").Short('w').StringVar(&opts.Watcher)
|
||||||
return nil
|
return nil
|
||||||
@@ -62,5 +76,5 @@ func CmdList(o *oreo.Client, globals *jiracli.GlobalOptions, opts *ListOptions)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return jiracli.RunTemplate(opts.Template.Value, data, nil)
|
return opts.PrintTemplate(data)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -35,6 +35,8 @@ func CmdRequestRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
if opts.Method == "" {
|
if opts.Method == "" {
|
||||||
opts.Method = "GET"
|
opts.Method = "GET"
|
||||||
}
|
}
|
||||||
|
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
|
||||||
return CmdRequestUsage(cmd, &opts)
|
return CmdRequestUsage(cmd, &opts)
|
||||||
},
|
},
|
||||||
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
|
func(o *oreo.Client, globals *jiracli.GlobalOptions) error {
|
||||||
@@ -89,5 +91,5 @@ func CmdRequest(o *oreo.Client, globals *jiracli.GlobalOptions, opts *RequestOpt
|
|||||||
return fmt.Errorf("JSON Parse Error: %s from %q", err, content)
|
return fmt.Errorf("JSON Parse Error: %s from %q", err, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
return jiracli.RunTemplate(opts.Template.Value, &data, nil)
|
return opts.PrintTemplate(&data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,15 @@ func CmdTransition(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Transit
|
|||||||
Overrides map[string]string `yaml:"overrides,omitempty" json:"overrides,omitempty"`
|
Overrides map[string]string `yaml:"overrides,omitempty" json:"overrides,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, ok := transMeta.Fields["comment"]; !ok && opts.Overrides["comment"] != "" {
|
||||||
|
comment := jiradata.Comment{
|
||||||
|
Body: opts.Overrides["comment"],
|
||||||
|
}
|
||||||
|
if _, err := jira.IssueAddComment(o, globals.Endpoint.Value, opts.Issue, &comment); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
issueUpdate := jiradata.IssueUpdate{}
|
issueUpdate := jiradata.IssueUpdate{}
|
||||||
input := templateInput{
|
input := templateInput{
|
||||||
Issue: issueData,
|
Issue: issueData,
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ func CmdTransitionsRegistry(defaultTemplate string) *jiracli.CommandRegistryEntr
|
|||||||
func CmdTransitionsUsage(cmd *kingpin.CmdClause, opts *TransitionsOptions) error {
|
func CmdTransitionsUsage(cmd *kingpin.CmdClause, opts *TransitionsOptions) error {
|
||||||
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
|
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
|
||||||
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
|
||||||
cmd.Arg("ISSUE", "issue to list valid transitions").Required().StringVar(&opts.Issue)
|
cmd.Arg("ISSUE", "issue to list valid transitions").Required().StringVar(&opts.Issue)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -45,7 +46,7 @@ func CmdTransitions(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Transi
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := jiracli.RunTemplate(opts.Template.Value, editMeta, nil); err != nil {
|
if err := opts.PrintTemplate(editMeta); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if opts.Browse.Value {
|
if opts.Browse.Value {
|
||||||
|
|||||||
+2
-1
@@ -36,6 +36,7 @@ func CmdViewRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
func CmdViewUsage(cmd *kingpin.CmdClause, opts *ViewOptions) error {
|
func CmdViewUsage(cmd *kingpin.CmdClause, opts *ViewOptions) error {
|
||||||
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
|
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
|
||||||
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
|
||||||
cmd.Flag("expand", "field to expand for the issue").StringsVar(&opts.Expand)
|
cmd.Flag("expand", "field to expand for the issue").StringsVar(&opts.Expand)
|
||||||
cmd.Flag("field", "field to return for the issue").StringsVar(&opts.Fields)
|
cmd.Flag("field", "field to return for the issue").StringsVar(&opts.Fields)
|
||||||
cmd.Flag("property", "property to return for issue").StringsVar(&opts.Properties)
|
cmd.Flag("property", "property to return for issue").StringsVar(&opts.Properties)
|
||||||
@@ -49,7 +50,7 @@ func CmdView(o *oreo.Client, globals *jiracli.GlobalOptions, opts *ViewOptions)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := jiracli.RunTemplate(opts.Template.Value, data, nil); err != nil {
|
if err := opts.PrintTemplate(data); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if opts.Browse.Value {
|
if opts.Browse.Value {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ func CmdWorklogAddUsage(cmd *kingpin.CmdClause, opts *WorklogAddOptions) error {
|
|||||||
cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing)
|
cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing)
|
||||||
cmd.Flag("comment", "Comment message for worklog").Short('m').StringVar(&opts.Comment)
|
cmd.Flag("comment", "Comment message for worklog").Short('m').StringVar(&opts.Comment)
|
||||||
cmd.Flag("time-spent", "Time spent working on issue").Short('T').StringVar(&opts.TimeSpent)
|
cmd.Flag("time-spent", "Time spent working on issue").Short('T').StringVar(&opts.TimeSpent)
|
||||||
|
cmd.Flag("started", "Time you started work").Short('S').StringVar(&opts.Started)
|
||||||
cmd.Arg("ISSUE", "issue id to fetch worklogs").Required().StringVar(&opts.Issue)
|
cmd.Arg("ISSUE", "issue id to fetch worklogs").Required().StringVar(&opts.Issue)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ func CmdWorklogListRegistry() *jiracli.CommandRegistryEntry {
|
|||||||
func CmdWorklogListUsage(cmd *kingpin.CmdClause, opts *WorklogListOptions) error {
|
func CmdWorklogListUsage(cmd *kingpin.CmdClause, opts *WorklogListOptions) error {
|
||||||
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
|
jiracli.BrowseUsage(cmd, &opts.CommonOptions)
|
||||||
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
jiracli.TemplateUsage(cmd, &opts.CommonOptions)
|
||||||
|
jiracli.GJsonQueryUsage(cmd, &opts.CommonOptions)
|
||||||
cmd.Arg("ISSUE", "issue id to fetch worklogs").Required().StringVar(&opts.Issue)
|
cmd.Arg("ISSUE", "issue id to fetch worklogs").Required().StringVar(&opts.Issue)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -45,9 +46,9 @@ func CmdWorklogList(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Worklo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := jiracli.RunTemplate(opts.Template.Value, struct {
|
if err := opts.PrintTemplate(struct {
|
||||||
Worklogs *jiradata.Worklogs `json:"worklogs,omitempty" yaml:"worklogs,omitempty"`
|
Worklogs *jiradata.Worklogs `json:"worklogs,omitempty" yaml:"worklogs,omitempty"`
|
||||||
}{data}, nil); err != nil {
|
}{data}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if opts.Browse.Value {
|
if opts.Browse.Value {
|
||||||
|
|||||||
@@ -14,16 +14,17 @@ type SearchProvider interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SearchOptions struct {
|
type SearchOptions struct {
|
||||||
Assignee string
|
Assignee string `yaml:"assignee,omitempty" json:"assignee,omitempty"`
|
||||||
Query string
|
Query string `yaml:"query,omitempty" json:"query,omitempty"`
|
||||||
QueryFields string
|
QueryFields string `yaml:"query-fields,omitempty" json:"query-fields,omitempty"`
|
||||||
Project string
|
Project string `yaml:"project,omitempty" json:"project,omitempty"`
|
||||||
Component string
|
Component string `yaml:"component,omitempty" json:"component,omitempty"`
|
||||||
IssueType string
|
IssueType string `yaml:"issue-type,omitempty" json:"issue-type,omitempty"`
|
||||||
Watcher string
|
Watcher string `yaml:"watcher,omitempty" json:"watcher,omitempty"`
|
||||||
Reporter string
|
Reporter string `yaml:"reporter,omitempty" json:"reporter,omitempty"`
|
||||||
Sort string
|
Status string `yaml:"status,omitempty" json:"status,omitempty"`
|
||||||
MaxResults int
|
Sort string `yaml:"sort,omitempty" json:"sort,omitempty"`
|
||||||
|
MaxResults int `yaml:"max-results,omitempty" json:"max-results,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *SearchOptions) ProvideSearchRequest() *jiradata.SearchRequest {
|
func (o *SearchOptions) ProvideSearchRequest() *jiradata.SearchRequest {
|
||||||
@@ -49,6 +50,9 @@ func (o *SearchOptions) ProvideSearchRequest() *jiradata.SearchRequest {
|
|||||||
if o.Reporter != "" {
|
if o.Reporter != "" {
|
||||||
qbuff.WriteString(fmt.Sprintf(" AND reporter = '%s'", o.Reporter))
|
qbuff.WriteString(fmt.Sprintf(" AND reporter = '%s'", o.Reporter))
|
||||||
}
|
}
|
||||||
|
if o.Status != "" {
|
||||||
|
qbuff.WriteString(fmt.Sprintf(" AND status = '%s'", o.Status))
|
||||||
|
}
|
||||||
if o.Sort != "" {
|
if o.Sort != "" {
|
||||||
qbuff.WriteString(fmt.Sprintf(" ORDER BY %s", o.Sort))
|
qbuff.WriteString(fmt.Sprintf(" ORDER BY %s", o.Sort))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,3 +3,42 @@ config:
|
|||||||
password-source: pass
|
password-source: pass
|
||||||
endpoint: https://go-jira.atlassian.net
|
endpoint: https://go-jira.atlassian.net
|
||||||
user: gojira
|
user: gojira
|
||||||
|
|
||||||
|
project: BASIC
|
||||||
|
|
||||||
|
custom-commands:
|
||||||
|
- name: env
|
||||||
|
help: print the JIRA environment variables available to custom commands
|
||||||
|
script: |-
|
||||||
|
env | sort | grep JIRA
|
||||||
|
- name: print-project
|
||||||
|
help: print the name of the configured project
|
||||||
|
script: "echo $JIRA_PROJECT"
|
||||||
|
- name: jira-path
|
||||||
|
help: print the path the jira command that is running this alias
|
||||||
|
script: |-
|
||||||
|
echo {{jira}}
|
||||||
|
- name: mine
|
||||||
|
help: display issues assigned to me
|
||||||
|
script: |-
|
||||||
|
if [ -n "$JIRA_PROJECT" ]; then
|
||||||
|
# if `project: ...` configured just list the issues for current project
|
||||||
|
{{jira}} list --template table --query "resolution = unresolved and assignee=currentuser() and project = $JIRA_PROJECT ORDER BY priority asc, created"
|
||||||
|
else
|
||||||
|
# otherwise list issues for all project
|
||||||
|
{{jira}} list --template table --query "resolution = unresolved and assignee=currentuser() ORDER BY priority asc, created"
|
||||||
|
fi
|
||||||
|
- name: argtest
|
||||||
|
help: testing passing args
|
||||||
|
script: |-
|
||||||
|
echo {{args.ARG}}
|
||||||
|
args:
|
||||||
|
- name: ARG
|
||||||
|
help: string to echo for testing
|
||||||
|
- name: opttest
|
||||||
|
help: testing passing option flags
|
||||||
|
script: |-
|
||||||
|
echo {{options.OPT}}
|
||||||
|
options:
|
||||||
|
- name: OPT
|
||||||
|
help: string to echo for testing
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
|||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
jira="../jira --user admin"
|
jira="../jira --user admin"
|
||||||
|
|
||||||
|
. env.sh
|
||||||
|
|
||||||
SKIP test -n "$JIRACLOUD" # using Jira Cloud at go-jira.atlassian.net
|
SKIP test -n "$JIRACLOUD" # using Jira Cloud at go-jira.atlassian.net
|
||||||
PLAN 15
|
PLAN 15
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
jira=../jira
|
jira=../jira
|
||||||
|
. env.sh
|
||||||
|
|
||||||
SKIP test -n "$JIRACLOUD" # using Jira Cloud at go-jira.atlassian.net
|
SKIP test -n "$JIRACLOUD" # using Jira Cloud at go-jira.atlassian.net
|
||||||
|
|
||||||
|
|||||||
+1
-7
@@ -2,13 +2,7 @@
|
|||||||
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
jira="../jira"
|
jira="../jira"
|
||||||
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
|
. env.sh
|
||||||
|
|
||||||
export COLUMNS=149
|
|
||||||
ENDPOINT="http://localhost:8080"
|
|
||||||
if [ -n "$JIRACLOUD" ]; then
|
|
||||||
ENDPOINT="https://go-jira.atlassian.net"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PLAN 86
|
PLAN 86
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,7 @@
|
|||||||
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
jira="../jira"
|
jira="../jira"
|
||||||
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
|
. env.sh
|
||||||
|
|
||||||
ENDPOINT="http://localhost:8080"
|
|
||||||
if [ -n "$JIRACLOUD" ]; then
|
|
||||||
ENDPOINT="https://go-jira.atlassian.net"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PLAN 8
|
PLAN 8
|
||||||
|
|
||||||
@@ -31,7 +26,7 @@ EOF
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
## Add a worklog to an issue
|
## Add a worklog to an issue
|
||||||
###############################################################################
|
###############################################################################
|
||||||
RUNS $jira worklog add $issue --comment "work is hard" --time-spent "1h 12m" --noedit
|
RUNS $jira worklog add $issue --comment "work is hard" --time-spent "1h 12m" -S "2017-01-29T09:17:00.000-0500" --noedit
|
||||||
DIFF <<EOF
|
DIFF <<EOF
|
||||||
OK $issue $ENDPOINT/browse/$issue
|
OK $issue $ENDPOINT/browse/$issue
|
||||||
EOF
|
EOF
|
||||||
@@ -43,6 +38,7 @@ RUNS $jira worklog $issue
|
|||||||
DIFF <<EOF
|
DIFF <<EOF
|
||||||
- # gojira, a minute ago
|
- # gojira, a minute ago
|
||||||
comment: work is hard
|
comment: work is hard
|
||||||
|
started: 2017-01-29T06:17:00.000-0800
|
||||||
timeSpent: 1h 12m
|
timeSpent: 1h 12m
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
Executable
+88
@@ -0,0 +1,88 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
||||||
|
cd $(dirname $0)
|
||||||
|
jira="../jira"
|
||||||
|
. env.sh
|
||||||
|
|
||||||
|
PLAN 16
|
||||||
|
|
||||||
|
# reset login
|
||||||
|
RUNS $jira logout
|
||||||
|
RUNS $jira login
|
||||||
|
|
||||||
|
# cleanup from previous failed test executions
|
||||||
|
($jira ls --project BASIC | awk -F: '{print $1}' | while read issue; do ../jira done $issue; done) | sed 's/^/# CLEANUP: /g'
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
## Create an issue
|
||||||
|
###############################################################################
|
||||||
|
RUNS $jira create --project BASIC -o summary=summary -o description=description --noedit --saveFile issue.props
|
||||||
|
issue=$(awk '/issue/{print $2}' issue.props)
|
||||||
|
|
||||||
|
DIFF <<EOF
|
||||||
|
OK $issue $ENDPOINT/browse/$issue
|
||||||
|
EOF
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
## Testing the example custom commands, print-project
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
RUNS $jira print-project
|
||||||
|
DIFF <<EOF
|
||||||
|
BASIC
|
||||||
|
EOF
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
## Testing the example custom commands, jira-path
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
RUNS $jira jira-path
|
||||||
|
DIFF <<EOF
|
||||||
|
../jira
|
||||||
|
EOF
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
## Testing the example custom commands, env
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
RUNS $jira env
|
||||||
|
DIFF <<'EOF'
|
||||||
|
JIRACLOUD=1
|
||||||
|
JIRA_CUSTOM_COMMANDS=[{"name":"env","script":"env | sort | grep JIRA","help":"print the JIRA environment variables available to custom commands"},{"name":"print-project","script":"echo $JIRA_PROJECT","help":"print the name of the configured project"},{"name":"jira-path","script":"echo {{jira}}","help":"print the path the jira command that is running this alias"},{"name":"mine","script":"if [ -n \"$JIRA_PROJECT\" ]; then\n # if `project: ...` configured just list the issues for current project\n {{jira}} list --template table --query \"resolution = unresolved and assignee=currentuser() and project = $JIRA_PROJECT ORDER BY priority asc, created\"\nelse\n # otherwise list issues for all project\n {{jira}} list --template table --query \"resolution = unresolved and assignee=currentuser() ORDER BY priority asc, created\"\nfi","help":"display issues assigned to me"},{"name":"argtest","args":[{"name":"ARG","help":"string to echo for testing"}],"script":"echo {{args.ARG}}","help":"testing passing args"},{"name":"opttest","options":[{"name":"OPT","help":"string to echo for testing"}],"script":"echo {{options.OPT}}","help":"testing passing option flags"}]
|
||||||
|
JIRA_ENDPOINT=https://go-jira.atlassian.net
|
||||||
|
JIRA_LOG_FORMAT=%{level:-5s} %{message}
|
||||||
|
JIRA_PASSWORD_SOURCE=pass
|
||||||
|
JIRA_PROJECT=BASIC
|
||||||
|
JIRA_USER=gojira
|
||||||
|
EOF
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
## Testing the example custom commands, argtest
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
RUNS $jira argtest TEST
|
||||||
|
DIFF <<EOF
|
||||||
|
TEST
|
||||||
|
EOF
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
## Testing the example custom commands, opttest
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
RUNS $jira opttest --OPT TEST
|
||||||
|
DIFF <<EOF
|
||||||
|
TEST
|
||||||
|
EOF
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
## Use the "mine" alias to list issues assigned to self
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
RUNS $jira mine
|
||||||
|
DIFF <<EOF
|
||||||
|
+----------------+---------------------------------------------------------+--------------+--------------+------------+--------------+--------------+
|
||||||
|
| Issue | Summary | Priority | Status | Age | Reporter | Assignee |
|
||||||
|
+----------------+---------------------------------------------------------+--------------+--------------+------------+--------------+--------------+
|
||||||
|
| $(printf %-14s $issue) | summary | Medium | To Do | a minute | gojira | gojira |
|
||||||
|
+----------------+---------------------------------------------------------+--------------+--------------+------------+--------------+--------------+
|
||||||
|
EOF
|
||||||
+1
-6
@@ -2,12 +2,7 @@
|
|||||||
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
jira="../jira"
|
jira="../jira"
|
||||||
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
|
. env.sh
|
||||||
|
|
||||||
ENDPOINT="http://localhost:8080"
|
|
||||||
if [ -n "$JIRACLOUD" ]; then
|
|
||||||
ENDPOINT="https://go-jira.atlassian.net"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PLAN 84
|
PLAN 84
|
||||||
|
|
||||||
|
|||||||
+1
-6
@@ -2,12 +2,7 @@
|
|||||||
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
jira="../jira"
|
jira="../jira"
|
||||||
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
|
. env.sh
|
||||||
|
|
||||||
ENDPOINT="http://localhost:8080"
|
|
||||||
if [ -n "$JIRACLOUD" ]; then
|
|
||||||
ENDPOINT="https://go-jira.atlassian.net"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PLAN 86
|
PLAN 86
|
||||||
|
|
||||||
|
|||||||
+1
-6
@@ -2,12 +2,7 @@
|
|||||||
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
jira="../jira"
|
jira="../jira"
|
||||||
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
|
. env.sh
|
||||||
|
|
||||||
ENDPOINT="http://localhost:8080"
|
|
||||||
if [ -n "$JIRACLOUD" ]; then
|
|
||||||
ENDPOINT="https://go-jira.atlassian.net"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PLAN 84
|
PLAN 84
|
||||||
|
|
||||||
|
|||||||
+1
-6
@@ -2,12 +2,7 @@
|
|||||||
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
jira="../jira"
|
jira="../jira"
|
||||||
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
|
. env.sh
|
||||||
|
|
||||||
ENDPOINT="http://localhost:8080"
|
|
||||||
if [ -n "$JIRACLOUD" ]; then
|
|
||||||
ENDPOINT="https://go-jira.atlassian.net"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PLAN 84
|
PLAN 84
|
||||||
|
|
||||||
|
|||||||
+1
-6
@@ -2,12 +2,7 @@
|
|||||||
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
jira="../jira"
|
jira="../jira"
|
||||||
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
|
. env.sh
|
||||||
|
|
||||||
ENDPOINT="http://localhost:8080"
|
|
||||||
if [ -n "$JIRACLOUD" ]; then
|
|
||||||
ENDPOINT="https://go-jira.atlassian.net"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PLAN 82
|
PLAN 82
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export COLUMNS=149
|
||||||
|
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
|
||||||
|
export ENDPOINT="https://go-jira.atlassian.net"
|
||||||
|
export GNUPGHOME=$(pwd)/.gnupg
|
||||||
|
export PASSWORD_STORE_DIR=$(pwd)/.password-store
|
||||||
|
export JIRACLOUD=1
|
||||||
|
|
||||||
-46
@@ -1,46 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
)
|
|
||||||
|
|
||||||
// the questions to ask
|
|
||||||
var simpleQs = []*survey.Question{
|
|
||||||
{
|
|
||||||
Name: "letter",
|
|
||||||
Prompt: &survey.Select{
|
|
||||||
Message: "Choose a letter:",
|
|
||||||
Options: []string{
|
|
||||||
"a",
|
|
||||||
"b",
|
|
||||||
"c",
|
|
||||||
"d",
|
|
||||||
"e",
|
|
||||||
"f",
|
|
||||||
"g",
|
|
||||||
"h",
|
|
||||||
"i",
|
|
||||||
"j",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
answers := struct {
|
|
||||||
Letter string
|
|
||||||
}{}
|
|
||||||
|
|
||||||
// ask the question
|
|
||||||
err := survey.Ask(simpleQs, &answers)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// print the answers
|
|
||||||
fmt.Printf("you chose %s.\n", answers.Letter)
|
|
||||||
}
|
|
||||||
-40
@@ -1,40 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
)
|
|
||||||
|
|
||||||
// the questions to ask
|
|
||||||
var simpleQs = []*survey.Question{
|
|
||||||
{
|
|
||||||
Name: "name",
|
|
||||||
Prompt: &survey.Input{
|
|
||||||
Message: "What is your name?",
|
|
||||||
},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "color",
|
|
||||||
Prompt: &survey.Select{
|
|
||||||
Message: "Choose a color:",
|
|
||||||
Options: []string{"red", "blue", "green"},
|
|
||||||
},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
ansmap := make(map[string]string)
|
|
||||||
|
|
||||||
// ask the question
|
|
||||||
err := survey.Ask(simpleQs, &ansmap)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// print the answers
|
|
||||||
fmt.Printf("%s chose %s.\n", ansmap["name"], ansmap["color"])
|
|
||||||
}
|
|
||||||
-43
@@ -1,43 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
)
|
|
||||||
|
|
||||||
// the questions to ask
|
|
||||||
var simpleQs = []*survey.Question{
|
|
||||||
{
|
|
||||||
Name: "name",
|
|
||||||
Prompt: &survey.Input{
|
|
||||||
Message: "What is your name?",
|
|
||||||
},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "color",
|
|
||||||
Prompt: &survey.Select{
|
|
||||||
Message: "Choose a color:",
|
|
||||||
Options: []string{"red", "blue", "green"},
|
|
||||||
},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
answers := struct {
|
|
||||||
Name string
|
|
||||||
Color string
|
|
||||||
}{}
|
|
||||||
|
|
||||||
// ask the question
|
|
||||||
err := survey.Ask(simpleQs, &answers)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// print the answers
|
|
||||||
fmt.Printf("%s chose %s.\n", answers.Name, answers.Color)
|
|
||||||
}
|
|
||||||
-41
@@ -1,41 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
)
|
|
||||||
|
|
||||||
// the questions to ask
|
|
||||||
var validationQs = []*survey.Question{
|
|
||||||
{
|
|
||||||
Name: "name",
|
|
||||||
Prompt: &survey.Input{Message: "What is your name?"},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "valid",
|
|
||||||
Prompt: &survey.Input{Message: "Enter 'foo':", Default: "not foo"},
|
|
||||||
Validate: func(val interface{}) error {
|
|
||||||
// if the input matches the expectation
|
|
||||||
if str := val.(string); str != "foo" {
|
|
||||||
return fmt.Errorf("You entered %s, not 'foo'.", str)
|
|
||||||
}
|
|
||||||
// nothing was wrong
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// the place to hold the answers
|
|
||||||
answers := struct {
|
|
||||||
Name string
|
|
||||||
Valid string
|
|
||||||
}{}
|
|
||||||
err := survey.Ask(validationQs, &answers)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("\n", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-6
@@ -1,6 +0,0 @@
|
|||||||
# survey/tests
|
|
||||||
|
|
||||||
Because of the nature of this library, I was having a hard time finding a reliable
|
|
||||||
way to run unit tests, therefore I decided to try to create a suite
|
|
||||||
of integration tests which must be run successfully before a PR can be merged.
|
|
||||||
I will try to add to this suite as new edge cases are known.
|
|
||||||
-60
@@ -1,60 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
)
|
|
||||||
|
|
||||||
// the questions to ask
|
|
||||||
var simpleQs = []*survey.Question{
|
|
||||||
{
|
|
||||||
Name: "name",
|
|
||||||
Prompt: &survey.Input{
|
|
||||||
Message: "What is your name?",
|
|
||||||
Default: "Johnny Appleseed",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "color",
|
|
||||||
Prompt: &survey.Select{
|
|
||||||
Message: "Choose a color:",
|
|
||||||
Options: []string{"red", "blue", "green", "yellow"},
|
|
||||||
Default: "yellow",
|
|
||||||
},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
fmt.Println("Asking many.")
|
|
||||||
// a place to store the answers
|
|
||||||
ans := struct {
|
|
||||||
Name string
|
|
||||||
Color string
|
|
||||||
}{}
|
|
||||||
err := survey.Ask(simpleQs, &ans)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Asking one.")
|
|
||||||
answer := ""
|
|
||||||
err = survey.AskOne(simpleQs[0].Prompt, &answer, nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Printf("Answered with %v.\n", answer)
|
|
||||||
|
|
||||||
fmt.Println("Asking one with validation.")
|
|
||||||
vAns := ""
|
|
||||||
err = survey.AskOne(&survey.Input{Message: "What is your name?"}, &vAns, survey.Required)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Printf("Answered with %v.\n", vAns)
|
|
||||||
}
|
|
||||||
-180
@@ -1,180 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DO NOT MODIFY THIS FILE!
|
|
||||||
//
|
|
||||||
// This file was automatically generated via the commands:
|
|
||||||
//
|
|
||||||
// go get github.com/coryb/autoplay
|
|
||||||
// autoplay -n autoplay/ask.go go run ask.go
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"github.com/kr/pty"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RED = "\033[31m"
|
|
||||||
RESET = "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fh, tty, _ := pty.Open()
|
|
||||||
defer tty.Close()
|
|
||||||
defer fh.Close()
|
|
||||||
c := exec.Command("go", "run", "ask.go")
|
|
||||||
c.Stdin = tty
|
|
||||||
c.Stdout = tty
|
|
||||||
c.Stderr = tty
|
|
||||||
c.Start()
|
|
||||||
buf := bufio.NewReaderSize(fh, 1024)
|
|
||||||
|
|
||||||
expect("Asking many.\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your name? \x1b[0m\x1b[37m(Johnny Appleseed) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("L"))
|
|
||||||
expect("L", buf)
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("a", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("r", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("r", buf)
|
|
||||||
fh.Write([]byte("y"))
|
|
||||||
expect("y", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect(" ", buf)
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("B", buf)
|
|
||||||
fh.Write([]byte("i"))
|
|
||||||
expect("i", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("r", buf)
|
|
||||||
fh.Write([]byte("d"))
|
|
||||||
expect("d", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your name? \x1b[0m\x1b[36mLarry Bird\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ yellow\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("A"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ green\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m yellow\x1b[0m\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("A"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m yellow\x1b[0m\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\x1b[36m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("Asking one.\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your name? \x1b[0m\x1b[37m(Johnny Appleseed) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("L"))
|
|
||||||
expect("L", buf)
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("a", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("r", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("r", buf)
|
|
||||||
fh.Write([]byte("y"))
|
|
||||||
expect("y", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect(" ", buf)
|
|
||||||
fh.Write([]byte("K"))
|
|
||||||
expect("K", buf)
|
|
||||||
fh.Write([]byte("i"))
|
|
||||||
expect("i", buf)
|
|
||||||
fh.Write([]byte("n"))
|
|
||||||
expect("n", buf)
|
|
||||||
fh.Write([]byte("g"))
|
|
||||||
expect("g", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your name? \x1b[0m\x1b[36mLarry King\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered with Larry King.\r\n", buf)
|
|
||||||
expect("Asking one with validation.\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your name? \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[31m✘ Sorry, your reply was invalid: Value is required\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your name? \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("L"))
|
|
||||||
expect("L", buf)
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("a", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("r", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("r", buf)
|
|
||||||
fh.Write([]byte("y"))
|
|
||||||
expect("y", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect(" ", buf)
|
|
||||||
fh.Write([]byte("W"))
|
|
||||||
expect("W", buf)
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("a", buf)
|
|
||||||
fh.Write([]byte("l"))
|
|
||||||
expect("l", buf)
|
|
||||||
fh.Write([]byte("l"))
|
|
||||||
expect("l", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your name? \x1b[0m\x1b[36mLarry Wall\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered with Larry Wall.\r\n", buf)
|
|
||||||
|
|
||||||
c.Wait()
|
|
||||||
tty.Close()
|
|
||||||
fh.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func expect(expected string, buf *bufio.Reader) {
|
|
||||||
sofar := []rune{}
|
|
||||||
for _, r := range expected {
|
|
||||||
got, _, _ := buf.ReadRune()
|
|
||||||
sofar = append(sofar, got)
|
|
||||||
if got != r {
|
|
||||||
fmt.Fprintln(os.Stderr, RESET)
|
|
||||||
|
|
||||||
// we want to quote the string but we also want to make the unexpected character RED
|
|
||||||
// so we use the strconv.Quote function but trim off the quoted characters so we can
|
|
||||||
// merge multiple quoted strings into one.
|
|
||||||
expStart := strings.TrimSuffix(strconv.Quote(expected[:len(sofar)-1]), "\"")
|
|
||||||
expMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(expected[len(sofar)-1])), "\""), "\"")
|
|
||||||
expEnd := strings.TrimPrefix(strconv.Quote(expected[len(sofar):]), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Expected: %s%s%s%s%s\n", expStart, RED, expMiss, RESET, expEnd)
|
|
||||||
|
|
||||||
// read the rest of the buffer
|
|
||||||
p := make([]byte, buf.Buffered())
|
|
||||||
buf.Read(p)
|
|
||||||
|
|
||||||
gotStart := strings.TrimSuffix(strconv.Quote(string(sofar[:len(sofar)-1])), "\"")
|
|
||||||
gotMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(sofar[len(sofar)-1])), "\""), "\"")
|
|
||||||
gotEnd := strings.TrimPrefix(strconv.Quote(string(p)), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Got: %s%s%s%s%s\n", gotStart, RED, gotMiss, RESET, gotEnd)
|
|
||||||
panic(fmt.Errorf("Unexpected Rune %q, Expected %q\n", got, r))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%c", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-132
@@ -1,132 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DO NOT MODIFY THIS FILE!
|
|
||||||
//
|
|
||||||
// This file was automatically generated via the commands:
|
|
||||||
//
|
|
||||||
// go get github.com/coryb/autoplay
|
|
||||||
// autoplay -n autoplay/confirm.go go run confirm.go
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"github.com/kr/pty"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RED = "\033[31m"
|
|
||||||
RESET = "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fh, tty, _ := pty.Open()
|
|
||||||
defer tty.Close()
|
|
||||||
defer fh.Close()
|
|
||||||
c := exec.Command("go", "run", "confirm.go")
|
|
||||||
c.Stdin = tty
|
|
||||||
c.Stdout = tty
|
|
||||||
c.Stderr = tty
|
|
||||||
c.Start()
|
|
||||||
buf := bufio.NewReaderSize(fh, 1024)
|
|
||||||
|
|
||||||
expect("Enter 'yes'\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[37m(y/N) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("y"))
|
|
||||||
expect("y", buf)
|
|
||||||
fh.Write([]byte("e"))
|
|
||||||
expect("e", buf)
|
|
||||||
fh.Write([]byte("s"))
|
|
||||||
expect("s", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[36mYes\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered true.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("Enter 'no'\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[37m(y/N) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("n"))
|
|
||||||
expect("n", buf)
|
|
||||||
fh.Write([]byte("o"))
|
|
||||||
expect("o", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[36mNo\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered false.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("default\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[37m(Y/n) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[36mYes\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered true.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("not recognized (enter random letter)\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[37m(Y/n) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("x"))
|
|
||||||
expect("x", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[31m✘ Sorry, your reply was invalid: \"x\" is not a valid answer, please try again.\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[37m(Y/n) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[36mYes\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered true.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("no help - type '?'\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[37m(Y/n) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("?"))
|
|
||||||
expect("?", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[31m✘ Sorry, your reply was invalid: \"?\" is not a valid answer, please try again.\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[37m(Y/n) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99myes: \x1b[0m\x1b[36mYes\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered true.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
|
|
||||||
c.Wait()
|
|
||||||
tty.Close()
|
|
||||||
fh.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func expect(expected string, buf *bufio.Reader) {
|
|
||||||
sofar := []rune{}
|
|
||||||
for _, r := range expected {
|
|
||||||
got, _, _ := buf.ReadRune()
|
|
||||||
sofar = append(sofar, got)
|
|
||||||
if got != r {
|
|
||||||
fmt.Fprintln(os.Stderr, RESET)
|
|
||||||
|
|
||||||
// we want to quote the string but we also want to make the unexpected character RED
|
|
||||||
// so we use the strconv.Quote function but trim off the quoted characters so we can
|
|
||||||
// merge multiple quoted strings into one.
|
|
||||||
expStart := strings.TrimSuffix(strconv.Quote(expected[:len(sofar)-1]), "\"")
|
|
||||||
expMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(expected[len(sofar)-1])), "\""), "\"")
|
|
||||||
expEnd := strings.TrimPrefix(strconv.Quote(expected[len(sofar):]), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Expected: %s%s%s%s%s\n", expStart, RED, expMiss, RESET, expEnd)
|
|
||||||
|
|
||||||
// read the rest of the buffer
|
|
||||||
p := make([]byte, buf.Buffered())
|
|
||||||
buf.Read(p)
|
|
||||||
|
|
||||||
gotStart := strings.TrimSuffix(strconv.Quote(string(sofar[:len(sofar)-1])), "\"")
|
|
||||||
gotMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(sofar[len(sofar)-1])), "\""), "\"")
|
|
||||||
gotEnd := strings.TrimPrefix(strconv.Quote(string(p)), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Got: %s%s%s%s%s\n", gotStart, RED, gotMiss, RESET, gotEnd)
|
|
||||||
panic(fmt.Errorf("Unexpected Rune %q, Expected %q\n", got, r))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%c", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-104
@@ -1,104 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DO NOT MODIFY THIS FILE!
|
|
||||||
//
|
|
||||||
// This file was automatically generated via the commands:
|
|
||||||
//
|
|
||||||
// go get github.com/coryb/autoplay
|
|
||||||
// autoplay -n autoplay/doubleSelect.go go run doubleSelect.go
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"github.com/kr/pty"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RED = "\033[31m"
|
|
||||||
RESET = "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fh, tty, _ := pty.Open()
|
|
||||||
defer tty.Close()
|
|
||||||
defer fh.Close()
|
|
||||||
c := exec.Command("go", "run", "doubleSelect.go")
|
|
||||||
c.Stdin = tty
|
|
||||||
c.Stdout = tty
|
|
||||||
c.Stderr = tty
|
|
||||||
c.Start()
|
|
||||||
buf := bufio.NewReaderSize(fh, 1024)
|
|
||||||
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mselect1:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mselect1:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mselect1:\x1b[0m\x1b[36m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mselect2:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mselect2:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mselect2:\x1b[0m\x1b[36m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("blue and blue.\r\n", buf)
|
|
||||||
|
|
||||||
c.Wait()
|
|
||||||
tty.Close()
|
|
||||||
fh.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func expect(expected string, buf *bufio.Reader) {
|
|
||||||
sofar := []rune{}
|
|
||||||
for _, r := range expected {
|
|
||||||
got, _, _ := buf.ReadRune()
|
|
||||||
sofar = append(sofar, got)
|
|
||||||
if got != r {
|
|
||||||
fmt.Fprintln(os.Stderr, RESET)
|
|
||||||
|
|
||||||
// we want to quote the string but we also want to make the unexpected character RED
|
|
||||||
// so we use the strconv.Quote function but trim off the quoted characters so we can
|
|
||||||
// merge multiple quoted strings into one.
|
|
||||||
expStart := strings.TrimSuffix(strconv.Quote(expected[:len(sofar)-1]), "\"")
|
|
||||||
expMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(expected[len(sofar)-1])), "\""), "\"")
|
|
||||||
expEnd := strings.TrimPrefix(strconv.Quote(expected[len(sofar):]), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Expected: %s%s%s%s%s\n", expStart, RED, expMiss, RESET, expEnd)
|
|
||||||
|
|
||||||
// read the rest of the buffer
|
|
||||||
p := make([]byte, buf.Buffered())
|
|
||||||
buf.Read(p)
|
|
||||||
|
|
||||||
gotStart := strings.TrimSuffix(strconv.Quote(string(sofar[:len(sofar)-1])), "\"")
|
|
||||||
gotMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(sofar[len(sofar)-1])), "\""), "\"")
|
|
||||||
gotEnd := strings.TrimPrefix(strconv.Quote(string(p)), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Got: %s%s%s%s%s\n", gotStart, RED, gotMiss, RESET, gotEnd)
|
|
||||||
panic(fmt.Errorf("Unexpected Rune %q, Expected %q\n", got, r))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%c", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-236
@@ -1,236 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DO NOT MODIFY THIS FILE!
|
|
||||||
//
|
|
||||||
// This file was automatically generated via the commands:
|
|
||||||
//
|
|
||||||
// go get github.com/coryb/autoplay
|
|
||||||
// autoplay -n autoplay/help.go go run help.go
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"github.com/kr/pty"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RED = "\033[31m"
|
|
||||||
RESET = "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fh, tty, _ := pty.Open()
|
|
||||||
defer tty.Close()
|
|
||||||
defer fh.Close()
|
|
||||||
c := exec.Command("go", "run", "help.go")
|
|
||||||
c.Stdin = tty
|
|
||||||
c.Stdout = tty
|
|
||||||
c.Stderr = tty
|
|
||||||
c.Start()
|
|
||||||
buf := bufio.NewReaderSize(fh, 1024)
|
|
||||||
|
|
||||||
expect("confirm\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mIs it raining? \x1b[0m\x1b[36m[? for help]\x1b[0m \x1b[37m(y/N) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("?"))
|
|
||||||
expect("?", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[36mⓘ Go outside, if your head becomes wet the answer is probably 'yes'\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mIs it raining? \x1b[0m\x1b[37m(y/N) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("y"))
|
|
||||||
expect("y", buf)
|
|
||||||
fh.Write([]byte("e"))
|
|
||||||
expect("e", buf)
|
|
||||||
fh.Write([]byte("s"))
|
|
||||||
expect("s", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mIs it raining? \x1b[0m\x1b[36mYes\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered true.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("input\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your phone number: \x1b[0m\x1b[36m[? for help]\x1b[0m ", buf)
|
|
||||||
fh.Write([]byte("?"))
|
|
||||||
expect("?", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[36mⓘ Phone number should include the area code, parentheses optional\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your phone number: \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("1"))
|
|
||||||
expect("1", buf)
|
|
||||||
fh.Write([]byte("2"))
|
|
||||||
expect("2", buf)
|
|
||||||
fh.Write([]byte("3"))
|
|
||||||
expect("3", buf)
|
|
||||||
fh.Write([]byte("-"))
|
|
||||||
expect("-", buf)
|
|
||||||
fh.Write([]byte("1"))
|
|
||||||
expect("1", buf)
|
|
||||||
fh.Write([]byte("2"))
|
|
||||||
expect("2", buf)
|
|
||||||
fh.Write([]byte("3"))
|
|
||||||
expect("3", buf)
|
|
||||||
fh.Write([]byte("-"))
|
|
||||||
expect("-", buf)
|
|
||||||
fh.Write([]byte("1"))
|
|
||||||
expect("1", buf)
|
|
||||||
fh.Write([]byte("2"))
|
|
||||||
expect("2", buf)
|
|
||||||
fh.Write([]byte("3"))
|
|
||||||
expect("3", buf)
|
|
||||||
fh.Write([]byte("4"))
|
|
||||||
expect("4", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your phone number: \x1b[0m\x1b[36m123-123-1234\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered 123-123-1234.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("select\r\n", buf)
|
|
||||||
expect("\x1b[?25l\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days are you available:\x1b[0m \x1b[36m[? for help]\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
fh.Write([]byte("?"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[36mⓘ We are closed weekends and avaibility is limited on Wednesday\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days are you available:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[36mⓘ We are closed weekends and avaibility is limited on Wednesday\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days are you available:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[36mⓘ We are closed weekends and avaibility is limited on Wednesday\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days are you available:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[36mⓘ We are closed weekends and avaibility is limited on Wednesday\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days are you available:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[36mⓘ We are closed weekends and avaibility is limited on Wednesday\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days are you available:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[36mⓘ We are closed weekends and avaibility is limited on Wednesday\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days are you available:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days are you available:\x1b[0m\x1b[36m Monday, Friday\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered [Monday Friday].\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("select\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m \x1b[36m[? for help]\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("?"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[36mⓘ Blue is the best color, but it is your choice\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\x1b[36m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered blue.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("password\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mEnter a secret: \x1b[0m\x1b[36m[? for help]\x1b[0m ", buf)
|
|
||||||
fh.Write([]byte("?"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[36mⓘ Don't really enter a secret, this is just for testing\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mEnter a secret: \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("f"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("o"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("o"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("b"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("Answered foobar.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
|
|
||||||
c.Wait()
|
|
||||||
tty.Close()
|
|
||||||
fh.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func expect(expected string, buf *bufio.Reader) {
|
|
||||||
sofar := []rune{}
|
|
||||||
for _, r := range expected {
|
|
||||||
got, _, _ := buf.ReadRune()
|
|
||||||
sofar = append(sofar, got)
|
|
||||||
if got != r {
|
|
||||||
fmt.Fprintln(os.Stderr, RESET)
|
|
||||||
|
|
||||||
// we want to quote the string but we also want to make the unexpected character RED
|
|
||||||
// so we use the strconv.Quote function but trim off the quoted characters so we can
|
|
||||||
// merge multiple quoted strings into one.
|
|
||||||
expStart := strings.TrimSuffix(strconv.Quote(expected[:len(sofar)-1]), "\"")
|
|
||||||
expMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(expected[len(sofar)-1])), "\""), "\"")
|
|
||||||
expEnd := strings.TrimPrefix(strconv.Quote(expected[len(sofar):]), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Expected: %s%s%s%s%s\n", expStart, RED, expMiss, RESET, expEnd)
|
|
||||||
|
|
||||||
// read the rest of the buffer
|
|
||||||
p := make([]byte, buf.Buffered())
|
|
||||||
buf.Read(p)
|
|
||||||
|
|
||||||
gotStart := strings.TrimSuffix(strconv.Quote(string(sofar[:len(sofar)-1])), "\"")
|
|
||||||
gotMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(sofar[len(sofar)-1])), "\""), "\"")
|
|
||||||
gotEnd := strings.TrimPrefix(strconv.Quote(string(p)), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Got: %s%s%s%s%s\n", gotStart, RED, gotMiss, RESET, gotEnd)
|
|
||||||
panic(fmt.Errorf("Unexpected Rune %q, Expected %q\n", got, r))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%c", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-176
@@ -1,176 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DO NOT MODIFY THIS FILE!
|
|
||||||
//
|
|
||||||
// This file was automatically generated via the commands:
|
|
||||||
//
|
|
||||||
// go get github.com/coryb/autoplay
|
|
||||||
// autoplay -n autoplay/input.go go run input.go
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"github.com/kr/pty"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RED = "\033[31m"
|
|
||||||
RESET = "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fh, tty, _ := pty.Open()
|
|
||||||
defer tty.Close()
|
|
||||||
defer fh.Close()
|
|
||||||
c := exec.Command("go", "run", "input.go")
|
|
||||||
c.Stdin = tty
|
|
||||||
c.Stdout = tty
|
|
||||||
c.Stderr = tty
|
|
||||||
c.Start()
|
|
||||||
buf := bufio.NewReaderSize(fh, 1024)
|
|
||||||
|
|
||||||
expect("no default\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mHello world \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("a", buf)
|
|
||||||
fh.Write([]byte("l"))
|
|
||||||
expect("l", buf)
|
|
||||||
fh.Write([]byte("e"))
|
|
||||||
expect("e", buf)
|
|
||||||
fh.Write([]byte("c"))
|
|
||||||
expect("c", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mHello world \x1b[0m\x1b[36malec\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered alec.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("default\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mHello world \x1b[0m\x1b[37m(default) \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mHello world \x1b[0m\x1b[36mdefault\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered default.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("no help, send '?'\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mHello world \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("?"))
|
|
||||||
expect("?", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mHello world \x1b[0m\x1b[36m?\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered ?.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("input text in random location\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mHello \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("h"))
|
|
||||||
expect("h", buf)
|
|
||||||
fh.Write([]byte("e"))
|
|
||||||
expect("e", buf)
|
|
||||||
fh.Write([]byte("l"))
|
|
||||||
expect("l", buf)
|
|
||||||
fh.Write([]byte("l"))
|
|
||||||
expect("l", buf)
|
|
||||||
fh.Write([]byte("o"))
|
|
||||||
expect("o", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect(" ", buf)
|
|
||||||
fh.Write([]byte("w"))
|
|
||||||
expect("w", buf)
|
|
||||||
fh.Write([]byte("o"))
|
|
||||||
expect("o", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("r", buf)
|
|
||||||
fh.Write([]byte("l"))
|
|
||||||
expect("l", buf)
|
|
||||||
fh.Write([]byte("d"))
|
|
||||||
expect("d", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("D"))
|
|
||||||
expect("\x1b[1D", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("\x1b[0Kad\x1b[1D", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("D"))
|
|
||||||
expect("\x1b[1D", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("D"))
|
|
||||||
expect("\x1b[1D", buf)
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("\x1b[0Kalad\x1b[3D", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("D"))
|
|
||||||
expect("\x1b[1D", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("D"))
|
|
||||||
expect("\x1b[1D", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("D"))
|
|
||||||
expect("\x1b[1D", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("D"))
|
|
||||||
expect("\x1b[1D", buf)
|
|
||||||
fh.Write([]byte("\u007f"))
|
|
||||||
expect("\x1b[1D\x1b[0Kworalad\x1b[7D", buf)
|
|
||||||
fh.Write([]byte("\u007f"))
|
|
||||||
expect("\x1b[1D\x1b[0Kworalad\x1b[7D", buf)
|
|
||||||
fh.Write([]byte("\u007f"))
|
|
||||||
expect("\x1b[1D\x1b[0Kworalad\x1b[7D", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mHello \x1b[0m\x1b[36mhelworalad\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered helworalad.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
|
|
||||||
c.Wait()
|
|
||||||
tty.Close()
|
|
||||||
fh.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func expect(expected string, buf *bufio.Reader) {
|
|
||||||
sofar := []rune{}
|
|
||||||
for _, r := range expected {
|
|
||||||
got, _, _ := buf.ReadRune()
|
|
||||||
sofar = append(sofar, got)
|
|
||||||
if got != r {
|
|
||||||
fmt.Fprintln(os.Stderr, RESET)
|
|
||||||
|
|
||||||
// we want to quote the string but we also want to make the unexpected character RED
|
|
||||||
// so we use the strconv.Quote function but trim off the quoted characters so we can
|
|
||||||
// merge multiple quoted strings into one.
|
|
||||||
expStart := strings.TrimSuffix(strconv.Quote(expected[:len(sofar)-1]), "\"")
|
|
||||||
expMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(expected[len(sofar)-1])), "\""), "\"")
|
|
||||||
expEnd := strings.TrimPrefix(strconv.Quote(expected[len(sofar):]), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Expected: %s%s%s%s%s\n", expStart, RED, expMiss, RESET, expEnd)
|
|
||||||
|
|
||||||
// read the rest of the buffer
|
|
||||||
p := make([]byte, buf.Buffered())
|
|
||||||
buf.Read(p)
|
|
||||||
|
|
||||||
gotStart := strings.TrimSuffix(strconv.Quote(string(sofar[:len(sofar)-1])), "\"")
|
|
||||||
gotMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(sofar[len(sofar)-1])), "\""), "\"")
|
|
||||||
gotEnd := strings.TrimPrefix(strconv.Quote(string(p)), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Got: %s%s%s%s%s\n", gotStart, RED, gotMiss, RESET, gotEnd)
|
|
||||||
panic(fmt.Errorf("Unexpected Rune %q, Expected %q\n", got, r))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%c", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-446
@@ -1,446 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DO NOT MODIFY THIS FILE!
|
|
||||||
//
|
|
||||||
// This file was automatically generated via the commands:
|
|
||||||
//
|
|
||||||
// go get github.com/coryb/autoplay
|
|
||||||
// autoplay -n autoplay/multiselect.go go run multiselect.go
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"github.com/kr/pty"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RED = "\033[31m"
|
|
||||||
RESET = "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fh, tty, _ := pty.Open()
|
|
||||||
defer tty.Close()
|
|
||||||
defer fh.Close()
|
|
||||||
c := exec.Command("go", "run", "multiselect.go")
|
|
||||||
c.Stdin = tty
|
|
||||||
c.Stdout = tty
|
|
||||||
c.Stderr = tty
|
|
||||||
c.Start()
|
|
||||||
buf := bufio.NewReaderSize(fh, 1024)
|
|
||||||
|
|
||||||
expect("standard\r\n", buf)
|
|
||||||
expect("\x1b[?25l\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\x1b[36m Monday, Friday\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered [Monday Friday].\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("default (sunday, tuesday)\r\n", buf)
|
|
||||||
expect("\x1b[?25l\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\x1b[36m Monday, Friday\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered [Monday Friday].\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("default not found\r\n", buf)
|
|
||||||
expect("\x1b[?25l\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\x1b[36m Monday, Friday\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered [Monday Friday].\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("no help - type ?\r\n", buf)
|
|
||||||
expect("\x1b[?25l\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("?"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[1;99m ◯ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Sunday\r\n", buf)
|
|
||||||
expect(" \x1b[32m ◉ \x1b[0m Monday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Tuesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Wednesday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Thursday\r\n", buf)
|
|
||||||
expect("\x1b[36m❯\x1b[0m\x1b[32m ◉ \x1b[0m Friday\r\n", buf)
|
|
||||||
expect(" \x1b[1;99m ◯ \x1b[0m Saturday\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat days do you prefer:\x1b[0m\x1b[36m Monday, Friday\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered [Monday Friday].\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
|
|
||||||
c.Wait()
|
|
||||||
tty.Close()
|
|
||||||
fh.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func expect(expected string, buf *bufio.Reader) {
|
|
||||||
sofar := []rune{}
|
|
||||||
for _, r := range expected {
|
|
||||||
got, _, _ := buf.ReadRune()
|
|
||||||
sofar = append(sofar, got)
|
|
||||||
if got != r {
|
|
||||||
fmt.Fprintln(os.Stderr, RESET)
|
|
||||||
|
|
||||||
// we want to quote the string but we also want to make the unexpected character RED
|
|
||||||
// so we use the strconv.Quote function but trim off the quoted characters so we can
|
|
||||||
// merge multiple quoted strings into one.
|
|
||||||
expStart := strings.TrimSuffix(strconv.Quote(expected[:len(sofar)-1]), "\"")
|
|
||||||
expMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(expected[len(sofar)-1])), "\""), "\"")
|
|
||||||
expEnd := strings.TrimPrefix(strconv.Quote(expected[len(sofar):]), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Expected: %s%s%s%s%s\n", expStart, RED, expMiss, RESET, expEnd)
|
|
||||||
|
|
||||||
// read the rest of the buffer
|
|
||||||
p := make([]byte, buf.Buffered())
|
|
||||||
buf.Read(p)
|
|
||||||
|
|
||||||
gotStart := strings.TrimSuffix(strconv.Quote(string(sofar[:len(sofar)-1])), "\"")
|
|
||||||
gotMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(sofar[len(sofar)-1])), "\""), "\"")
|
|
||||||
gotEnd := strings.TrimPrefix(strconv.Quote(string(p)), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Got: %s%s%s%s%s\n", gotStart, RED, gotMiss, RESET, gotEnd)
|
|
||||||
panic(fmt.Errorf("Unexpected Rune %q, Expected %q\n", got, r))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%c", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-114
@@ -1,114 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DO NOT MODIFY THIS FILE!
|
|
||||||
//
|
|
||||||
// This file was automatically generated via the commands:
|
|
||||||
//
|
|
||||||
// go get github.com/coryb/autoplay
|
|
||||||
// autoplay -n autoplay/password.go go run password.go
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"github.com/kr/pty"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RED = "\033[31m"
|
|
||||||
RESET = "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fh, tty, _ := pty.Open()
|
|
||||||
defer tty.Close()
|
|
||||||
defer fh.Close()
|
|
||||||
c := exec.Command("go", "run", "password.go")
|
|
||||||
c.Stdin = tty
|
|
||||||
c.Stdout = tty
|
|
||||||
c.Stderr = tty
|
|
||||||
c.Start()
|
|
||||||
buf := bufio.NewReaderSize(fh, 1024)
|
|
||||||
|
|
||||||
expect("standard\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mPlease type your password: \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("f"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("o"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("o"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("b"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("Answered foobar.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("please make sure paste works\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mPlease paste your password: \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("f"))
|
|
||||||
fh.Write([]byte("o"))
|
|
||||||
fh.Write([]byte("o"))
|
|
||||||
fh.Write([]byte("b"))
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("******", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("Answered foobar.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("no help, send '?'\r\n", buf)
|
|
||||||
expect("\x1b[1;92m? \x1b[0m\x1b[1;99mPlease type your password: \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("?"))
|
|
||||||
expect("*", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("Answered ?.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
|
|
||||||
c.Wait()
|
|
||||||
tty.Close()
|
|
||||||
fh.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func expect(expected string, buf *bufio.Reader) {
|
|
||||||
sofar := []rune{}
|
|
||||||
for _, r := range expected {
|
|
||||||
got, _, _ := buf.ReadRune()
|
|
||||||
sofar = append(sofar, got)
|
|
||||||
if got != r {
|
|
||||||
fmt.Fprintln(os.Stderr, RESET)
|
|
||||||
|
|
||||||
// we want to quote the string but we also want to make the unexpected character RED
|
|
||||||
// so we use the strconv.Quote function but trim off the quoted characters so we can
|
|
||||||
// merge multiple quoted strings into one.
|
|
||||||
expStart := strings.TrimSuffix(strconv.Quote(expected[:len(sofar)-1]), "\"")
|
|
||||||
expMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(expected[len(sofar)-1])), "\""), "\"")
|
|
||||||
expEnd := strings.TrimPrefix(strconv.Quote(expected[len(sofar):]), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Expected: %s%s%s%s%s\n", expStart, RED, expMiss, RESET, expEnd)
|
|
||||||
|
|
||||||
// read the rest of the buffer
|
|
||||||
p := make([]byte, buf.Buffered())
|
|
||||||
buf.Read(p)
|
|
||||||
|
|
||||||
gotStart := strings.TrimSuffix(strconv.Quote(string(sofar[:len(sofar)-1])), "\"")
|
|
||||||
gotMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(sofar[len(sofar)-1])), "\""), "\"")
|
|
||||||
gotEnd := strings.TrimPrefix(strconv.Quote(string(p)), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Got: %s%s%s%s%s\n", gotStart, RED, gotMiss, RESET, gotEnd)
|
|
||||||
panic(fmt.Errorf("Unexpected Rune %q, Expected %q\n", got, r))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%c", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-158
@@ -1,158 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DO NOT MODIFY THIS FILE!
|
|
||||||
//
|
|
||||||
// This file was automatically generated via the commands:
|
|
||||||
//
|
|
||||||
// go get github.com/coryb/autoplay
|
|
||||||
// autoplay -n autoplay/select.go go run select.go
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"github.com/kr/pty"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RED = "\033[31m"
|
|
||||||
RESET = "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fh, tty, _ := pty.Open()
|
|
||||||
defer tty.Close()
|
|
||||||
defer fh.Close()
|
|
||||||
c := exec.Command("go", "run", "select.go")
|
|
||||||
c.Stdin = tty
|
|
||||||
c.Stdout = tty
|
|
||||||
c.Stderr = tty
|
|
||||||
c.Start()
|
|
||||||
buf := bufio.NewReaderSize(fh, 1024)
|
|
||||||
|
|
||||||
expect("standard\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\x1b[36m red\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered red.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("short\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\x1b[36m red\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered red.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("default\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color (should default blue):\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color (should default blue):\x1b[0m\x1b[36m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered blue.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("one\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose one:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ hello\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose one:\x1b[0m\x1b[36m hello\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered hello.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("no help, type ?\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\x1b[36m red\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered red.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("passes through bottom\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose one:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose one:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ blue\x1b[0m\r\n", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose one:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose one:\x1b[0m\x1b[36m red\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered red.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("passes through top\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose one:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("A"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose one:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ blue\x1b[0m\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose one:\x1b[0m\x1b[36m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("Answered blue.\r\n", buf)
|
|
||||||
expect("---------------------\r\n", buf)
|
|
||||||
expect("no options\r\n", buf)
|
|
||||||
|
|
||||||
c.Wait()
|
|
||||||
tty.Close()
|
|
||||||
fh.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func expect(expected string, buf *bufio.Reader) {
|
|
||||||
sofar := []rune{}
|
|
||||||
for _, r := range expected {
|
|
||||||
got, _, _ := buf.ReadRune()
|
|
||||||
sofar = append(sofar, got)
|
|
||||||
if got != r {
|
|
||||||
fmt.Fprintln(os.Stderr, RESET)
|
|
||||||
|
|
||||||
// we want to quote the string but we also want to make the unexpected character RED
|
|
||||||
// so we use the strconv.Quote function but trim off the quoted characters so we can
|
|
||||||
// merge multiple quoted strings into one.
|
|
||||||
expStart := strings.TrimSuffix(strconv.Quote(expected[:len(sofar)-1]), "\"")
|
|
||||||
expMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(expected[len(sofar)-1])), "\""), "\"")
|
|
||||||
expEnd := strings.TrimPrefix(strconv.Quote(expected[len(sofar):]), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Expected: %s%s%s%s%s\n", expStart, RED, expMiss, RESET, expEnd)
|
|
||||||
|
|
||||||
// read the rest of the buffer
|
|
||||||
p := make([]byte, buf.Buffered())
|
|
||||||
buf.Read(p)
|
|
||||||
|
|
||||||
gotStart := strings.TrimSuffix(strconv.Quote(string(sofar[:len(sofar)-1])), "\"")
|
|
||||||
gotMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(sofar[len(sofar)-1])), "\""), "\"")
|
|
||||||
gotEnd := strings.TrimPrefix(strconv.Quote(string(p)), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Got: %s%s%s%s%s\n", gotStart, RED, gotMiss, RESET, gotEnd)
|
|
||||||
panic(fmt.Errorf("Unexpected Rune %q, Expected %q\n", got, r))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%c", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-114
@@ -1,114 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DO NOT MODIFY THIS FILE!
|
|
||||||
//
|
|
||||||
// This file was automatically generated via the commands:
|
|
||||||
//
|
|
||||||
// go get github.com/coryb/autoplay
|
|
||||||
// autoplay -n autoplay/selectThenInput.go go run selectThenInput.go
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"github.com/kr/pty"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RED = "\033[31m"
|
|
||||||
RESET = "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fh, tty, _ := pty.Open()
|
|
||||||
defer tty.Close()
|
|
||||||
defer fh.Close()
|
|
||||||
c := exec.Command("go", "run", "selectThenInput.go")
|
|
||||||
c.Stdin = tty
|
|
||||||
c.Stdout = tty
|
|
||||||
c.Stderr = tty
|
|
||||||
c.Start()
|
|
||||||
buf := bufio.NewReaderSize(fh, 1024)
|
|
||||||
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[?25l", buf)
|
|
||||||
fh.Write([]byte("\x1b"))
|
|
||||||
fh.Write([]byte("["))
|
|
||||||
fh.Write([]byte("B"))
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m red\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;36m❯ blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[1;99m green\x1b[0m\r\n", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\x1b[?25h\x1b[0G\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1F\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mChoose a color:\x1b[0m\x1b[36m blue\x1b[0m\r\n", buf)
|
|
||||||
expect("\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your name? \x1b[0m", buf)
|
|
||||||
fh.Write([]byte("L"))
|
|
||||||
expect("L", buf)
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("a", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("r", buf)
|
|
||||||
fh.Write([]byte("r"))
|
|
||||||
expect("r", buf)
|
|
||||||
fh.Write([]byte("y"))
|
|
||||||
expect("y", buf)
|
|
||||||
fh.Write([]byte(" "))
|
|
||||||
expect(" ", buf)
|
|
||||||
fh.Write([]byte("W"))
|
|
||||||
expect("W", buf)
|
|
||||||
fh.Write([]byte("a"))
|
|
||||||
expect("a", buf)
|
|
||||||
fh.Write([]byte("l"))
|
|
||||||
expect("l", buf)
|
|
||||||
fh.Write([]byte("l"))
|
|
||||||
expect("l", buf)
|
|
||||||
fh.Write([]byte("\r"))
|
|
||||||
expect("\r\r\n", buf)
|
|
||||||
expect("\x1b[1F\x1b[0G\x1b[2K\x1b[1;92m? \x1b[0m\x1b[1;99mWhat is your name? \x1b[0m\x1b[36mLarry Wall\x1b[0m\r\n", buf)
|
|
||||||
expect("Larry Wall chose blue.\r\n", buf)
|
|
||||||
|
|
||||||
c.Wait()
|
|
||||||
tty.Close()
|
|
||||||
fh.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func expect(expected string, buf *bufio.Reader) {
|
|
||||||
sofar := []rune{}
|
|
||||||
for _, r := range expected {
|
|
||||||
got, _, _ := buf.ReadRune()
|
|
||||||
sofar = append(sofar, got)
|
|
||||||
if got != r {
|
|
||||||
fmt.Fprintln(os.Stderr, RESET)
|
|
||||||
|
|
||||||
// we want to quote the string but we also want to make the unexpected character RED
|
|
||||||
// so we use the strconv.Quote function but trim off the quoted characters so we can
|
|
||||||
// merge multiple quoted strings into one.
|
|
||||||
expStart := strings.TrimSuffix(strconv.Quote(expected[:len(sofar)-1]), "\"")
|
|
||||||
expMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(expected[len(sofar)-1])), "\""), "\"")
|
|
||||||
expEnd := strings.TrimPrefix(strconv.Quote(expected[len(sofar):]), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Expected: %s%s%s%s%s\n", expStart, RED, expMiss, RESET, expEnd)
|
|
||||||
|
|
||||||
// read the rest of the buffer
|
|
||||||
p := make([]byte, buf.Buffered())
|
|
||||||
buf.Read(p)
|
|
||||||
|
|
||||||
gotStart := strings.TrimSuffix(strconv.Quote(string(sofar[:len(sofar)-1])), "\"")
|
|
||||||
gotMiss := strings.TrimSuffix(strings.TrimPrefix(strconv.Quote(string(sofar[len(sofar)-1])), "\""), "\"")
|
|
||||||
gotEnd := strings.TrimPrefix(strconv.Quote(string(p)), "\"")
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Got: %s%s%s%s%s\n", gotStart, RED, gotMiss, RESET, gotEnd)
|
|
||||||
panic(fmt.Errorf("Unexpected Rune %q, Expected %q\n", got, r))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%c", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-43
@@ -1,43 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
"github.com/AlecAivazis/survey/tests/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
var answer = false
|
|
||||||
|
|
||||||
var goodTable = []TestUtil.TestTableEntry{
|
|
||||||
{
|
|
||||||
"Enter 'yes'", &survey.Confirm{
|
|
||||||
Message: "yes:",
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Enter 'no'", &survey.Confirm{
|
|
||||||
Message: "yes:",
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default", &survey.Confirm{
|
|
||||||
Message: "yes:",
|
|
||||||
Default: true,
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not recognized (enter random letter)", &survey.Confirm{
|
|
||||||
Message: "yes:",
|
|
||||||
Default: true,
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"no help - type '?'", &survey.Confirm{
|
|
||||||
Message: "yes:",
|
|
||||||
Default: true,
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
TestUtil.RunTable(goodTable)
|
|
||||||
}
|
|
||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
)
|
|
||||||
|
|
||||||
var simpleQs = []*survey.Question{
|
|
||||||
{
|
|
||||||
Name: "color",
|
|
||||||
Prompt: &survey.Select{
|
|
||||||
Message: "select1:",
|
|
||||||
Options: []string{"red", "blue", "green"},
|
|
||||||
},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "color2",
|
|
||||||
Prompt: &survey.Select{
|
|
||||||
Message: "select2:",
|
|
||||||
Options: []string{"red", "blue", "green"},
|
|
||||||
},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
answers := struct {
|
|
||||||
Color string
|
|
||||||
Color2 string
|
|
||||||
}{}
|
|
||||||
// ask the question
|
|
||||||
err := survey.Ask(simpleQs, &answers)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// print the answers
|
|
||||||
fmt.Printf("%s and %s.\n", answers.Color, answers.Color2)
|
|
||||||
}
|
|
||||||
-55
@@ -1,55 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
"github.com/AlecAivazis/survey/tests/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
confirmAns = false
|
|
||||||
inputAns = ""
|
|
||||||
multiselectAns = []string{}
|
|
||||||
selectAns = ""
|
|
||||||
passwordAns = ""
|
|
||||||
)
|
|
||||||
|
|
||||||
var goodTable = []TestUtil.TestTableEntry{
|
|
||||||
{
|
|
||||||
"confirm", &survey.Confirm{
|
|
||||||
Message: "Is it raining?",
|
|
||||||
Help: "Go outside, if your head becomes wet the answer is probably 'yes'",
|
|
||||||
}, &confirmAns,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input", &survey.Input{
|
|
||||||
Message: "What is your phone number:",
|
|
||||||
Help: "Phone number should include the area code, parentheses optional",
|
|
||||||
}, &inputAns,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"select", &survey.MultiSelect{
|
|
||||||
Message: "What days are you available:",
|
|
||||||
Help: "We are closed weekends and avaibility is limited on Wednesday",
|
|
||||||
Options: []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"},
|
|
||||||
Default: []string{"Monday", "Tuesday", "Thursday", "Friday"},
|
|
||||||
}, &multiselectAns,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"select", &survey.Select{
|
|
||||||
Message: "Choose a color:",
|
|
||||||
Help: "Blue is the best color, but it is your choice",
|
|
||||||
Options: []string{"red", "blue", "green"},
|
|
||||||
Default: "blue",
|
|
||||||
}, &selectAns,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"password", &survey.Password{
|
|
||||||
Message: "Enter a secret:",
|
|
||||||
Help: "Don't really enter a secret, this is just for testing",
|
|
||||||
}, &passwordAns,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
TestUtil.RunTable(goodTable)
|
|
||||||
}
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
"github.com/AlecAivazis/survey/tests/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
var val = ""
|
|
||||||
|
|
||||||
var table = []TestUtil.TestTableEntry{
|
|
||||||
{
|
|
||||||
"no default", &survey.Input{Message: "Hello world"}, &val,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default", &survey.Input{Message: "Hello world", Default: "default"}, &val,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"no help, send '?'", &survey.Input{Message: "Hello world"}, &val,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input text in random location", &survey.Input{Message: "Hello"}, &val,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
TestUtil.RunTable(table)
|
|
||||||
}
|
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import "github.com/AlecAivazis/survey"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
color := ""
|
|
||||||
prompt := &survey.Select{
|
|
||||||
Message: "Choose a color:",
|
|
||||||
Options: []string{
|
|
||||||
"a",
|
|
||||||
"b",
|
|
||||||
"c",
|
|
||||||
"d",
|
|
||||||
"e",
|
|
||||||
"f",
|
|
||||||
"g",
|
|
||||||
"h",
|
|
||||||
"i",
|
|
||||||
"j",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
survey.AskOne(prompt, &color, nil)
|
|
||||||
}
|
|
||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
"github.com/AlecAivazis/survey/tests/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
var answer = []string{}
|
|
||||||
|
|
||||||
var table = []TestUtil.TestTableEntry{
|
|
||||||
{
|
|
||||||
"standard", &survey.MultiSelect{
|
|
||||||
Message: "What days do you prefer:",
|
|
||||||
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default (sunday, tuesday)", &survey.MultiSelect{
|
|
||||||
Message: "What days do you prefer:",
|
|
||||||
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
|
|
||||||
Default: []string{"Sunday", "Tuesday"},
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default not found", &survey.MultiSelect{
|
|
||||||
Message: "What days do you prefer:",
|
|
||||||
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
|
|
||||||
Default: []string{"Sundayaa"},
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"no help - type ?", &survey.MultiSelect{
|
|
||||||
Message: "What days do you prefer:",
|
|
||||||
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
|
|
||||||
Default: []string{"Sundayaa"},
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
TestUtil.RunTable(table)
|
|
||||||
}
|
|
||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
"github.com/AlecAivazis/survey/tests/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
var value = ""
|
|
||||||
|
|
||||||
var table = []TestUtil.TestTableEntry{
|
|
||||||
{
|
|
||||||
"standard", &survey.Password{Message: "Please type your password:"}, &value,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"please make sure paste works", &survey.Password{Message: "Please paste your password:"}, &value,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"no help, send '?'", &survey.Password{Message: "Please type your password:"}, &value,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
TestUtil.RunTable(table)
|
|
||||||
}
|
|
||||||
-67
@@ -1,67 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
"github.com/AlecAivazis/survey/tests/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
var answer = ""
|
|
||||||
|
|
||||||
var goodTable = []TestUtil.TestTableEntry{
|
|
||||||
{
|
|
||||||
"standard", &survey.Select{
|
|
||||||
Message: "Choose a color:",
|
|
||||||
Options: []string{"red", "blue", "green"},
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"short", &survey.Select{
|
|
||||||
Message: "Choose a color:",
|
|
||||||
Options: []string{"red", "blue"},
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default", &survey.Select{
|
|
||||||
Message: "Choose a color (should default blue):",
|
|
||||||
Options: []string{"red", "blue", "green"},
|
|
||||||
Default: "blue",
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"one", &survey.Select{
|
|
||||||
Message: "Choose one:",
|
|
||||||
Options: []string{"hello"},
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"no help, type ?", &survey.Select{
|
|
||||||
Message: "Choose a color:",
|
|
||||||
Options: []string{"red", "blue"},
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"passes through bottom", &survey.Select{
|
|
||||||
Message: "Choose one:",
|
|
||||||
Options: []string{"red", "blue"},
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"passes through top", &survey.Select{
|
|
||||||
Message: "Choose one:",
|
|
||||||
Options: []string{"red", "blue"},
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var badTable = []TestUtil.TestTableEntry{
|
|
||||||
{
|
|
||||||
"no options", &survey.Select{
|
|
||||||
Message: "Choose one:",
|
|
||||||
}, &answer,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
TestUtil.RunTable(goodTable)
|
|
||||||
TestUtil.RunErrorTable(badTable)
|
|
||||||
}
|
|
||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
)
|
|
||||||
|
|
||||||
// the questions to ask
|
|
||||||
var simpleQs = []*survey.Question{
|
|
||||||
{
|
|
||||||
Name: "color",
|
|
||||||
Prompt: &survey.Select{
|
|
||||||
Message: "Choose a color:",
|
|
||||||
Options: []string{"red", "blue", "green"},
|
|
||||||
},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "name",
|
|
||||||
Prompt: &survey.Input{
|
|
||||||
Message: "What is your name?",
|
|
||||||
},
|
|
||||||
Validate: survey.Required,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
answers := struct {
|
|
||||||
Color string
|
|
||||||
Name string
|
|
||||||
}{}
|
|
||||||
// ask the question
|
|
||||||
err := survey.Ask(simpleQs, &answers)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// print the answers
|
|
||||||
fmt.Printf("%s chose %s.\n", answers.Name, answers.Color)
|
|
||||||
}
|
|
||||||
-50
@@ -1,50 +0,0 @@
|
|||||||
package TestUtil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TestTableEntry struct {
|
|
||||||
Name string
|
|
||||||
Prompt survey.Prompt
|
|
||||||
Value interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func formatAnswer(ans interface{}) {
|
|
||||||
// show the answer to the user
|
|
||||||
fmt.Printf("Answered %v.\n", reflect.ValueOf(ans).Elem())
|
|
||||||
fmt.Println("---------------------")
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunTable(table []TestTableEntry) {
|
|
||||||
// go over every entry in the table
|
|
||||||
for _, entry := range table {
|
|
||||||
// tell the user what we are going to ask them
|
|
||||||
fmt.Println(entry.Name)
|
|
||||||
// perform the ask
|
|
||||||
err := survey.AskOne(entry.Prompt, entry.Value, nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("AskOne on %v's prompt failed: %v.", entry.Name, err.Error())
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// show the answer to the user
|
|
||||||
formatAnswer(entry.Value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunErrorTable(table []TestTableEntry) {
|
|
||||||
// go over every entry in the table
|
|
||||||
for _, entry := range table {
|
|
||||||
// tell the user what we are going to ask them
|
|
||||||
fmt.Println(entry.Name)
|
|
||||||
// perform the ask
|
|
||||||
err := survey.AskOne(entry.Prompt, entry.Value, nil)
|
|
||||||
if err == nil {
|
|
||||||
fmt.Printf("AskOne on %v's prompt didn't fail.", entry.Name)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-2
@@ -1,2 +0,0 @@
|
|||||||
{{define "x"}}TEXT{{end}}
|
|
||||||
{{define "dotV"}}{{.V}}{{end}}
|
|
||||||
-2
@@ -1,2 +0,0 @@
|
|||||||
{{define "dot"}}{{.}}{{end}}
|
|
||||||
{{define "nested"}}{{template "dot" .}}{{end}}
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
template1
|
|
||||||
{{define "x"}}x{{end}}
|
|
||||||
{{template "y"}}
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
template2
|
|
||||||
{{define "y"}}y{{end}}
|
|
||||||
{{template "x"}}
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
package math
|
|
||||||
|
|
||||||
import "github.com/cheekybits/genny/generic"
|
|
||||||
|
|
||||||
type ThisNumberType generic.Number
|
|
||||||
|
|
||||||
func ThisNumberTypeMax(fn func(a, b ThisNumberType) bool, a, b ThisNumberType) ThisNumberType {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
cat ./generic_max.go | ../../genny gen "NumberType=NUMBERS" > numbers_max_get.go
|
|
||||||
cat ./func_thing.go | ../../genny gen "ThisNumberType=NUMBERS" > numbers_func_thing.go
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
package math
|
|
||||||
|
|
||||||
import "github.com/cheekybits/genny/generic"
|
|
||||||
|
|
||||||
type NumberType generic.Number
|
|
||||||
|
|
||||||
// NumberTypeMax gets the maximum number from the
|
|
||||||
// two specified.
|
|
||||||
func NumberTypeMax(a, b NumberType) NumberType {
|
|
||||||
if a > b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
package math_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/cheekybits/genny/examples/davechaney"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNumberTypeMax(t *testing.T) {
|
|
||||||
|
|
||||||
var v math.NumberType
|
|
||||||
v = math.NumberTypeMax(10, 20)
|
|
||||||
if v != 20 {
|
|
||||||
t.Errorf("Max of 10 and 20 is 20")
|
|
||||||
}
|
|
||||||
|
|
||||||
v = math.NumberTypeMax(20, 20)
|
|
||||||
if v != 20 {
|
|
||||||
t.Errorf("Max of 20 and 20 is 20")
|
|
||||||
}
|
|
||||||
|
|
||||||
v = math.NumberTypeMax(25, 20)
|
|
||||||
if v != 25 {
|
|
||||||
t.Errorf("Max of 25 and 20 is 25")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-89
@@ -1,89 +0,0 @@
|
|||||||
// This file was automatically generated by genny.
|
|
||||||
// Any changes will be lost if this file is regenerated.
|
|
||||||
// see https://github.com/cheekybits/genny
|
|
||||||
|
|
||||||
package math
|
|
||||||
|
|
||||||
func Float32Max(fn func(a, b float32) bool, a, b float32) float32 {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func Float64Max(fn func(a, b float64) bool, a, b float64) float64 {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func IntMax(fn func(a, b int) bool, a, b int) int {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func Int16Max(fn func(a, b int16) bool, a, b int16) int16 {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func Int32Max(fn func(a, b int32) bool, a, b int32) int32 {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func Int64Max(fn func(a, b int64) bool, a, b int64) int64 {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func Int8Max(fn func(a, b int8) bool, a, b int8) int8 {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func UintMax(fn func(a, b uint) bool, a, b uint) uint {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func Uint16Max(fn func(a, b uint16) bool, a, b uint16) uint16 {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func Uint32Max(fn func(a, b uint32) bool, a, b uint32) uint32 {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func Uint64Max(fn func(a, b uint64) bool, a, b uint64) uint64 {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func Uint8Max(fn func(a, b uint8) bool, a, b uint8) uint8 {
|
|
||||||
if fn(a, b) {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
// This file was automatically generated by genny.
|
|
||||||
// Any changes will be lost if this file is regenerated.
|
|
||||||
// see https://github.com/cheekybits/genny
|
|
||||||
|
|
||||||
package gogenerate
|
|
||||||
|
|
||||||
type StringStringMap map[string]string
|
|
||||||
|
|
||||||
func NewStringStringMap() map[string]string {
|
|
||||||
return make(map[string]string)
|
|
||||||
}
|
|
||||||
|
|
||||||
type StringIntMap map[string]int
|
|
||||||
|
|
||||||
func NewStringIntMap() map[string]int {
|
|
||||||
return make(map[string]int)
|
|
||||||
}
|
|
||||||
|
|
||||||
type IntStringMap map[int]string
|
|
||||||
|
|
||||||
func NewIntStringMap() map[int]string {
|
|
||||||
return make(map[int]string)
|
|
||||||
}
|
|
||||||
|
|
||||||
type IntIntMap map[int]int
|
|
||||||
|
|
||||||
func NewIntIntMap() map[int]int {
|
|
||||||
return make(map[int]int)
|
|
||||||
}
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
package gogenerate
|
|
||||||
|
|
||||||
import "github.com/cheekybits/genny/generic"
|
|
||||||
|
|
||||||
//go:generate genny -in=$GOFILE -out=gen-$GOFILE gen "KeyType=string,int ValueType=string,int"
|
|
||||||
|
|
||||||
type KeyType generic.Type
|
|
||||||
type ValueType generic.Type
|
|
||||||
|
|
||||||
type KeyTypeValueTypeMap map[KeyType]ValueType
|
|
||||||
|
|
||||||
func NewKeyTypeValueTypeMap() map[KeyType]ValueType {
|
|
||||||
return make(map[KeyType]ValueType)
|
|
||||||
}
|
|
||||||
-2
@@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
cat ./queue_generic.go | ../../genny gen "Generic=string,int" > queue_generic_gen.go
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
package example
|
|
||||||
|
|
||||||
import "github.com/cheekybits/genny/generic"
|
|
||||||
|
|
||||||
type Generic generic.Type
|
|
||||||
|
|
||||||
// GenericQueue represents a queue of Generic types.
|
|
||||||
type GenericQueue struct {
|
|
||||||
items []Generic
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewGenericQueue makes a new empty Generic queue.
|
|
||||||
func NewGenericQueue() *GenericQueue {
|
|
||||||
return &GenericQueue{items: make([]Generic, 0)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enq adds an item to the queue.
|
|
||||||
func (q *GenericQueue) Enq(obj Generic) *GenericQueue {
|
|
||||||
q.items = append(q.items, obj)
|
|
||||||
return q
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deq removes and returns the next item in the queue.
|
|
||||||
func (q *GenericQueue) Deq() Generic {
|
|
||||||
obj := q.items[0]
|
|
||||||
q.items = q.items[1:]
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len gets the current number of Generic items in the queue.
|
|
||||||
func (q *GenericQueue) Len() int {
|
|
||||||
return len(q.items)
|
|
||||||
}
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
package example
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNew(t *testing.T) {
|
|
||||||
|
|
||||||
q := NewGenericQueue()
|
|
||||||
assert.NotNil(t, q)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEnqueueAndDequeue(t *testing.T) {
|
|
||||||
|
|
||||||
item1 := new(Generic)
|
|
||||||
item2 := new(Generic)
|
|
||||||
q := NewGenericQueue()
|
|
||||||
|
|
||||||
assert.Equal(t, q, q.Enq(item1), "Enq should return the queue")
|
|
||||||
assert.Equal(t, 1, q.Len())
|
|
||||||
assert.Equal(t, q, q.Enq(item2), "Enq should return the queue")
|
|
||||||
assert.Equal(t, 2, q.Len())
|
|
||||||
|
|
||||||
assert.Equal(t, item1, q.Deq())
|
|
||||||
assert.Equal(t, 1, q.Len())
|
|
||||||
assert.Equal(t, item2, q.Deq())
|
|
||||||
assert.Equal(t, 0, q.Len())
|
|
||||||
|
|
||||||
}
|
|
||||||
-41
@@ -1,41 +0,0 @@
|
|||||||
package parse
|
|
||||||
|
|
||||||
// Builtins contains a slice of all built-in Go types.
|
|
||||||
var Builtins = []string{
|
|
||||||
"bool",
|
|
||||||
"byte",
|
|
||||||
"complex128",
|
|
||||||
"complex64",
|
|
||||||
"error",
|
|
||||||
"float32",
|
|
||||||
"float64",
|
|
||||||
"int",
|
|
||||||
"int16",
|
|
||||||
"int32",
|
|
||||||
"int64",
|
|
||||||
"int8",
|
|
||||||
"rune",
|
|
||||||
"string",
|
|
||||||
"uint",
|
|
||||||
"uint16",
|
|
||||||
"uint32",
|
|
||||||
"uint64",
|
|
||||||
"uint8",
|
|
||||||
"uintptr",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Numbers contains a slice of all built-in number types.
|
|
||||||
var Numbers = []string{
|
|
||||||
"float32",
|
|
||||||
"float64",
|
|
||||||
"int",
|
|
||||||
"int16",
|
|
||||||
"int32",
|
|
||||||
"int64",
|
|
||||||
"int8",
|
|
||||||
"uint",
|
|
||||||
"uint16",
|
|
||||||
"uint32",
|
|
||||||
"uint64",
|
|
||||||
"uint8",
|
|
||||||
}
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
// Package parse contains the generic code generation capabilities
|
|
||||||
// that power genny.
|
|
||||||
//
|
|
||||||
// genny gen "{types}"
|
|
||||||
//
|
|
||||||
// gen - generates type specific code (to stdout) from generic code (via stdin)
|
|
||||||
//
|
|
||||||
// {types} - (required) Specific types for each generic type in the source
|
|
||||||
// {types} format: {generic}={specific}[,another][ {generic2}={specific2}]
|
|
||||||
// Examples:
|
|
||||||
// Generic=Specific
|
|
||||||
// Generic1=Specific1 Generic2=Specific2
|
|
||||||
// Generic1=Specific1,Specific2 Generic2=Specific3,Specific4
|
|
||||||
package parse
|
|
||||||
-47
@@ -1,47 +0,0 @@
|
|||||||
package parse
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// errMissingSpecificType represents an error when a generic type is not
|
|
||||||
// satisfied by a specific type.
|
|
||||||
type errMissingSpecificType struct {
|
|
||||||
GenericType string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error gets a human readable string describing this error.
|
|
||||||
func (e errMissingSpecificType) Error() string {
|
|
||||||
return "Missing specific type for '" + e.GenericType + "' generic type"
|
|
||||||
}
|
|
||||||
|
|
||||||
// errImports represents an error from goimports.
|
|
||||||
type errImports struct {
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error gets a human readable string describing this error.
|
|
||||||
func (e errImports) Error() string {
|
|
||||||
return "Failed to goimports the generated code: " + e.Err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// errSource represents an error with the source file.
|
|
||||||
type errSource struct {
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error gets a human readable string describing this error.
|
|
||||||
func (e errSource) Error() string {
|
|
||||||
return "Failed to parse source file: " + e.Err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
type errBadTypeArgs struct {
|
|
||||||
Message string
|
|
||||||
Arg string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e errBadTypeArgs) Error() string {
|
|
||||||
return "\"" + e.Arg + "\" is bad: " + e.Message
|
|
||||||
}
|
|
||||||
|
|
||||||
var errMissingTypeInformation = errors.New("No type arguments were specified and no \"// +gogen\" tag was found in the source.")
|
|
||||||
-271
@@ -1,271 +0,0 @@
|
|||||||
package parse
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
|
||||||
"go/parser"
|
|
||||||
"go/token"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
|
|
||||||
"golang.org/x/tools/imports"
|
|
||||||
)
|
|
||||||
|
|
||||||
type isExported bool
|
|
||||||
|
|
||||||
var header = []byte(`
|
|
||||||
|
|
||||||
// This file was automatically generated by genny.
|
|
||||||
// Any changes will be lost if this file is regenerated.
|
|
||||||
// see https://github.com/cheekybits/genny
|
|
||||||
|
|
||||||
`)
|
|
||||||
|
|
||||||
var (
|
|
||||||
packageKeyword = []byte("package")
|
|
||||||
importKeyword = []byte("import")
|
|
||||||
openBrace = []byte("(")
|
|
||||||
closeBrace = []byte(")")
|
|
||||||
space = " "
|
|
||||||
genericPackage = "generic"
|
|
||||||
genericType = "generic.Type"
|
|
||||||
genericNumber = "generic.Number"
|
|
||||||
linefeed = "\r\n"
|
|
||||||
)
|
|
||||||
var unwantedLinePrefixes = [][]byte{
|
|
||||||
[]byte("//go:generate genny "),
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateSpecific(filename string, in io.ReadSeeker, typeSet map[string]string) ([]byte, error) {
|
|
||||||
|
|
||||||
// ensure we are at the beginning of the file
|
|
||||||
in.Seek(0, os.SEEK_SET)
|
|
||||||
|
|
||||||
// parse the source file
|
|
||||||
fs := token.NewFileSet()
|
|
||||||
file, err := parser.ParseFile(fs, filename, in, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, &errSource{Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure every generic.Type is represented in the types
|
|
||||||
// argument.
|
|
||||||
for _, decl := range file.Decls {
|
|
||||||
switch it := decl.(type) {
|
|
||||||
case *ast.GenDecl:
|
|
||||||
for _, spec := range it.Specs {
|
|
||||||
ts, ok := spec.(*ast.TypeSpec)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch tt := ts.Type.(type) {
|
|
||||||
case *ast.SelectorExpr:
|
|
||||||
if name, ok := tt.X.(*ast.Ident); ok {
|
|
||||||
if name.Name == genericPackage {
|
|
||||||
if _, ok := typeSet[ts.Name.Name]; !ok {
|
|
||||||
return nil, &errMissingSpecificType{GenericType: ts.Name.Name}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// go back to the start of the file
|
|
||||||
in.Seek(0, os.SEEK_SET)
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
|
|
||||||
comment := ""
|
|
||||||
scanner := bufio.NewScanner(in)
|
|
||||||
for scanner.Scan() {
|
|
||||||
|
|
||||||
l := scanner.Text()
|
|
||||||
|
|
||||||
// does this line contain generic.Type?
|
|
||||||
if strings.Contains(l, genericType) || strings.Contains(l, genericNumber) {
|
|
||||||
comment = ""
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for t, specificType := range typeSet {
|
|
||||||
|
|
||||||
// does the line contain our type
|
|
||||||
if strings.Contains(l, t) {
|
|
||||||
|
|
||||||
var newLine string
|
|
||||||
// check each word
|
|
||||||
for _, word := range strings.Fields(l) {
|
|
||||||
|
|
||||||
i := 0
|
|
||||||
for {
|
|
||||||
i = strings.Index(word[i:], t) // find out where
|
|
||||||
|
|
||||||
if i > -1 {
|
|
||||||
|
|
||||||
// if this isn't an exact match
|
|
||||||
if i > 0 && isAlphaNumeric(rune(word[i-1])) || i < len(word)-len(t) && isAlphaNumeric(rune(word[i+len(t)])) {
|
|
||||||
// replace the word with a capitolized version
|
|
||||||
word = strings.Replace(word, t, wordify(specificType, unicode.IsUpper(rune(strings.TrimLeft(word, "*&")[0]))), 1)
|
|
||||||
} else {
|
|
||||||
// replace the word as is
|
|
||||||
word = strings.Replace(word, t, specificType, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
newLine = newLine + word + space
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
l = newLine
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if comment != "" {
|
|
||||||
buf.WriteString(line(comment))
|
|
||||||
comment = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// is this line a comment?
|
|
||||||
// TODO: should we handle /* */ comments?
|
|
||||||
if strings.HasPrefix(l, "//") {
|
|
||||||
// record this line to print later
|
|
||||||
comment = l
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// write the line
|
|
||||||
buf.WriteString(line(l))
|
|
||||||
}
|
|
||||||
|
|
||||||
// write it out
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generics parses the source file and generates the bytes replacing the
|
|
||||||
// generic types for the keys map with the specific types (its value).
|
|
||||||
func Generics(filename, pkgName string, in io.ReadSeeker, typeSets []map[string]string) ([]byte, error) {
|
|
||||||
|
|
||||||
totalOutput := header
|
|
||||||
|
|
||||||
for _, typeSet := range typeSets {
|
|
||||||
|
|
||||||
// generate the specifics
|
|
||||||
parsed, err := generateSpecific(filename, in, typeSet)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
totalOutput = append(totalOutput, parsed...)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean up the code line by line
|
|
||||||
packageFound := false
|
|
||||||
insideImportBlock := false
|
|
||||||
var cleanOutputLines []string
|
|
||||||
scanner := bufio.NewScanner(bytes.NewReader(totalOutput))
|
|
||||||
for scanner.Scan() {
|
|
||||||
|
|
||||||
// end of imports block?
|
|
||||||
if insideImportBlock {
|
|
||||||
if bytes.HasSuffix(scanner.Bytes(), closeBrace) {
|
|
||||||
insideImportBlock = false
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if bytes.HasPrefix(scanner.Bytes(), packageKeyword) {
|
|
||||||
if packageFound {
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
packageFound = true
|
|
||||||
}
|
|
||||||
} else if bytes.HasPrefix(scanner.Bytes(), importKeyword) {
|
|
||||||
if bytes.HasSuffix(scanner.Bytes(), openBrace) {
|
|
||||||
insideImportBlock = true
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// check all unwantedLinePrefixes - and skip them
|
|
||||||
skipline := false
|
|
||||||
for _, prefix := range unwantedLinePrefixes {
|
|
||||||
if bytes.HasPrefix(scanner.Bytes(), prefix) {
|
|
||||||
skipline = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if skipline {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanOutputLines = append(cleanOutputLines, line(scanner.Text()))
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanOutput := strings.Join(cleanOutputLines, "")
|
|
||||||
|
|
||||||
output := []byte(cleanOutput)
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// change package name
|
|
||||||
if pkgName != "" {
|
|
||||||
output = changePackage(bytes.NewReader([]byte(output)), pkgName)
|
|
||||||
}
|
|
||||||
// fix the imports
|
|
||||||
output, err = imports.Process(filename, output, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, &errImports{Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func line(s string) string {
|
|
||||||
return fmt.Sprintln(strings.TrimRight(s, linefeed))
|
|
||||||
}
|
|
||||||
|
|
||||||
// isAlphaNumeric gets whether the rune is alphanumeric or _.
|
|
||||||
func isAlphaNumeric(r rune) bool {
|
|
||||||
return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// wordify turns a type into a nice word for function and type
|
|
||||||
// names etc.
|
|
||||||
func wordify(s string, exported bool) string {
|
|
||||||
s = strings.TrimRight(s, "{}")
|
|
||||||
s = strings.TrimLeft(s, "*&")
|
|
||||||
s = strings.Replace(s, ".", "", -1)
|
|
||||||
if !exported {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return strings.ToUpper(string(s[0])) + s[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
func changePackage(r io.Reader, pkgName string) []byte {
|
|
||||||
var out bytes.Buffer
|
|
||||||
sc := bufio.NewScanner(r)
|
|
||||||
done := false
|
|
||||||
|
|
||||||
for sc.Scan() {
|
|
||||||
s := sc.Text()
|
|
||||||
|
|
||||||
if !done && strings.HasPrefix(s, "package") {
|
|
||||||
parts := strings.Split(s, " ")
|
|
||||||
parts[1] = pkgName
|
|
||||||
s = strings.Join(parts, " ")
|
|
||||||
done = true
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintln(&out, s)
|
|
||||||
}
|
|
||||||
return out.Bytes()
|
|
||||||
}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
package parse
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestIsAlphaNumeric(t *testing.T) {
|
|
||||||
|
|
||||||
for _, r := range []rune{'a', '1', '_', 'A', 'Z'} {
|
|
||||||
assert.True(t, isAlphaNumeric(r))
|
|
||||||
}
|
|
||||||
for _, r := range []rune{' ', '[', ']', '!', '"'} {
|
|
||||||
assert.False(t, isAlphaNumeric(r))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWordify(t *testing.T) {
|
|
||||||
|
|
||||||
for word, wordified := range map[string]string{
|
|
||||||
"int": "Int",
|
|
||||||
"*int": "Int",
|
|
||||||
"string": "String",
|
|
||||||
"*MyType": "MyType",
|
|
||||||
"*myType": "MyType",
|
|
||||||
"interface{}": "Interface",
|
|
||||||
"pack.type": "Packtype",
|
|
||||||
"*pack.type": "Packtype",
|
|
||||||
} {
|
|
||||||
assert.Equal(t, wordified, wordify(word, true))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-126
@@ -1,126 +0,0 @@
|
|||||||
package parse_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/cheekybits/genny/parse"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
var tests = []struct {
|
|
||||||
// input
|
|
||||||
filename string
|
|
||||||
pkgName string
|
|
||||||
in string
|
|
||||||
types []map[string]string
|
|
||||||
|
|
||||||
// expectations
|
|
||||||
expectedOut string
|
|
||||||
expectedErr error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
filename: "generic_queue.go",
|
|
||||||
in: `test/queue/generic_queue.go`,
|
|
||||||
types: []map[string]string{{"Something": "int"}},
|
|
||||||
expectedOut: `test/queue/int_queue.go`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "generic_queue.go",
|
|
||||||
pkgName: "changed",
|
|
||||||
in: `test/queue/generic_queue.go`,
|
|
||||||
types: []map[string]string{{"Something": "int"}},
|
|
||||||
expectedOut: `test/queue/changed/int_queue.go`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "generic_queue.go",
|
|
||||||
in: `test/queue/generic_queue.go`,
|
|
||||||
types: []map[string]string{{"Something": "float32"}},
|
|
||||||
expectedOut: `test/queue/float32_queue.go`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "generic_simplemap.go",
|
|
||||||
in: `test/multipletypes/generic_simplemap.go`,
|
|
||||||
types: []map[string]string{{"KeyType": "string", "ValueType": "int"}},
|
|
||||||
expectedOut: `test/multipletypes/string_int_simplemap.go`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "generic_simplemap.go",
|
|
||||||
in: `test/multipletypes/generic_simplemap.go`,
|
|
||||||
types: []map[string]string{{"KeyType": "interface{}", "ValueType": "int"}},
|
|
||||||
expectedOut: `test/multipletypes/interface_int_simplemap.go`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "generic_simplemap.go",
|
|
||||||
in: `test/multipletypes/generic_simplemap.go`,
|
|
||||||
types: []map[string]string{{"KeyType": "*MyType1", "ValueType": "*MyOtherType"}},
|
|
||||||
expectedOut: `test/multipletypes/custom_types_simplemap.go`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "generic_internal.go",
|
|
||||||
in: `test/unexported/generic_internal.go`,
|
|
||||||
types: []map[string]string{{"secret": "*myType"}},
|
|
||||||
expectedOut: `test/unexported/mytype_internal.go`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "generic_simplemap.go",
|
|
||||||
in: `test/multipletypesets/generic_simplemap.go`,
|
|
||||||
types: []map[string]string{
|
|
||||||
{"KeyType": "int", "ValueType": "string"},
|
|
||||||
{"KeyType": "float64", "ValueType": "bool"},
|
|
||||||
},
|
|
||||||
expectedOut: `test/multipletypesets/many_simplemaps.go`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "generic_number.go",
|
|
||||||
in: `test/numbers/generic_number.go`,
|
|
||||||
types: []map[string]string{{"NumberType": "int"}},
|
|
||||||
expectedOut: `test/numbers/int_number.go`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "generic_digraph.go",
|
|
||||||
in: `test/bugreports/generic_digraph.go`,
|
|
||||||
types: []map[string]string{{"Node": "int"}},
|
|
||||||
expectedOut: `test/bugreports/int_digraph.go`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
|
|
||||||
test.in = contents(test.in)
|
|
||||||
test.expectedOut = contents(test.expectedOut)
|
|
||||||
|
|
||||||
bytes, err := parse.Generics(test.filename, test.pkgName, strings.NewReader(test.in), test.types)
|
|
||||||
|
|
||||||
// check the error
|
|
||||||
if test.expectedErr == nil {
|
|
||||||
assert.NoError(t, err, "(%s) No error was expected but got: %s", test.filename, err)
|
|
||||||
} else {
|
|
||||||
assert.NotNil(t, err, "(%s) No error was returned by one was expected: %s", test.filename, test.expectedErr)
|
|
||||||
assert.IsType(t, test.expectedErr, err, "(%s) Generate should return object of type %v", test.filename, test.expectedErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert the response
|
|
||||||
if !assert.Equal(t, string(bytes), test.expectedOut, "Parse didn't generate the expected output.") {
|
|
||||||
log.Println("EXPECTED: " + test.expectedOut)
|
|
||||||
log.Println("ACTUAL: " + string(bytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func contents(s string) string {
|
|
||||||
if strings.HasSuffix(s, "go") {
|
|
||||||
file, err := ioutil.ReadFile(s)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return string(file)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
-30
@@ -1,30 +0,0 @@
|
|||||||
package bugreports
|
|
||||||
|
|
||||||
import "github.com/cheekybits/genny/generic"
|
|
||||||
|
|
||||||
type Node generic.Type
|
|
||||||
|
|
||||||
type DigraphNode struct {
|
|
||||||
nodes map[Node][]Node
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDigraphNode() *DigraphNode {
|
|
||||||
return &DigraphNode{
|
|
||||||
nodes: make(map[Node][]Node),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dig *DigraphNode) Add(n Node) {
|
|
||||||
if _, exists := dig.nodes[n]; exists {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
dig.nodes[n] = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dig *DigraphNode) Connect(a, b Node) {
|
|
||||||
dig.Add(a)
|
|
||||||
dig.Add(b)
|
|
||||||
|
|
||||||
dig.nodes[a] = append(dig.nodes[a], b)
|
|
||||||
}
|
|
||||||
-30
@@ -1,30 +0,0 @@
|
|||||||
// This file was automatically generated by genny.
|
|
||||||
// Any changes will be lost if this file is regenerated.
|
|
||||||
// see https://github.com/cheekybits/genny
|
|
||||||
|
|
||||||
package bugreports
|
|
||||||
|
|
||||||
type DigraphInt struct {
|
|
||||||
nodes map[int][]int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDigraphInt() *DigraphInt {
|
|
||||||
return &DigraphInt{
|
|
||||||
nodes: make(map[int][]int),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dig *DigraphInt) Add(n int) {
|
|
||||||
if _, exists := dig.nodes[n]; exists {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
dig.nodes[n] = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dig *DigraphInt) Connect(a, b int) {
|
|
||||||
dig.Add(a)
|
|
||||||
dig.Add(b)
|
|
||||||
|
|
||||||
dig.nodes[a] = append(dig.nodes[a], b)
|
|
||||||
}
|
|
||||||
-5
@@ -1,5 +0,0 @@
|
|||||||
package multipletypes
|
|
||||||
|
|
||||||
type MyType1 struct{}
|
|
||||||
|
|
||||||
type MyOtherType struct{}
|
|
||||||
Generated
Vendored
-21
@@ -1,21 +0,0 @@
|
|||||||
// This file was automatically generated by genny.
|
|
||||||
// Any changes will be lost if this file is regenerated.
|
|
||||||
// see https://github.com/cheekybits/genny
|
|
||||||
|
|
||||||
package multipletypes
|
|
||||||
|
|
||||||
type MyType1MyOtherTypeMap map[*MyType1]*MyOtherType
|
|
||||||
|
|
||||||
func (m MyType1MyOtherTypeMap) Has(key *MyType1) bool {
|
|
||||||
_, ok := m[key]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m MyType1MyOtherTypeMap) Get(key *MyType1) *MyOtherType {
|
|
||||||
return m[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m MyType1MyOtherTypeMap) Set(key *MyType1, value *MyOtherType) MyType1MyOtherTypeMap {
|
|
||||||
m[key] = value
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
package multipletypes
|
|
||||||
|
|
||||||
import "github.com/cheekybits/genny/generic"
|
|
||||||
|
|
||||||
type KeyType generic.Type
|
|
||||||
type ValueType generic.Type
|
|
||||||
|
|
||||||
type KeyTypeValueTypeMap map[KeyType]ValueType
|
|
||||||
|
|
||||||
func (m KeyTypeValueTypeMap) Has(key KeyType) bool {
|
|
||||||
_, ok := m[key]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m KeyTypeValueTypeMap) Get(key KeyType) ValueType {
|
|
||||||
return m[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m KeyTypeValueTypeMap) Set(key KeyType, value ValueType) KeyTypeValueTypeMap {
|
|
||||||
m[key] = value
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
Generated
Vendored
-35
@@ -1,35 +0,0 @@
|
|||||||
package multipletypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSimpleMap(t *testing.T) {
|
|
||||||
|
|
||||||
key1 := new(KeyType)
|
|
||||||
key2 := new(KeyType)
|
|
||||||
value1 := new(ValueType)
|
|
||||||
m := make(KeyTypeValueTypeMap)
|
|
||||||
|
|
||||||
assert.Equal(t, m, m.Set(key1, value1))
|
|
||||||
assert.True(t, m.Has(key1))
|
|
||||||
assert.False(t, m.Has(key2))
|
|
||||||
assert.Equal(t, value1, m.Get(key1))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCustomTypesMap(t *testing.T) {
|
|
||||||
|
|
||||||
key1 := new(MyType1)
|
|
||||||
key2 := new(MyType1)
|
|
||||||
value1 := new(MyOtherType)
|
|
||||||
m := make(MyType1MyOtherTypeMap)
|
|
||||||
|
|
||||||
assert.Equal(t, m, m.Set(key1, value1))
|
|
||||||
assert.True(t, m.Has(key1))
|
|
||||||
assert.False(t, m.Has(key2))
|
|
||||||
assert.Equal(t, value1, m.Get(key1))
|
|
||||||
|
|
||||||
}
|
|
||||||
Generated
Vendored
-21
@@ -1,21 +0,0 @@
|
|||||||
// This file was automatically generated by genny.
|
|
||||||
// Any changes will be lost if this file is regenerated.
|
|
||||||
// see https://github.com/cheekybits/genny
|
|
||||||
|
|
||||||
package multipletypes
|
|
||||||
|
|
||||||
type InterfaceIntMap map[interface{}]int
|
|
||||||
|
|
||||||
func (m InterfaceIntMap) Has(key interface{}) bool {
|
|
||||||
_, ok := m[key]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m InterfaceIntMap) Get(key interface{}) int {
|
|
||||||
return m[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m InterfaceIntMap) Set(key interface{}, value int) InterfaceIntMap {
|
|
||||||
m[key] = value
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
Generated
Vendored
-21
@@ -1,21 +0,0 @@
|
|||||||
// This file was automatically generated by genny.
|
|
||||||
// Any changes will be lost if this file is regenerated.
|
|
||||||
// see https://github.com/cheekybits/genny
|
|
||||||
|
|
||||||
package multipletypes
|
|
||||||
|
|
||||||
type StringIntMap map[string]int
|
|
||||||
|
|
||||||
func (m StringIntMap) Has(key string) bool {
|
|
||||||
_, ok := m[key]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m StringIntMap) Get(key string) int {
|
|
||||||
return m[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m StringIntMap) Set(key string, value int) StringIntMap {
|
|
||||||
m[key] = value
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
Generated
Vendored
-27
@@ -1,27 +0,0 @@
|
|||||||
package multipletypesets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/cheekybits/genny/generic"
|
|
||||||
)
|
|
||||||
|
|
||||||
type KeyType generic.Type
|
|
||||||
type ValueType generic.Type
|
|
||||||
|
|
||||||
type KeyTypeValueTypeMap map[KeyType]ValueType
|
|
||||||
|
|
||||||
func (m KeyTypeValueTypeMap) Has(key KeyType) bool {
|
|
||||||
_, ok := m[key]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m KeyTypeValueTypeMap) Get(key KeyType) ValueType {
|
|
||||||
return m[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m KeyTypeValueTypeMap) Set(key KeyType, value ValueType) KeyTypeValueTypeMap {
|
|
||||||
log.Println(value)
|
|
||||||
m[key] = value
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
Generated
Vendored
-21
@@ -1,21 +0,0 @@
|
|||||||
package multipletypesets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSimpleMap(t *testing.T) {
|
|
||||||
|
|
||||||
key1 := new(KeyType)
|
|
||||||
key2 := new(KeyType)
|
|
||||||
value1 := new(ValueType)
|
|
||||||
m := make(KeyTypeValueTypeMap)
|
|
||||||
|
|
||||||
assert.Equal(t, m, m.Set(key1, value1))
|
|
||||||
assert.True(t, m.Has(key1))
|
|
||||||
assert.False(t, m.Has(key2))
|
|
||||||
assert.Equal(t, value1, m.Get(key1))
|
|
||||||
|
|
||||||
}
|
|
||||||
Generated
Vendored
-41
@@ -1,41 +0,0 @@
|
|||||||
// This file was automatically generated by genny.
|
|
||||||
// Any changes will be lost if this file is regenerated.
|
|
||||||
// see https://github.com/cheekybits/genny
|
|
||||||
|
|
||||||
package multipletypesets
|
|
||||||
|
|
||||||
import "log"
|
|
||||||
|
|
||||||
type IntStringMap map[int]string
|
|
||||||
|
|
||||||
func (m IntStringMap) Has(key int) bool {
|
|
||||||
_, ok := m[key]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m IntStringMap) Get(key int) string {
|
|
||||||
return m[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m IntStringMap) Set(key int, value string) IntStringMap {
|
|
||||||
log.Println(value)
|
|
||||||
m[key] = value
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
type Float64BoolMap map[float64]bool
|
|
||||||
|
|
||||||
func (m Float64BoolMap) Has(key float64) bool {
|
|
||||||
_, ok := m[key]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m Float64BoolMap) Get(key float64) bool {
|
|
||||||
return m[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m Float64BoolMap) Set(key float64, value bool) Float64BoolMap {
|
|
||||||
log.Println(value)
|
|
||||||
m[key] = value
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
package numbers
|
|
||||||
|
|
||||||
import "github.com/cheekybits/genny/generic"
|
|
||||||
|
|
||||||
type NumberType generic.Number
|
|
||||||
|
|
||||||
func NumberTypeMax(a, b NumberType) NumberType {
|
|
||||||
if a > b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
// This file was automatically generated by genny.
|
|
||||||
// Any changes will be lost if this file is regenerated.
|
|
||||||
// see https://github.com/cheekybits/genny
|
|
||||||
|
|
||||||
package numbers
|
|
||||||
|
|
||||||
func IntMax(a, b int) int {
|
|
||||||
if a > b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
// This file was automatically generated by genny.
|
|
||||||
// Any changes will be lost if this file is regenerated.
|
|
||||||
// see https://github.com/cheekybits/genny
|
|
||||||
|
|
||||||
package changed
|
|
||||||
|
|
||||||
// IntQueue is a queue of Ints.
|
|
||||||
type IntQueue struct {
|
|
||||||
items []int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIntQueue() *IntQueue {
|
|
||||||
return &IntQueue{items: make([]int, 0)}
|
|
||||||
}
|
|
||||||
func (q *IntQueue) Push(item int) {
|
|
||||||
q.items = append(q.items, item)
|
|
||||||
}
|
|
||||||
func (q *IntQueue) Pop() int {
|
|
||||||
item := q.items[0]
|
|
||||||
q.items = q.items[1:]
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user