defunkt-github 0.3.1 → 0.3.2
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 +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
|