riquedafreak-github 0.2.1 → 0.3.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/Manifest +6 -4
- data/README +8 -8
- data/bin/gh +5 -0
- data/commands/commands.rb +75 -35
- data/commands/helpers.rb +103 -18
- data/github-gem.gemspec +6 -5
- data/lib/github/command.rb +12 -41
- data/lib/github.rb +18 -2
- data/spec/ui_spec.rb +69 -20
- metadata +15 -4
data/Manifest
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
LICENSE
|
2
|
+
Manifest
|
3
|
+
README
|
4
|
+
bin/gh
|
1
5
|
bin/github
|
2
6
|
commands/commands.rb
|
3
7
|
commands/helpers.rb
|
4
|
-
|
8
|
+
github-gem.gemspec
|
5
9
|
lib/github/command.rb
|
10
|
+
lib/github/extensions.rb
|
6
11
|
lib/github/helper.rb
|
7
12
|
lib/github.rb
|
8
|
-
LICENSE
|
9
|
-
Manifest
|
10
|
-
README
|
11
13
|
spec/command_spec.rb
|
12
14
|
spec/extensions_spec.rb
|
13
15
|
spec/github_spec.rb
|
data/README
CHANGED
@@ -22,7 +22,7 @@ Pulling Upstream Changes
|
|
22
22
|
|
23
23
|
Let's say you just forked `github-gem` on GitHub from defunkt.
|
24
24
|
|
25
|
-
$
|
25
|
+
$ github clone git://github.com/YOU/github-gem.git
|
26
26
|
$ cd github-gem
|
27
27
|
$ github pull defunkt
|
28
28
|
|
@@ -36,8 +36,8 @@ checkout master` and then `git merge defunkt/master` to merge defunkt's changes
|
|
36
36
|
into your own master branch. In summary:
|
37
37
|
|
38
38
|
$ github pull defunkt
|
39
|
-
$
|
40
|
-
$
|
39
|
+
$ github checkout master
|
40
|
+
$ github merge defunkt/master
|
41
41
|
|
42
42
|
If you've already reviewed defunkt's changes and just want to merge them into your
|
43
43
|
master branch, use the `merge` flag:
|
@@ -67,12 +67,12 @@ Your local 'mojombo/master' branch is now at the exact same place as mojombo's
|
|
67
67
|
If mojombo's changes are good, you'll want to merge your 'master' (or another
|
68
68
|
branch) into those changes so you can retest post-integration:
|
69
69
|
|
70
|
-
$
|
70
|
+
$ github merge master
|
71
71
|
|
72
72
|
Test/analyze again and if everything is ok:
|
73
73
|
|
74
|
-
$
|
75
|
-
$
|
74
|
+
$ github checkout master
|
75
|
+
$ github merge mojombo/master
|
76
76
|
|
77
77
|
The latter command will be a fast-forward merge since you already did the
|
78
78
|
real merge previously.
|
@@ -111,12 +111,12 @@ which will show you something like this:
|
|
111
111
|
These are all the commits that you don't have in your current branch that have been
|
112
112
|
pushed to other forks of your project. If you want to incorporate them, you can use:
|
113
113
|
|
114
|
-
$
|
114
|
+
$ github cherry-pick ee013a
|
115
115
|
|
116
116
|
for example to apply that single patch to your branch. You can also merge a branch,
|
117
117
|
if you want all the changes introduced in another branch:
|
118
118
|
|
119
|
-
$
|
119
|
+
$ github merge jchris/gist
|
120
120
|
|
121
121
|
The next time you run the 'github network commits' command, you won't see any of the
|
122
122
|
patches you have cherry-picked or merged (or rebased). If you want to ignore a
|
data/bin/gh
ADDED
data/commands/commands.rb
CHANGED
@@ -27,10 +27,13 @@ flags :shas => "Only show shas"
|
|
27
27
|
flags :project => "Filter commits on a certain project"
|
28
28
|
flags :author => "Filter commits on a email address of author"
|
29
29
|
flags :applies => "Filter commits to patches that apply cleanly"
|
30
|
+
flags :noapply => "Filter commits to patches that do not apply cleanly"
|
30
31
|
flags :nocache => "Do not use the cached network data"
|
31
32
|
flags :cache => "Use the network data even if it's expired"
|
32
33
|
flags :sort => "How to sort : date(*), branch, author"
|
33
34
|
flags :common => "Show common branch point"
|
35
|
+
flags :thisbranch => "Look at branches that match the current one"
|
36
|
+
flags :limit => "Only look through the first X heads - useful for really large projects"
|
34
37
|
command :network do |command, user|
|
35
38
|
return if !helper.project
|
36
39
|
user ||= helper.owner
|
@@ -39,13 +42,13 @@ command :network do |command, user|
|
|
39
42
|
when 'web'
|
40
43
|
helper.open helper.network_page_for(user)
|
41
44
|
when 'list'
|
42
|
-
data = get_network_data(user, options)
|
45
|
+
data = helper.get_network_data(user, options)
|
43
46
|
data['users'].each do |hsh|
|
44
47
|
puts [ hsh['name'].ljust(20), hsh['heads'].map {|a| a['name']}.uniq.join(', ') ].join(' ')
|
45
48
|
end
|
46
49
|
when 'fetch'
|
47
50
|
# fetch each remote we don't have
|
48
|
-
data = get_network_data(user, options)
|
51
|
+
data = helper.get_network_data(user, options)
|
49
52
|
data['users'].each do |hsh|
|
50
53
|
u = hsh['name']
|
51
54
|
GitHub.invoke(:track, u) unless helper.tracking?(u)
|
@@ -54,36 +57,69 @@ command :network do |command, user|
|
|
54
57
|
end
|
55
58
|
when 'commits'
|
56
59
|
# show commits we don't have yet
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
60
|
+
|
61
|
+
$stderr.puts 'gathering heads'
|
62
|
+
cherry = []
|
63
|
+
|
64
|
+
if helper.cache_commits_data(options)
|
65
|
+
ids = []
|
66
|
+
data = helper.get_network_data(user, options)
|
67
|
+
data['users'].each do |hsh|
|
68
|
+
u = hsh['name']
|
69
|
+
if options[:thisbranch]
|
70
|
+
user_ids = hsh['heads'].map { |a| a['id'] if a['name'] == helper.current_branch }.compact
|
71
|
+
else
|
72
|
+
user_ids = hsh['heads'].map { |a| a['id'] }
|
73
|
+
end
|
74
|
+
user_ids.each do |id|
|
75
|
+
if !helper.has_commit?(id) && helper.cache_expired?
|
76
|
+
GitHub.invoke(:track, u) unless helper.tracking?(u)
|
77
|
+
puts "fetching #{u}"
|
78
|
+
GitHub.invoke(:fetch_all, u)
|
79
|
+
end
|
67
80
|
end
|
81
|
+
ids += user_ids
|
68
82
|
end
|
69
|
-
ids
|
70
|
-
end
|
71
|
-
ids.uniq!
|
83
|
+
ids.uniq!
|
72
84
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
85
|
+
$stderr.puts 'has heads'
|
86
|
+
|
87
|
+
# check that we have all these shas locally
|
88
|
+
local_heads = helper.local_heads
|
89
|
+
local_heads_not = local_heads.map { |a| "^#{a}"}
|
90
|
+
looking_for = (ids - local_heads) + local_heads_not
|
91
|
+
commits = helper.get_commits(looking_for)
|
92
|
+
|
93
|
+
$stderr.puts 'ID SIZE:' + ids.size.to_s
|
94
|
+
|
95
|
+
ignores = helper.ignore_sha_array
|
96
|
+
|
97
|
+
ids.each do |id|
|
98
|
+
next if ignores[id] || !commits.assoc(id)
|
99
|
+
cherries = helper.get_cherry(id)
|
100
|
+
cherries = helper.remove_ignored(cherries, ignores)
|
101
|
+
cherry += cherries
|
102
|
+
helper.ignore_shas([id]) if cherries.size == 0
|
103
|
+
$stderr.puts "checking head #{id} : #{cherry.size.to_s}"
|
104
|
+
break if options[:limit] && cherry.size > options[:limit].to_i
|
105
|
+
end
|
83
106
|
end
|
84
|
-
|
107
|
+
|
108
|
+
if cherry.size > 0 || !helper.cache_commits_data(options)
|
85
109
|
helper.print_network_cherry_help if !options[:shas]
|
86
|
-
|
110
|
+
|
111
|
+
if helper.cache_commits_data(options)
|
112
|
+
$stderr.puts "caching..."
|
113
|
+
$stderr.puts "commits: " + cherry.size.to_s
|
114
|
+
our_commits = cherry.map { |item| c = commits.assoc(item[1]); [item, c] if c }
|
115
|
+
our_commits.delete_if { |item| item == nil }
|
116
|
+
helper.cache_commits(our_commits)
|
117
|
+
else
|
118
|
+
$stderr.puts "using cached..."
|
119
|
+
our_commits = helper.commits_cache
|
120
|
+
end
|
121
|
+
|
122
|
+
helper.print_commits(our_commits, options)
|
87
123
|
else
|
88
124
|
puts "no unapplied commits"
|
89
125
|
end
|
@@ -158,34 +194,38 @@ flags :merge => "Automatically merge remote's changes into your master."
|
|
158
194
|
command :pull do |user, branch|
|
159
195
|
die "Specify a user to pull from" if user.nil?
|
160
196
|
user, branch = user.split("/", 2) if branch.nil?
|
197
|
+
|
198
|
+
if !helper.network_members.include?(user)
|
199
|
+
git_exec "#{helper.argv.join(' ')}".strip
|
200
|
+
end
|
201
|
+
|
161
202
|
branch ||= 'master'
|
162
203
|
GitHub.invoke(:track, user) unless helper.tracking?(user)
|
163
204
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
unless options[:merge]
|
205
|
+
if options[:merge]
|
206
|
+
git_exec "pull #{user} #{branch}"
|
207
|
+
else
|
168
208
|
puts "Switching to #{user}/#{branch}"
|
169
209
|
git "update-ref refs/heads/#{user}/#{branch} HEAD"
|
170
210
|
git "checkout #{user}/#{branch}"
|
171
211
|
end
|
172
|
-
git_exec "pull #{user} #{branch}"
|
173
212
|
end
|
174
213
|
|
175
214
|
desc "Clone a repo."
|
176
215
|
flags :ssh => "Clone using the git@github.com style url."
|
177
216
|
command :clone do |user, repo, dir|
|
178
217
|
die "Specify a user to pull from" if user.nil?
|
179
|
-
if user.include?
|
218
|
+
if user.include?('/') && !user.include?('@') && !user.include?(':')
|
180
219
|
die "Expected user/repo dir, given extra argument" if dir
|
181
220
|
(user, repo), dir = [user.split('/', 2), repo]
|
182
221
|
end
|
183
|
-
die "Specify a repo to pull from" if repo.nil?
|
184
222
|
|
185
223
|
if options[:ssh]
|
186
224
|
git_exec "clone git@github.com:#{user}/#{repo}.git" + (dir ? " #{dir}" : "")
|
187
|
-
|
225
|
+
elsif repo
|
188
226
|
git_exec "clone git://github.com/#{user}/#{repo}.git" + (dir ? " #{dir}" : "")
|
227
|
+
else
|
228
|
+
git_exec "#{helper.argv.join(' ')}".strip
|
189
229
|
end
|
190
230
|
end
|
191
231
|
|
data/commands/helpers.rb
CHANGED
@@ -53,7 +53,7 @@ helper :resolve_commits do |treeish|
|
|
53
53
|
else
|
54
54
|
# standard in
|
55
55
|
puts 'reading from stdin...'
|
56
|
-
commits = $stdin.read.split("\n")
|
56
|
+
commits = $stdin.read.split("\n")
|
57
57
|
end
|
58
58
|
commits.select { |a| a.size == 40 } # only the shas, not the ^SHAs
|
59
59
|
end
|
@@ -67,6 +67,10 @@ helper :ignore_sha_array do
|
|
67
67
|
File.open( ignore_file_path ) { |yf| YAML::load( yf ) } rescue {}
|
68
68
|
end
|
69
69
|
|
70
|
+
helper :remove_ignored do |array, ignore_array|
|
71
|
+
array.reject { |id| ignore_array[id] }
|
72
|
+
end
|
73
|
+
|
70
74
|
helper :ignore_shas do |shas|
|
71
75
|
ignores = ignore_sha_array
|
72
76
|
shas.each do |sha|
|
@@ -91,19 +95,18 @@ helper :get_common do |branch|
|
|
91
95
|
`git rev-list ..#{branch} --boundary | tail -1 | git name-rev --stdin`.split(' ')[1] rescue 'unknown'
|
92
96
|
end
|
93
97
|
|
94
|
-
helper :print_commits do |
|
98
|
+
helper :print_commits do |our_commits, options|
|
95
99
|
ignores = ignore_sha_array
|
96
|
-
|
97
|
-
|
100
|
+
|
98
101
|
case options[:sort]
|
99
102
|
when 'branch'
|
100
103
|
our_commits.sort! { |a, b| a[0][2] <=> b[0][2] }
|
101
104
|
when 'author'
|
102
105
|
our_commits.sort! { |a, b| a[1][1] <=> b[1][1] }
|
103
106
|
else
|
104
|
-
our_commits.sort! { |a, b| Date.parse(a[1][4]) <=> Date.parse(b[1][4]) }
|
107
|
+
our_commits.sort! { |a, b| Date.parse(a[1][4]) <=> Date.parse(b[1][4]) } rescue 'cant parse dates'
|
105
108
|
end
|
106
|
-
|
109
|
+
|
107
110
|
shown_commits = {}
|
108
111
|
before = Date.parse(options[:before]) if options[:before] rescue puts 'cant parse before date'
|
109
112
|
after = Date.parse(options[:after]) if options[:after] rescue puts 'cant parse after date'
|
@@ -114,15 +117,17 @@ helper :print_commits do |cherries, commits, options|
|
|
114
117
|
ref_name = ref_name.gsub('remotes/', '')
|
115
118
|
if status == '+' && commit
|
116
119
|
next if options[:author] && !commit[1].match(Regexp.new(options[:author]))
|
117
|
-
next if options[:before] && before && (before < Date.parse(commit[4]))
|
118
|
-
next if options[:after] && after && (after > Date.parse(commit[4]))
|
119
|
-
|
120
|
+
next if options[:before] && before && (before < Date.parse(commit[4])) rescue false
|
121
|
+
next if options[:after] && after && (after > Date.parse(commit[4])) rescue false
|
122
|
+
applies = applies_cleanly(sha)
|
123
|
+
next if options[:applies] && !applies
|
124
|
+
next if options[:noapply] && applies
|
120
125
|
if options[:shas]
|
121
126
|
puts sha
|
122
127
|
else
|
123
128
|
common = options[:common] ? get_common(sha) : ''
|
124
|
-
puts [sha[0,6], ref_name.ljust(25), commit[1][0,20].ljust(21),
|
125
|
-
commit[2][0, 36].ljust(38), commit[3], common].join(" ")
|
129
|
+
puts [sha[0,6], ref_name.ljust(25), commit[1][0,20].ljust(21),
|
130
|
+
commit[2][0, 36].ljust(38), commit[3][0,15], common].join(" ")
|
126
131
|
end
|
127
132
|
end
|
128
133
|
shown_commits[sha] = true
|
@@ -184,8 +189,12 @@ helper :owner do
|
|
184
189
|
user_for(:origin)
|
185
190
|
end
|
186
191
|
|
192
|
+
helper :current_branch do
|
193
|
+
`git rev-parse --symbolic-full-name HEAD`.chomp.sub(/^refs\/heads\//, '')
|
194
|
+
end
|
195
|
+
|
187
196
|
helper :user_and_branch do
|
188
|
-
raw_branch =
|
197
|
+
raw_branch = current_branch
|
189
198
|
user, branch = raw_branch.split(/\//, 2)
|
190
199
|
if branch
|
191
200
|
[user, branch]
|
@@ -253,17 +262,17 @@ You have to provide a command :
|
|
253
262
|
|
254
263
|
web [user] - opens your web browser to the network graph page for this
|
255
264
|
project, or for the graph page for [user] if provided
|
256
|
-
|
265
|
+
|
257
266
|
list - shows the projects in your network that have commits
|
258
|
-
that you have not pulled in yet, and branch names
|
259
|
-
|
267
|
+
that you have not pulled in yet, and branch names
|
268
|
+
|
260
269
|
fetch - adds all projects in your network as remotes and fetches
|
261
270
|
any objects from them that you don't have yet
|
262
|
-
|
271
|
+
|
263
272
|
commits - will show you a list of all commits in your network that
|
264
273
|
you have not ignored or have not merged or cherry-picked.
|
265
274
|
This will automatically fetch objects you don't have yet.
|
266
|
-
|
275
|
+
|
267
276
|
--project (user/branch) - only show projects that match string
|
268
277
|
--author (email) - only show projects that match string
|
269
278
|
--after (date) - only show commits after date
|
@@ -275,7 +284,7 @@ You have to provide a command :
|
|
275
284
|
end
|
276
285
|
|
277
286
|
helper :print_network_cherry_help do
|
278
|
-
puts "
|
287
|
+
$stderr.puts "
|
279
288
|
=========================================================================================
|
280
289
|
These are all the commits that other people have pushed that you have not
|
281
290
|
applied or ignored yet (see 'github ignore'). Some things you might want to do:
|
@@ -289,3 +298,79 @@ applied or ignored yet (see 'github ignore'). Some things you might want to do:
|
|
289
298
|
"
|
290
299
|
end
|
291
300
|
|
301
|
+
helper :argv do
|
302
|
+
GitHub.original_args
|
303
|
+
end
|
304
|
+
|
305
|
+
helper :network_members do
|
306
|
+
get_network_data(owner, {})['users'].map do |hash|
|
307
|
+
hash['name']
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
|
312
|
+
helper :get_network_data do |user, options|
|
313
|
+
if options[:cache] && has_cache?
|
314
|
+
return get_cache
|
315
|
+
end
|
316
|
+
if cache_network_data(options)
|
317
|
+
return cache_data(user)
|
318
|
+
else
|
319
|
+
return get_cache
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
helper :cache_commits do |commits|
|
324
|
+
File.open( commits_cache_path, 'w' ) do |out|
|
325
|
+
out.write(commits.to_yaml)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
helper :commits_cache do
|
330
|
+
YAML.load(File.open(commits_cache_path))
|
331
|
+
end
|
332
|
+
|
333
|
+
helper :cache_commits_data do |options|
|
334
|
+
cache_expired? || options[:nocache] || !has_commits_cache?
|
335
|
+
end
|
336
|
+
|
337
|
+
helper :cache_network_data do |options|
|
338
|
+
cache_expired? || options[:nocache] || !has_cache?
|
339
|
+
end
|
340
|
+
|
341
|
+
helper :network_cache_path do
|
342
|
+
dir = `git rev-parse --git-dir`.chomp
|
343
|
+
File.join(dir, 'network-cache')
|
344
|
+
end
|
345
|
+
|
346
|
+
helper :commits_cache_path do
|
347
|
+
dir = `git rev-parse --git-dir`.chomp
|
348
|
+
File.join(dir, 'commits-cache')
|
349
|
+
end
|
350
|
+
|
351
|
+
helper :cache_data do |user|
|
352
|
+
raw_data = Kernel.open(network_meta_for(user)).read
|
353
|
+
File.open( network_cache_path, 'w' ) do |out|
|
354
|
+
out.write(raw_data)
|
355
|
+
end
|
356
|
+
data = JSON.parse(raw_data)
|
357
|
+
end
|
358
|
+
|
359
|
+
helper :cache_expired? do
|
360
|
+
return true if !has_cache?
|
361
|
+
age = Time.now - File.stat(network_cache_path).mtime
|
362
|
+
return true if age > (60 * 60) # 1 hour
|
363
|
+
false
|
364
|
+
end
|
365
|
+
|
366
|
+
helper :has_cache? do
|
367
|
+
File.file?(network_cache_path)
|
368
|
+
end
|
369
|
+
|
370
|
+
helper :has_commits_cache? do
|
371
|
+
File.file?(commits_cache_path)
|
372
|
+
end
|
373
|
+
|
374
|
+
helper :get_cache do
|
375
|
+
JSON.parse(File.read(network_cache_path))
|
376
|
+
end
|
data/github-gem.gemspec
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
|
-
s.name =
|
3
|
-
s.version = "0.
|
2
|
+
s.name = "github"
|
3
|
+
s.version = "0.3.1"
|
4
4
|
|
5
5
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Chris Wanstrath, Kevin Ballard, Scott Chacon"]
|
9
9
|
s.date = %q{2008-05-18}
|
10
|
-
s.default_executable = %q{
|
10
|
+
s.default_executable = %q{gh}
|
11
11
|
s.description = %q{The official `github` command line helper for simplifying your GitHub experience.}
|
12
12
|
s.email = %q{chris@ozmm.org}
|
13
|
-
s.executables = ["github"]
|
14
|
-
s.extra_rdoc_files = ["bin/github", "lib/github/extensions.rb", "lib/github/command.rb", "lib/github/helper.rb", "lib/github.rb", "LICENSE", "README"]
|
13
|
+
s.executables = ["github", "gh"]
|
14
|
+
s.extra_rdoc_files = ["bin/github", "bin/gh", "lib/github/extensions.rb", "lib/github/command.rb", "lib/github/helper.rb", "lib/github.rb", "LICENSE", "README"]
|
15
15
|
s.files = ["bin/github", "commands/commands.rb", "commands/helpers.rb", "lib/github/extensions.rb", "lib/github/command.rb", "lib/github/helper.rb", "lib/github.rb", "LICENSE", "Manifest", "README", "spec/command_spec.rb", "spec/extensions_spec.rb", "spec/github_spec.rb", "spec/helper_spec.rb", "spec/spec_helper.rb", "spec/ui_spec.rb", "spec/windoze_spec.rb", "github-gem.gemspec"]
|
16
16
|
s.has_rdoc = true
|
17
17
|
s.homepage = %q{http://github.com/}
|
@@ -22,4 +22,5 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.summary = %q{The official `github` command line helper for simplifying your GitHub experience.}
|
23
23
|
|
24
24
|
# s.add_dependency(%q<launchy>, [">= 0"])
|
25
|
+
s.add_dependency('json', [">= 0"])
|
25
26
|
end
|
data/lib/github/command.rb
CHANGED
@@ -20,7 +20,7 @@ module GitHub
|
|
20
20
|
args << nil while args.size < arity
|
21
21
|
send :command, *args
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def helper
|
25
25
|
@helper ||= Helper.new
|
26
26
|
end
|
@@ -46,45 +46,6 @@ module GitHub
|
|
46
46
|
def sh(*command)
|
47
47
|
Shell.new(*command).run
|
48
48
|
end
|
49
|
-
|
50
|
-
def get_network_data(user, options)
|
51
|
-
if options[:cache] && has_cache?
|
52
|
-
return get_cache
|
53
|
-
end
|
54
|
-
if cache_expired? || options[:nocache] || !has_cache?
|
55
|
-
return cache_data(user)
|
56
|
-
else
|
57
|
-
return get_cache
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def network_cache_path
|
62
|
-
dir = `git rev-parse --git-dir`.chomp
|
63
|
-
File.join(dir, 'network-cache')
|
64
|
-
end
|
65
|
-
|
66
|
-
def cache_data(user)
|
67
|
-
raw_data = open(helper.network_meta_for(user)).read
|
68
|
-
File.open( network_cache_path, 'w' ) do |out|
|
69
|
-
out.write(raw_data)
|
70
|
-
end
|
71
|
-
data = JSON.parse(raw_data)
|
72
|
-
end
|
73
|
-
|
74
|
-
def cache_expired?
|
75
|
-
return true if !has_cache?
|
76
|
-
age = Time.now - File.stat(network_cache_path).mtime
|
77
|
-
return true if age > (60 * 60) # 1 hour
|
78
|
-
false
|
79
|
-
end
|
80
|
-
|
81
|
-
def has_cache?
|
82
|
-
File.file?(network_cache_path)
|
83
|
-
end
|
84
|
-
|
85
|
-
def get_cache
|
86
|
-
JSON.parse(File.read(network_cache_path))
|
87
|
-
end
|
88
49
|
|
89
50
|
def die(message)
|
90
51
|
puts "=> #{message}"
|
@@ -102,7 +63,7 @@ module GitHub
|
|
102
63
|
def run
|
103
64
|
GitHub.debug "sh: #{command}"
|
104
65
|
_, out, err = Open3.popen3(*@command)
|
105
|
-
|
66
|
+
|
106
67
|
out = out.read.strip
|
107
68
|
err = err.read.strip
|
108
69
|
|
@@ -125,4 +86,14 @@ module GitHub
|
|
125
86
|
end
|
126
87
|
end
|
127
88
|
end
|
89
|
+
|
90
|
+
class GitCommand < Command
|
91
|
+
def initialize(name)
|
92
|
+
@name = name
|
93
|
+
end
|
94
|
+
|
95
|
+
def command(*args)
|
96
|
+
git_exec *[ @name, args ]
|
97
|
+
end
|
98
|
+
end
|
128
99
|
end
|
data/lib/github.rb
CHANGED
@@ -13,7 +13,7 @@ require 'yaml'
|
|
13
13
|
# $ github <command> <args>
|
14
14
|
#
|
15
15
|
# GitHub.command <command> do |*args|
|
16
|
-
# whatever
|
16
|
+
# whatever
|
17
17
|
# end
|
18
18
|
#
|
19
19
|
# We'll probably want to use the `choice` gem for concise, tasty DSL
|
@@ -49,6 +49,7 @@ module GitHub
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def activate(args)
|
52
|
+
@@original_args = args.clone
|
52
53
|
@options = parse_options(args)
|
53
54
|
@debug = @options[:debug]
|
54
55
|
load 'helpers.rb'
|
@@ -57,11 +58,16 @@ module GitHub
|
|
57
58
|
end
|
58
59
|
|
59
60
|
def invoke(command, *args)
|
60
|
-
block =
|
61
|
+
block = find_command(command)
|
61
62
|
debug "Invoking `#{command}`"
|
62
63
|
block.call(*args)
|
63
64
|
end
|
64
65
|
|
66
|
+
def find_command(name)
|
67
|
+
name = name.to_s
|
68
|
+
commands[name] || GitCommand.new(name) || commands['default']
|
69
|
+
end
|
70
|
+
|
65
71
|
def commands
|
66
72
|
@commands ||= {}
|
67
73
|
end
|
@@ -78,6 +84,10 @@ module GitHub
|
|
78
84
|
@options
|
79
85
|
end
|
80
86
|
|
87
|
+
def original_args
|
88
|
+
@@original_args ||= []
|
89
|
+
end
|
90
|
+
|
81
91
|
def parse_options(args)
|
82
92
|
idx = 0
|
83
93
|
args.clone.inject({}) do |memo, arg|
|
@@ -128,3 +138,9 @@ GitHub.command :default do
|
|
128
138
|
end
|
129
139
|
puts
|
130
140
|
end
|
141
|
+
|
142
|
+
GitHub.commands[''] = GitHub.commands['default']
|
143
|
+
GitHub.commands['-h'] = GitHub.commands['default']
|
144
|
+
GitHub.commands['--help'] = GitHub.commands['default']
|
145
|
+
GitHub.commands['-help'] = GitHub.commands['default']
|
146
|
+
GitHub.commands['help'] = GitHub.commands['default']
|
data/spec/ui_spec.rb
CHANGED
@@ -165,8 +165,9 @@ EOF
|
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
168
|
-
specify "
|
169
|
-
running :
|
168
|
+
specify "pull defunkt should start tracking defunkt if they're not already tracked" do
|
169
|
+
running :pull, "defunkt" do
|
170
|
+
mock_members 'defunkt'
|
170
171
|
setup_remote(:origin, :user => "user", :ssh => true)
|
171
172
|
setup_remote(:external, :url => "home:/path/to/project.git")
|
172
173
|
GitHub.should_receive(:invoke).with(:track, "defunkt").and_return { raise "Tracked" }
|
@@ -174,8 +175,9 @@ EOF
|
|
174
175
|
end
|
175
176
|
end
|
176
177
|
|
177
|
-
specify "
|
178
|
-
running :
|
178
|
+
specify "pull defunkt should create defunkt/master and pull from the defunkt remote" do
|
179
|
+
running :pull, "defunkt" do
|
180
|
+
mock_members 'defunkt'
|
179
181
|
setup_remote(:defunkt)
|
180
182
|
@helper.should_receive(:branch_dirty?).and_return false
|
181
183
|
@command.should_receive(:git).with("update-ref refs/heads/defunkt/master HEAD").ordered
|
@@ -185,8 +187,9 @@ EOF
|
|
185
187
|
end
|
186
188
|
end
|
187
189
|
|
188
|
-
specify "
|
189
|
-
running :
|
190
|
+
specify "pull defunkt should switch to pre-existing defunkt/master and pull from the defunkt remote" do
|
191
|
+
running :pull, "defunkt" do
|
192
|
+
mock_members 'defunkt'
|
190
193
|
setup_remote(:defunkt)
|
191
194
|
@helper.should_receive(:branch_dirty?).and_return true
|
192
195
|
@command.should_receive(:die).with("Unable to switch branches, your current branch has uncommitted changes").and_return { raise "Died" }
|
@@ -241,8 +244,9 @@ EOF
|
|
241
244
|
end
|
242
245
|
end
|
243
246
|
|
244
|
-
specify "
|
245
|
-
running :
|
247
|
+
specify "pull defunkt wip should create defunkt/wip and pull from wip branch on defunkt remote" do
|
248
|
+
running :pull, "defunkt", "wip" do
|
249
|
+
mock_members 'defunkt'
|
246
250
|
setup_remote(:defunkt)
|
247
251
|
@helper.should_receive(:branch_dirty?).and_return true
|
248
252
|
@command.should_receive(:die).with("Unable to switch branches, your current branch has uncommitted changes").and_return { raise "Died" }
|
@@ -250,25 +254,42 @@ EOF
|
|
250
254
|
end
|
251
255
|
end
|
252
256
|
|
253
|
-
specify "
|
254
|
-
running :
|
255
|
-
|
256
|
-
|
257
|
-
@command.should_receive(:git).with("
|
257
|
+
specify "pull defunkt/wip should switch to pre-existing defunkt/wip and pull from wip branch on defunkt remote" do
|
258
|
+
running :pull, "defunkt/wip" do
|
259
|
+
mock_members 'defunkt'
|
260
|
+
setup_remote(:defunkt)
|
261
|
+
@command.should_receive(:git).with("checkout -b defunkt/wip").ordered.and_return do
|
262
|
+
mock("checkout -b defunkt/wip").tap { |m| m.should_receive(:error?) { true } }
|
263
|
+
end
|
258
264
|
@command.should_receive(:git).with("checkout defunkt/wip").ordered
|
259
265
|
@command.should_receive(:git_exec).with("fetch defunkt wip").ordered
|
260
266
|
stdout.should == "Switching to defunkt/wip\n"
|
261
267
|
end
|
262
268
|
end
|
263
269
|
|
264
|
-
specify "
|
265
|
-
running :
|
270
|
+
specify "pull --merge defunkt should pull from defunkt remote into current branch" do
|
271
|
+
running :pull, "--merge", "defunkt" do
|
272
|
+
mock_members 'defunkt'
|
266
273
|
setup_remote(:defunkt)
|
267
274
|
@helper.should_receive(:branch_dirty?).and_return false
|
268
275
|
@command.should_receive(:git_exec).with("fetch defunkt master")
|
269
276
|
end
|
270
277
|
end
|
271
278
|
|
279
|
+
specify "pull falls through for non-recognized commands" do
|
280
|
+
running :pull, 'remote' do
|
281
|
+
mock_members 'defunkt'
|
282
|
+
@command.should_receive(:git_exec).with("pull remote")
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
specify "pull passes along args when falling through" do
|
287
|
+
running :pull, 'remote', '--stat' do
|
288
|
+
mock_members 'defunkt'
|
289
|
+
@command.should_receive(:git_exec).with("pull remote --stat")
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
272
293
|
# -- clone --
|
273
294
|
specify "clone should die with no args" do
|
274
295
|
running :clone do
|
@@ -277,10 +298,9 @@ EOF
|
|
277
298
|
end
|
278
299
|
end
|
279
300
|
|
280
|
-
specify "clone should
|
281
|
-
running :clone, "
|
282
|
-
@command.should_receive(:
|
283
|
-
self.should raise_error("Died")
|
301
|
+
specify "clone should fall through with just one arg" do
|
302
|
+
running :clone, "git://git.kernel.org/linux.git" do
|
303
|
+
@command.should_receive(:git_exec).with("clone git://git.kernel.org/linux.git")
|
284
304
|
end
|
285
305
|
end
|
286
306
|
|
@@ -290,6 +310,12 @@ EOF
|
|
290
310
|
end
|
291
311
|
end
|
292
312
|
|
313
|
+
specify "clone defunkt/github-gem should clone the repo" do
|
314
|
+
running :clone, "defunkt/github-gem" do
|
315
|
+
@command.should_receive(:git_exec).with("clone git://github.com/defunkt/github-gem.git")
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
293
319
|
specify "clone --ssh defunkt github-gem should clone the repo using the private URL" do
|
294
320
|
running :clone, "--ssh", "defunkt", "github-gem" do
|
295
321
|
@command.should_receive(:git_exec).with("clone git@github.com:defunkt/github-gem.git")
|
@@ -302,6 +328,12 @@ EOF
|
|
302
328
|
end
|
303
329
|
end
|
304
330
|
|
331
|
+
specify "clone defunkt/github-gem repo should clone the repo into the dir 'repo'" do
|
332
|
+
running :clone, "defunkt/github-gem", "repo" do
|
333
|
+
@command.should_receive(:git_exec).with("clone git://github.com/defunkt/github-gem.git repo")
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
305
337
|
specify "clone --ssh defunkt github-gem repo should clone the repo using the private URL into the dir 'repo'" do
|
306
338
|
running :clone, "--ssh", "defunkt", "github-gem", "repo" do
|
307
339
|
@command.should_receive(:git_exec).with("clone git@github.com:defunkt/github-gem.git repo")
|
@@ -360,6 +392,19 @@ EOF
|
|
360
392
|
end
|
361
393
|
end
|
362
394
|
|
395
|
+
# -- fallthrough --
|
396
|
+
specify "should fall through to actual git commands" do
|
397
|
+
running :commit do
|
398
|
+
@command.should_receive(:git_exec).with("commit")
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
specify "should pass along arguments when falling through" do
|
403
|
+
running :commit, '-a', '-m', 'yo mama' do
|
404
|
+
@command.should_receive(:git_exec).with("commit -a -m 'yo mama'")
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
363
408
|
# -- default --
|
364
409
|
specify "should print the default message" do
|
365
410
|
running :default do
|
@@ -399,7 +444,7 @@ EOF
|
|
399
444
|
|
400
445
|
def initialize(parent, cmd, *args, &block)
|
401
446
|
@cmd_name = cmd.to_s
|
402
|
-
@command = GitHub.
|
447
|
+
@command = GitHub.find_command(cmd)
|
403
448
|
@helper = @command.helper
|
404
449
|
@args = args
|
405
450
|
@block = block
|
@@ -458,6 +503,10 @@ EOF
|
|
458
503
|
@helper.should_receive(:remotes).any_number_of_times.and_return(@remotes)
|
459
504
|
end
|
460
505
|
|
506
|
+
def mock_members(members)
|
507
|
+
@helper.should_receive(:network_members).any_number_of_times.and_return(members)
|
508
|
+
end
|
509
|
+
|
461
510
|
def should(result)
|
462
511
|
@expected_result = [:should, result]
|
463
512
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riquedafreak-github
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Wanstrath, Kevin Ballard, Scott Chacon
|
@@ -10,17 +10,27 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
|
12
12
|
date: 2008-05-18 00:00:00 -07:00
|
13
|
-
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
13
|
+
default_executable: gh
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: json
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
16
24
|
description: The official `github` command line helper for simplifying your GitHub experience.
|
17
25
|
email: chris@ozmm.org
|
18
26
|
executables:
|
19
27
|
- github
|
28
|
+
- gh
|
20
29
|
extensions: []
|
21
30
|
|
22
31
|
extra_rdoc_files:
|
23
32
|
- bin/github
|
33
|
+
- bin/gh
|
24
34
|
- lib/github/extensions.rb
|
25
35
|
- lib/github/command.rb
|
26
36
|
- lib/github/helper.rb
|
@@ -46,6 +56,7 @@ files:
|
|
46
56
|
- spec/ui_spec.rb
|
47
57
|
- spec/windoze_spec.rb
|
48
58
|
- github-gem.gemspec
|
59
|
+
- bin/gh
|
49
60
|
has_rdoc: true
|
50
61
|
homepage: http://github.com/
|
51
62
|
post_install_message:
|