{"action":"created","issue":{"url":"https://api.github.com/repos/AlecAivazis/survey/issues/143","repository_url":"https://api.github.com/repos/AlecAivazis/survey","labels_url":"https://api.github.com/repos/AlecAivazis/survey/issues/143/labels{/name}","comments_url":"https://api.github.com/repos/AlecAivazis/survey/issues/143/comments","events_url":"https://api.github.com/repos/AlecAivazis/survey/issues/143/events","html_url":"https://github.com/AlecAivazis/survey/pull/143","id":331396138,"node_id":"MDExOlB1bGxSZXF1ZXN0MTk0MTM3ODI1","number":143,"title":"Refactor survey to use optionally specified stdio.","user":{"login":"hinshun","id":6493975,"node_id":"MDQ6VXNlcjY0OTM5NzU=","avatar_url":"https://avatars1.githubusercontent.com/u/6493975?v=4","gravatar_id":"","url":"https://api.github.com/users/hinshun","html_url":"https://github.com/hinshun","followers_url":"https://api.github.com/users/hinshun/followers","following_url":"https://api.github.com/users/hinshun/following{/other_user}","gists_url":"https://api.github.com/users/hinshun/gists{/gist_id}","starred_url":"https://api.github.com/users/hinshun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hinshun/subscriptions","organizations_url":"https://api.github.com/users/hinshun/orgs","repos_url":"https://api.github.com/users/hinshun/repos","events_url":"https://api.github.com/users/hinshun/events{/privacy}","received_events_url":"https://api.github.com/users/hinshun/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-06-12T00:32:11Z","updated_at":"2018-06-13T15:41:30Z","closed_at":null,"author_association":"NONE","pull_request":{"url":"https://api.github.com/repos/AlecAivazis/survey/pulls/143","html_url":"https://github.com/AlecAivazis/survey/pull/143","diff_url":"https://github.com/AlecAivazis/survey/pull/143.diff","patch_url":"https://github.com/AlecAivazis/survey/pull/143.patch"},"body":"We wanted to refactor out survey's stdin/stdout to optionally use a different pair of files. The refactor was doing using the [functional options pattern](https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis). The main purpose was to automate testing of interactive applications at Netflix, and one of which used this library. In order to demonstrate why having controllable stdio is useful, I've also included a full set of integration tests using https://github.com/Netflix/go-expect that leverages this refactor.\r\n\r\nFAQ\r\n---\r\n- What is `go-expect`?\r\n  - It's a library that can expect sequences from a output stream and send data into an input stream byte for byte, so that one can automate testing of an interactive application.\r\n- What is `vt10x`?\r\n  - It's an in-memory terminal emulator fulfilling the VT10X specifications, so that it can respond to e.g. cursor position report of its in-memory cursor. `go-expect` can multiplex the escape sequence from `survey` to `vt10x` and multiplex the cursor position report back to `survey`.\r\n- Why modify `CursorLocation`?\r\n  - Bytes sent in while the prompt is rendering and before the cursor position report is discarded due to the way that it was implemented. Unmatched bytes are saved to a `BufferedReader` which is used in `RuneReader` so that it will first read from this internal buffer before it's stdin. Before this change, if you send the character `\"R\"` before the cursor position report, it will hang indefinitely.\r\n- Why vendor?\r\n  - If a golang project imports any packages that has a vendor directory, go doesn't allow using nested dependencies from your `GOPATH`. It's also important for the library to be pinned to a set of versions (that consumers not necessarily have to match exactly) to have reproducible tests and for vendoring programs (like `dep`) to solve dependency constraints.\r\n- Why not autoexpect or some other expect library?\r\n  - Autoexpect isn't reliable, and `Netflix/go-expect` doesn't spawn processes to control them. It only interacts with the pty that it creates. This means that `go-expect` tests can be regular go `_test.go` files and can leverage golang's test features (race, coverage, parallelism)."},"comment":{"url":"https://api.github.com/repos/AlecAivazis/survey/issues/comments/396984647","html_url":"https://github.com/AlecAivazis/survey/pull/143#issuecomment-396984647","issue_url":"https://api.github.com/repos/AlecAivazis/survey/issues/143","id":396984647,"node_id":"MDEyOklzc3VlQ29tbWVudDM5Njk4NDY0Nw==","user":{"login":"AlecAivazis","id":916317,"node_id":"MDQ6VXNlcjkxNjMxNw==","avatar_url":"https://avatars1.githubusercontent.com/u/916317?v=4","gravatar_id":"","url":"https://api.github.com/users/AlecAivazis","html_url":"https://github.com/AlecAivazis","followers_url":"https://api.github.com/users/AlecAivazis/followers","following_url":"https://api.github.com/users/AlecAivazis/following{/other_user}","gists_url":"https://api.github.com/users/AlecAivazis/gists{/gist_id}","starred_url":"https://api.github.com/users/AlecAivazis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AlecAivazis/subscriptions","organizations_url":"https://api.github.com/users/AlecAivazis/orgs","repos_url":"https://api.github.com/users/AlecAivazis/repos","events_url":"https://api.github.com/users/AlecAivazis/events{/privacy}","received_events_url":"https://api.github.com/users/AlecAivazis/received_events","type":"User","site_admin":false},"created_at":"2018-06-13T15:41:30Z","updated_at":"2018-06-13T15:41:30Z","author_association":"OWNER","body":"I would much prefer it if we could leave the interface for `Prompt` the same as before, per @coryb's suggestion. \r\n\r\nAlthough I do not know of anyone with custom Prompts, my gut says that a change to a core interface like `Prompt` is a public-API breaking change and would deserve bumping the major version of `survey`, something I\"ve been trying to avoid for a while. \r\n\r\nI think it's perfectly reasonable to modify the internals of `Ask` to accommodate this ability to specify stdout/in. "}}
{"actor":{"display_login":"AlecAivazis"}}