{"action":"opened","number":152,"pull_request":{"url":"https://api.github.com/repos/haskell/haskell-ide-engine/pulls/152","id":54890176,"html_url":"https://github.com/haskell/haskell-ide-engine/pull/152","diff_url":"https://github.com/haskell/haskell-ide-engine/pull/152.diff","patch_url":"https://github.com/haskell/haskell-ide-engine/pull/152.patch","issue_url":"https://api.github.com/repos/haskell/haskell-ide-engine/issues/152","number":152,"state":"open","locked":false,"title":"[POC] Move plugin and command names to the typelevel","user":{"login":"cocreature","id":1313584,"avatar_url":"https://avatars.githubusercontent.com/u/1313584?v=3","gravatar_id":"","url":"https://api.github.com/users/cocreature","html_url":"https://github.com/cocreature","followers_url":"https://api.github.com/users/cocreature/followers","following_url":"https://api.github.com/users/cocreature/following{/other_user}","gists_url":"https://api.github.com/users/cocreature/gists{/gist_id}","starred_url":"https://api.github.com/users/cocreature/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cocreature/subscriptions","organizations_url":"https://api.github.com/users/cocreature/orgs","repos_url":"https://api.github.com/users/cocreature/repos","events_url":"https://api.github.com/users/cocreature/events{/privacy}","received_events_url":"https://api.github.com/users/cocreature/received_events","type":"User","site_admin":false},"body":"This is more of a POC than finished code, but hopefully it can help to start a discussion if we want to move in that direction.\r\n\r\nNow let me explain my motivation for doing this:\r\n\r\nIn the current state servant knows pretty much nothing about our api. All it knows is that there are two routes, but it doesn’t know which plugins exists. That means that all the nice stuff servant brings us, like auto generated bindings is pretty much useless. In particular I played around with `servant-swagger` which works but the documentation it generates is useless for that exact reason (pinging @tobiasgwaaler since he wanted to work on that).\r\n\r\nWith this approach we get at least the plugins and the commands correctly documented although we can and probably should take this further so the parameters a command receives are also somewhere on the typelevel so that servant-swagger can just pick them up and use them instead of saying that it needs an `object`.\r\n\r\nAnother cool idea would be to reuse that same type to generate the documentation and possibly also for the json stdio although I’m less sure how useful it is there. In general the servant approach seems to be to declare the API once and then generate the rest from it which I kinda like. @rvion might be interested in that since we wanted to go for code generation. Afaik there is not yet a python backend for servant but as soon as someone adds that you should be able to get bindings for the http backend for free.\r\n\r\nNow to the downsides:\r\n\r\n- It adds complexity (although it was a lot of fun :)), I don’t have a problem with that but it might scare off beginners.\r\n- We now have three places where we have lists of plugins (`PluginList` and `pluginList` once in the documentation generator and once here). Even worse we have an additional list of command names here. Not sure how much effort we should put into fixing that until we have figured out #25 (which we can hopefully do rather soon). An upside of duplicating the command names is that at least for the servant backend (and once we use that type for the other backends also there) it allows selectively disabling certain commands.  However I can’t come up with a reason why you would want to do that right now.","created_at":"2016-01-01T11:24:41Z","updated_at":"2016-01-01T11:24:41Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/haskell/haskell-ide-engine/pulls/152/commits","review_comments_url":"https://api.github.com/repos/haskell/haskell-ide-engine/pulls/152/comments","review_comment_url":"https://api.github.com/repos/haskell/haskell-ide-engine/pulls/comments{/number}","comments_url":"https://api.github.com/repos/haskell/haskell-ide-engine/issues/152/comments","statuses_url":"https://api.github.com/repos/haskell/haskell-ide-engine/statuses/5c7fd2044861719c1cf832260ecd4588baeaeca1","head":{"label":"cocreature:servant-fancy","ref":"servant-fancy","sha":"5c7fd2044861719c1cf832260ecd4588baeaeca1","user":{"login":"cocreature","id":1313584,"avatar_url":"https://avatars.githubusercontent.com/u/1313584?v=3","gravatar_id":"","url":"https://api.github.com/users/cocreature","html_url":"https://github.com/cocreature","followers_url":"https://api.github.com/users/cocreature/followers","following_url":"https://api.github.com/users/cocreature/following{/other_user}","gists_url":"https://api.github.com/users/cocreature/gists{/gist_id}","starred_url":"https://api.github.com/users/cocreature/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cocreature/subscriptions","organizations_url":"https://api.github.com/users/cocreature/orgs","repos_url":"https://api.github.com/users/cocreature/repos","events_url":"https://api.github.com/users/cocreature/events{/privacy}","received_events_url":"https://api.github.com/users/cocreature/received_events","type":"User","site_admin":false},"repo":{"id":45755068,"name":"haskell-ide-engine","full_name":"cocreature/haskell-ide-engine","owner":{"login":"cocreature","id":1313584,"avatar_url":"https://avatars.githubusercontent.com/u/1313584?v=3","gravatar_id":"","url":"https://api.github.com/users/cocreature","html_url":"https://github.com/cocreature","followers_url":"https://api.github.com/users/cocreature/followers","following_url":"https://api.github.com/users/cocreature/following{/other_user}","gists_url":"https://api.github.com/users/cocreature/gists{/gist_id}","starred_url":"https://api.github.com/users/cocreature/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cocreature/subscriptions","organizations_url":"https://api.github.com/users/cocreature/orgs","repos_url":"https://api.github.com/users/cocreature/repos","events_url":"https://api.github.com/users/cocreature/events{/privacy}","received_events_url":"https://api.github.com/users/cocreature/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/cocreature/haskell-ide-engine","description":"The engine for haskell ide-integration. Not an IDE","fork":true,"url":"https://api.github.com/repos/cocreature/haskell-ide-engine","forks_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/forks","keys_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/teams","hooks_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/hooks","issue_events_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/issues/events{/number}","events_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/events","assignees_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/assignees{/user}","branches_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/branches{/branch}","tags_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/tags","blobs_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/git/refs{/sha}","trees_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/statuses/{sha}","languages_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/languages","stargazers_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/stargazers","contributors_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/contributors","subscribers_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/subscribers","subscription_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/subscription","commits_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/commits{/sha}","git_commits_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/git/commits{/sha}","comments_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/comments{/number}","issue_comment_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/issues/comments{/number}","contents_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/contents/{+path}","compare_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/merges","archive_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/downloads","issues_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/issues{/number}","pulls_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/pulls{/number}","milestones_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/milestones{/number}","notifications_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/labels{/name}","releases_url":"https://api.github.com/repos/cocreature/haskell-ide-engine/releases{/id}","created_at":"2015-11-07T21:19:41Z","updated_at":"2015-11-07T21:19:41Z","pushed_at":"2016-01-01T11:01:51Z","git_url":"git://github.com/cocreature/haskell-ide-engine.git","ssh_url":"git@github.com:cocreature/haskell-ide-engine.git","clone_url":"https://github.com/cocreature/haskell-ide-engine.git","svn_url":"https://github.com/cocreature/haskell-ide-engine","homepage":"","size":707,"stargazers_count":0,"watchers_count":0,"language":"Haskell","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"haskell:master","ref":"master","sha":"1b856f7998fa9284321144f9e45aabcc683650ec","user":{"login":"haskell","id":450574,"avatar_url":"https://avatars.githubusercontent.com/u/450574?v=3","gravatar_id":"","url":"https://api.github.com/users/haskell","html_url":"https://github.com/haskell","followers_url":"https://api.github.com/users/haskell/followers","following_url":"https://api.github.com/users/haskell/following{/other_user}","gists_url":"https://api.github.com/users/haskell/gists{/gist_id}","starred_url":"https://api.github.com/users/haskell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/haskell/subscriptions","organizations_url":"https://api.github.com/users/haskell/orgs","repos_url":"https://api.github.com/users/haskell/repos","events_url":"https://api.github.com/users/haskell/events{/privacy}","received_events_url":"https://api.github.com/users/haskell/received_events","type":"Organization","site_admin":false},"repo":{"id":44727837,"name":"haskell-ide-engine","full_name":"haskell/haskell-ide-engine","owner":{"login":"haskell","id":450574,"avatar_url":"https://avatars.githubusercontent.com/u/450574?v=3","gravatar_id":"","url":"https://api.github.com/users/haskell","html_url":"https://github.com/haskell","followers_url":"https://api.github.com/users/haskell/followers","following_url":"https://api.github.com/users/haskell/following{/other_user}","gists_url":"https://api.github.com/users/haskell/gists{/gist_id}","starred_url":"https://api.github.com/users/haskell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/haskell/subscriptions","organizations_url":"https://api.github.com/users/haskell/orgs","repos_url":"https://api.github.com/users/haskell/repos","events_url":"https://api.github.com/users/haskell/events{/privacy}","received_events_url":"https://api.github.com/users/haskell/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/haskell/haskell-ide-engine","description":"The engine for haskell ide-integration. Not an IDE","fork":false,"url":"https://api.github.com/repos/haskell/haskell-ide-engine","forks_url":"https://api.github.com/repos/haskell/haskell-ide-engine/forks","keys_url":"https://api.github.com/repos/haskell/haskell-ide-engine/keys{/key_id}","collaborators_url":"https://api.github.com/repos/haskell/haskell-ide-engine/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/haskell/haskell-ide-engine/teams","hooks_url":"https://api.github.com/repos/haskell/haskell-ide-engine/hooks","issue_events_url":"https://api.github.com/repos/haskell/haskell-ide-engine/issues/events{/number}","events_url":"https://api.github.com/repos/haskell/haskell-ide-engine/events","assignees_url":"https://api.github.com/repos/haskell/haskell-ide-engine/assignees{/user}","branches_url":"https://api.github.com/repos/haskell/haskell-ide-engine/branches{/branch}","tags_url":"https://api.github.com/repos/haskell/haskell-ide-engine/tags","blobs_url":"https://api.github.com/repos/haskell/haskell-ide-engine/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/haskell/haskell-ide-engine/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/haskell/haskell-ide-engine/git/refs{/sha}","trees_url":"https://api.github.com/repos/haskell/haskell-ide-engine/git/trees{/sha}","statuses_url":"https://api.github.com/repos/haskell/haskell-ide-engine/statuses/{sha}","languages_url":"https://api.github.com/repos/haskell/haskell-ide-engine/languages","stargazers_url":"https://api.github.com/repos/haskell/haskell-ide-engine/stargazers","contributors_url":"https://api.github.com/repos/haskell/haskell-ide-engine/contributors","subscribers_url":"https://api.github.com/repos/haskell/haskell-ide-engine/subscribers","subscription_url":"https://api.github.com/repos/haskell/haskell-ide-engine/subscription","commits_url":"https://api.github.com/repos/haskell/haskell-ide-engine/commits{/sha}","git_commits_url":"https://api.github.com/repos/haskell/haskell-ide-engine/git/commits{/sha}","comments_url":"https://api.github.com/repos/haskell/haskell-ide-engine/comments{/number}","issue_comment_url":"https://api.github.com/repos/haskell/haskell-ide-engine/issues/comments{/number}","contents_url":"https://api.github.com/repos/haskell/haskell-ide-engine/contents/{+path}","compare_url":"https://api.github.com/repos/haskell/haskell-ide-engine/compare/{base}...{head}","merges_url":"https://api.github.com/repos/haskell/haskell-ide-engine/merges","archive_url":"https://api.github.com/repos/haskell/haskell-ide-engine/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/haskell/haskell-ide-engine/downloads","issues_url":"https://api.github.com/repos/haskell/haskell-ide-engine/issues{/number}","pulls_url":"https://api.github.com/repos/haskell/haskell-ide-engine/pulls{/number}","milestones_url":"https://api.github.com/repos/haskell/haskell-ide-engine/milestones{/number}","notifications_url":"https://api.github.com/repos/haskell/haskell-ide-engine/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/haskell/haskell-ide-engine/labels{/name}","releases_url":"https://api.github.com/repos/haskell/haskell-ide-engine/releases{/id}","created_at":"2015-10-22T06:59:33Z","updated_at":"2015-12-30T21:31:30Z","pushed_at":"2016-01-01T11:24:41Z","git_url":"git://github.com/haskell/haskell-ide-engine.git","ssh_url":"git@github.com:haskell/haskell-ide-engine.git","clone_url":"https://github.com/haskell/haskell-ide-engine.git","svn_url":"https://github.com/haskell/haskell-ide-engine","homepage":"","size":728,"stargazers_count":250,"watchers_count":250,"language":"Haskell","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":16,"mirror_url":null,"open_issues_count":30,"forks":16,"open_issues":30,"watchers":250,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/haskell/haskell-ide-engine/pulls/152"},"html":{"href":"https://github.com/haskell/haskell-ide-engine/pull/152"},"issue":{"href":"https://api.github.com/repos/haskell/haskell-ide-engine/issues/152"},"comments":{"href":"https://api.github.com/repos/haskell/haskell-ide-engine/issues/152/comments"},"review_comments":{"href":"https://api.github.com/repos/haskell/haskell-ide-engine/pulls/152/comments"},"review_comment":{"href":"https://api.github.com/repos/haskell/haskell-ide-engine/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/haskell/haskell-ide-engine/pulls/152/commits"},"statuses":{"href":"https://api.github.com/repos/haskell/haskell-ide-engine/statuses/5c7fd2044861719c1cf832260ecd4588baeaeca1"}},"merged":false,"mergeable":null,"mergeable_state":"unknown","merged_by":null,"comments":0,"review_comments":0,"commits":1,"additions":95,"deletions":23,"changed_files":1}}