gh 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +2 -3
- data/README.md +102 -22
- data/lib/gh.rb +10 -8
- data/lib/gh/link_follower.rb +19 -0
- data/lib/gh/response.rb +1 -1
- data/lib/gh/version.rb +1 -1
- data/spec/link_follower_spec.rb +20 -0
- data/spec/payloads/repos/sinatra/sinatra/issues/56/comments.yml +36 -0
- data/spec/payloads/repos/sinatra/sinatra/issues/comments/383214.yml +21 -0
- data/spec/payloads/repos/sinatra/sinatra/pulls/56.yml +23 -0
- data/spec/payloads/users/rtomayko.yml +21 -0
- data/spec/response_spec.rb +11 -1
- metadata +24 -13
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,38 +1,118 @@
|
|
1
|
-
|
1
|
+
# GH - Layered GitHub API client
|
2
2
|
|
3
|
-
|
3
|
+
This is a highly flexible, layered, low-level GitHub client library, trying to get out of your way and let you get to the GitHub data as simple as possible. Unless you add layers, you will end up with Hashes and Arrays. The approach and API should be familiar from projects like Rack or Faraday.
|
4
4
|
|
5
|
-
|
5
|
+
Simple example:
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
``` ruby
|
8
|
+
require 'gh'
|
9
|
+
puts GH['users/rkh']['name']
|
10
|
+
```
|
11
|
+
|
12
|
+
This will by default use all the middleware that ships with GH, in the following order
|
13
|
+
|
14
|
+
* `GH::Remote` - sends HTTP requests to GitHub and parses the response
|
15
|
+
* `GH::Normalizer` - renames fields consistenly, adds hypermedia links if possible
|
16
|
+
* `GH::Cache` - caches the responses (will use Rails cache if in Rails, in-memory cache otherwise)
|
17
|
+
* `GH::LazyLoader` - will load missing fields when accessed (handy for dealing with incomplete data without sending to many requests)
|
18
|
+
* `GH::LinkFollower` - will add content of hypermedia links as fields (lazyly), allows you to traverse relations
|
19
|
+
|
20
|
+
## Main Entry Points
|
21
|
+
|
22
|
+
Every layer has two main entry points:
|
23
|
+
|
24
|
+
* `[key]` - loads data from GitHub
|
25
|
+
* `load(data)` - takes data and applies modifications (handy for dealing with service hook payloads)
|
26
|
+
|
27
|
+
These two methods are exposed by any instance of a layer and the `GH` constant.
|
28
|
+
|
29
|
+
## Using a Single Layer
|
30
|
+
|
31
|
+
You can initialize and use any layer on its own:
|
32
|
+
|
33
|
+
``` ruby
|
34
|
+
gh = GH::Remote.new
|
35
|
+
puts gh['users/rkh']['name']
|
36
|
+
```
|
37
|
+
|
38
|
+
Layers know which other layer they should usually wrap (`Remote` wraps no other layer, `LazyLoader` and `LinkFollower` wrap `Normalizer` by default, anything else wraps `Remote`), so you can initialize them right away:
|
39
|
+
|
40
|
+
``` ruby
|
41
|
+
gh = GH::LazyLoader.new
|
42
|
+
```
|
43
|
+
|
44
|
+
You can also pass the layer that should be wrapped as an argument:
|
45
|
+
|
46
|
+
``` ruby
|
47
|
+
gh = GH::LazyLoader.new(GH::LinkFollower.new)
|
48
|
+
```
|
49
|
+
|
50
|
+
## Creating Your Own Stack
|
51
|
+
|
52
|
+
For convinience a stack DSL is provided:
|
14
53
|
|
15
|
-
|
54
|
+
``` ruby
|
55
|
+
gh = GH::Stack.build do
|
56
|
+
use GH::Normalizer
|
57
|
+
use GH::Cache
|
58
|
+
end
|
16
59
|
|
17
|
-
|
60
|
+
puts gh['users/rkh']['name']
|
61
|
+
```
|
62
|
+
|
63
|
+
You can also create reusable `Stack` instances:
|
18
64
|
|
19
65
|
``` ruby
|
20
|
-
|
21
|
-
use GH::Cache, cache: Rails.cache
|
66
|
+
stack = GH::Stack.new do
|
22
67
|
use GH::Normalizer
|
23
|
-
use GH::
|
68
|
+
use GH::Cache
|
24
69
|
end
|
70
|
+
|
71
|
+
gh = stack.build username: 'rkh', password: 'abc123'
|
72
|
+
puts gh['user']['name']
|
25
73
|
```
|
26
74
|
|
27
|
-
|
75
|
+
One such instance (with the standard setup) can be accessed as `GH::DefaultStack`
|
76
|
+
|
77
|
+
## Scoping
|
78
|
+
|
79
|
+
With the main goal to separate authentication from other logic, the `gh` library supports scopting:
|
28
80
|
|
29
81
|
``` ruby
|
30
|
-
GH.with
|
31
|
-
|
82
|
+
GH.with GH::LazyLoader.new do
|
83
|
+
puts GH['users/rkh']['name']
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
That way, you could create a stack with, for instance, an [access token](http://developer.github.com/v3/oauth/):
|
32
88
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
89
|
+
``` ruby
|
90
|
+
authenticated = GH::DefaultStack token: 'e72e16c7e42f292c6912e7710c838347ae178b4a'
|
91
|
+
|
92
|
+
GH.with(authenticated) do
|
93
|
+
# ...
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
Since this is rather common, you can pass options directly to `with`:
|
98
|
+
|
99
|
+
``` ruby
|
100
|
+
GH.with(username: 'rkh', password: 'abc123') do
|
101
|
+
# ...
|
37
102
|
end
|
38
103
|
```
|
104
|
+
|
105
|
+
Scoping is thread-safe.
|
106
|
+
|
107
|
+
## Is this production ready?
|
108
|
+
|
109
|
+
I hope so, we use it in production for [Travis CI](http://travis-ci.org/). The work on this library has been funded by the [Travis Love Campaign](https://love.travis-ci.org/).
|
110
|
+
|
111
|
+
## History
|
112
|
+
|
113
|
+
* 2012-04-10: 0.2.0 - added link following plus bug fixes (mainly encoding issues)
|
114
|
+
* 2012-04-06: 0.1.2 - bug fix release (issues with cache reloading)
|
115
|
+
* 2012-04-06: 0.1.1 - bug fix release (DSL fixes)
|
116
|
+
* 2012-04-04: 0.1.0 - many bug fixes plus lazy loading
|
117
|
+
* 2012-03-21: 0.0.1 - first public release
|
118
|
+
* 2012-03-05: project started
|
data/lib/gh.rb
CHANGED
@@ -3,14 +3,15 @@ require 'backports'
|
|
3
3
|
require 'forwardable'
|
4
4
|
|
5
5
|
module GH
|
6
|
-
autoload :Cache,
|
7
|
-
autoload :Case,
|
8
|
-
autoload :LazyLoader,
|
9
|
-
autoload :
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
6
|
+
autoload :Cache, 'gh/cache'
|
7
|
+
autoload :Case, 'gh/case'
|
8
|
+
autoload :LazyLoader, 'gh/lazy_loader'
|
9
|
+
autoload :LinkFollower, 'gh/link_follower'
|
10
|
+
autoload :Normalizer, 'gh/normalizer'
|
11
|
+
autoload :Remote, 'gh/remote'
|
12
|
+
autoload :Response, 'gh/response'
|
13
|
+
autoload :Stack, 'gh/stack'
|
14
|
+
autoload :Wrapper, 'gh/wrapper'
|
14
15
|
|
15
16
|
def self.with(backend)
|
16
17
|
backend = DefaultStack.build(backend) if Hash === backend
|
@@ -32,6 +33,7 @@ module GH
|
|
32
33
|
def_delegators :current, :api_host, :[], :reset
|
33
34
|
|
34
35
|
DefaultStack = Stack.new do
|
36
|
+
use LinkFollower
|
35
37
|
use LazyLoader
|
36
38
|
use Cache
|
37
39
|
use Normalizer
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module GH
|
2
|
+
class LinkFollower < Wrapper
|
3
|
+
wraps GH::Normalizer
|
4
|
+
double_dispatch
|
5
|
+
|
6
|
+
def modify_hash(hash)
|
7
|
+
hash = super
|
8
|
+
setup_lazy_loading(hash) if hash['_links']
|
9
|
+
hash
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def lazy_load(hash, key)
|
15
|
+
link = hash['_links'][key]
|
16
|
+
{ key => backend[link['href']] } if link
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/gh/response.rb
CHANGED
@@ -34,8 +34,8 @@ module GH
|
|
34
34
|
else raise ArgumentError, "cannot parse #{body.inspect}"
|
35
35
|
end
|
36
36
|
|
37
|
+
@body.force_encoding("utf-8") if @body.respond_to? :force_encoding
|
37
38
|
@body ||= MultiJson.encode(@data)
|
38
|
-
@body = @body.encode("utf-8") if @body.respond_to? :encode
|
39
39
|
@data ||= MultiJson.decode(@body)
|
40
40
|
end
|
41
41
|
|
data/lib/gh/version.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GH::LinkFollower do
|
4
|
+
before { subject.backend = GH::Normalizer.new(GH::MockBackend.new) }
|
5
|
+
|
6
|
+
let(:pull_request) { subject['/repos/sinatra/sinatra/pulls/56'] }
|
7
|
+
let(:comments) { pull_request['comments'] }
|
8
|
+
let(:comment) { comments.first }
|
9
|
+
let(:commentator) { comment['owner'] }
|
10
|
+
|
11
|
+
it 'follows links' do
|
12
|
+
commentator['login'].should be == 'rtomayko'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'works with lazy loading' do
|
16
|
+
subject.backend = GH::LazyLoader.new(subject.backend)
|
17
|
+
# location is not included in the comment payload
|
18
|
+
commentator["location"].should be == "San Francisco"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
- !binary "c2VydmVy": !binary |-
|
3
|
+
bmdpbngvMS4wLjEz
|
4
|
+
!binary "ZGF0ZQ==": !binary |-
|
5
|
+
VHVlLCAxMCBBcHIgMjAxMiAxMTo1MzoxMiBHTVQ=
|
6
|
+
!binary "Y29udGVudC10eXBl": !binary |-
|
7
|
+
YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
|
8
|
+
!binary "dHJhbnNmZXItZW5jb2Rpbmc=": !binary |-
|
9
|
+
Y2h1bmtlZA==
|
10
|
+
!binary "Y29ubmVjdGlvbg==": !binary |-
|
11
|
+
a2VlcC1hbGl2ZQ==
|
12
|
+
!binary "c3RhdHVz": !binary |-
|
13
|
+
MjAwIE9L
|
14
|
+
!binary "eC1yYXRlbGltaXQtbGltaXQ=": !binary |-
|
15
|
+
NTAwMA==
|
16
|
+
!binary "ZXRhZw==": !binary |-
|
17
|
+
ImI5MDUzNGQ0Zjk3YTU0OGEwNTY1NWIyODg4OGM4YTZhIg==
|
18
|
+
!binary "eC1yYXRlbGltaXQtcmVtYWluaW5n": !binary |-
|
19
|
+
NDk5Mw==
|
20
|
+
- ! '[{"created_at":"2010-09-01T15:42:44Z","body":"This all looks good to me. Anyone
|
21
|
+
run the unit tests under 1.8.6, 1.8.7, 1.9.2?","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/383214","updated_at":"2010-09-01T15:42:44Z","user":{"gravatar_id":"abfc88b96ae18c85ba7aac3bded2ec5e","url":"https://api.github.com/users/rtomayko","login":"rtomayko","avatar_url":"https://secure.gravatar.com/avatar/abfc88b96ae18c85ba7aac3bded2ec5e?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","id":404},"id":383214},{"created_at":"2010-09-01T15:48:46Z","body":"Yep,
|
22
|
+
all pass. Even on JRuby 1.5.2. But on 1.9.2 they have to be run manually (see #52),
|
23
|
+
at least on my box. Same goes for current master, however.","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/383231","updated_at":"2010-09-01T16:00:16Z","user":{"gravatar_id":"5c2b452f6eea4a6d84c105ebd971d2a4","url":"https://api.github.com/users/rkh","login":"rkh","avatar_url":"https://secure.gravatar.com/avatar/5c2b452f6eea4a6d84c105ebd971d2a4?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","id":30442},"id":383231},{"created_at":"2010-09-01T16:16:08Z","body":"Hi,
|
24
|
+
why would you want to keep a version of Tilt bundled on Sinatra when Sinatra can
|
25
|
+
include Tilt as a dependency?","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/383302","updated_at":"2010-09-01T16:16:08Z","user":{"gravatar_id":"9d0d8afbcf75a57c86e41ba0fc6f8a98","url":"https://api.github.com/users/mr-rock","login":"mr-rock","avatar_url":"https://secure.gravatar.com/avatar/9d0d8afbcf75a57c86e41ba0fc6f8a98?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","id":23641},"id":383302},{"created_at":"2010-09-01T16:18:24Z","body":"Yeah.
|
26
|
+
I think the last time blake and I discussed tilt bundling, we decided to *not* bundle
|
27
|
+
it and just make it a dependency.","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/383307","updated_at":"2010-09-01T16:18:24Z","user":{"gravatar_id":"abfc88b96ae18c85ba7aac3bded2ec5e","url":"https://api.github.com/users/rtomayko","login":"rtomayko","avatar_url":"https://secure.gravatar.com/avatar/abfc88b96ae18c85ba7aac3bded2ec5e?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","id":404},"id":383307},{"created_at":"2010-09-01T16:21:54Z","body":"Lots
|
28
|
+
of goodies in here, particularly added support for scss views.","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/383320","updated_at":"2010-09-01T16:21:54Z","user":{"gravatar_id":"7fe945668a4fc098e886e20dea71d2ee","url":"https://api.github.com/users/zzak","login":"zzak","avatar_url":"https://secure.gravatar.com/avatar/7fe945668a4fc098e886e20dea71d2ee?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","id":277819},"id":383320},{"created_at":"2010-09-01T16:27:24Z","body":"@RTomayko:
|
29
|
+
I don''t see the point to repeat code that is going to be obsolete in some time
|
30
|
+
anyway. I already made a pull request in which Tilt is removed from Sinatra and
|
31
|
+
Tilt is a dependency of the gem. I tested it in Ruby 1.9.1 and it seems to work.","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/383334","updated_at":"2010-09-01T20:46:27Z","user":{"gravatar_id":"9d0d8afbcf75a57c86e41ba0fc6f8a98","url":"https://api.github.com/users/mr-rock","login":"mr-rock","avatar_url":"https://secure.gravatar.com/avatar/9d0d8afbcf75a57c86e41ba0fc6f8a98?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","id":23641},"id":383334},{"created_at":"2010-09-02T05:20:52Z","body":"@RTomayko:
|
32
|
+
Before Tilt is unbundled, could you please do another Tilt release? I think the
|
33
|
+
ScssTemplate hasn''t made it into 1.0.1.","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/384475","updated_at":"2010-09-02T05:20:52Z","user":{"gravatar_id":"5c2b452f6eea4a6d84c105ebd971d2a4","url":"https://api.github.com/users/rkh","login":"rkh","avatar_url":"https://secure.gravatar.com/avatar/5c2b452f6eea4a6d84c105ebd971d2a4?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","id":30442},"id":384475},{"created_at":"2010-09-02T05:35:17Z","body":"Scss
|
34
|
+
support was added after 1.0.1: http://github.com/rtomayko/tilt/commit/d6e8795c619970d0cfdbf4aead0869c592c44fe6","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/384487","updated_at":"2010-09-02T05:35:17Z","user":{"gravatar_id":"7fe945668a4fc098e886e20dea71d2ee","url":"https://api.github.com/users/zzak","login":"zzak","avatar_url":"https://secure.gravatar.com/avatar/7fe945668a4fc098e886e20dea71d2ee?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","id":277819},"id":384487},{"created_at":"2010-09-07T05:35:18Z","body":"You
|
35
|
+
can now do `rake spec` on 1.9.2p0, too. (And it passes, of course.)","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/392094","updated_at":"2010-09-07T05:35:39Z","user":{"gravatar_id":"5c2b452f6eea4a6d84c105ebd971d2a4","url":"https://api.github.com/users/rkh","login":"rkh","avatar_url":"https://secure.gravatar.com/avatar/5c2b452f6eea4a6d84c105ebd971d2a4?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","id":30442},"id":392094},{"created_at":"2010-09-19T21:21:50Z","body":"How
|
36
|
+
do you feel about including #62 and #63, maybe even #58?","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/416490","updated_at":"2010-09-19T21:21:50Z","user":{"gravatar_id":"5c2b452f6eea4a6d84c105ebd971d2a4","url":"https://api.github.com/users/rkh","login":"rkh","avatar_url":"https://secure.gravatar.com/avatar/5c2b452f6eea4a6d84c105ebd971d2a4?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","id":30442},"id":416490}]'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
- !binary "c2VydmVy": !binary |-
|
3
|
+
bmdpbngvMS4wLjEz
|
4
|
+
!binary "ZGF0ZQ==": !binary |-
|
5
|
+
VHVlLCAxMCBBcHIgMjAxMiAxMTo1MzoyNyBHTVQ=
|
6
|
+
!binary "Y29udGVudC10eXBl": !binary |-
|
7
|
+
YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
|
8
|
+
!binary "dHJhbnNmZXItZW5jb2Rpbmc=": !binary |-
|
9
|
+
Y2h1bmtlZA==
|
10
|
+
!binary "Y29ubmVjdGlvbg==": !binary |-
|
11
|
+
a2VlcC1hbGl2ZQ==
|
12
|
+
!binary "c3RhdHVz": !binary |-
|
13
|
+
MjAwIE9L
|
14
|
+
!binary "eC1yYXRlbGltaXQtbGltaXQ=": !binary |-
|
15
|
+
NTAwMA==
|
16
|
+
!binary "ZXRhZw==": !binary |-
|
17
|
+
ImJhOWJlN2ViNTlmZjBkZDZhNWFhYTU3MzM0ODE5ZjI5Ig==
|
18
|
+
!binary "eC1yYXRlbGltaXQtcmVtYWluaW5n": !binary |-
|
19
|
+
NDk5Mg==
|
20
|
+
- ! '{"created_at":"2010-09-01T15:42:44Z","body":"This all looks good to me. Anyone
|
21
|
+
run the unit tests under 1.8.6, 1.8.7, 1.9.2?","url":"https://api.github.com/repos/sinatra/sinatra/issues/comments/383214","updated_at":"2010-09-01T15:42:44Z","user":{"gravatar_id":"abfc88b96ae18c85ba7aac3bded2ec5e","avatar_url":"https://secure.gravatar.com/avatar/abfc88b96ae18c85ba7aac3bded2ec5e?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","url":"https://api.github.com/users/rtomayko","login":"rtomayko","id":404},"id":383214}'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
- !binary "c2VydmVy": !binary |-
|
3
|
+
bmdpbngvMS4wLjEz
|
4
|
+
!binary "ZGF0ZQ==": !binary |-
|
5
|
+
VHVlLCAxMCBBcHIgMjAxMiAxMTo1MzoxMSBHTVQ=
|
6
|
+
!binary "Y29udGVudC10eXBl": !binary |-
|
7
|
+
YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
|
8
|
+
!binary "dHJhbnNmZXItZW5jb2Rpbmc=": !binary |-
|
9
|
+
Y2h1bmtlZA==
|
10
|
+
!binary "Y29ubmVjdGlvbg==": !binary |-
|
11
|
+
a2VlcC1hbGl2ZQ==
|
12
|
+
!binary "c3RhdHVz": !binary |-
|
13
|
+
MjAwIE9L
|
14
|
+
!binary "eC1yYXRlbGltaXQtbGltaXQ=": !binary |-
|
15
|
+
NTAwMA==
|
16
|
+
!binary "ZXRhZw==": !binary |-
|
17
|
+
Ijg2ODgwMDdjMWIwMWZiZmM3OTY2NGE1OWJiMjc2MjVlIg==
|
18
|
+
!binary "eC1yYXRlbGltaXQtcmVtYWluaW5n": !binary |-
|
19
|
+
NDk5NA==
|
20
|
+
- ! '{"merged":true,"created_at":"2010-09-01T11:33:50Z","review_comments":0,"number":56,"additions":2956,"head":{"repo":{"has_wiki":false,"created_at":"2009-12-03T10:42:35Z","description":"Classy
|
21
|
+
web-development dressed in a DSL","open_issues":0,"git_url":"git://github.com/rkh/sinatra.git","watchers":10,"pushed_at":"2012-03-22T10:06:05Z","url":"https://api.github.com/repos/rkh/sinatra","mirror_url":null,"fork":true,"html_url":"https://github.com/rkh/sinatra","homepage":"http://sinatra.github.com","svn_url":"https://github.com/rkh/sinatra","has_downloads":false,"size":160,"private":false,"updated_at":"2012-03-22T10:06:06Z","master_branch":"master","has_issues":false,"owner":{"gravatar_id":"5c2b452f6eea4a6d84c105ebd971d2a4","avatar_url":"https://secure.gravatar.com/avatar/5c2b452f6eea4a6d84c105ebd971d2a4?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","url":"https://api.github.com/users/rkh","login":"rkh","id":30442},"name":"sinatra","forks":3,"language":"Ruby","clone_url":"https://github.com/rkh/sinatra.git","ssh_url":"git@github.com:rkh/sinatra.git","id":393951},"ref":"1.1","sha":"69791f71285c84e217efc061eee15ef32ffca515","label":"rkh:1.1","user":{"gravatar_id":"5c2b452f6eea4a6d84c105ebd971d2a4","avatar_url":"https://secure.gravatar.com/avatar/5c2b452f6eea4a6d84c105ebd971d2a4?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","url":"https://api.github.com/users/rkh","login":"rkh","id":30442}},"merged_at":"2010-09-25T19:43:05Z","body":"Patches
|
22
|
+
prepared for 1.1 release. See also http://github.com/sinatra/sinatra/issues/issue/55","diff_url":"https://github.com/sinatra/sinatra/pull/56.diff","commits":81,"url":"https://api.github.com/repos/sinatra/sinatra/pulls/56","deletions":1065,"html_url":"https://github.com/sinatra/sinatra/pull/56","patch_url":"https://github.com/sinatra/sinatra/pull/56.patch","comments":10,"base":{"repo":{"has_wiki":false,"created_at":"2009-01-14T01:27:30Z","description":"Classy
|
23
|
+
web-development dressed in a DSL (official / canonical repo)","open_issues":12,"git_url":"git://github.com/sinatra/sinatra.git","watchers":3442,"pushed_at":"2012-04-02T13:58:27Z","url":"https://api.github.com/repos/sinatra/sinatra","mirror_url":null,"fork":true,"html_url":"https://github.com/sinatra/sinatra","homepage":"http://www.sinatrarb.com/","svn_url":"https://github.com/sinatra/sinatra","has_downloads":true,"size":460,"private":false,"updated_at":"2012-04-10T10:05:43Z","has_issues":true,"owner":{"gravatar_id":"22be51f9cf3849462ffc4107675ec182","avatar_url":"https://secure.gravatar.com/avatar/22be51f9cf3849462ffc4107675ec182?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-orgs.png","url":"https://api.github.com/users/sinatra","login":"sinatra","id":8312},"name":"sinatra","forks":431,"language":"Ruby","clone_url":"https://github.com/sinatra/sinatra.git","ssh_url":"git@github.com:sinatra/sinatra.git","id":106995},"ref":"master","sha":"1187a866346e82c98b8ad545b8f155632f7d9283","label":"sinatra:master","user":{"gravatar_id":"22be51f9cf3849462ffc4107675ec182","avatar_url":"https://secure.gravatar.com/avatar/22be51f9cf3849462ffc4107675ec182?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-orgs.png","url":"https://api.github.com/users/sinatra","login":"sinatra","id":8312}},"updated_at":"2010-09-25T19:43:06Z","state":"closed","mergeable":null,"_links":{"review_comments":{"href":"https://api.github.com/repos/sinatra/sinatra/pulls/56/comments"},"html":{"href":"https://github.com/sinatra/sinatra/pull/56"},"comments":{"href":"https://api.github.com/repos/sinatra/sinatra/issues/56/comments"},"self":{"href":"https://api.github.com/repos/sinatra/sinatra/pulls/56"}},"user":{"gravatar_id":"5c2b452f6eea4a6d84c105ebd971d2a4","avatar_url":"https://secure.gravatar.com/avatar/5c2b452f6eea4a6d84c105ebd971d2a4?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","url":"https://api.github.com/users/rkh","login":"rkh","id":30442},"id":632,"merged_by":null,"changed_files":41,"closed_at":"2010-09-25T19:43:05Z","title":"1.1","issue_url":"https://github.com/sinatra/sinatra/issues/56"}'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
- !binary "c2VydmVy": !binary |-
|
3
|
+
bmdpbngvMS4wLjEz
|
4
|
+
!binary "ZGF0ZQ==": !binary |-
|
5
|
+
VHVlLCAxMCBBcHIgMjAxMiAxMjowODo1MSBHTVQ=
|
6
|
+
!binary "Y29udGVudC10eXBl": !binary |-
|
7
|
+
YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
|
8
|
+
!binary "dHJhbnNmZXItZW5jb2Rpbmc=": !binary |-
|
9
|
+
Y2h1bmtlZA==
|
10
|
+
!binary "Y29ubmVjdGlvbg==": !binary |-
|
11
|
+
a2VlcC1hbGl2ZQ==
|
12
|
+
!binary "c3RhdHVz": !binary |-
|
13
|
+
MjAwIE9L
|
14
|
+
!binary "eC1yYXRlbGltaXQtbGltaXQ=": !binary |-
|
15
|
+
NTAwMA==
|
16
|
+
!binary "ZXRhZw==": !binary |-
|
17
|
+
ImE2NGMxMmQ5Y2YyZTJmM2E5ZDgyNWMxNjJkNTc0ZjE2Ig==
|
18
|
+
!binary "eC1yYXRlbGltaXQtcmVtYWluaW5n": !binary |-
|
19
|
+
NDk4Nw==
|
20
|
+
- ! '{"created_at":"2008-02-19T03:30:53Z","type":"User","blog":"http://twitter.com/rtomayko","email":"r@tomayko.com","gravatar_id":"abfc88b96ae18c85ba7aac3bded2ec5e","followers":1099,"following":97,"url":"https://api.github.com/users/rtomayko","login":"rtomayko","public_repos":39,"hireable":false,"avatar_url":"https://secure.gravatar.com/avatar/abfc88b96ae18c85ba7aac3bded2ec5e?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","public_gists":84,"name":"Ryan
|
21
|
+
Tomayko","location":"San Francisco","bio":null,"html_url":"https://github.com/rtomayko","company":"GitHub","id":404}'
|
data/spec/response_spec.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe GH::Response do
|
4
|
-
it '
|
5
|
+
it 'handles UTF-8 properly, even if encoded binary' do
|
6
|
+
raw = '{"foo":"über cool sista året"}'
|
7
|
+
raw.force_encoding 'binary' if raw.respond_to? :force_encoding
|
8
|
+
response = GH::Response.new({}, raw)
|
9
|
+
response['foo'].should be == 'über cool sista året'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'handles broken encodings properly' do
|
13
|
+
GH::Response.new({}, "{\"foo\":\"\xC3\"}")["foo"].should be == "\xC3"
|
14
|
+
end
|
5
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-10 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70274565390500 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70274565390500
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: webmock
|
27
|
-
requirement: &
|
27
|
+
requirement: &70274565390060 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70274565390060
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: faraday
|
38
|
-
requirement: &
|
38
|
+
requirement: &70274565389500 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0.7'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70274565389500
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: backports
|
49
|
-
requirement: &
|
49
|
+
requirement: &70274565388980 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '2.3'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70274565388980
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: multi_json
|
60
|
-
requirement: &
|
60
|
+
requirement: &70274565388440 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '1.0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70274565388440
|
69
69
|
description: multi-layer client for the github api v3
|
70
70
|
email:
|
71
71
|
- konstantin.mailinglists@googlemail.com
|
@@ -84,6 +84,7 @@ files:
|
|
84
84
|
- lib/gh/case.rb
|
85
85
|
- lib/gh/faraday.rb
|
86
86
|
- lib/gh/lazy_loader.rb
|
87
|
+
- lib/gh/link_follower.rb
|
87
88
|
- lib/gh/normalizer.rb
|
88
89
|
- lib/gh/remote.rb
|
89
90
|
- lib/gh/response.rb
|
@@ -93,8 +94,13 @@ files:
|
|
93
94
|
- spec/cache_spec.rb
|
94
95
|
- spec/gh_spec.rb
|
95
96
|
- spec/lazy_loader_spec.rb
|
97
|
+
- spec/link_follower_spec.rb
|
96
98
|
- spec/normalizer_spec.rb
|
99
|
+
- spec/payloads/repos/sinatra/sinatra/issues/56/comments.yml
|
100
|
+
- spec/payloads/repos/sinatra/sinatra/issues/comments/383214.yml
|
101
|
+
- spec/payloads/repos/sinatra/sinatra/pulls/56.yml
|
97
102
|
- spec/payloads/users/rkh.yml
|
103
|
+
- spec/payloads/users/rtomayko.yml
|
98
104
|
- spec/payloads/users/svenfuchs.yml
|
99
105
|
- spec/remote_spec.rb
|
100
106
|
- spec/response_spec.rb
|
@@ -121,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
127
|
version: '0'
|
122
128
|
requirements: []
|
123
129
|
rubyforge_project:
|
124
|
-
rubygems_version: 1.8.
|
130
|
+
rubygems_version: 1.8.10
|
125
131
|
signing_key:
|
126
132
|
specification_version: 3
|
127
133
|
summary: layered github client
|
@@ -129,8 +135,13 @@ test_files:
|
|
129
135
|
- spec/cache_spec.rb
|
130
136
|
- spec/gh_spec.rb
|
131
137
|
- spec/lazy_loader_spec.rb
|
138
|
+
- spec/link_follower_spec.rb
|
132
139
|
- spec/normalizer_spec.rb
|
140
|
+
- spec/payloads/repos/sinatra/sinatra/issues/56/comments.yml
|
141
|
+
- spec/payloads/repos/sinatra/sinatra/issues/comments/383214.yml
|
142
|
+
- spec/payloads/repos/sinatra/sinatra/pulls/56.yml
|
133
143
|
- spec/payloads/users/rkh.yml
|
144
|
+
- spec/payloads/users/rtomayko.yml
|
134
145
|
- spec/payloads/users/svenfuchs.yml
|
135
146
|
- spec/remote_spec.rb
|
136
147
|
- spec/response_spec.rb
|