gittycent 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ v0.0.1. Initial release.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Elijah Miller
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,7 @@
1
+ CHANGELOG
2
+ LICENSE
3
+ Manifest
4
+ README.rdoc
5
+ Rakefile
6
+ gittycent.gemspec
7
+ lib/gittycent.rb
data/README.rdoc ADDED
@@ -0,0 +1,33 @@
1
+ = GittyCent
2
+
3
+ Up in the Hub.
4
+
5
+ == Examples
6
+
7
+ The following example adds a set of users to all projects of another user. We use it to add all of our company to each client project.
8
+
9
+ ## Add this to your ~/.gitconfig
10
+ # [github-company]
11
+ # user = fastestforward
12
+ # token = ...
13
+
14
+ require 'rubygems'
15
+ require 'gittycent'
16
+
17
+ default_users = %w(jqr kristopher netshade)
18
+
19
+ GitHub.connect_with_git_config('github-company') do |github|
20
+ user = github.authenticated_user
21
+ user.repos.each do |repo|
22
+ repo.collaborators = repo.collaborators + default_users
23
+ puts "#{repo}: #{repo.collaborators.join(', ')}"
24
+ end
25
+ end
26
+
27
+
28
+ == Install
29
+
30
+ gem install gittycent
31
+
32
+ Homepage:: http://github.com/fastestforward/gittycent
33
+ Copyright:: Copyright (c) 2008 Elijah Miller <mailto:elijah.miller@gmail.com>, released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ require 'echoe'
4
+ Echoe.new 'gittycent' do |p|
5
+ p.description = "Up in the Hub."
6
+ p.url = "http://github.com/fastestforward/gittycent"
7
+ p.author = "Elijah Miller"
8
+ p.email = "elijah.miller@gmail.com"
9
+ p.retain_gemspec = true
10
+ p.need_tar_gz = false
11
+ p.extra_deps = [
12
+ ]
13
+ end
14
+
15
+ desc 'Default: run specs'
16
+ task :default => :spec
17
+ Spec::Rake::SpecTask.new do |t|
18
+ t.spec_files = FileList["spec/**/*_spec.rb"]
19
+ end
20
+
21
+ task :test => :spec
data/gittycent.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{gittycent}
5
+ s.version = "0.0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Elijah Miller"]
9
+ s.date = %q{2010-03-12}
10
+ s.description = %q{Up in the Hub.}
11
+ s.email = %q{elijah.miller@gmail.com}
12
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.rdoc", "lib/gittycent.rb"]
13
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.rdoc", "Rakefile", "gittycent.gemspec", "lib/gittycent.rb"]
14
+ s.homepage = %q{http://github.com/fastestforward/gittycent}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Gittycent", "--main", "README.rdoc"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{gittycent}
18
+ s.rubygems_version = %q{1.3.4}
19
+ s.summary = %q{Up in the Hub.}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
data/lib/gittycent.rb ADDED
@@ -0,0 +1,262 @@
1
+ require 'active_support'
2
+ require 'httparty'
3
+ require 'pp'
4
+
5
+ class GitHub
6
+ API_VERSION = 'v2'
7
+ FORMAT = 'yaml'
8
+ NONE, WARNING, INFO, DEBUG = *1..10
9
+
10
+ attr_accessor :options
11
+
12
+ def self.connect(options)
13
+ connection = new(options)
14
+ if block_given?
15
+ yield(connection)
16
+ else
17
+ connection
18
+ end
19
+ end
20
+
21
+ def self.connect_with_git_config(section = :github, &block)
22
+ config = Hash[*`git config -l`.scan(/^(.*?)=(.*)$/).flatten]
23
+ connect(:login => config["#{section}.user"], :token => config["#{section}.token"], &block)
24
+ end
25
+
26
+ def initialize(options)
27
+ self.options = options
28
+ debug "Login using login #{options[:login]} with token #{options[:token]}"
29
+ end
30
+
31
+ def verbosity
32
+ options[:verbosity] || NONE
33
+ end
34
+
35
+ def user(login)
36
+ if login == options[:login]
37
+ AuthenticatedUser.new(self, :login => options[:login])
38
+ else
39
+ User.new(self, :login => login)
40
+ end
41
+ end
42
+
43
+ def user_search(query)
44
+ get("/user/search/#{query}")['users'].map { |u| User.new(self, u) }
45
+ end
46
+
47
+ def authenticated_user
48
+ @authenticated_user ||= user(options[:login])
49
+ end
50
+
51
+ def inspect
52
+ "#<#{self.class}#{' ' + options[:login] if options[:login].present?}>"
53
+ end
54
+
55
+ def default_http_options
56
+ {
57
+ :query => {
58
+ :login => options[:login],
59
+ :token => options[:token]
60
+ }
61
+ }
62
+ end
63
+
64
+ def get(path)
65
+ with_retry do
66
+ url = "http://github.com/api/#{API_VERSION}/#{FORMAT}#{path}"
67
+ debug "GET #{url}"
68
+ response = HTTParty.get(url, default_http_options)
69
+ debug response.code
70
+ debug response.body
71
+ debug
72
+ response
73
+ end
74
+ end
75
+
76
+ def post(path, params = {})
77
+ with_retry do
78
+ url = "http://github.com/api/#{API_VERSION}/#{FORMAT}#{path}"
79
+ debug "POST #{url}"
80
+ debug_inspect params
81
+ response = HTTParty.post(url, default_http_options.deep_merge(:query => params))
82
+ debug response.code
83
+ debug response.body
84
+ debug
85
+ response
86
+ end
87
+ end
88
+
89
+ def debug(message = "")
90
+ puts message if verbosity >= DEBUG
91
+ end
92
+
93
+ def warn(message = "")
94
+ puts message if verbosity >= WARNING
95
+ end
96
+
97
+ def debug_inspect(object)
98
+ debug object.pretty_inspect
99
+ end
100
+
101
+ def with_retry
102
+ count = 0
103
+ loop do
104
+ response = yield
105
+ if response.code == 403 && response['error'].any? { |e| e['error'] == 'too many requests' }
106
+ count += 1
107
+ delay = 2 ** count
108
+ warn "too many requests, sleeping for #{delay} seconds"
109
+ sleep delay
110
+ else
111
+ return response
112
+ end
113
+ end
114
+ end
115
+
116
+ class Connectable
117
+ class_inheritable_accessor :identified_by
118
+ attr_accessor :connection, :name
119
+
120
+ def initialize(connection, options)
121
+ self.connection = connection
122
+ @attributes = options.dup
123
+ if self.class.identified_by && @attributes.include?(self.class.identified_by)
124
+ send("#{identified_by}=", @attributes.delete(self.class.identified_by))
125
+ end
126
+ self.connection = connection
127
+ end
128
+
129
+ def get(*args)
130
+ connection.get(*args)
131
+ end
132
+
133
+ def post(*args)
134
+ connection.post(*args)
135
+ end
136
+
137
+ def debug(*args)
138
+ connection.debug(*args)
139
+ end
140
+
141
+ def reload
142
+ @attributes = {}
143
+ load
144
+ end
145
+
146
+ def self.loadable_attributes(*attributes)
147
+ (attributes - [identified_by]).each do |attribute|
148
+ define_method(attribute) do
149
+ if !@attributes.include?(attributes)
150
+ load
151
+ end
152
+ @attributes[attribute]
153
+ end
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ class User < Connectable
160
+ attr_accessor :login
161
+ self.identified_by = :login
162
+
163
+ loadable_attributes :created_at, :gravatar_id, :public_repo_count,
164
+ :public_gist_count, :following_count, :followers_count
165
+
166
+ def to_s
167
+ login.to_s
168
+ end
169
+
170
+ def repos
171
+ @repos ||= get("/repos/show/#{login}")['repositories'].map { |r| Repo.new(connection, r) }
172
+ end
173
+
174
+ def watched_repos
175
+ @repos ||= get("/repos/watched/#{login}")['repositories'].map { |r| Repo.new(connection, r) }
176
+ end
177
+
178
+ # supported options include: :name, :description, :homepage, :public
179
+ def create_repo(options)
180
+ options = options.dup
181
+ Repo.new(connection, post("/repos/create", options)['repository'])
182
+ end
183
+
184
+ def load
185
+ @attributes = get("/user/show/#{login}")['user'].symbolize_keys
186
+ end
187
+
188
+ def followers
189
+ @followers ||= get("/user/show/#{login}/followers")['users'].map { |u| User.new(connection, :login => u) }
190
+ end
191
+
192
+ def following
193
+ @following||= get("/user/show/#{login}/following")['users'].map { |u| User.new(connection, :login => u) }
194
+ end
195
+ end
196
+
197
+ class AuthenticatedUser < User
198
+ loadable_attributes :followers_count, :owned_private_repo_count,
199
+ :created_at, :company, :private_gist_count, :plan, :gravatar_id,
200
+ :total_private_repo_count, :public_repo_count, :location, :email,
201
+ :collaborators, :public_gist_count, :blog, :name, :following_count,
202
+ :disk_usage
203
+ end
204
+
205
+ class Repo < Connectable
206
+ attr_accessor :name
207
+ self.identified_by = :name
208
+
209
+ loadable_attributes :owner, :open_issues, :description, :fork, :forks,
210
+ :private, :url, :homepage, :watchers
211
+
212
+ def to_s
213
+ name.to_s
214
+ end
215
+
216
+ def owner
217
+ @owner ||= User.new(connection, :login => @attributes[:owner])
218
+ end
219
+
220
+ def collaborators
221
+ @collaborators ||= get("/repos/show/#{owner.login}/#{name}/collaborators")['collaborators'] || []
222
+ end
223
+
224
+ def collaborators=(value)
225
+ value = value.dup.uniq
226
+ removals = collaborators - value
227
+ additions = value - collaborators
228
+ debug "removals: #{removals.join(', ')}"
229
+ debug "additions: #{additions.join(', ')}"
230
+ removals.each do |remove|
231
+ post("/repos/collaborators/#{name}/remove/#{remove}")
232
+ end
233
+ additions.each do |addition|
234
+ post("/repos/collaborators/#{name}/add/#{addition}")
235
+ end
236
+ @collaborators = nil
237
+ end
238
+
239
+ def initial_push_command
240
+ "git remote add origin git@github.com:#{owner.login}/#{name}.git &&\n" +
241
+ "git push origin master &&\n" +
242
+ "git config --add branch.master.remote origin &&\n" +
243
+ "git config --add branch.master.merge refs/heads/master"
244
+ end
245
+
246
+ def network
247
+ @network ||= get("/repos/show/#{owner.login}/#{name}/network")['network'].map { |r| Repo.new(connection, r) }
248
+ end
249
+
250
+ def languages
251
+ get("/repos/show/#{owner.login}/#{name}/languages")['languages']
252
+ end
253
+
254
+ def tags
255
+ get("/repos/show/#{owner.login}/#{name}/tags")['tags']
256
+ end
257
+
258
+ def branches
259
+ get("/repos/show/#{owner.login}/#{name}/branches")['branches']
260
+ end
261
+ end
262
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gittycent
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Elijah Miller
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-12 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Up in the Hub.
17
+ email: elijah.miller@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - CHANGELOG
24
+ - LICENSE
25
+ - README.rdoc
26
+ - lib/gittycent.rb
27
+ files:
28
+ - CHANGELOG
29
+ - LICENSE
30
+ - Manifest
31
+ - README.rdoc
32
+ - Rakefile
33
+ - gittycent.gemspec
34
+ - lib/gittycent.rb
35
+ has_rdoc: true
36
+ homepage: http://github.com/fastestforward/gittycent
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options:
41
+ - --line-numbers
42
+ - --inline-source
43
+ - --title
44
+ - Gittycent
45
+ - --main
46
+ - README.rdoc
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "1.2"
60
+ version:
61
+ requirements: []
62
+
63
+ rubyforge_project: gittycent
64
+ rubygems_version: 1.3.4
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: Up in the Hub.
68
+ test_files: []
69
+