-
Notifications
You must be signed in to change notification settings - Fork 188
/
commands.rb
251 lines (225 loc) · 8.4 KB
/
commands.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
desc "Open this repo's master branch in a web browser."
command :home do |user|
if helper.project
homepage = helper.homepage_for(user || helper.owner, 'master')
homepage.gsub!(%r{/tree/master$}, '')
helper.open homepage
end
end
desc "Automatically set configuration info, or pass args to specify."
usage "github config [my_username] [my_repo_name]"
command :config do |user, repo|
user ||= ENV['USER']
repo ||= File.basename(FileUtils.pwd)
git "config --global github.user #{user}"
git "config github.repo #{repo}"
puts "Configured with github.user #{user}, github.repo #{repo}"
end
desc "Open this repo in a web browser."
usage "github browse [user] [branch]"
command :browse do |user, branch|
if helper.project
# if one arg given, treat it as a branch name
# unless it maches user/branch, then split it
# if two args given, treat as user branch
# if no args given, use defaults
user, branch = user.split("/", 2) if branch.nil? unless user.nil?
branch = user and user = nil if branch.nil?
user ||= helper.branch_user
branch ||= helper.branch_name
helper.open helper.homepage_for(user, branch)
end
end
desc 'Open the given user/project in a web browser'
usage 'github open [user/project]'
command :open do |arg|
helper.open "http://github.com/#{arg}"
end
desc "Info about this project."
command :info do
puts "== Info for #{helper.project}"
puts "You are #{helper.owner}"
puts "Currently tracking:"
helper.tracking.sort { |(a,),(b,)| a == helper.origin ? -1 : b == helper.origin ? 1 : a.to_s <=> b.to_s }.each do |(name,user_or_url)|
puts " - #{user_or_url} (as #{name})"
end
end
desc "Track another user's repository."
usage "github track remote [user]"
usage "github track remote [user/repo]"
usage "github track [user]"
usage "github track [user/repo]"
flags :private => "Use git@github.com: instead of git://github.com/."
flags :ssh => 'Equivalent to --private'
command :track do |remote, user|
# track remote user
# track remote user/repo
# track user
# track user/repo
user, remote = remote, nil if user.nil?
die "Specify a user to track" if user.nil?
user, repo = user.split("/", 2)
die "Already tracking #{user}" if helper.tracking?(user)
repo = @helper.project if repo.nil?
repo.chomp!(".git")
remote ||= user
if options[:private] || options[:ssh]
git "remote add #{remote} #{helper.private_url_for_user_and_repo(user, repo)}"
else
git "remote add #{remote} #{helper.public_url_for_user_and_repo(user, repo)}"
end
end
desc "Fetch all refs from a user"
command :fetch_all do |user|
GitHub.invoke(:track, user) unless helper.tracking?(user)
git "fetch #{user}"
end
desc "Fetch from a remote to a local branch."
command :fetch do |user, branch|
die "Specify a user to pull from" if user.nil?
user, branch = user.split("/", 2) if branch.nil?
branch ||= 'master'
GitHub.invoke(:track, user) unless helper.tracking?(user)
die "Unknown branch (#{branch}) specified" unless helper.remote_branch?(user, branch)
die "Unable to switch branches, your current branch has uncommitted changes" if helper.branch_dirty?
puts "Fetching #{user}/#{branch}"
git "fetch #{user} #{branch}:refs/remotes/#{user}/#{branch}"
git "update-ref refs/heads/#{user}/#{branch} refs/remotes/#{user}/#{branch}"
git_exec "checkout #{user}/#{branch}"
end
desc "Pull from a remote."
usage "github pull [user] [branch]"
flags :merge => "Automatically merge remote's changes into your master."
command :pull do |user, branch|
die "Specify a user to pull from" if user.nil?
user, branch = user.split("/", 2) if branch.nil?
if !helper.network_members(user, {}).include?(user)
git_exec "#{helper.argv.join(' ')}".strip
return
end
branch ||= 'master'
GitHub.invoke(:track, user) unless helper.tracking?(user)
die "Unable to switch branches, your current branch has uncommitted changes" if helper.branch_dirty?
if options[:merge]
git_exec "pull #{user} #{branch}"
else
puts "Switching to #{user}-#{branch}"
git "fetch #{user}"
git_exec "checkout -b #{user}/#{branch} #{user}/#{branch}"
end
end
desc "Clone a repo. Uses ssh if current user is "
usage "github clone [user] [repo] [dir]"
flags :ssh => "Clone using the git@github.com style url."
flags :search => "Search for [user|repo] and clone selected repository"
command :clone do |user, repo, dir|
die "Specify a user to pull from" if user.nil?
if options[:search]
query = [user, repo, dir].compact.join(" ")
data = JSON.parse(open("http://github.com/api/v1/json/search/#{URI.escape query}").read)
if (repos = data['repositories']) && !repos.nil? && repos.length > 0
repo_list = repos.map do |r|
{ "name" => "#{r['username']}/#{r['name']}", "description" => r['description'] }
end
formatted_list = helper.format_list(repo_list).split("\n")
if user_repo = GitHub::UI.display_select_list(formatted_list)
user, repo = user_repo.strip.split('/', 2)
end
end
die "Perhaps try another search" unless user && repo
end
if user.include?('/') && !user.include?('@') && !user.include?(':')
die "Expected user/repo dir, given extra argument" if dir
(user, repo), dir = [user.split('/', 2), repo]
end
if repo
if options[:ssh] || current_user?(user)
git_exec "clone git@github.com:#{user}/#{repo}.git" + (dir ? " #{dir}" : "")
else
git_exec "clone git://github.com/#{user}/#{repo}.git" + (dir ? " #{dir}" : "")
end
else
git_exec "#{helper.argv.join(' ')}".strip
end
end
desc "Generate the text for a pull request."
usage "github pull-request [user] [branch]"
command :'pull-request' do |user, branch|
if helper.project
die "Specify a user for the pull request" if user.nil?
user, branch = user.split('/', 2) if branch.nil?
branch ||= 'master'
GitHub.invoke(:track, user) unless helper.tracking?(user)
git_exec "request-pull #{user}/#{branch} #{helper.origin}"
end
end
desc "Create a new, empty GitHub repository"
usage "github create [repo]"
flags :markdown => 'Create README.markdown'
flags :mdown => 'Create README.mdown'
flags :textile => 'Create README.textile'
flags :rdoc => 'Create README.rdoc'
flags :rst => 'Create README.rst'
flags :private => 'Create private repository'
command :create do |repo|
sh "curl -F 'repository[name]=#{repo}' -F 'repository[public]=#{!options[:private]}' -F 'login=#{github_user}' -F 'token=#{github_token}' http://github.com/repositories"
mkdir repo
cd repo
git "init"
extension = options.keys.first
touch extension ? "README.#{extension}" : "README"
git "add *"
git "commit -m 'First commit!'"
git "remote add origin git@github.com:#{github_user}/#{repo}.git"
git_exec "push origin master"
end
desc "Forks a GitHub repository"
usage "github fork"
usage "github fork [user]/[repo]"
command :fork do |user, repo|
if repo.nil?
if user
user, repo = user.split('/')
else
unless helper.remotes.empty?
is_repo = true
user = helper.owner
repo = helper.project
else
die "Specify a user/project to fork, or run from within a repo"
end
end
end
sh "curl -F 'login=#{github_user}' -F 'token=#{github_token}' http://github.com/#{user}/#{repo}/fork"
url = "git@github.com:#{github_user}/#{repo}.git"
if is_repo
git "config remote.origin.url #{url}"
puts "#{user}/#{repo} forked"
else
puts "Giving GitHub a moment to create the fork..."
sleep 3
git_exec "clone #{url}"
end
end
desc "Create a new GitHub repository from the current local repository"
flags :private => 'Create private repository'
command :'create-from-local' do
cwd = sh "pwd"
repo = File.basename(cwd)
is_repo = !git("status").match(/fatal/)
raise "Not a git repository. Use gh create instead" unless is_repo
sh "curl -F 'repository[name]=#{repo}' -F 'repository[public]=#{!options[:private].inspect} -F 'login=#{github_user}' -F 'token=#{github_token}' http://github.com/repositories"
git "remote add origin git@github.com:#{github_user}/#{repo}.git"
git_exec "push origin master"
end
desc "Search GitHub for the given repository name."
usage "github search [query]"
command :search do |query|
die "Usage: github search [query]" if query.nil?
data = JSON.parse(open("http://github.com/api/v1/json/search/#{URI.escape query}").read)
if (repos = data['repositories']) && !repos.nil? && repos.length > 0
puts repos.map { |r| "#{r['username']}/#{r['name']}"}.sort.uniq
else
puts "No results found"
end
end