github_api 0.10.1 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/README.md +1 -1
  2. data/features/cassettes/ratelimit/get.yml +64 -0
  3. data/features/cassettes/ratelimit/get_remaining.yml +64 -0
  4. data/features/cassettes/repos/contents/create.yml +60 -0
  5. data/features/cassettes/repos/contents/delete.yml +59 -0
  6. data/features/cassettes/repos/contents/update.yml +62 -0
  7. data/features/issues.feature +3 -3
  8. data/features/pagination.feature +12 -12
  9. data/features/rate_limit.feature +16 -0
  10. data/features/repos/contents.feature +39 -0
  11. data/features/support/settings.rb +5 -1
  12. data/features/support/vcr.rb +1 -0
  13. data/lib/github_api/issues.rb +2 -16
  14. data/lib/github_api/jsonable.rb +1 -0
  15. data/lib/github_api/params_hash.rb +13 -0
  16. data/lib/github_api/rate_limit.rb +8 -4
  17. data/lib/github_api/repos.rb +2 -2
  18. data/lib/github_api/repos/contents.rb +110 -0
  19. data/lib/github_api/response/raise_error.rb +2 -2
  20. data/lib/github_api/version.rb +1 -1
  21. data/spec/fixtures/repos/content_created.json +44 -0
  22. data/spec/fixtures/repos/content_deleted.json +30 -0
  23. data/spec/github/api_spec.rb +2 -0
  24. data/spec/github/issues/list_spec.rb +10 -0
  25. data/spec/github/mime_type_spec.rb +2 -0
  26. data/spec/github/normalizer_spec.rb +2 -0
  27. data/spec/github/parameter_filter_spec.rb +2 -0
  28. data/spec/github/params_hash_spec.rb +5 -0
  29. data/spec/github/repos/contents/create_spec.rb +41 -0
  30. data/spec/github/repos/contents/delete_spec.rb +55 -0
  31. data/spec/github/repos/downloads/delete_spec.rb +2 -3
  32. data/spec/github/request/jsonize_spec.rb +2 -0
  33. data/spec/github/request/oauth2_spec.rb +2 -0
  34. data/spec/github/s3_uploader_spec.rb +2 -0
  35. data/spec/github/utils/url_spec.rb +2 -0
  36. data/spec/github/validations_spec.rb +2 -0
  37. data/spec/integration/multiple_invocations_spec.rb +2 -2
  38. metadata +52 -42
@@ -4,4 +4,8 @@ def settings_file
4
4
  Pathname.new(File.expand_path("../../settings.yml", __FILE__))
5
5
  end
6
6
 
7
- SETTINGS = (File.exists?(settings_file) && yaml= YAML.load_file(settings_file)) ? yaml : {'basic_auth' => 'login:password', 'oauth_token' => 'as79asfd79ads', 'user'=> 'octokat', 'repo' => 'dummy', 'email' => 'email@example.com'}
7
+ def live_credentials?
8
+ true
9
+ end
10
+
11
+ SETTINGS = (live_credentials? && File.exists?(settings_file) && yaml= YAML.load_file(settings_file)) ? yaml : {'basic_auth' => 'login:password', 'oauth_token' => 'as79asfd79ads', 'user'=> 'murek', 'repo' => 'dummy', 'email' => 'email@example.com'}
@@ -8,6 +8,7 @@ VCR.configure do |conf|
8
8
  conf.filter_sensitive_data('<TOKEN>') { SETTINGS['oauth_token'] }
9
9
  conf.filter_sensitive_data('<BASIC_AUTH>') { SETTINGS['basic_auth'] }
10
10
  conf.filter_sensitive_data('<USER>') { SETTINGS['user'] }
11
+ conf.debug_logger = File.open('test.log', 'w')
11
12
  end
12
13
 
13
14
  VCR.cucumber_tags do |t|
@@ -126,15 +126,6 @@ module Github
126
126
  # :sort => 'comments',
127
127
  # :direction => 'asc'
128
128
  #
129
- # github = Github.new :user => 'user-name', :repo => 'repo-name'
130
- # github.issues.list_repo :milestone => 1,
131
- # :state => 'open',
132
- # :assignee => '*',
133
- # :mentioned => 'octocat',
134
- # :labels => "bug,ui,bla",
135
- # :sort => 'comments',
136
- # :direction => 'asc'
137
- #
138
129
  def list(*args)
139
130
  params = arguments(args) do
140
131
  assert_values VALID_ISSUE_PARAM_VALUES
@@ -146,7 +137,7 @@ module Github
146
137
  elsif (user_name = params.delete('user')) &&
147
138
  (repo_name = params.delete('repo'))
148
139
 
149
- list_repo user_name, repo_name, params
140
+ list_repo user_name, repo_name
150
141
  elsif args.include? :user
151
142
  get_request("/user/issues", params)
152
143
  else
@@ -160,12 +151,7 @@ module Github
160
151
  # List issues for a repository
161
152
  #
162
153
  # def list_repo(user_name, repo_name, params)
163
- def list_repo(*args)
164
- arguments(args, :required => [:user, :repo]) do
165
- sift VALID_ISSUE_PARAM_NAMES
166
- assert_values VALID_ISSUE_PARAM_VALUES
167
- end
168
-
154
+ def list_repo(user, repo)
169
155
  get_request("/repos/#{user}/#{repo}/issues", arguments.params)
170
156
  end
171
157
  private :list_repo
@@ -7,6 +7,7 @@ module Github
7
7
  extend self
8
8
 
9
9
  def decode(*args)
10
+ return unless args.first
10
11
  if MultiJson.respond_to?(:load)
11
12
  MultiJson.load *args
12
13
  else
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'delegate'
4
+ require 'base64'
4
5
 
5
6
  module Github
6
7
 
@@ -66,5 +67,17 @@ module Github
66
67
  self
67
68
  end
68
69
 
70
+ # Base64 encode string removing newline characters
71
+ #
72
+ def strict_encode64(key)
73
+ value = self[key]
74
+ encoded = if Base64.respond_to?(:strict_encode64)
75
+ Base64.strict_encode64(value)
76
+ else
77
+ [value].pack("m0")
78
+ end
79
+ self[key] = encoded.delete("\n\r")
80
+ end
81
+
69
82
  end # ParamsHash
70
83
  end # Github
@@ -3,12 +3,16 @@
3
3
  module Github
4
4
  module RateLimit
5
5
 
6
- def ratelimit
7
- get_request("/rate_limit").rate.limit
6
+ def ratelimit(*args)
7
+ arguments(args)
8
+
9
+ get_request("/rate_limit", arguments.params).rate.limit
8
10
  end
9
11
 
10
- def ratelimit_remaining
11
- get_request("/rate_limit").rate.remaining
12
+ def ratelimit_remaining(*args)
13
+ arguments(args)
14
+
15
+ get_request("/rate_limit", arguments.params).rate.remaining
12
16
  end
13
17
 
14
18
  end # RateLimit
@@ -120,8 +120,8 @@ module Github
120
120
  #
121
121
  # = Examples
122
122
  # github = Github.new
123
- # github.repos.list every: true
124
- # github.repos.list every: true { |repo| ... }
123
+ # github.repos.list :every
124
+ # github.repos.list :every { |repo| ... }
125
125
  #
126
126
  # List public repositories for the specified user.
127
127
  #
@@ -6,6 +6,8 @@ module Github
6
6
  # as Base64 encoded content.
7
7
  class Repos::Contents < API
8
8
 
9
+ REQUIRED_CONTENT_OPTIONS = %w[ path message content ]
10
+
9
11
  # Get the README
10
12
  #
11
13
  # This method returns the preferred README for a repository.
@@ -46,6 +48,114 @@ module Github
46
48
  end
47
49
  alias :find :get
48
50
 
51
+ # Create a file
52
+ #
53
+ # This method creates a new file in a repository
54
+ #
55
+ # = Parameters
56
+ # * <tt>:path</tt> - Requried string - The content path
57
+ # * <tt>:message</tt> - Requried string - The commit message
58
+ # * <tt>:content</tt> - Requried string - The new file content,
59
+ # which will be Base64 encoded
60
+ # * <tt>:branch</tt> - Optional string - The branch name. If not provided,
61
+ # uses the repository’s default branch (usually master)
62
+ # = Optional Parameters
63
+ #
64
+ # The <tt>author</tt> section is optional and is filled in with the
65
+ # <tt>committer</tt> information if omitted. If the <tt>committer</tt>
66
+ # information is omitted, the authenticated user’s information is used.
67
+ #
68
+ # You must provide values for both <tt>name</tt> and <tt>email</tt>, whether
69
+ # you choose to use <tt>author</tt> or <tt>committer</tt>. Otherwise, you’ll
70
+ # receive a <tt>500</tt> status code.
71
+ #
72
+ # * <tt>author.name</tt> - string - The name of the author of the commit
73
+ # * <tt>author.email</tt> - string - The email of the author of the commit
74
+ # * <tt>committer.name</tt> - string - The name of the committer of the commit
75
+ # * <tt>committer.email</tt> - string - The email of the committer of the commit
76
+ #
77
+ # = Examples
78
+ # github = Github.new
79
+ # github.repos.contents.create 'user-name', 'repo-name', 'path',
80
+ # path: 'hello.rb',
81
+ # content: "puts 'hello ruby'",
82
+ # message: "my commit message"
83
+ #
84
+ def create(*args)
85
+ arguments(args, :required => [:user, :repo, :path]) do
86
+ assert_required REQUIRED_CONTENT_OPTIONS
87
+ end
88
+ params = arguments.params
89
+ params.strict_encode64('content')
90
+
91
+ put_request("/repos/#{user}/#{repo}/contents/#{path}", params)
92
+ end
93
+
94
+ # Update a file
95
+ #
96
+ # This method updates a file in a repository
97
+ #
98
+ # = Parameters
99
+ # * <tt>:path</tt> - Requried string - The content path
100
+ # * <tt>:message</tt> - Requried string - The commit message
101
+ # * <tt>:content</tt> - Requried string - The new file content,
102
+ # which will be Base64 encoded
103
+ # * <tt>:sha</tt> - Requried string - The blob SHA of the file being replaced.
104
+ # * <tt>:branch</tt> - Optional string - The branch name. If not provided,
105
+ # uses the repository’s default branch (usually master)
106
+ #
107
+ # = Examples
108
+ # github = Github.new
109
+ # github.repos.contents.update 'user-name', 'repo-name', 'path',
110
+ # path: 'hello.rb',
111
+ # content: "puts 'hello ruby again'",
112
+ # message: "my commit message",
113
+ # sha: "25b0bef9e404bd2e3233de26b7ef8cbd86d0e913"
114
+ #
115
+ def update(*args)
116
+ create(*args)
117
+ end
118
+
119
+ # Delete a file
120
+ #
121
+ # This method deletes a file in a repository
122
+ #
123
+ # = Parameters
124
+ # * <tt>:path</tt> - Requried string - The content path
125
+ # * <tt>:message</tt> - Requried string - The commit message
126
+ # * <tt>:sha</tt> - Requried string - The blob SHA of the file being removed.
127
+ # * <tt>:branch</tt> - Optional string - The branch name. If not provided,
128
+ # uses the repository’s default branch (usually master)
129
+ # = Optional Parameters
130
+ #
131
+ # The <tt>author</tt> section is optional and is filled in with the
132
+ # <tt>committer</tt> information if omitted. If the <tt>committer</tt>
133
+ # information is omitted, the authenticated user’s information is used.
134
+ #
135
+ # You must provide values for both <tt>name</tt> and <tt>email</tt>, whether
136
+ # you choose to use <tt>author</tt> or <tt>committer</tt>. Otherwise, you’ll
137
+ # receive a <tt>500</tt> status code.
138
+ #
139
+ # * <tt>author.name</tt> - string - The name of the author of the commit
140
+ # * <tt>author.email</tt> - string - The email of the author of the commit
141
+ # * <tt>committer.name</tt> - string - The name of the committer of the commit
142
+ # * <tt>committer.email</tt> - string - The email of the committer of the commit
143
+ #
144
+ # = Examples
145
+ # github = Github.new
146
+ # github.repos.contents.delete 'user-name', 'repo-name', 'path',
147
+ # path: 'hello.rb',
148
+ # message: "delete hello.rb file",
149
+ # sha: "329688480d39049927147c162b9d2deaf885005f"
150
+ #
151
+ def delete(*args)
152
+ arguments(args, :required => [:user, :repo, :path]) do
153
+ assert_required %w[ path message sha ]
154
+ end
155
+
156
+ delete_request("/repos/#{user}/#{repo}/contents/#{path}", arguments.params)
157
+ end
158
+
49
159
  # Get archive link
50
160
  #
51
161
  # This method will return a 302 to a URL to download a tarball or zipball
@@ -7,10 +7,10 @@ module Github
7
7
  class Response::RaiseError < Faraday::Response::Middleware
8
8
 
9
9
  def on_complete(env)
10
- status_code = env[:status].to_i
10
+ status_code = env[:status].to_i
11
11
  service_error = Github::Error::ServiceError
12
12
  error_class = service_error.errors[status_code]
13
- error_class = service_error if !error_class and (400...600).include? status_code
13
+ error_class = service_error if !error_class and (400...600) === status_code
14
14
  raise error_class.new(env) if error_class
15
15
  end
16
16
 
@@ -4,7 +4,7 @@ module Github
4
4
  module VERSION
5
5
  MAJOR = 0
6
6
  MINOR = 10
7
- PATCH = 1
7
+ PATCH = 2
8
8
  BUILD = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.');
@@ -0,0 +1,44 @@
1
+ {
2
+ "content": {
3
+ "name": "hello.txt",
4
+ "path": "notes/hello.txt",
5
+ "sha": "95b966ae1c166bd92f8ae7d1c313e738c731dfc3",
6
+ "size": 9,
7
+ "url": "https://api.github.com/repos/octocat/Hello-World/contents/notes/hello.txt",
8
+ "html_url": "https://github.com/octocat/Hello-World/blob/master/notes/hello.txt",
9
+ "git_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs/95b966ae1c166bd92f8ae7d1c313e738c731dfc3",
10
+ "type": "file",
11
+ "_links": {
12
+ "self": "https://api.github.com/repos/octocat/Hello-World/contents/notes/hello.txt",
13
+ "git": "https://api.github.com/repos/octocat/Hello-World/git/blobs/95b966ae1c166bd92f8ae7d1c313e738c731dfc3",
14
+ "html": "https://github.com/octocat/Hello-World/blob/master/notes/hello.txt"
15
+ }
16
+ },
17
+ "commit": {
18
+ "sha": "7638417db6d59f3c431d3e1f261cc637155684cd",
19
+ "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/7638417db6d59f3c431d3e1f261cc637155684cd",
20
+ "html_url": "https://github.com/octocat/Hello-World/git/commit/7638417db6d59f3c431d3e1f261cc637155684cd",
21
+ "author": {
22
+ "date": "2010-04-10T14:10:01-07:00",
23
+ "name": "Scott Chacon",
24
+ "email": "schacon@gmail.com"
25
+ },
26
+ "committer": {
27
+ "date": "2010-04-10T14:10:01-07:00",
28
+ "name": "Scott Chacon",
29
+ "email": "schacon@gmail.com"
30
+ },
31
+ "message": "my commit message",
32
+ "tree": {
33
+ "url": "https://api.github.com/repos/octocat/Hello-World/git/trees/691272480426f78a0138979dd3ce63b77f706feb",
34
+ "sha": "691272480426f78a0138979dd3ce63b77f706feb"
35
+ },
36
+ "parents": [
37
+ {
38
+ "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/1acc419d4d6a9ce985db7be48c6349a0475975b5",
39
+ "html_url": "https://github.com/octocat/Hello-World/git/commit/1acc419d4d6a9ce985db7be48c6349a0475975b5",
40
+ "sha": "1acc419d4d6a9ce985db7be48c6349a0475975b5"
41
+ }
42
+ ]
43
+ }
44
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "content": null,
3
+ "commit": {
4
+ "sha": "7638417db6d59f3c431d3e1f261cc637155684cd",
5
+ "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/7638417db6d59f3c431d3e1f261cc637155684cd",
6
+ "html_url": "https://github.com/octocat/Hello-World/git/commit/7638417db6d59f3c431d3e1f261cc637155684cd",
7
+ "author": {
8
+ "date": "2010-04-10T14:10:01-07:00",
9
+ "name": "Scott Chacon",
10
+ "email": "schacon@gmail.com"
11
+ },
12
+ "committer": {
13
+ "date": "2010-04-10T14:10:01-07:00",
14
+ "name": "Scott Chacon",
15
+ "email": "schacon@gmail.com"
16
+ },
17
+ "message": "my commit message",
18
+ "tree": {
19
+ "url": "https://api.github.com/repos/octocat/Hello-World/git/trees/691272480426f78a0138979dd3ce63b77f706feb",
20
+ "sha": "691272480426f78a0138979dd3ce63b77f706feb"
21
+ },
22
+ "parents": [
23
+ {
24
+ "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/1acc419d4d6a9ce985db7be48c6349a0475975b5",
25
+ "html_url": "https://github.com/octocat/Hello-World/git/commit/1acc419d4d6a9ce985db7be48c6349a0475975b5",
26
+ "sha": "1acc419d4d6a9ce985db7be48c6349a0475975b5"
27
+ }
28
+ ]
29
+ }
30
+ }
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Github::API do
@@ -63,6 +63,11 @@ describe Github::Issues, '#list' do
63
63
  let(:repo) { 'github' }
64
64
  let(:request_path) { "/repos/#{user}/#{repo}/issues" }
65
65
 
66
+ before {
67
+ stub_request(:get, "https://api.github.com/repos/peter-murach/github/issues?param1=foo&param2=bar").
68
+ to_return(:headers => {:content_type => "application/json; charset=utf-8"})
69
+ }
70
+
66
71
  it "should get the resources" do
67
72
  subject.list :user => user, :repo => repo
68
73
  a_get(request_path).should have_been_made
@@ -82,6 +87,11 @@ describe Github::Issues, '#list' do
82
87
  result = subject.list(:user => user, :repo => repo) { |obj| yielded << obj }
83
88
  yielded.should == result
84
89
  end
90
+
91
+ it "should pass parameters" do
92
+ subject.list :user => user, :repo => repo, :param1 => "foo", :param2 => "bar"
93
+ a_get(request_path + "?param1=foo&param2=bar").should have_been_made
94
+ end
85
95
  end
86
96
 
87
97
  it_should_behave_like 'request failure' do
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Github::MimeType do
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
  require 'github_api/core_ext/hash'
3
5
 
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
  require 'github_api/core_ext/hash'
3
5
 
@@ -61,4 +61,9 @@ describe Github::ParamsHash do
61
61
  end
62
62
  end
63
63
 
64
+ context 'strict encode' do
65
+ let(:hash) { { :content => "puts 'hello ruby'"} }
66
+
67
+ it { expect(subject.strict_encode64('content')).to eql('cHV0cyAnaGVsbG8gcnVieSc=') }
68
+ end
64
69
  end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Github::Repos::Contents, '#create' do
6
+ let(:user) { 'peter-murach' }
7
+ let(:repo) { 'github' }
8
+ let(:path) { 'hello.rb' }
9
+ let(:request_path) { "/repos/#{user}/#{repo}/contents/#{path}" }
10
+
11
+ before {
12
+ stub_put(request_path).to_return(:body => body, :status => status,
13
+ :headers => {:content_type => "application/json; charset=utf-8"})
14
+ }
15
+
16
+ after { reset_authentication_for(subject) }
17
+
18
+ let(:params) {
19
+ {
20
+ "path" => 'hello.rb',
21
+ "content" => "puts 'hello ruby'",
22
+ "message" => "initial commit"
23
+ }
24
+ }
25
+ let(:body) { fixture('repos/content_created.json') }
26
+ let(:status) { 201 }
27
+
28
+ it { expect { subject.create }.to raise_error(ArgumentError)}
29
+
30
+ it { expect { subject.create user, repo, path }.to raise_error(Github::Error::RequiredParams) }
31
+
32
+ it "creates the resource" do
33
+ subject.create user, repo, path, params
34
+ a_put(request_path).should have_been_made
35
+ end
36
+
37
+ it "gets repository contents information" do
38
+ content = subject.create user, repo, path, params
39
+ content.content.name.should == 'hello.txt'
40
+ end
41
+ end