{"action":"created","comment":{"url":"https://api.github.com/repos/Originate/git-town/pulls/comments/28191988","id":28191988,"diff_hunk":"@@ -104,6 +104,27 @@ For discussion around this architecture see\n where it was proposed.\n \n \n+### Drivers\n+\n+_Drivers_ implement third-party specific functionality in a standardized way.\n+For example, the [GitHub driver](./src/drivers/code_hosting/github.sh)\n+implements GitHub-related operations like creating a pull request there.\n+\n+There is also a similar\n+[Bitbucket driver](./src/drivers/code_hosting/bitbucket.sh)\n+that does the same things on Bitbucket.\n+Both drivers are part of the _driver family_ for\n+[code hosting](./src/drivers/code_hosting).\n+\n+The operations that a driver needs to support in order to be usable by Git Town\n+are described in the documentation for the respective driver family.\n+\n+In order to use a driver family, all that a script needs to do is activate it","path":"CONTRIBUTING.md","position":null,"original_position":28,"commit_id":"380eba66dbe9c06d5eddb810c67e77745a555e87","original_commit_id":"4c33f116c87fa4c63fe134fd472d2f377c465a4d","user":{"login":"kevgo","id":268934,"avatar_url":"https://avatars.githubusercontent.com/u/268934?v=3","gravatar_id":"","url":"https://api.github.com/users/kevgo","html_url":"https://github.com/kevgo","followers_url":"https://api.github.com/users/kevgo/followers","following_url":"https://api.github.com/users/kevgo/following{/other_user}","gists_url":"https://api.github.com/users/kevgo/gists{/gist_id}","starred_url":"https://api.github.com/users/kevgo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kevgo/subscriptions","organizations_url":"https://api.github.com/users/kevgo/orgs","repos_url":"https://api.github.com/users/kevgo/repos","events_url":"https://api.github.com/users/kevgo/events{/privacy}","received_events_url":"https://api.github.com/users/kevgo/received_events","type":"User","site_admin":false},"body":"Okay, changed.","created_at":"2015-04-11T03:44:22Z","updated_at":"2015-04-11T03:44:22Z","html_url":"https://github.com/Originate/git-town/pull/483#discussion_r28191988","pull_request_url":"https://api.github.com/repos/Originate/git-town/pulls/483","_links":{"self":{"href":"https://api.github.com/repos/Originate/git-town/pulls/comments/28191988"},"html":{"href":"https://github.com/Originate/git-town/pull/483#discussion_r28191988"},"pull_request":{"href":"https://api.github.com/repos/Originate/git-town/pulls/483"}}},"pull_request":{"url":"https://api.github.com/repos/Originate/git-town/pulls/483","id":32657832,"html_url":"https://github.com/Originate/git-town/pull/483","diff_url":"https://github.com/Originate/git-town/pull/483.diff","patch_url":"https://github.com/Originate/git-town/pull/483.patch","issue_url":"https://api.github.com/repos/Originate/git-town/issues/483","number":483,"state":"open","locked":false,"title":"Initial driver architecture","user":{"login":"kevgo","id":268934,"avatar_url":"https://avatars.githubusercontent.com/u/268934?v=3","gravatar_id":"","url":"https://api.github.com/users/kevgo","html_url":"https://github.com/kevgo","followers_url":"https://api.github.com/users/kevgo/followers","following_url":"https://api.github.com/users/kevgo/following{/other_user}","gists_url":"https://api.github.com/users/kevgo/gists{/gist_id}","starred_url":"https://api.github.com/users/kevgo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kevgo/subscriptions","organizations_url":"https://api.github.com/users/kevgo/orgs","repos_url":"https://api.github.com/users/kevgo/repos","events_url":"https://api.github.com/users/kevgo/events{/privacy}","received_events_url":"https://api.github.com/users/kevgo/received_events","type":"User","site_admin":false},"body":"@charlierudolph @allewun @ricmatsui \r\n\r\nThis is a first attempt at separating third-party specific functionality into \"drivers\" for those third-party APIs, as a parts of #477. The first driver family created here is around code hosting (GitHub, Bitbucket), with another driver family around CI coming soon (CircleCI, Travis, etc).\r\n\r\nThe motivation for this change is that this makes it much easier to add support for additional third-party systems.\r\n\r\nThe right patterns to use here is certainly a topic for great debates, and I have gone back and forth (in my head) on the various solutions. On the simple side we have a simple driver infrastructure like in this PR. On the complex side is a full extension system that can define its own Git commands, integration tests, and helpers, which can depend on each other, and be loaded through our own package manager. Following KISS and YAGNI as principles that have always served me very well, this PR contains the simplest possible approach, as a start. I'm happy to add more complexity when it is really needed and makes things simpler. In Bash one doesn't want to over-engineer things!\r\n\r\nI don't want to explain the changes too much myself here. The architecture should be documented sufficiently in the developer documentation changes in this PR. If it leaves anything unclear, please let me know, and I'll add more details there, so that they are around for everybody to understand.\r\n\r\nWhat do you think?","created_at":"2015-04-06T01:26:06Z","updated_at":"2015-04-11T03:44:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ce54d3b77fc1e5910990f1c5a5d3c4ef2f597b5f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Originate/git-town/pulls/483/commits","review_comments_url":"https://api.github.com/repos/Originate/git-town/pulls/483/comments","review_comment_url":"https://api.github.com/repos/Originate/git-town/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Originate/git-town/issues/483/comments","statuses_url":"https://api.github.com/repos/Originate/git-town/statuses/380eba66dbe9c06d5eddb810c67e77745a555e87","head":{"label":"Originate:kg-extensions-1","ref":"kg-extensions-1","sha":"380eba66dbe9c06d5eddb810c67e77745a555e87","user":{"login":"Originate","id":1627168,"avatar_url":"https://avatars.githubusercontent.com/u/1627168?v=3","gravatar_id":"","url":"https://api.github.com/users/Originate","html_url":"https://github.com/Originate","followers_url":"https://api.github.com/users/Originate/followers","following_url":"https://api.github.com/users/Originate/following{/other_user}","gists_url":"https://api.github.com/users/Originate/gists{/gist_id}","starred_url":"https://api.github.com/users/Originate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Originate/subscriptions","organizations_url":"https://api.github.com/users/Originate/orgs","repos_url":"https://api.github.com/users/Originate/repos","events_url":"https://api.github.com/users/Originate/events{/privacy}","received_events_url":"https://api.github.com/users/Originate/received_events","type":"Organization","site_admin":false},"repo":{"id":19825320,"name":"git-town","full_name":"Originate/git-town","owner":{"login":"Originate","id":1627168,"avatar_url":"https://avatars.githubusercontent.com/u/1627168?v=3","gravatar_id":"","url":"https://api.github.com/users/Originate","html_url":"https://github.com/Originate","followers_url":"https://api.github.com/users/Originate/followers","following_url":"https://api.github.com/users/Originate/following{/other_user}","gists_url":"https://api.github.com/users/Originate/gists{/gist_id}","starred_url":"https://api.github.com/users/Originate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Originate/subscriptions","organizations_url":"https://api.github.com/users/Originate/orgs","repos_url":"https://api.github.com/users/Originate/repos","events_url":"https://api.github.com/users/Originate/events{/privacy}","received_events_url":"https://api.github.com/users/Originate/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Originate/git-town","description":"Git extensions for robust, high-level development workflows","fork":false,"url":"https://api.github.com/repos/Originate/git-town","forks_url":"https://api.github.com/repos/Originate/git-town/forks","keys_url":"https://api.github.com/repos/Originate/git-town/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Originate/git-town/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Originate/git-town/teams","hooks_url":"https://api.github.com/repos/Originate/git-town/hooks","issue_events_url":"https://api.github.com/repos/Originate/git-town/issues/events{/number}","events_url":"https://api.github.com/repos/Originate/git-town/events","assignees_url":"https://api.github.com/repos/Originate/git-town/assignees{/user}","branches_url":"https://api.github.com/repos/Originate/git-town/branches{/branch}","tags_url":"https://api.github.com/repos/Originate/git-town/tags","blobs_url":"https://api.github.com/repos/Originate/git-town/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Originate/git-town/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Originate/git-town/git/refs{/sha}","trees_url":"https://api.github.com/repos/Originate/git-town/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Originate/git-town/statuses/{sha}","languages_url":"https://api.github.com/repos/Originate/git-town/languages","stargazers_url":"https://api.github.com/repos/Originate/git-town/stargazers","contributors_url":"https://api.github.com/repos/Originate/git-town/contributors","subscribers_url":"https://api.github.com/repos/Originate/git-town/subscribers","subscription_url":"https://api.github.com/repos/Originate/git-town/subscription","commits_url":"https://api.github.com/repos/Originate/git-town/commits{/sha}","git_commits_url":"https://api.github.com/repos/Originate/git-town/git/commits{/sha}","comments_url":"https://api.github.com/repos/Originate/git-town/comments{/number}","issue_comment_url":"https://api.github.com/repos/Originate/git-town/issues/comments{/number}","contents_url":"https://api.github.com/repos/Originate/git-town/contents/{+path}","compare_url":"https://api.github.com/repos/Originate/git-town/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Originate/git-town/merges","archive_url":"https://api.github.com/repos/Originate/git-town/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Originate/git-town/downloads","issues_url":"https://api.github.com/repos/Originate/git-town/issues{/number}","pulls_url":"https://api.github.com/repos/Originate/git-town/pulls{/number}","milestones_url":"https://api.github.com/repos/Originate/git-town/milestones{/number}","notifications_url":"https://api.github.com/repos/Originate/git-town/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Originate/git-town/labels{/name}","releases_url":"https://api.github.com/repos/Originate/git-town/releases{/id}","created_at":"2014-05-15T15:44:29Z","updated_at":"2015-04-10T02:23:44Z","pushed_at":"2015-04-11T03:44:18Z","git_url":"git://github.com/Originate/git-town.git","ssh_url":"git@github.com:Originate/git-town.git","clone_url":"https://github.com/Originate/git-town.git","svn_url":"https://github.com/Originate/git-town","homepage":"","size":15773,"stargazers_count":46,"watchers_count":46,"language":"Cucumber","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":2,"mirror_url":null,"open_issues_count":50,"forks":2,"open_issues":50,"watchers":46,"default_branch":"master"}},"base":{"label":"Originate:master","ref":"master","sha":"d52802cd211f40e4966b598acc584c2abe326645","user":{"login":"Originate","id":1627168,"avatar_url":"https://avatars.githubusercontent.com/u/1627168?v=3","gravatar_id":"","url":"https://api.github.com/users/Originate","html_url":"https://github.com/Originate","followers_url":"https://api.github.com/users/Originate/followers","following_url":"https://api.github.com/users/Originate/following{/other_user}","gists_url":"https://api.github.com/users/Originate/gists{/gist_id}","starred_url":"https://api.github.com/users/Originate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Originate/subscriptions","organizations_url":"https://api.github.com/users/Originate/orgs","repos_url":"https://api.github.com/users/Originate/repos","events_url":"https://api.github.com/users/Originate/events{/privacy}","received_events_url":"https://api.github.com/users/Originate/received_events","type":"Organization","site_admin":false},"repo":{"id":19825320,"name":"git-town","full_name":"Originate/git-town","owner":{"login":"Originate","id":1627168,"avatar_url":"https://avatars.githubusercontent.com/u/1627168?v=3","gravatar_id":"","url":"https://api.github.com/users/Originate","html_url":"https://github.com/Originate","followers_url":"https://api.github.com/users/Originate/followers","following_url":"https://api.github.com/users/Originate/following{/other_user}","gists_url":"https://api.github.com/users/Originate/gists{/gist_id}","starred_url":"https://api.github.com/users/Originate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Originate/subscriptions","organizations_url":"https://api.github.com/users/Originate/orgs","repos_url":"https://api.github.com/users/Originate/repos","events_url":"https://api.github.com/users/Originate/events{/privacy}","received_events_url":"https://api.github.com/users/Originate/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Originate/git-town","description":"Git extensions for robust, high-level development workflows","fork":false,"url":"https://api.github.com/repos/Originate/git-town","forks_url":"https://api.github.com/repos/Originate/git-town/forks","keys_url":"https://api.github.com/repos/Originate/git-town/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Originate/git-town/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Originate/git-town/teams","hooks_url":"https://api.github.com/repos/Originate/git-town/hooks","issue_events_url":"https://api.github.com/repos/Originate/git-town/issues/events{/number}","events_url":"https://api.github.com/repos/Originate/git-town/events","assignees_url":"https://api.github.com/repos/Originate/git-town/assignees{/user}","branches_url":"https://api.github.com/repos/Originate/git-town/branches{/branch}","tags_url":"https://api.github.com/repos/Originate/git-town/tags","blobs_url":"https://api.github.com/repos/Originate/git-town/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Originate/git-town/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Originate/git-town/git/refs{/sha}","trees_url":"https://api.github.com/repos/Originate/git-town/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Originate/git-town/statuses/{sha}","languages_url":"https://api.github.com/repos/Originate/git-town/languages","stargazers_url":"https://api.github.com/repos/Originate/git-town/stargazers","contributors_url":"https://api.github.com/repos/Originate/git-town/contributors","subscribers_url":"https://api.github.com/repos/Originate/git-town/subscribers","subscription_url":"https://api.github.com/repos/Originate/git-town/subscription","commits_url":"https://api.github.com/repos/Originate/git-town/commits{/sha}","git_commits_url":"https://api.github.com/repos/Originate/git-town/git/commits{/sha}","comments_url":"https://api.github.com/repos/Originate/git-town/comments{/number}","issue_comment_url":"https://api.github.com/repos/Originate/git-town/issues/comments{/number}","contents_url":"https://api.github.com/repos/Originate/git-town/contents/{+path}","compare_url":"https://api.github.com/repos/Originate/git-town/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Originate/git-town/merges","archive_url":"https://api.github.com/repos/Originate/git-town/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Originate/git-town/downloads","issues_url":"https://api.github.com/repos/Originate/git-town/issues{/number}","pulls_url":"https://api.github.com/repos/Originate/git-town/pulls{/number}","milestones_url":"https://api.github.com/repos/Originate/git-town/milestones{/number}","notifications_url":"https://api.github.com/repos/Originate/git-town/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Originate/git-town/labels{/name}","releases_url":"https://api.github.com/repos/Originate/git-town/releases{/id}","created_at":"2014-05-15T15:44:29Z","updated_at":"2015-04-10T02:23:44Z","pushed_at":"2015-04-11T03:44:18Z","git_url":"git://github.com/Originate/git-town.git","ssh_url":"git@github.com:Originate/git-town.git","clone_url":"https://github.com/Originate/git-town.git","svn_url":"https://github.com/Originate/git-town","homepage":"","size":15773,"stargazers_count":46,"watchers_count":46,"language":"Cucumber","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":2,"mirror_url":null,"open_issues_count":50,"forks":2,"open_issues":50,"watchers":46,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Originate/git-town/pulls/483"},"html":{"href":"https://github.com/Originate/git-town/pull/483"},"issue":{"href":"https://api.github.com/repos/Originate/git-town/issues/483"},"comments":{"href":"https://api.github.com/repos/Originate/git-town/issues/483/comments"},"review_comments":{"href":"https://api.github.com/repos/Originate/git-town/pulls/483/comments"},"review_comment":{"href":"https://api.github.com/repos/Originate/git-town/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Originate/git-town/pulls/483/commits"},"statuses":{"href":"https://api.github.com/repos/Originate/git-town/statuses/380eba66dbe9c06d5eddb810c67e77745a555e87"}}}}