git-hub 1.5.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/hub/commands.rb +51 -15
- data/lib/hub/context.rb +12 -0
- data/lib/hub/runner.rb +3 -8
- data/lib/hub/version.rb +1 -1
- data/test/hub_test.rb +85 -26
- metadata +28 -8
data/lib/hub/commands.rb
CHANGED
@@ -41,6 +41,22 @@ module Hub
|
|
41
41
|
API_FORK = 'http://github.com/api/v2/yaml/repos/fork/%s/%s'
|
42
42
|
API_CREATE = 'http://github.com/api/v2/yaml/repos/create'
|
43
43
|
|
44
|
+
def run(args)
|
45
|
+
# Hack to emulate git-style
|
46
|
+
args.unshift 'help' if args.grep(/^[^-]|version|exec-path$|html-path/).empty?
|
47
|
+
|
48
|
+
cmd = args[0]
|
49
|
+
expanded_args = expand_alias(cmd)
|
50
|
+
cmd = expanded_args[0] if expanded_args
|
51
|
+
|
52
|
+
# git commands can have dashes
|
53
|
+
cmd = cmd.sub(/(\w)-/, '\1_')
|
54
|
+
if method_defined?(cmd) and cmd != 'run'
|
55
|
+
args[0, 1] = expanded_args if expanded_args
|
56
|
+
send(cmd, args)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
44
60
|
# $ hub clone rtomayko/tilt
|
45
61
|
# > git clone git://github.com/rtomayko/tilt.
|
46
62
|
#
|
@@ -54,16 +70,14 @@ module Hub
|
|
54
70
|
# > git clone git@github.com:YOUR_LOGIN/hemingway.git
|
55
71
|
def clone(args)
|
56
72
|
ssh = args.delete('-p')
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
if arg =~ %r{.+?://|.+?@} || File.directory?(arg)
|
73
|
+
has_values = /^(--(upload-pack|template|depth|origin|branch|reference)|-[ubo])$/
|
74
|
+
|
75
|
+
idx = 1
|
76
|
+
while idx < args.length
|
77
|
+
arg = args[idx]
|
78
|
+
if arg.index('-') == 0
|
79
|
+
idx += 1 if arg =~ has_values
|
80
|
+
elsif arg.index('://') or arg.index('@') or File.directory?(arg)
|
67
81
|
# Bail out early for URLs and local paths.
|
68
82
|
break
|
69
83
|
elsif arg.scan('/').size <= 1 && !arg.include?(':')
|
@@ -72,6 +86,7 @@ module Hub
|
|
72
86
|
args[args.index(arg)] = github_url(:repo => arg, :private => ssh)
|
73
87
|
break
|
74
88
|
end
|
89
|
+
idx += 1
|
75
90
|
end
|
76
91
|
end
|
77
92
|
|
@@ -218,10 +233,12 @@ module Hub
|
|
218
233
|
# > curl https://github.com/defunkt/hub/pull/55.patch -o /tmp/55.patch
|
219
234
|
# > git am /tmp/55.patch
|
220
235
|
def am(args)
|
221
|
-
if url = args.find { |a| a =~ %r{^https?://github\.com/} }
|
236
|
+
if url = args.find { |a| a =~ %r{^https?://(gist\.)?github\.com/} }
|
222
237
|
idx = args.index(url)
|
223
|
-
|
224
|
-
|
238
|
+
gist = $1 == 'gist.'
|
239
|
+
ext = gist ? '.txt' : '.patch'
|
240
|
+
url += ext unless File.extname(url) == ext
|
241
|
+
patch_file = File.join(ENV['TMPDIR'], "#{gist ? 'gist-' : ''}#{File.basename(url)}")
|
225
242
|
args.before 'curl', ['-#LA', "hub #{Hub::Version}", url, '-o', patch_file]
|
226
243
|
args[idx] = patch_file
|
227
244
|
end
|
@@ -257,6 +274,10 @@ module Hub
|
|
257
274
|
args.after { puts "new remote: #{github_user}" }
|
258
275
|
end
|
259
276
|
end
|
277
|
+
rescue Net::HTTPExceptions
|
278
|
+
response = $!.response
|
279
|
+
warn "error creating fork: #{response.message} (HTTP #{response.code})"
|
280
|
+
exit 1
|
260
281
|
end
|
261
282
|
|
262
283
|
# $ hub create
|
@@ -301,6 +322,10 @@ module Hub
|
|
301
322
|
|
302
323
|
args.after { puts "#{action}: #{github_user}/#{repo_name}" }
|
303
324
|
end
|
325
|
+
rescue Net::HTTPExceptions
|
326
|
+
response = $!.response
|
327
|
+
warn "error creating repository: #{response.message} (HTTP #{response.code})"
|
328
|
+
exit 1
|
304
329
|
end
|
305
330
|
|
306
331
|
# $ hub push origin,staging cool-feature
|
@@ -660,7 +685,8 @@ help
|
|
660
685
|
# Returns nothing.
|
661
686
|
def fork_repo
|
662
687
|
url = API_FORK % [repo_owner, repo_name]
|
663
|
-
Net::HTTP.post_form(URI(url), 'login' => github_user, 'token' => github_token)
|
688
|
+
response = Net::HTTP.post_form(URI(url), 'login' => github_user, 'token' => github_token)
|
689
|
+
response.error! unless Net::HTTPSuccess === response
|
664
690
|
end
|
665
691
|
|
666
692
|
# Creates a new repo using the GitHub API.
|
@@ -673,7 +699,17 @@ help
|
|
673
699
|
params['description'] = options[:description] if options[:description]
|
674
700
|
params['homepage'] = options[:homepage] if options[:homepage]
|
675
701
|
|
676
|
-
Net::HTTP.post_form(URI(url), params)
|
702
|
+
response = Net::HTTP.post_form(URI(url), params)
|
703
|
+
response.error! unless Net::HTTPSuccess === response
|
704
|
+
end
|
705
|
+
|
706
|
+
def expand_alias(cmd)
|
707
|
+
if expanded = git_alias_for(cmd)
|
708
|
+
if expanded.index('!') != 0
|
709
|
+
require 'shellwords' unless expanded.respond_to? :shellsplit
|
710
|
+
expanded.shellsplit
|
711
|
+
end
|
712
|
+
end
|
677
713
|
end
|
678
714
|
|
679
715
|
end
|
data/lib/hub/context.rb
CHANGED
@@ -106,6 +106,10 @@ module Hub
|
|
106
106
|
GIT_CONFIG['config --bool hub.http-clone'] == 'true'
|
107
107
|
end
|
108
108
|
|
109
|
+
def git_alias_for(name)
|
110
|
+
GIT_CONFIG["config alias.#{name}"]
|
111
|
+
end
|
112
|
+
|
109
113
|
# Core.repositoryformatversion should exist for all git
|
110
114
|
# repositories, and be blank for all non-git repositories. If
|
111
115
|
# there's a better config setting to check here, this can be
|
@@ -124,6 +128,14 @@ module Hub
|
|
124
128
|
if options[:web]
|
125
129
|
scheme = secure ? 'https:' : 'http:'
|
126
130
|
path = options[:web] == true ? '' : options[:web].to_s
|
131
|
+
if repo =~ /\.wiki$/
|
132
|
+
repo = repo.sub(/\.wiki$/, '')
|
133
|
+
unless '/wiki' == path
|
134
|
+
path = '/wiki%s' % if path =~ %r{^/commits/} then '/_history'
|
135
|
+
else path.sub(/\w+/, '_\0')
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
127
139
|
'%s//github.com/%s/%s%s' % [scheme, user, repo, path]
|
128
140
|
else
|
129
141
|
if secure
|
data/lib/hub/runner.rb
CHANGED
@@ -9,13 +9,7 @@ module Hub
|
|
9
9
|
|
10
10
|
def initialize(*args)
|
11
11
|
@args = Args.new(args)
|
12
|
-
|
13
|
-
# Hack to emulate git-style
|
14
|
-
@args.unshift 'help' if @args.grep(/^[^-]|version|exec-path$|html-path/).empty?
|
15
|
-
|
16
|
-
# git commands can have dashes
|
17
|
-
cmd = @args[0].sub(/(\w)-/, '\1_')
|
18
|
-
Commands.send(cmd, @args) if Commands.method_defined?(cmd)
|
12
|
+
Commands.run(@args)
|
19
13
|
end
|
20
14
|
|
21
15
|
# Shortcut
|
@@ -36,7 +30,8 @@ module Hub
|
|
36
30
|
def commands
|
37
31
|
args.commands.map do |cmd|
|
38
32
|
if cmd.respond_to?(:join)
|
39
|
-
|
33
|
+
# a simplified `Shellwords.join` but it's OK since this is only used to inspect
|
34
|
+
cmd.map { |c| (c.index(' ') || c.empty?) ? "'#{c}'" : c }.join(' ')
|
40
35
|
else
|
41
36
|
cmd.to_s
|
42
37
|
end
|
data/lib/hub/version.rb
CHANGED
data/test/hub_test.rb
CHANGED
@@ -30,7 +30,9 @@ class HubTest < Test::Unit::TestCase
|
|
30
30
|
Hub::Context::REMOTES.clear
|
31
31
|
|
32
32
|
@git = Hub::Context::GIT_CONFIG.replace(Hash.new { |h, k|
|
33
|
-
|
33
|
+
unless k.index('config alias.') == 0
|
34
|
+
raise ArgumentError, "`git #{k}` not stubbed"
|
35
|
+
end
|
34
36
|
}).update(
|
35
37
|
'remote' => "mislav\norigin",
|
36
38
|
'symbolic-ref -q HEAD' => 'refs/heads/master',
|
@@ -72,12 +74,16 @@ class HubTest < Test::Unit::TestCase
|
|
72
74
|
assert_command input, command
|
73
75
|
end
|
74
76
|
|
75
|
-
def
|
76
|
-
input = "clone --bare -o master
|
77
|
-
command = "git clone --bare -o master
|
77
|
+
def test_clone_with_arguments
|
78
|
+
input = "clone --bare -o master resque"
|
79
|
+
command = "git clone --bare -o master git://github.com/tpw/resque.git"
|
78
80
|
assert_command input, command
|
79
81
|
end
|
80
82
|
|
83
|
+
def test_clone_with_arguments_and_destination
|
84
|
+
assert_forwarded "clone --template=one/two git://github.com/tpw/resque.git --origin master resquetastic"
|
85
|
+
end
|
86
|
+
|
81
87
|
def test_your_private_clone_fails_without_config
|
82
88
|
out = hub("clone -p mustache") do
|
83
89
|
stub_github_user(nil)
|
@@ -95,29 +101,40 @@ class HubTest < Test::Unit::TestCase
|
|
95
101
|
end
|
96
102
|
|
97
103
|
def test_private_clone_left_alone
|
98
|
-
|
99
|
-
command = "git clone git@github.com:rtomayko/ronn.git"
|
100
|
-
assert_command input, command
|
104
|
+
assert_forwarded "clone git@github.com:rtomayko/ronn.git"
|
101
105
|
end
|
102
106
|
|
103
107
|
def test_public_clone_left_alone
|
104
|
-
|
105
|
-
command = "git clone git://github.com/rtomayko/ronn.git"
|
106
|
-
assert_command input, command
|
108
|
+
assert_forwarded "clone git://github.com/rtomayko/ronn.git"
|
107
109
|
end
|
108
110
|
|
109
111
|
def test_normal_public_clone_with_path
|
110
|
-
|
111
|
-
command = "git clone git://github.com/rtomayko/ronn.git ronn-dev"
|
112
|
-
assert_command input, command
|
112
|
+
assert_forwarded "clone git://github.com/rtomayko/ronn.git ronn-dev"
|
113
113
|
end
|
114
114
|
|
115
115
|
def test_normal_clone_from_path
|
116
|
-
|
117
|
-
|
116
|
+
assert_forwarded "clone ./test"
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_alias_expand
|
120
|
+
stub_alias 'c', 'clone --bare'
|
121
|
+
input = "c rtomayko/ronn"
|
122
|
+
command = "git clone --bare git://github.com/rtomayko/ronn.git"
|
118
123
|
assert_command input, command
|
119
124
|
end
|
120
125
|
|
126
|
+
def test_alias_expand_advanced
|
127
|
+
stub_alias 'c', 'clone --template="white space"'
|
128
|
+
input = "c rtomayko/ronn"
|
129
|
+
command = "git clone '--template=white space' git://github.com/rtomayko/ronn.git"
|
130
|
+
assert_command input, command
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_alias_doesnt_expand_for_unknown_commands
|
134
|
+
stub_alias 'c', 'compute --fast'
|
135
|
+
assert_forwarded "c rtomayko/ronn"
|
136
|
+
end
|
137
|
+
|
121
138
|
def test_remote_origin
|
122
139
|
input = "remote add origin"
|
123
140
|
command = "git remote add origin git://github.com/tpw/hub.git"
|
@@ -137,21 +154,15 @@ class HubTest < Test::Unit::TestCase
|
|
137
154
|
end
|
138
155
|
|
139
156
|
def test_remote_from_rel_path
|
140
|
-
|
141
|
-
command = "git remote add origin ./path"
|
142
|
-
assert_command input, command
|
157
|
+
assert_forwarded "remote add origin ./path"
|
143
158
|
end
|
144
159
|
|
145
160
|
def test_remote_from_abs_path
|
146
|
-
|
147
|
-
command = "git remote add origin /path"
|
148
|
-
assert_command input, command
|
161
|
+
assert_forwarded "remote add origin /path"
|
149
162
|
end
|
150
163
|
|
151
164
|
def test_private_remote_origin_as_normal
|
152
|
-
|
153
|
-
command = "git remote add origin git@github.com:defunkt/resque.git"
|
154
|
-
assert_command input, command
|
165
|
+
assert_forwarded "remote add origin git@github.com:defunkt/resque.git"
|
155
166
|
end
|
156
167
|
|
157
168
|
def test_public_submodule
|
@@ -233,7 +244,7 @@ class HubTest < Test::Unit::TestCase
|
|
233
244
|
end
|
234
245
|
|
235
246
|
def test_fetch_existing_remote
|
236
|
-
|
247
|
+
assert_forwarded "fetch mislav"
|
237
248
|
end
|
238
249
|
|
239
250
|
def test_fetch_new_remote
|
@@ -362,6 +373,16 @@ class HubTest < Test::Unit::TestCase
|
|
362
373
|
end
|
363
374
|
end
|
364
375
|
|
376
|
+
def test_am_gist
|
377
|
+
with_tmpdir('/tmp/') do
|
378
|
+
url = 'https://gist.github.com/8da7fb575debd88c54cf'
|
379
|
+
|
380
|
+
assert_commands "curl -#LA 'hub #{Hub::Version}' #{url}.txt -o /tmp/gist-8da7fb575debd88c54cf.txt",
|
381
|
+
"git am --signoff /tmp/gist-8da7fb575debd88c54cf.txt -p2",
|
382
|
+
"am --signoff #{url} -p2"
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
365
386
|
def test_init
|
366
387
|
assert_commands "git init", "git remote add origin git@github.com:tpw/hub.git", "init -g"
|
367
388
|
end
|
@@ -397,6 +418,16 @@ class HubTest < Test::Unit::TestCase
|
|
397
418
|
assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
|
398
419
|
end
|
399
420
|
|
421
|
+
def test_create_failed
|
422
|
+
stub_no_remotes
|
423
|
+
stub_nonexisting_fork('tpw')
|
424
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/create").
|
425
|
+
to_return(:status => [401, "Your token is fail"])
|
426
|
+
|
427
|
+
expected = "error creating repository: Your token is fail (HTTP 401)\n"
|
428
|
+
assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
|
429
|
+
end
|
430
|
+
|
400
431
|
def test_create_with_env_authentication
|
401
432
|
stub_no_remotes
|
402
433
|
stub_nonexisting_fork('mojombo')
|
@@ -484,6 +515,15 @@ class HubTest < Test::Unit::TestCase
|
|
484
515
|
assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
|
485
516
|
end
|
486
517
|
|
518
|
+
def test_fork_failed
|
519
|
+
stub_nonexisting_fork('tpw')
|
520
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/fork/defunkt/hub").
|
521
|
+
to_return(:status => [500, "Your fork is fail"])
|
522
|
+
|
523
|
+
expected = "error creating fork: Your fork is fail (HTTP 500)\n"
|
524
|
+
assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
|
525
|
+
end
|
526
|
+
|
487
527
|
def test_fork_no_remote
|
488
528
|
stub_nonexisting_fork('tpw')
|
489
529
|
stub_request(:post, "github.com/api/v2/yaml/repos/fork/defunkt/hub")
|
@@ -579,6 +619,12 @@ config
|
|
579
619
|
"open https://github.com/defunkt/hub/compare/1.0...fix"
|
580
620
|
end
|
581
621
|
|
622
|
+
def test_hub_compare_on_wiki
|
623
|
+
stub_repo_url 'git://github.com/defunkt/hub.wiki.git'
|
624
|
+
assert_command "compare 1.0...fix",
|
625
|
+
"open https://github.com/defunkt/hub/wiki/_compare/1.0...fix"
|
626
|
+
end
|
627
|
+
|
582
628
|
def test_hub_compare_fork
|
583
629
|
assert_command "compare myfork feature",
|
584
630
|
"open https://github.com/myfork/hub/compare/feature"
|
@@ -635,6 +681,15 @@ config
|
|
635
681
|
assert_command "browse --", "open https://github.com/defunkt/hub"
|
636
682
|
end
|
637
683
|
|
684
|
+
def test_hub_browse_current_wiki
|
685
|
+
stub_repo_url 'git://github.com/defunkt/hub.wiki.git'
|
686
|
+
|
687
|
+
assert_command "browse", "open https://github.com/defunkt/hub/wiki"
|
688
|
+
assert_command "browse -- wiki", "open https://github.com/defunkt/hub/wiki"
|
689
|
+
assert_command "browse -- commits", "open https://github.com/defunkt/hub/wiki/_history"
|
690
|
+
assert_command "browse -- pages", "open https://github.com/defunkt/hub/wiki/_pages"
|
691
|
+
end
|
692
|
+
|
638
693
|
def test_hub_browse_current_subpage
|
639
694
|
assert_command "browse -- network",
|
640
695
|
"open https://github.com/defunkt/hub/network"
|
@@ -688,7 +743,7 @@ config
|
|
688
743
|
end
|
689
744
|
|
690
745
|
def test_context_method_doesnt_hijack_git_command
|
691
|
-
|
746
|
+
assert_forwarded 'remotes'
|
692
747
|
end
|
693
748
|
|
694
749
|
def test_not_choking_on_ruby_methods
|
@@ -737,6 +792,10 @@ config
|
|
737
792
|
@git.replace({})
|
738
793
|
end
|
739
794
|
|
795
|
+
def stub_alias(name, value)
|
796
|
+
@git["config alias.#{name}"] = value
|
797
|
+
end
|
798
|
+
|
740
799
|
def stub_existing_fork(user)
|
741
800
|
stub_fork(user, 200)
|
742
801
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-hub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 1
|
5
|
+
prerelease:
|
5
6
|
segments:
|
6
7
|
- 1
|
7
8
|
- 5
|
8
|
-
-
|
9
|
-
version: 1.5.
|
9
|
+
- 1
|
10
|
+
version: 1.5.1
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Chris Wanstrath
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date:
|
18
|
+
date: 2011-03-18 00:00:00 +01:00
|
18
19
|
default_executable:
|
19
20
|
dependencies: []
|
20
21
|
|
@@ -52,9 +53,26 @@ has_rdoc: true
|
|
52
53
|
homepage: http://github.com/defunkt/hub
|
53
54
|
licenses: []
|
54
55
|
|
55
|
-
post_install_message:
|
56
|
-
|
57
|
-
|
56
|
+
post_install_message: |+
|
57
|
+
|
58
|
+
------------------------------------------------------------
|
59
|
+
|
60
|
+
You there! Wait, I say!
|
61
|
+
=======================
|
62
|
+
|
63
|
+
If you are a heavy user of `git` on the command
|
64
|
+
line you may want to install `hub` the old
|
65
|
+
fashioned way. Faster startup time, you see.
|
66
|
+
|
67
|
+
Check out the installation instructions at
|
68
|
+
http://github.com/defunkt/hub#readme under the
|
69
|
+
"Standalone" section.
|
70
|
+
|
71
|
+
Cheers,
|
72
|
+
defunkt
|
73
|
+
|
74
|
+
------------------------------------------------------------
|
75
|
+
|
58
76
|
rdoc_options: []
|
59
77
|
|
60
78
|
require_paths:
|
@@ -64,6 +82,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
64
82
|
requirements:
|
65
83
|
- - ">="
|
66
84
|
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
67
86
|
segments:
|
68
87
|
- 0
|
69
88
|
version: "0"
|
@@ -72,13 +91,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
91
|
requirements:
|
73
92
|
- - ">="
|
74
93
|
- !ruby/object:Gem::Version
|
94
|
+
hash: 3
|
75
95
|
segments:
|
76
96
|
- 0
|
77
97
|
version: "0"
|
78
98
|
requirements: []
|
79
99
|
|
80
100
|
rubyforge_project:
|
81
|
-
rubygems_version: 1.3
|
101
|
+
rubygems_version: 1.5.3
|
82
102
|
signing_key:
|
83
103
|
specification_version: 3
|
84
104
|
summary: hub introduces git to GitHub
|