github-api-client 0.3.3 → 0.4.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +1 -15
  4. data/Gemfile.lock +23 -25
  5. data/NEWS +18 -0
  6. data/Rakefile +38 -0
  7. data/TODO +6 -0
  8. data/bin/api-browser.rb +12 -17
  9. data/bin/github-api-client +33 -0
  10. data/db/migrate/001_migrate_everything.rb +18 -0
  11. data/features/user_api.feature +88 -0
  12. data/github-api-client.gemspec +41 -0
  13. data/lib/github-api-client.rb +31 -9
  14. data/lib/github-api-client/browser.rb +11 -8
  15. data/lib/github-api-client/config.rb +0 -5
  16. data/lib/github-api-client/fetchers.rb +11 -0
  17. data/lib/github-api-client/fetchers/repo.rb +32 -0
  18. data/lib/github-api-client/fetchers/user.rb +49 -0
  19. data/lib/github-api-client/helpers.rb +15 -0
  20. data/lib/github-api-client/resource.rb +72 -0
  21. data/lib/github-api-client/resources/repo.rb +13 -0
  22. data/lib/github-api-client/resources/user.rb +10 -0
  23. data/lib/github-api-client/strategies/ask.rb +14 -0
  24. data/lib/github-api-client/strategies/local.rb +14 -0
  25. data/lib/github-api-client/strategies/remote.rb +14 -0
  26. data/lib/github-api-client/strategy.rb +15 -0
  27. data/lib/github-api-client/version.rb +10 -0
  28. data/new_design +4 -0
  29. metadata +62 -68
  30. data/VERSION +0 -1
  31. data/db/migrate/001_create_users.rb +0 -21
  32. data/db/migrate/002_create_user_followings.rb +0 -12
  33. data/db/migrate/003_create_repos.rb +0 -32
  34. data/db/migrate/004_create_repo_watchings.rb +0 -12
  35. data/db/migrate/005_create_organizations.rb +0 -15
  36. data/db/migrate/006_create_organizations_members.rb +0 -12
  37. data/lib/github-api-client/organization.rb +0 -64
  38. data/lib/github-api-client/repo.rb +0 -99
  39. data/lib/github-api-client/user.rb +0 -186
@@ -4,15 +4,18 @@ module GitHub
4
4
  include Singleton
5
5
 
6
6
  # Returnes root uri for GitHub API
7
- # @param [String] version GitHub api keyword, defaults to v2
8
- # @option version "v1"
9
- # @option version "v2"
10
- # @option version "v3"
11
- # @return [String] Base GitHub API url for v2
12
- def self.base_uri(version = 'v2')
13
- gh_uri = GitHub::Config::Options[:server]||'github.com'
14
- "http://#{gh_uri}/api/#{version}/yaml"
7
+ # @param [Object] *options only for backwards compatibility!
8
+ # @return [String] Base GitHub API url
9
+ def self.base_uri(*options)
10
+ gh_uri = GitHub::Config::Options[:server]||'api.github.com'
11
+ "http://#{gh_uri}/"
15
12
  end
13
+
14
+ # Sets up a net/http connection
15
+ # @return [http transaction] transaction to github
16
+ def self.start(&block)
17
+ Net::HTTP.start(URI.parse(self.base_uri).host, :use_ssl => true, &block)
18
+ end
16
19
 
17
20
  # Runs HTTP GET request at given uri
18
21
  # @param [String] uri URI to be joined with base_uri and requested
@@ -9,11 +9,6 @@ module GitHub
9
9
  :secrets => ENV['HOME'] + "/.github" + "/secrets.yml"
10
10
  }
11
11
 
12
- Version = File.read(
13
- ROOT + "/VERSION"
14
- )
15
- VERSION = Version
16
-
17
12
  # Secrets array, uses env vars if defined
18
13
  Secrets = case
19
14
  when ENV['GITHUB_USER'] && ENV['GITHUB_TOKEN']
@@ -0,0 +1,11 @@
1
+ require 'active_support/core_ext/hash'
2
+
3
+ module GitHub
4
+ module Fetchers
5
+ class << self
6
+ def parse(data)
7
+ JSON.parse(data, symbolize_names: true)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ module GitHub
2
+ module Fetchers
3
+ module Repository
4
+ class << self
5
+ def get(permalink)
6
+ attributes = {}
7
+ name = permalink.split('/').last
8
+ owner = Models::User.find_or_create_by_login(permalink.split('/').first)
9
+ model = owner.repositories.find_by_name(name)
10
+ model ||= nil
11
+ should_refresh = (if model then Config::Options[:strategy].should_refresh?(model); else false; end) # refactor
12
+ if not model or should_refresh
13
+ Browser.start do |http|
14
+ request = Net::HTTP::Get.new "/repos/#{permalink}"
15
+ attributes = Fetchers.parse(http.request(request).body)
16
+ model = Models::Repository.find_or_create_by_permalink(permalink)
17
+ model.owner = owner
18
+ model.update_attributes(Resources::Repository.valid_attributes(attributes))
19
+ end
20
+ end
21
+ repo = Resources::Repository.new.tap do |repo|
22
+ repo.attributes = Resources::Repository.valid_attributes(model.attributes.symbolize_keys)
23
+ end
24
+ end
25
+
26
+ def association_owner(repo)
27
+ User.get(repo.model.owner.login) # requires #get function to associate owner *always*
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,49 @@
1
+ module GitHub
2
+ module Fetchers
3
+ module User
4
+ def self.get(login)
5
+ attributes = {}
6
+ model = Models::User.find_by_login(login)
7
+ should_refresh = (if model then Config::Options[:strategy].should_refresh?(model); else false; end)
8
+ if not model or should_refresh
9
+ Browser.start do |http|
10
+ request = Net::HTTP::Get.new "/users/#{login}"
11
+ attributes = Fetchers.parse(http.request(request).body)
12
+ model = Models::User.find_or_create_by_login(login)
13
+ model.update_attributes(Resources::User.valid_attributes(attributes))
14
+ end
15
+ end
16
+ Resources::User.new.tap do |user|
17
+ user.attributes = model.attributes.symbolize_keys!
18
+ end
19
+ end
20
+
21
+ def self.association_repositories(user)
22
+ attributes = {}
23
+ models = (if um = Models::User.find_by_name(user.name) then um.repositories else []; end)
24
+ should_refresh = (if not models.empty? then Config::Options[:strategy].should_refresh?(models); else false; end)
25
+ if models.empty? or should_refresh
26
+ Browser.start do |http|
27
+ request = Net::HTTP::Get.new "/users/#{user.login}/repos"
28
+ attributes = Fetchers.parse(http.request(request).body)
29
+ end
30
+
31
+ ActiveRecord::Base.transaction do
32
+ attributes.each do |repo|
33
+ permalink = repo[:owner][:login] + '/' + repo[:name]
34
+ models << Models::Repository.find_or_create_by_permalink(permalink)
35
+ models.last.update_attributes(Resources::Repository.valid_attributes(repo))
36
+ end
37
+ end
38
+ end
39
+ collection = []
40
+ models.each do |model|
41
+ collection << Resources::Repository.new.tap do |repo|
42
+ repo.attributes = Resources::Repository.valid_attributes(model.attributes.symbolize_keys!)
43
+ end
44
+ end
45
+ return collection
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ module GitHub
2
+ module Helpers
3
+ class << self
4
+ def const_at(sym, scope)
5
+ throw ArgumentError, "first parameter must be a symbol" unless sym.is_a? Symbol
6
+ throw ArgumentError, "scope must be a module" unless scope.is_a? Module
7
+ return scope.const_get(sym)
8
+ end
9
+
10
+ def const_name(object)
11
+ return object.class.name.split('::').last.to_sym
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,72 @@
1
+ require 'active_support/concern'
2
+ require 'active_model/dirty'
3
+ require 'active_support/core_ext/string'
4
+
5
+ module Resource
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ attr_accessor :attributes
10
+ include ActiveModel::Dirty
11
+
12
+ define_attribute_methods = class_variable_get(:@@pushables)
13
+
14
+ define_method :initialize do
15
+ instance_variable_set(:@attributes, {})
16
+ instance_variable_set(:@changed_attributes, {})
17
+ end
18
+
19
+ class_variable_get(:@@attributes).each_pair do |key, value|
20
+ method_name = (if value == :boolean then "#{key}?"; else key; end)
21
+ define_method method_name do
22
+ return self.instance_variable_get(:@attributes)[key]
23
+ end
24
+ define_method "#{key}=" do |o|
25
+ send(:attribute_will_change!, key) unless o == self.instance_variable_get(:@attributes)[key]
26
+ return instance_variable_get(:@attributes)[key] = o
27
+ end if class_variable_get(:@@pushables).include? key
28
+ end
29
+
30
+ define_singleton_method :valid_attributes do |options|
31
+ options.select do |element|
32
+ class_variable_get(:@@attributes).include?(element) or element == :id
33
+ end
34
+ end
35
+
36
+ class_variable_get(:@@associations).each_pair do |key, value|
37
+ define_method key do
38
+ return GitHub::Fetchers.const_get(GitHub::Helpers.const_name(self)).send(:"association_#{key}", self)
39
+ end
40
+ end
41
+
42
+ define_method :save do
43
+ @changed_attributes.clear
44
+ end
45
+
46
+ define_method :model do
47
+ GitHub::Helpers.const_at(GitHub::Helpers.const_name(self), GitHub::Models).find(instance_variable_get(:@attributes)[:id])
48
+ end
49
+
50
+ define_method :inspect do
51
+ s = "#<Resource:#{self.class.to_s.split('::').last}"
52
+ instance_variable_get(:@attributes).each do |key, value|
53
+ value = "\"#{value.truncate(20, separator: ' ')}\"" if value.is_a? String
54
+ if not value.to_s.empty? and not (key == :id)
55
+ s += " #{key}: #{value}"
56
+ s += "," unless key == instance_variable_get(:@attributes).keys.last
57
+ end
58
+ end
59
+ s += ">"
60
+ end
61
+
62
+ # Create ActiveRecord model (for storing locally)
63
+ GitHub.const_set :Models, Module.new unless GitHub.const_defined? :Models
64
+ const_name = self.name.to_s.split('::').last.to_sym
65
+ klass = GitHub::Models.const_set const_name, (Class.new(ActiveRecord::Base))
66
+ klass.class_exec do
67
+ GitHub::Resources.const_get(const_name).class_variable_get(:@@associations).each_pair do |key, value|
68
+ self.class_exec &value.last
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,13 @@
1
+ module GitHub
2
+ module Resources
3
+ class Repository
4
+ @@attributes = {name: :string, description: :string, homepage: :string, private: :boolean, fork: :boolean, language: :string, master_branch: :string, size: :integer, pushed_at: :datetime, created_at: :datetime, has_issues: :boolean, has_wiki: :boolean, has_downloads: :boolean, permalink: :string}
5
+ @@pushables = [:name, :description, :homepage, :private, :has_issues, :has_wiki, :has_downloads] #team_id
6
+ @@associations = {parent: [:parent, -> { belongs_to :parent, :class_name => 'GitHub::Models::Repository'}],
7
+ contributors: [nil, -> {}], # habtm
8
+ owner: [:owner, -> { belongs_to :owner, class_name: 'GitHub::Models::User'}]
9
+ }
10
+ include Resource
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ module GitHub
2
+ module Resources
3
+ class User
4
+ @@attributes = {login: :string, name: :string, location: :string, bio: :string, email: :string, hireable: :boolean, blog: :string}
5
+ @@pushables = [:name, :location, :bio, :email, :hireable, :blog, :company]
6
+ @@associations = {repositories: [nil, -> { has_many :repositories, class_name: 'GitHub::Models::Repository', foreign_key: :owner_id}]}
7
+ include Resource
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ module GitHub
2
+ module Strategies
3
+ module Ask
4
+ class << self
5
+ def should_refresh?(model)
6
+ puts "Should I refresh #{Helpers.const_name(model)}? [y/n]"
7
+ return gets.chomp == 'y'
8
+ end
9
+
10
+ def update_strategy(model); end # no need for updating on this strategy
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module GitHub
2
+ # always refresh
3
+ module Strategies
4
+ module Local
5
+ class << self
6
+ def should_refresh?(model)
7
+ return false
8
+ end
9
+
10
+ def update_strategy(model); end # no need for updating on this strategy
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module GitHub
2
+ # always refresh
3
+ module Strategies
4
+ module Remote
5
+ class << self
6
+ def should_refresh?(model)
7
+ return true
8
+ end
9
+
10
+ def update_strategy(model); end # no need for updating on this strategy
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ module GitHub
2
+ class CachingStrategyNotImplemented < StandardError; end
3
+ # Template
4
+ module CachingStrategy
5
+ class << self
6
+ def should_refresh?(model)
7
+ throw CachingStrategyNotImplemented
8
+ end
9
+
10
+ def update_strategy(model)
11
+ throw CachingStrategyNotImplemented
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ module GitHub
2
+ module Version
3
+ Major = 0
4
+ Minor = 4
5
+ Patch = 0
6
+ Build = 'pre'
7
+
8
+ String = [Major, Minor, Patch, Build].join('.')
9
+ end
10
+ end
data/new_design ADDED
@@ -0,0 +1,4 @@
1
+ GitHub::User #=> GitHub::Frontend::User
2
+ GitHub::Storage::User #=> AR::Base
3
+ GitHub::Middleware::Fetchers::User
4
+ GitHub::Middleware::Pushers::User
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: github-api-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
5
- prerelease:
4
+ version: 0.4.0.pre
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jakub Okoński
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-19 00:00:00.000000000 Z
12
+ date: 2012-01-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rainbow
16
- requirement: &22621520 !ruby/object:Gem::Requirement
16
+ requirement: &21457680 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.1.3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *22621520
24
+ version_requirements: *21457680
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &22621040 !ruby/object:Gem::Requirement
27
+ requirement: &21457160 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - =
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.8.7
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *22621040
35
+ version_requirements: *21457160
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: activerecord
38
- requirement: &22620560 !ruby/object:Gem::Requirement
38
+ requirement: &21456500 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 3.1.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *22620560
46
+ version_requirements: *21456500
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: activesupport
49
- requirement: &22620080 !ruby/object:Gem::Requirement
49
+ requirement: &21455800 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 3.1.0
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *22620080
57
+ version_requirements: *21455800
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: sqlite3
60
- requirement: &22619600 !ruby/object:Gem::Requirement
60
+ requirement: &21472340 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.3.5
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *22619600
68
+ version_requirements: *21472340
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: OptionParser
71
- requirement: &22619120 !ruby/object:Gem::Requirement
71
+ requirement: &21471640 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.5.1
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *22619120
79
+ version_requirements: *21471640
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &22618640 !ruby/object:Gem::Requirement
82
+ requirement: &21471040 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 2.7.0
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *22618640
90
+ version_requirements: *21471040
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: mocha
93
- requirement: &22618160 !ruby/object:Gem::Requirement
93
+ requirement: &21470560 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: 0.10.0
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *22618160
101
+ version_requirements: *21470560
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: yard
104
- requirement: &22617680 !ruby/object:Gem::Requirement
104
+ requirement: &21470080 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: 0.6.0
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *22617680
112
+ version_requirements: *21470080
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: cucumber
115
- requirement: &22617200 !ruby/object:Gem::Requirement
115
+ requirement: &21469580 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,65 +120,58 @@ dependencies:
120
120
  version: 1.1.4
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *22617200
124
- - !ruby/object:Gem::Dependency
125
- name: jeweler
126
- requirement: &22616720 !ruby/object:Gem::Requirement
127
- none: false
128
- requirements:
129
- - - ! '>='
130
- - !ruby/object:Gem::Version
131
- version: 1.6.4
132
- type: :development
133
- prerelease: false
134
- version_requirements: *22616720
135
- - !ruby/object:Gem::Dependency
136
- name: rcov
137
- requirement: &22616240 !ruby/object:Gem::Requirement
138
- none: false
139
- requirements:
140
- - - ! '>='
141
- - !ruby/object:Gem::Version
142
- version: 0.9.11
143
- type: :development
144
- prerelease: false
145
- version_requirements: *22616240
123
+ version_requirements: *21469580
146
124
  description: Caches retrieved information to your user profile and reuses it when
147
125
  you query again.
148
126
  email: kuba@okonski.org
149
127
  executables:
150
128
  - api-browser.rb
129
+ - github-api-client
151
130
  extensions: []
152
131
  extra_rdoc_files:
153
132
  - LICENSE.txt
154
133
  - README.md
134
+ - TODO
135
+ - NEWS
155
136
  files:
137
+ - .gitignore
138
+ - .rspec
156
139
  - Gemfile
157
140
  - Gemfile.lock
158
- - VERSION
159
- - db/migrate/001_create_users.rb
160
- - db/migrate/002_create_user_followings.rb
161
- - db/migrate/003_create_repos.rb
162
- - db/migrate/004_create_repo_watchings.rb
163
- - db/migrate/005_create_organizations.rb
164
- - db/migrate/006_create_organizations_members.rb
141
+ - LICENSE.txt
142
+ - NEWS
143
+ - README.md
144
+ - Rakefile
145
+ - TODO
146
+ - bin/api-browser.rb
147
+ - bin/github-api-client
148
+ - db/migrate/001_migrate_everything.rb
149
+ - features/fetching.feature
150
+ - features/step_definitions/fetching_steps.rb
151
+ - features/support/env.rb
152
+ - features/user_api.feature
153
+ - github-api-client.gemspec
165
154
  - lib/core_ext/habtm.rb
166
155
  - lib/github-api-client.rb
167
156
  - lib/github-api-client/base.rb
168
157
  - lib/github-api-client/browser.rb
169
158
  - lib/github-api-client/config.rb
170
- - lib/github-api-client/organization.rb
171
- - lib/github-api-client/repo.rb
172
- - lib/github-api-client/user.rb
173
- - LICENSE.txt
174
- - README.md
175
- - features/support/env.rb
176
- - features/step_definitions/fetching_steps.rb
177
- - features/fetching.feature
178
- - spec/spec_helper.rb
159
+ - lib/github-api-client/fetchers.rb
160
+ - lib/github-api-client/fetchers/repo.rb
161
+ - lib/github-api-client/fetchers/user.rb
162
+ - lib/github-api-client/helpers.rb
163
+ - lib/github-api-client/resource.rb
164
+ - lib/github-api-client/resources/repo.rb
165
+ - lib/github-api-client/resources/user.rb
166
+ - lib/github-api-client/strategies/ask.rb
167
+ - lib/github-api-client/strategies/local.rb
168
+ - lib/github-api-client/strategies/remote.rb
169
+ - lib/github-api-client/strategy.rb
170
+ - lib/github-api-client/version.rb
171
+ - new_design
179
172
  - spec/github-api-client_spec.rb
180
- - bin/api-browser.rb
181
- homepage: http://github.com/okonski/github-api-client
173
+ - spec/spec_helper.rb
174
+ homepage: http://github.com/farnoy/github-api-client
182
175
  licenses:
183
176
  - MIT
184
177
  post_install_message:
@@ -194,9 +187,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
194
187
  required_rubygems_version: !ruby/object:Gem::Requirement
195
188
  none: false
196
189
  requirements:
197
- - - ! '>='
190
+ - - ! '>'
198
191
  - !ruby/object:Gem::Version
199
- version: '0'
192
+ version: 1.3.1
200
193
  requirements: []
201
194
  rubyforge_project:
202
195
  rubygems_version: 1.8.12
@@ -204,9 +197,10 @@ signing_key:
204
197
  specification_version: 3
205
198
  summary: Library for easy GitHub API browsing
206
199
  test_files:
207
- - features/support/env.rb
208
- - features/step_definitions/fetching_steps.rb
209
200
  - features/fetching.feature
210
- - spec/spec_helper.rb
201
+ - features/step_definitions/fetching_steps.rb
202
+ - features/support/env.rb
203
+ - features/user_api.feature
211
204
  - spec/github-api-client_spec.rb
205
+ - spec/spec_helper.rb
212
206
  has_rdoc: