{"action":"closed","number":30,"pull_request":{"url":"https://api.github.com/repos/jarun/googler/pulls/30","id":60303199,"html_url":"https://github.com/jarun/googler/pull/30","diff_url":"https://github.com/jarun/googler/pull/30.diff","patch_url":"https://github.com/jarun/googler/pull/30.patch","issue_url":"https://api.github.com/repos/jarun/googler/issues/30","number":30,"state":"closed","locked":false,"title":"Fix failure when sys.stderr is not a tty (mostly for non-interactive invocation)","user":{"login":"zmwangx","id":4149852,"avatar_url":"https://avatars.githubusercontent.com/u/4149852?v=3","gravatar_id":"","url":"https://api.github.com/users/zmwangx","html_url":"https://github.com/zmwangx","followers_url":"https://api.github.com/users/zmwangx/followers","following_url":"https://api.github.com/users/zmwangx/following{/other_user}","gists_url":"https://api.github.com/users/zmwangx/gists{/gist_id}","starred_url":"https://api.github.com/users/zmwangx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zmwangx/subscriptions","organizations_url":"https://api.github.com/users/zmwangx/orgs","repos_url":"https://api.github.com/users/zmwangx/repos","events_url":"https://api.github.com/users/zmwangx/events{/privacy}","received_events_url":"https://api.github.com/users/zmwangx/received_events","type":"User","site_admin":false},"body":"I became aware of this the hard way when I was writing a test case for the [Homebrew formula](https://github.com/Homebrew/homebrew/blob/master/Library/Formula/googler.rb). I didn't report at that time because this related to how the project owner defines the project. Now that I've been honored as a collaborator, I think I might be able to influence the project a little bit more substantially. So here it goes.\r\n\r\n---\r\nCurrently, `fcntl.ioctl` fails with `IOError` (`OSError` on Python 3.x, where `IOError` is an alias for `OSError`) when sys.stderr is not a terminal. A very easy way to test:\r\n\r\n```python-traceback\r\n> googler hello 2>>(tee /dev/null) </dev/null\r\nTraceback (most recent call last):\r\n  File \"./googler\", line 365, in <module>\r\n    winsz = fcntl.ioctl(sys.stderr, termios.TIOCGWINSZ, \"1234\")\r\nIOError: [Errno 25] Inappropriate ioctl for device\r\n```\r\n\r\nAlthough googler is mostly terminal oriented, we should not preclude noninteractive use (it is an entirely conceivable use case to query googler with a set of keywords and grep out all URLs in the output); and even for interactive use, `2>/dev/null` leading to an error isn't nice UX either, especially considering that googler prints to stdout for the most part. This failure also precludes any meaningful automated testing.\r\n\r\nThis commit removes the aforementioned limitation, and also fixes a related comment (hard wrap != truncate, the latter implies loss of information).\r\n\r\n---\r\n\r\nIf this one is merged, then the discussion can be taken to the next level: CI. I believe we'll greatly benefit from using a free CI, say Travis, to do automated testing against multiple Python versions and all TLDs, as well as a set of randomized queries to shake out both coding oversight (say, wrote something that's incompatible with Python 3.2) and actual problems like the one in https://github.com/jarun/googler/issues/21#issuecomment-187255335 with `-c fr`.\r\n\r\nThe test script can be a simple shell script, and once the CI is set up (which takes like two minutes), that won't be any extra maintenance burden, except we'll be alerted when something breaks, and we'll be able to stop regressions at bay.","created_at":"2016-02-23T08:21:05Z","updated_at":"2016-02-23T08:35:30Z","closed_at":"2016-02-23T08:35:30Z","merged_at":null,"merge_commit_sha":"fc2303d93ba7bff1f648470b1d3e1bb514a8d429","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/jarun/googler/pulls/30/commits","review_comments_url":"https://api.github.com/repos/jarun/googler/pulls/30/comments","review_comment_url":"https://api.github.com/repos/jarun/googler/pulls/comments{/number}","comments_url":"https://api.github.com/repos/jarun/googler/issues/30/comments","statuses_url":"https://api.github.com/repos/jarun/googler/statuses/4bc14dd794be99f1731d3d134078ff461327ba92","head":{"label":"zmwangx:noninteractive-columns-fix","ref":"noninteractive-columns-fix","sha":"4bc14dd794be99f1731d3d134078ff461327ba92","user":{"login":"zmwangx","id":4149852,"avatar_url":"https://avatars.githubusercontent.com/u/4149852?v=3","gravatar_id":"","url":"https://api.github.com/users/zmwangx","html_url":"https://github.com/zmwangx","followers_url":"https://api.github.com/users/zmwangx/followers","following_url":"https://api.github.com/users/zmwangx/following{/other_user}","gists_url":"https://api.github.com/users/zmwangx/gists{/gist_id}","starred_url":"https://api.github.com/users/zmwangx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zmwangx/subscriptions","organizations_url":"https://api.github.com/users/zmwangx/orgs","repos_url":"https://api.github.com/users/zmwangx/repos","events_url":"https://api.github.com/users/zmwangx/events{/privacy}","received_events_url":"https://api.github.com/users/zmwangx/received_events","type":"User","site_admin":false},"repo":{"id":52060771,"name":"googler","full_name":"zmwangx/googler","owner":{"login":"zmwangx","id":4149852,"avatar_url":"https://avatars.githubusercontent.com/u/4149852?v=3","gravatar_id":"","url":"https://api.github.com/users/zmwangx","html_url":"https://github.com/zmwangx","followers_url":"https://api.github.com/users/zmwangx/followers","following_url":"https://api.github.com/users/zmwangx/following{/other_user}","gists_url":"https://api.github.com/users/zmwangx/gists{/gist_id}","starred_url":"https://api.github.com/users/zmwangx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zmwangx/subscriptions","organizations_url":"https://api.github.com/users/zmwangx/orgs","repos_url":"https://api.github.com/users/zmwangx/repos","events_url":"https://api.github.com/users/zmwangx/events{/privacy}","received_events_url":"https://api.github.com/users/zmwangx/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/zmwangx/googler","description":"Google from the command-line","fork":true,"url":"https://api.github.com/repos/zmwangx/googler","forks_url":"https://api.github.com/repos/zmwangx/googler/forks","keys_url":"https://api.github.com/repos/zmwangx/googler/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zmwangx/googler/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zmwangx/googler/teams","hooks_url":"https://api.github.com/repos/zmwangx/googler/hooks","issue_events_url":"https://api.github.com/repos/zmwangx/googler/issues/events{/number}","events_url":"https://api.github.com/repos/zmwangx/googler/events","assignees_url":"https://api.github.com/repos/zmwangx/googler/assignees{/user}","branches_url":"https://api.github.com/repos/zmwangx/googler/branches{/branch}","tags_url":"https://api.github.com/repos/zmwangx/googler/tags","blobs_url":"https://api.github.com/repos/zmwangx/googler/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zmwangx/googler/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zmwangx/googler/git/refs{/sha}","trees_url":"https://api.github.com/repos/zmwangx/googler/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zmwangx/googler/statuses/{sha}","languages_url":"https://api.github.com/repos/zmwangx/googler/languages","stargazers_url":"https://api.github.com/repos/zmwangx/googler/stargazers","contributors_url":"https://api.github.com/repos/zmwangx/googler/contributors","subscribers_url":"https://api.github.com/repos/zmwangx/googler/subscribers","subscription_url":"https://api.github.com/repos/zmwangx/googler/subscription","commits_url":"https://api.github.com/repos/zmwangx/googler/commits{/sha}","git_commits_url":"https://api.github.com/repos/zmwangx/googler/git/commits{/sha}","comments_url":"https://api.github.com/repos/zmwangx/googler/comments{/number}","issue_comment_url":"https://api.github.com/repos/zmwangx/googler/issues/comments{/number}","contents_url":"https://api.github.com/repos/zmwangx/googler/contents/{+path}","compare_url":"https://api.github.com/repos/zmwangx/googler/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zmwangx/googler/merges","archive_url":"https://api.github.com/repos/zmwangx/googler/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zmwangx/googler/downloads","issues_url":"https://api.github.com/repos/zmwangx/googler/issues{/number}","pulls_url":"https://api.github.com/repos/zmwangx/googler/pulls{/number}","milestones_url":"https://api.github.com/repos/zmwangx/googler/milestones{/number}","notifications_url":"https://api.github.com/repos/zmwangx/googler/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zmwangx/googler/labels{/name}","releases_url":"https://api.github.com/repos/zmwangx/googler/releases{/id}","deployments_url":"https://api.github.com/repos/zmwangx/googler/deployments","created_at":"2016-02-19T04:13:55Z","updated_at":"2016-02-19T04:13:55Z","pushed_at":"2016-02-23T08:07:51Z","git_url":"git://github.com/zmwangx/googler.git","ssh_url":"git@github.com:zmwangx/googler.git","clone_url":"https://github.com/zmwangx/googler.git","svn_url":"https://github.com/zmwangx/googler","homepage":"","size":778,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"jarun:master","ref":"master","sha":"f9d1aff560628488c597483b725c8bbe442e8470","user":{"login":"jarun","id":5959286,"avatar_url":"https://avatars.githubusercontent.com/u/5959286?v=3","gravatar_id":"","url":"https://api.github.com/users/jarun","html_url":"https://github.com/jarun","followers_url":"https://api.github.com/users/jarun/followers","following_url":"https://api.github.com/users/jarun/following{/other_user}","gists_url":"https://api.github.com/users/jarun/gists{/gist_id}","starred_url":"https://api.github.com/users/jarun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jarun/subscriptions","organizations_url":"https://api.github.com/users/jarun/orgs","repos_url":"https://api.github.com/users/jarun/repos","events_url":"https://api.github.com/users/jarun/events{/privacy}","received_events_url":"https://api.github.com/users/jarun/received_events","type":"User","site_admin":false},"repo":{"id":40797633,"name":"googler","full_name":"jarun/googler","owner":{"login":"jarun","id":5959286,"avatar_url":"https://avatars.githubusercontent.com/u/5959286?v=3","gravatar_id":"","url":"https://api.github.com/users/jarun","html_url":"https://github.com/jarun","followers_url":"https://api.github.com/users/jarun/followers","following_url":"https://api.github.com/users/jarun/following{/other_user}","gists_url":"https://api.github.com/users/jarun/gists{/gist_id}","starred_url":"https://api.github.com/users/jarun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jarun/subscriptions","organizations_url":"https://api.github.com/users/jarun/orgs","repos_url":"https://api.github.com/users/jarun/repos","events_url":"https://api.github.com/users/jarun/events{/privacy}","received_events_url":"https://api.github.com/users/jarun/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jarun/googler","description":"Google from the command-line","fork":false,"url":"https://api.github.com/repos/jarun/googler","forks_url":"https://api.github.com/repos/jarun/googler/forks","keys_url":"https://api.github.com/repos/jarun/googler/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jarun/googler/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jarun/googler/teams","hooks_url":"https://api.github.com/repos/jarun/googler/hooks","issue_events_url":"https://api.github.com/repos/jarun/googler/issues/events{/number}","events_url":"https://api.github.com/repos/jarun/googler/events","assignees_url":"https://api.github.com/repos/jarun/googler/assignees{/user}","branches_url":"https://api.github.com/repos/jarun/googler/branches{/branch}","tags_url":"https://api.github.com/repos/jarun/googler/tags","blobs_url":"https://api.github.com/repos/jarun/googler/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jarun/googler/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jarun/googler/git/refs{/sha}","trees_url":"https://api.github.com/repos/jarun/googler/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jarun/googler/statuses/{sha}","languages_url":"https://api.github.com/repos/jarun/googler/languages","stargazers_url":"https://api.github.com/repos/jarun/googler/stargazers","contributors_url":"https://api.github.com/repos/jarun/googler/contributors","subscribers_url":"https://api.github.com/repos/jarun/googler/subscribers","subscription_url":"https://api.github.com/repos/jarun/googler/subscription","commits_url":"https://api.github.com/repos/jarun/googler/commits{/sha}","git_commits_url":"https://api.github.com/repos/jarun/googler/git/commits{/sha}","comments_url":"https://api.github.com/repos/jarun/googler/comments{/number}","issue_comment_url":"https://api.github.com/repos/jarun/googler/issues/comments{/number}","contents_url":"https://api.github.com/repos/jarun/googler/contents/{+path}","compare_url":"https://api.github.com/repos/jarun/googler/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jarun/googler/merges","archive_url":"https://api.github.com/repos/jarun/googler/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jarun/googler/downloads","issues_url":"https://api.github.com/repos/jarun/googler/issues{/number}","pulls_url":"https://api.github.com/repos/jarun/googler/pulls{/number}","milestones_url":"https://api.github.com/repos/jarun/googler/milestones{/number}","notifications_url":"https://api.github.com/repos/jarun/googler/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jarun/googler/labels{/name}","releases_url":"https://api.github.com/repos/jarun/googler/releases{/id}","deployments_url":"https://api.github.com/repos/jarun/googler/deployments","created_at":"2015-08-16T03:33:02Z","updated_at":"2016-02-22T03:25:55Z","pushed_at":"2016-02-23T08:21:05Z","git_url":"git://github.com/jarun/googler.git","ssh_url":"git@github.com:jarun/googler.git","clone_url":"https://github.com/jarun/googler.git","svn_url":"https://github.com/jarun/googler","homepage":"","size":791,"stargazers_count":125,"watchers_count":125,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":18,"mirror_url":null,"open_issues_count":1,"forks":18,"open_issues":1,"watchers":125,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/jarun/googler/pulls/30"},"html":{"href":"https://github.com/jarun/googler/pull/30"},"issue":{"href":"https://api.github.com/repos/jarun/googler/issues/30"},"comments":{"href":"https://api.github.com/repos/jarun/googler/issues/30/comments"},"review_comments":{"href":"https://api.github.com/repos/jarun/googler/pulls/30/comments"},"review_comment":{"href":"https://api.github.com/repos/jarun/googler/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/jarun/googler/pulls/30/commits"},"statuses":{"href":"https://api.github.com/repos/jarun/googler/statuses/4bc14dd794be99f1731d3d134078ff461327ba92"}},"merged":false,"mergeable":true,"mergeable_state":"clean","merged_by":null,"comments":1,"review_comments":0,"commits":1,"additions":8,"deletions":5,"changed_files":1}}