Permalink
Browse files

Make hub fetch respect private github respositories

  • Loading branch information...
1 parent d44e24c commit 114029cec85a0f16f03e777aa19718e9ce538d51 Andy Delcambre committed Apr 23, 2012
Showing with 101 additions and 18 deletions.
  1. +1 −1 lib/hub/commands.rb
  2. +57 −14 lib/hub/github_api.rb
  3. +43 −3 test/hub_test.rb
View
2 lib/hub/commands.rb
@@ -327,7 +327,7 @@ def fetch(args)
if projects.any?
projects.each do |project|
- args.before ['remote', 'add', project.owner, project.git_url(:https => https_protocol?)]
+ args.before ['remote', 'add', project.owner, project.git_url(:private => api_client.private_repo?(project), :https => https_protocol?)]
end
end
end
View
71 lib/hub/github_api.rb
@@ -31,10 +31,8 @@ def self.===(exception)
end
end
- def api_v2? host
- return true # TODO
- host = host.host if host.respond_to? :host
- host !~ /(^|\.)github\.com$/i
+ def api_v2? project
+ project.host.downcase != 'github.com'
end
# Public: Determine whether a specific repo already exists.
@@ -44,7 +42,24 @@ def repo_exists? project
[project.host, project.owner, project.name]
res.success?
else
- raise NotImplementedError
+ res = get "https://api.%s/repos/%s/%s" %
+ [project.host, project.owner, project.name]
+ res.success?
+ end
+ end
+
+ # Determines whether a project is private or not
+ def private_repo?(project)
+ if api_v2? project
+ res = get "https://%s/api/v2/json/repos/show/%s/%s" %
+ [project.host, project.owner, project.name]
+ res.data["repository"]["private"]
+ else
+ res = get "https://api.%s/repos/%s/%s" %
+ [project.host, project.owner, project.name]
+ require 'pp'
+ pp res.data
+ res.data["private"]
end
end
@@ -55,23 +70,34 @@ def fork_repo project
[project.host, project.owner, project.name]
res.error! unless res.success?
else
- raise NotImplementedError
+ res = post "https://api.%s/repos/%s/%s/forks" %
+ [project.host, project.owner, project.name]
+ res.error! unless res.success?
end
end
# Public: Create a new project.
def create_repo project, options = {}
+ is_org = project.owner != config.username(project.host)
+ params = { :name => project.name }
+ params[:description] = options[:description] if options[:description]
+ params[:homepage] = options[:homepage] if options[:homepage]
+
if api_v2? project
- is_org = project.owner != config.username(project.host)
- params = {'name' => is_org ? project.name_with_owner : project.name}
- params['public'] = '0' if options[:private]
- params['description'] = options[:description] if options[:description]
- params['homepage'] = options[:homepage] if options[:homepage]
+ params[:name] = project.name_with_owner if is_org
+ params[:public] = '0' if options[:private]
res = post_form "https://%s/api/v2/json/repos/create" % project.host, params
res.error! unless res.success?
else
- raise NotImplementedError
+ params[:private] = !!options[:private]
+
+ if is_org
+ res = post "https://api.%s/orgs/%s/repos" % [project.host, project.owner], params
+ else
+ res = post "https://api.%s/user/repos" % project.host, params
+ end
+ res.error! unless res.success?
end
end
@@ -83,7 +109,10 @@ def pullrequest_info project, pull_id
res.error! unless res.success?
res.data['pull']
else
- raise NotImplementedError
+ res = get "https://api.%s/repos/%s/%s/pulls/%d" %
+ [project.host, project.owner, project.name, pull_id]
+ res.error! unless res.success?
+ res.data
end
end
@@ -105,7 +134,21 @@ def create_pullrequest options
res.error! unless res.success?
res.data['pull']
else
- raise NotImplementedError
+ params = {
+ :base => options.fetch(:base),
+ :head => options.fetch(:head)
+ }
+ if options[:issue]
+ params[:issue] = options[:issue]
+ else
+ params[:title] = options[:title] if options[:title]
+ params[:body] = options[:body] if options[:body]
+ end
+
+ res = post "https://api.%s/repos/%s/%s/pulls" %
+ [project.host, project.owner, project.name], params
+ res.error! unless res.success?
+ res.data
end
end
View
46 test/hub_test.rb
@@ -50,7 +50,7 @@ def setup
prompt_stubs.shift.call(what)
end
define_method :prompt_password do |host, user|
- password_prompt_stubs.shift.call(what)
+ password_prompt_stubs.shift.call(host, user)
end
end
@@ -365,6 +365,15 @@ def test_fetch_new_remote
"fetch xoebus"
end
+ def test_fetch_new_private_remote
+ stub_remotes_group('xoebus', nil)
+ stub_existing_private_fork('xoebus')
+
+ assert_commands "git remote add xoebus git@github.com:xoebus/hub.git",
+ "git fetch xoebus",
+ "fetch xoebus"
+ end
+
def test_fetch_new_remote_https_protocol
stub_remotes_group('xoebus', nil)
stub_existing_fork('xoebus')
@@ -1369,13 +1378,44 @@ def stub_existing_fork(user, repo = 'hub')
stub_fork(user, repo, 200)
end
+ def stub_existing_private_fork(user, repo = 'hub')
+ stub_fork(user, repo, 200, true)
+ end
+
def stub_nonexisting_fork(user, repo = 'hub')
stub_fork(user, repo, 404)
end
- def stub_fork(user, repo, status)
+ def stub_fork(user, repo, status, private_repo=false)
+ response = <<-EOF
+ {
+ "repository": {
+ "description": "Some description",
+ "source": "#{user}/#{repo}",
+ "watchers": 1,
+ "has_downloads": false,
+ "parent": "other_user/#{repo}",
+ "homepage": "http://example.org/#{repo}/",
+ "fork": true,
+ "has_issues": false,
+ "has_wiki": false,
+ "forks": 0,
+ "size": 304,
+ "private": #{private_repo},
+ "language": "Ruby",
+ "name": "#{repo}",
+ "owner": "#{user}",
+ "open_issues": 0,
+ "created_at": "2012/04/23 07:35:42 -0700",
+ "url": "https://github.com/#{user}/#{repo}",
+ "pushed_at": "2012/04/17 03:34:04 -0700"
+ }
+ }
+ EOF
stub_request(:get, "https://#{auth}github.com/api/v2/yaml/repos/show/#{user}/#{repo}").
- to_return(:status => status)
+ to_return(:status => status,
+ :headers => {"Content-type" => "application/yaml"},
+ :body => response)
end
def stub_available_commands(*names)

0 comments on commit 114029c

Please sign in to comment.