defunkt-github 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +5 -5
- data/README +1 -1
- data/commands/commands.rb +21 -116
- data/github-gem.gemspec +1 -1
- data/lib/github/command.rb +30 -8
- data/lib/github/extensions.rb +11 -0
- data/lib/github.rb +47 -21
- data/spec/github_spec.rb +20 -0
- metadata +1 -1
data/Manifest
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
+
History.txt
|
1
2
|
LICENSE
|
2
|
-
Manifest
|
3
|
-
README
|
4
|
-
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
5
6
|
bin/github
|
6
7
|
commands/commands.rb
|
7
8
|
commands/helpers.rb
|
8
|
-
github
|
9
|
+
lib/github.rb
|
9
10
|
lib/github/command.rb
|
10
11
|
lib/github/extensions.rb
|
11
12
|
lib/github/helper.rb
|
12
|
-
lib/github.rb
|
13
13
|
spec/command_spec.rb
|
14
14
|
spec/extensions_spec.rb
|
15
15
|
spec/github_spec.rb
|
data/README
CHANGED
data/commands/commands.rb
CHANGED
@@ -5,7 +5,18 @@ command :home do |user|
|
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
+
desc "Automatically set configuration info, or pass args to specify."
|
9
|
+
usage "github config [my_username] [my_repo_name]"
|
10
|
+
command :config do |user, repo|
|
11
|
+
user ||= ENV['USER']
|
12
|
+
repo ||= File.basename(FileUtils.pwd)
|
13
|
+
git "config --global github.user #{user}"
|
14
|
+
git "config github.repo #{repo}"
|
15
|
+
puts "Configured with github.user #{user}, github.repo #{repo}"
|
16
|
+
end
|
17
|
+
|
8
18
|
desc "Open this repo in a web browser."
|
19
|
+
usage "github browse [user] [branch]"
|
9
20
|
command :browse do |user, branch|
|
10
21
|
if helper.project
|
11
22
|
# if one arg given, treat it as a branch name
|
@@ -20,119 +31,6 @@ command :browse do |user, branch|
|
|
20
31
|
end
|
21
32
|
end
|
22
33
|
|
23
|
-
desc "Project network tools - sub-commands : web [user], list, fetch, commits"
|
24
|
-
flags :after => "Only show commits after a certain date"
|
25
|
-
flags :before => "Only show commits before a certain date"
|
26
|
-
flags :shas => "Only show shas"
|
27
|
-
flags :project => "Filter commits on a certain project"
|
28
|
-
flags :author => "Filter commits on a email address of author"
|
29
|
-
flags :applies => "Filter commits to patches that apply cleanly"
|
30
|
-
flags :noapply => "Filter commits to patches that do not apply cleanly"
|
31
|
-
flags :nocache => "Do not use the cached network data"
|
32
|
-
flags :cache => "Use the network data even if it's expired"
|
33
|
-
flags :sort => "How to sort : date(*), branch, author"
|
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"
|
37
|
-
command :network do |command, user|
|
38
|
-
return if !helper.project
|
39
|
-
user ||= helper.owner
|
40
|
-
|
41
|
-
case command
|
42
|
-
when 'web'
|
43
|
-
helper.open helper.network_page_for(user)
|
44
|
-
when 'list'
|
45
|
-
data = helper.get_network_data(user, options)
|
46
|
-
data['users'].each do |hsh|
|
47
|
-
puts [ hsh['name'].ljust(20), hsh['heads'].map {|a| a['name']}.uniq.join(', ') ].join(' ')
|
48
|
-
end
|
49
|
-
when 'fetch'
|
50
|
-
# fetch each remote we don't have
|
51
|
-
data = helper.get_network_data(user, options)
|
52
|
-
data['users'].each do |hsh|
|
53
|
-
u = hsh['name']
|
54
|
-
GitHub.invoke(:track, u) unless helper.tracking?(u)
|
55
|
-
puts "fetching #{u}"
|
56
|
-
GitHub.invoke(:fetch_all, u)
|
57
|
-
end
|
58
|
-
when 'commits'
|
59
|
-
# show commits we don't have yet
|
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
|
80
|
-
end
|
81
|
-
ids += user_ids
|
82
|
-
end
|
83
|
-
ids.uniq!
|
84
|
-
|
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
|
106
|
-
end
|
107
|
-
|
108
|
-
if cherry.size > 0 || !helper.cache_commits_data(options)
|
109
|
-
helper.print_network_cherry_help if !options[:shas]
|
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)
|
123
|
-
else
|
124
|
-
puts "no unapplied commits"
|
125
|
-
end
|
126
|
-
else
|
127
|
-
helper.print_network_help
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
desc "Ignore a SHA (from 'github network commits')"
|
132
|
-
command :ignore do |sha|
|
133
|
-
commits = helper.resolve_commits(sha)
|
134
|
-
helper.ignore_shas(commits) # add to .git/ignore-shas file
|
135
|
-
end
|
136
34
|
|
137
35
|
desc "Info about this project."
|
138
36
|
command :info do
|
@@ -145,6 +43,10 @@ command :info do
|
|
145
43
|
end
|
146
44
|
|
147
45
|
desc "Track another user's repository."
|
46
|
+
usage "github track remote [user]"
|
47
|
+
usage "github track remote [user/repo]"
|
48
|
+
usage "github track [user]"
|
49
|
+
usage "github track [user/repo]"
|
148
50
|
flags :private => "Use git@github.com: instead of git://github.com/."
|
149
51
|
flags :ssh => 'Equivalent to --private'
|
150
52
|
command :track do |remote, user|
|
@@ -179,7 +81,7 @@ command :fetch do |user, branch|
|
|
179
81
|
user, branch = user.split("/", 2) if branch.nil?
|
180
82
|
branch ||= 'master'
|
181
83
|
GitHub.invoke(:track, user) unless helper.tracking?(user)
|
182
|
-
|
84
|
+
|
183
85
|
die "Unknown branch (#{branch}) specified" unless helper.remote_branch?(user, branch)
|
184
86
|
die "Unable to switch branches, your current branch has uncommitted changes" if helper.branch_dirty?
|
185
87
|
|
@@ -190,6 +92,7 @@ command :fetch do |user, branch|
|
|
190
92
|
end
|
191
93
|
|
192
94
|
desc "Pull from a remote."
|
95
|
+
usage "github pull [user] [branch]"
|
193
96
|
flags :merge => "Automatically merge remote's changes into your master."
|
194
97
|
command :pull do |user, branch|
|
195
98
|
die "Specify a user to pull from" if user.nil?
|
@@ -211,7 +114,8 @@ command :pull do |user, branch|
|
|
211
114
|
end
|
212
115
|
end
|
213
116
|
|
214
|
-
desc "Clone a repo."
|
117
|
+
desc "Clone a repo. Uses ssh if current user is "
|
118
|
+
usage "github clone [user] [repo] [dir]"
|
215
119
|
flags :ssh => "Clone using the git@github.com style url."
|
216
120
|
command :clone do |user, repo, dir|
|
217
121
|
die "Specify a user to pull from" if user.nil?
|
@@ -220,7 +124,7 @@ command :clone do |user, repo, dir|
|
|
220
124
|
(user, repo), dir = [user.split('/', 2), repo]
|
221
125
|
end
|
222
126
|
|
223
|
-
if options[:ssh]
|
127
|
+
if options[:ssh] || current_user?(user)
|
224
128
|
git_exec "clone git@github.com:#{user}/#{repo}.git" + (dir ? " #{dir}" : "")
|
225
129
|
elsif repo
|
226
130
|
git_exec "clone git://github.com/#{user}/#{repo}.git" + (dir ? " #{dir}" : "")
|
@@ -230,6 +134,7 @@ command :clone do |user, repo, dir|
|
|
230
134
|
end
|
231
135
|
|
232
136
|
desc "Generate the text for a pull request."
|
137
|
+
usage "github pull-request [user] [branch]"
|
233
138
|
command :'pull-request' do |user, branch|
|
234
139
|
if helper.project
|
235
140
|
die "Specify a user for the pull request" if user.nil?
|
data/github-gem.gemspec
CHANGED
data/lib/github/command.rb
CHANGED
@@ -33,25 +33,47 @@ module GitHub
|
|
33
33
|
puts git(*command)
|
34
34
|
end
|
35
35
|
|
36
|
-
def git(
|
37
|
-
sh
|
36
|
+
def git(command)
|
37
|
+
run :sh, command
|
38
38
|
end
|
39
39
|
|
40
|
-
def git_exec(
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
def git_exec(command)
|
41
|
+
run :exec, command
|
42
|
+
end
|
43
|
+
|
44
|
+
def run(method, command)
|
45
|
+
if command.is_a? Array
|
46
|
+
command = [ 'git', command ].flatten
|
47
|
+
GitHub.learn command.join(' ')
|
48
|
+
else
|
49
|
+
command = 'git ' + command
|
50
|
+
GitHub.learn command
|
51
|
+
end
|
52
|
+
|
53
|
+
send method, *command
|
44
54
|
end
|
45
55
|
|
46
56
|
def sh(*command)
|
47
57
|
Shell.new(*command).run
|
48
58
|
end
|
49
|
-
|
59
|
+
|
50
60
|
def die(message)
|
51
61
|
puts "=> #{message}"
|
52
62
|
exit!
|
53
63
|
end
|
54
64
|
|
65
|
+
def github_user
|
66
|
+
git("config --get github.user")
|
67
|
+
end
|
68
|
+
|
69
|
+
def shell_user
|
70
|
+
ENV['USER']
|
71
|
+
end
|
72
|
+
|
73
|
+
def current_user?(user)
|
74
|
+
user == github_user || user == shell_user
|
75
|
+
end
|
76
|
+
|
55
77
|
class Shell < String
|
56
78
|
attr_reader :error
|
57
79
|
attr_reader :out
|
@@ -93,7 +115,7 @@ module GitHub
|
|
93
115
|
end
|
94
116
|
|
95
117
|
def command(*args)
|
96
|
-
git_exec
|
118
|
+
git_exec [ @name, args ]
|
97
119
|
end
|
98
120
|
end
|
99
121
|
end
|
data/lib/github/extensions.rb
CHANGED
@@ -26,3 +26,14 @@ class Object
|
|
26
26
|
self
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
# cute
|
31
|
+
module Color
|
32
|
+
COLORS = { :clear => 0, :red => 31, :green => 32, :yellow => 33 }
|
33
|
+
def self.method_missing(color_name, *args)
|
34
|
+
color(color_name) + args.first + color(:clear)
|
35
|
+
end
|
36
|
+
def self.color(color)
|
37
|
+
"\e[#{COLORS[color.to_sym]}m"
|
38
|
+
end
|
39
|
+
end
|
data/lib/github.rb
CHANGED
@@ -2,6 +2,7 @@ $:.unshift File.dirname(__FILE__)
|
|
2
2
|
require 'github/extensions'
|
3
3
|
require 'github/command'
|
4
4
|
require 'github/helper'
|
5
|
+
require 'fileutils'
|
5
6
|
require 'rubygems'
|
6
7
|
require 'open-uri'
|
7
8
|
require 'json'
|
@@ -16,22 +17,24 @@ require 'yaml'
|
|
16
17
|
# whatever
|
17
18
|
# end
|
18
19
|
#
|
19
|
-
# We'll probably want to use the `choice` gem for concise, tasty DSL
|
20
|
-
# arg parsing action.
|
21
|
-
#
|
22
20
|
|
23
21
|
module GitHub
|
24
22
|
extend self
|
25
23
|
|
26
24
|
BasePath = File.expand_path(File.dirname(__FILE__) + '/..')
|
27
25
|
|
28
|
-
def command(command, &block)
|
26
|
+
def command(command, options = {}, &block)
|
29
27
|
debug "Registered `#{command}`"
|
30
28
|
descriptions[command] = @next_description if @next_description
|
31
29
|
@next_description = nil
|
32
30
|
flag_descriptions[command].update @next_flags if @next_flags
|
31
|
+
usage_descriptions[command] = @next_usage if @next_usage
|
33
32
|
@next_flags = nil
|
33
|
+
@next_usage = []
|
34
34
|
commands[command.to_s] = Command.new(block)
|
35
|
+
Array(options[:alias] || options[:aliases]).each do |command_alias|
|
36
|
+
commands[command_alias.to_s] = commands[command.to_s]
|
37
|
+
end
|
35
38
|
end
|
36
39
|
|
37
40
|
def desc(str)
|
@@ -43,6 +46,11 @@ module GitHub
|
|
43
46
|
@next_flags.update hash
|
44
47
|
end
|
45
48
|
|
49
|
+
def usage(string)
|
50
|
+
@next_usage ||= []
|
51
|
+
@next_usage << string
|
52
|
+
end
|
53
|
+
|
46
54
|
def helper(command, &block)
|
47
55
|
debug "Helper'd `#{command}`"
|
48
56
|
Helper.send :define_method, command, &block
|
@@ -51,9 +59,11 @@ module GitHub
|
|
51
59
|
def activate(args)
|
52
60
|
@@original_args = args.clone
|
53
61
|
@options = parse_options(args)
|
54
|
-
@debug = @options
|
55
|
-
|
56
|
-
|
62
|
+
@debug = @options.delete(:debug)
|
63
|
+
@learn = @options.delete(:learn)
|
64
|
+
Dir[BasePath + '/commands/*.rb'].each do |command|
|
65
|
+
load command
|
66
|
+
end
|
57
67
|
invoke(args.shift, *args)
|
58
68
|
end
|
59
69
|
|
@@ -80,6 +90,10 @@ module GitHub
|
|
80
90
|
@flagdescs ||= Hash.new { |h, k| h[k] = {} }
|
81
91
|
end
|
82
92
|
|
93
|
+
def usage_descriptions
|
94
|
+
@usage_descriptions ||= Hash.new { |h, k| h[k] = [] }
|
95
|
+
end
|
96
|
+
|
83
97
|
def options
|
84
98
|
@options
|
85
99
|
end
|
@@ -108,29 +122,47 @@ module GitHub
|
|
108
122
|
end
|
109
123
|
end
|
110
124
|
|
111
|
-
def load(file)
|
112
|
-
file[0] == ?/ ? path = file : path = BasePath + "/commands/#{file}"
|
113
|
-
data = File.read(path)
|
114
|
-
GitHub.module_eval data, path
|
115
|
-
end
|
116
|
-
|
117
125
|
def debug(*messages)
|
118
126
|
puts *messages.map { |m| "== #{m}" } if debug?
|
119
127
|
end
|
120
128
|
|
129
|
+
def learn(message)
|
130
|
+
if learn?
|
131
|
+
puts "== " + Color.yellow(message)
|
132
|
+
else
|
133
|
+
debug(message)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def learn?
|
138
|
+
!!@learn
|
139
|
+
end
|
140
|
+
|
121
141
|
def debug?
|
122
142
|
!!@debug
|
123
143
|
end
|
144
|
+
|
145
|
+
def load(file)
|
146
|
+
file[0] == ?/ ? path = file : path = BasePath + "/commands/#{file}"
|
147
|
+
data = File.read(path)
|
148
|
+
GitHub.module_eval data, path
|
149
|
+
end
|
124
150
|
end
|
125
151
|
|
126
|
-
GitHub.command :default do
|
152
|
+
GitHub.command :default, :aliases => ['', '-h', 'help', '-help', '--help'] do
|
127
153
|
puts "Usage: github command <space separated arguments>", ''
|
128
154
|
puts "Available commands:", ''
|
129
155
|
longest = GitHub.descriptions.map { |d,| d.to_s.size }.max
|
130
|
-
GitHub.descriptions.each do |command, desc|
|
156
|
+
GitHub.descriptions.sort {|a,b| a.to_s <=> b.to_s }.each do |command, desc|
|
131
157
|
cmdstr = "%-#{longest}s" % command
|
132
158
|
puts " #{cmdstr} => #{desc}"
|
133
159
|
flongest = GitHub.flag_descriptions[command].map { |d,| "--#{d}".size }.max
|
160
|
+
GitHub.usage_descriptions[command].each do |usage_descriptions|
|
161
|
+
usage_descriptions.each do |usage|
|
162
|
+
usage_str = "#{" " * longest} %% %-#{flongest}s" % usage
|
163
|
+
puts usage_str
|
164
|
+
end
|
165
|
+
end
|
134
166
|
GitHub.flag_descriptions[command].each do |flag, fdesc|
|
135
167
|
flagstr = "#{" " * longest} %-#{flongest}s" % "--#{flag}"
|
136
168
|
puts " #{flagstr}: #{fdesc}"
|
@@ -138,9 +170,3 @@ GitHub.command :default do
|
|
138
170
|
end
|
139
171
|
puts
|
140
172
|
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/github_spec.rb
CHANGED
@@ -62,4 +62,24 @@ describe "GitHub.parse_options" do
|
|
62
62
|
GitHub.activate(['default', '--debug'])
|
63
63
|
GitHub.should be_debug
|
64
64
|
end
|
65
|
+
|
66
|
+
it "should allow for an alias on a commad" do
|
67
|
+
GitHub.command 'some-command', :aliases => 'an-alias' do
|
68
|
+
end
|
69
|
+
GitHub.commands['an-alias'].should_not be_nil
|
70
|
+
GitHub.commands['an-alias'].should_not == GitHub.commands['non-existant-command']
|
71
|
+
GitHub.commands['an-alias'].should == GitHub.commands['some-command']
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should allow for an array of aliases on a commad" do
|
75
|
+
GitHub.command 'another-command', :aliases => ['some-alias-1', 'some-alias-2'] do
|
76
|
+
end
|
77
|
+
GitHub.commands['some-alias-1'].should_not be_nil
|
78
|
+
GitHub.commands['some-alias-1'].should_not == GitHub.commands['non-existant-command']
|
79
|
+
GitHub.commands['some-alias-1'].should_not be_nil
|
80
|
+
GitHub.commands['some-alias-1'].should_not == GitHub.commands['non-existant-command']
|
81
|
+
GitHub.commands['some-alias-1'].should == GitHub.commands['another-command']
|
82
|
+
GitHub.commands['some-alias-2'].should == GitHub.commands['another-command']
|
83
|
+
end
|
84
|
+
|
65
85
|
end
|