hub 1.11.0 → 1.11.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of hub might be problematic. Click here for more details.
- data/Rakefile +1 -1
- data/lib/hub/context.rb +72 -44
- data/lib/hub/runner.rb +1 -0
- data/lib/hub/ssh_config.rb +12 -57
- data/lib/hub/version.rb +1 -1
- metadata +5 -50
- data/bin/bench +0 -37
- data/script/cached-bundle +0 -46
- data/script/s3-put +0 -71
- data/script/test +0 -41
- data/script/test_each +0 -9
- data/test/context_test.rb +0 -79
- data/test/deps.rip +0 -1
- data/test/fakebin/git +0 -11
- data/test/fakebin/open +0 -3
- data/test/github_api_test.rb +0 -79
- data/test/helper.rb +0 -131
- data/test/hub_test.rb +0 -607
- data/test/standalone_test.rb +0 -57
data/Rakefile
CHANGED
@@ -173,7 +173,7 @@ task :homebrew do
|
|
173
173
|
sh "git checkout -q -B #{branch}"
|
174
174
|
sh "git commit -m 'hub v#{Hub::VERSION}' -- #{formula_file}"
|
175
175
|
sh "git push -u mislav #{branch}"
|
176
|
-
sh "hub pull-request 'upgrade hub to v#{Hub::VERSION}'"
|
176
|
+
sh "hub pull-request -m 'upgrade hub to v#{Hub::VERSION}'"
|
177
177
|
|
178
178
|
sh "git checkout -q master"
|
179
179
|
end
|
data/lib/hub/context.rb
CHANGED
@@ -18,7 +18,8 @@ module Hub
|
|
18
18
|
@executable = executable || 'git'
|
19
19
|
# caches output when shelling out to git
|
20
20
|
read_proc ||= lambda { |cache, cmd|
|
21
|
-
|
21
|
+
str = command_to_string(cmd)
|
22
|
+
result = silence_stderr { %x{#{str}}.chomp }
|
22
23
|
cache[cmd] = $?.success? && !result.empty? ? result : nil
|
23
24
|
}
|
24
25
|
@cache = Hash.new(&read_proc)
|
@@ -61,6 +62,14 @@ module Hub
|
|
61
62
|
full_cmd = to_exec(cmd)
|
62
63
|
full_cmd.respond_to?(:shelljoin) ? full_cmd.shelljoin : full_cmd.join(' ')
|
63
64
|
end
|
65
|
+
|
66
|
+
def silence_stderr
|
67
|
+
oldio = STDERR.dup
|
68
|
+
STDERR.reopen(NULL)
|
69
|
+
yield
|
70
|
+
ensure
|
71
|
+
STDERR.reopen(oldio)
|
72
|
+
end
|
64
73
|
end
|
65
74
|
|
66
75
|
module GitReaderMethods
|
@@ -88,17 +97,19 @@ module Hub
|
|
88
97
|
private :git_config, :git_command
|
89
98
|
|
90
99
|
def local_repo(fatal = true)
|
91
|
-
@local_repo
|
92
|
-
|
93
|
-
|
100
|
+
return nil if defined?(@local_repo) && @local_repo == false
|
101
|
+
@local_repo =
|
102
|
+
if git_dir = git_command('rev-parse -q --git-dir')
|
103
|
+
LocalRepo.new(git_reader, current_dir, git_dir)
|
94
104
|
elsif fatal
|
95
105
|
raise FatalError, "Not a git repository"
|
106
|
+
else
|
107
|
+
false
|
96
108
|
end
|
97
|
-
end
|
98
109
|
end
|
99
110
|
|
100
111
|
repo_methods = [
|
101
|
-
:current_branch,
|
112
|
+
:current_branch, :git_dir,
|
102
113
|
:remote_branch_and_project,
|
103
114
|
:repo_owner, :repo_host,
|
104
115
|
:remotes, :remotes_group, :origin_remote
|
@@ -116,7 +127,7 @@ module Hub
|
|
116
127
|
end
|
117
128
|
end
|
118
129
|
|
119
|
-
class LocalRepo < Struct.new(:git_reader, :dir)
|
130
|
+
class LocalRepo < Struct.new(:git_reader, :dir, :git_dir)
|
120
131
|
include GitReaderMethods
|
121
132
|
|
122
133
|
def name
|
@@ -151,28 +162,49 @@ module Hub
|
|
151
162
|
end
|
152
163
|
|
153
164
|
def current_branch
|
154
|
-
|
155
|
-
|
165
|
+
@current_branch ||= branch_at_ref('HEAD')
|
166
|
+
end
|
167
|
+
|
168
|
+
def branch_at_ref(*parts)
|
169
|
+
begin
|
170
|
+
head = file_read(*parts)
|
171
|
+
rescue Errno::ENOENT
|
172
|
+
return nil
|
173
|
+
else
|
174
|
+
Branch.new(self, head.rstrip) if head.sub!('ref: ', '')
|
156
175
|
end
|
157
176
|
end
|
158
177
|
|
178
|
+
def file_read(*parts)
|
179
|
+
File.read(File.join(git_dir, *parts))
|
180
|
+
end
|
181
|
+
|
182
|
+
def file_exist?(*parts)
|
183
|
+
File.exist?(File.join(git_dir, *parts))
|
184
|
+
end
|
185
|
+
|
159
186
|
def master_branch
|
160
187
|
if remote = origin_remote
|
161
|
-
default_branch =
|
188
|
+
default_branch = branch_at_ref("refs/remotes/#{remote}/HEAD")
|
162
189
|
end
|
163
|
-
Branch.new(self,
|
190
|
+
default_branch || Branch.new(self, 'refs/heads/master')
|
164
191
|
end
|
165
192
|
|
166
193
|
ORIGIN_NAMES = %w[ upstream github origin ]
|
167
194
|
|
168
195
|
def remotes
|
169
196
|
@remotes ||= begin
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
197
|
+
names = []
|
198
|
+
url_memo = Hash.new {|h,k| names << k; h[k]=[] }
|
199
|
+
git_command('remote -v').to_s.split("\n").map do |line|
|
200
|
+
next if line !~ /^(.+?)\t(.+) \(/
|
201
|
+
name, url = $1, $2
|
202
|
+
url_memo[name] << url
|
203
|
+
end
|
204
|
+
((ORIGIN_NAMES + names) & names).map do |name|
|
205
|
+
urls = url_memo[name].uniq
|
206
|
+
Remote.new(self, name, urls)
|
207
|
+
end
|
176
208
|
end
|
177
209
|
end
|
178
210
|
|
@@ -194,12 +226,10 @@ module Hub
|
|
194
226
|
remotes.find {|r| r.name == remote_name }
|
195
227
|
end
|
196
228
|
|
197
|
-
def
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
# https://help.github.com/articles/using-ssh-over-the-https-port
|
202
|
-
hosts << "ssh.#{default_host}"
|
229
|
+
def known_host?(host)
|
230
|
+
default = default_host
|
231
|
+
default == host || "ssh.#{default}" == host ||
|
232
|
+
git_config('hub.host', :all).to_s.split("\n").include?(host)
|
203
233
|
end
|
204
234
|
|
205
235
|
def self.default_host
|
@@ -220,7 +250,7 @@ module Hub
|
|
220
250
|
|
221
251
|
class GithubProject < Struct.new(:local_repo, :owner, :name, :host)
|
222
252
|
def self.from_url(url, local_repo)
|
223
|
-
if local_repo.
|
253
|
+
if local_repo.known_host?(url.host)
|
224
254
|
_, owner, name = url.path.split('/', 4)
|
225
255
|
GithubProject.new(local_repo, owner, name.sub(/\.git$/, ''), url.host)
|
226
256
|
end
|
@@ -335,7 +365,7 @@ module Hub
|
|
335
365
|
refs = local_repo.remotes_for_publish(owner_name).map { |remote|
|
336
366
|
"refs/remotes/#{remote}/#{short}"
|
337
367
|
}
|
338
|
-
if branch = refs.detect {|ref| local_repo.
|
368
|
+
if branch = refs.detect {|ref| local_repo.file_exist?(ref) }
|
339
369
|
Branch.new(local_repo, branch)
|
340
370
|
end
|
341
371
|
end
|
@@ -351,7 +381,7 @@ module Hub
|
|
351
381
|
end
|
352
382
|
end
|
353
383
|
|
354
|
-
class Remote < Struct.new(:local_repo, :name)
|
384
|
+
class Remote < Struct.new(:local_repo, :name, :raw_urls)
|
355
385
|
alias to_s name
|
356
386
|
|
357
387
|
def ==(other)
|
@@ -359,7 +389,7 @@ module Hub
|
|
359
389
|
end
|
360
390
|
|
361
391
|
def project
|
362
|
-
urls.
|
392
|
+
urls.each { |url|
|
363
393
|
if valid = GithubProject.from_url(url, local_repo)
|
364
394
|
return valid
|
365
395
|
end
|
@@ -368,27 +398,29 @@ module Hub
|
|
368
398
|
end
|
369
399
|
|
370
400
|
def urls
|
371
|
-
|
372
|
-
|
373
|
-
local_repo.git_command('remote -v').to_s.split("\n").map do |line|
|
374
|
-
next if line !~ /^(.+?)\t(.+) \((.+)\)$/
|
375
|
-
remote, uri, type = $1, $2, $3
|
376
|
-
next if remote != self.name
|
377
|
-
if uri =~ %r{^[\w-]+://} or uri =~ %r{^([^/]+?):}
|
378
|
-
uri = "ssh://#{$1}/#{$'}" if $1
|
401
|
+
@urls ||= raw_urls.map do |url|
|
402
|
+
with_normalized_url(url) do |normalized|
|
379
403
|
begin
|
380
|
-
|
404
|
+
uri_parse(normalized)
|
381
405
|
rescue URI::InvalidURIError
|
382
406
|
end
|
383
407
|
end
|
384
408
|
end
|
385
|
-
|
409
|
+
end
|
410
|
+
|
411
|
+
def with_normalized_url(url)
|
412
|
+
if url =~ %r{^[\w-]+://} || url =~ %r{^([^/]+?):}
|
413
|
+
url = "ssh://#{$1}/#{$'}" if $1
|
414
|
+
yield url
|
415
|
+
end
|
386
416
|
end
|
387
417
|
|
388
418
|
def uri_parse uri
|
389
419
|
uri = URI.parse uri
|
390
|
-
uri.host
|
391
|
-
|
420
|
+
if uri.host != local_repo.default_host
|
421
|
+
ssh = local_repo.ssh_config
|
422
|
+
uri.host = ssh.get_value(uri.host, :HostName) { uri.host }
|
423
|
+
end
|
392
424
|
uri
|
393
425
|
end
|
394
426
|
end
|
@@ -447,12 +479,8 @@ module Hub
|
|
447
479
|
PWD
|
448
480
|
end
|
449
481
|
|
450
|
-
def git_dir
|
451
|
-
git_command 'rev-parse -q --git-dir'
|
452
|
-
end
|
453
|
-
|
454
482
|
def is_repo?
|
455
|
-
!!
|
483
|
+
!!local_repo(false)
|
456
484
|
end
|
457
485
|
|
458
486
|
def git_editor
|
data/lib/hub/runner.rb
CHANGED
data/lib/hub/ssh_config.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
module Hub
|
2
|
-
# Reads
|
3
|
-
#
|
2
|
+
# Reads ssh_config(5) files and records "Host" to "HostName" mappings to
|
3
|
+
# provide resolving of ssh aliases.
|
4
4
|
class SshConfig
|
5
5
|
CONFIG_FILES = %w(~/.ssh/config /etc/ssh_config /etc/ssh/ssh_config)
|
6
|
+
CONFIG_RE = /^\s*(Host|HostName)\s+/
|
6
7
|
|
7
8
|
def initialize files = nil
|
8
9
|
@settings = Hash.new {|h,k| h[k] = {} }
|
@@ -15,67 +16,21 @@ module Hub
|
|
15
16
|
# Public: Get a setting as it would apply to a specific hostname.
|
16
17
|
#
|
17
18
|
# Yields if not found.
|
18
|
-
def get_value
|
19
|
-
|
20
|
-
@settings.
|
21
|
-
if pattern.match? hostname and found = settings[key]
|
22
|
-
return found
|
23
|
-
end
|
24
|
-
end
|
25
|
-
yield
|
26
|
-
end
|
27
|
-
|
28
|
-
class HostPattern
|
29
|
-
def initialize pattern
|
30
|
-
@pattern = pattern.to_s.downcase
|
31
|
-
end
|
32
|
-
|
33
|
-
def to_s() @pattern end
|
34
|
-
def ==(other) other.to_s == self.to_s end
|
35
|
-
|
36
|
-
def matcher
|
37
|
-
@matcher ||=
|
38
|
-
if '*' == @pattern
|
39
|
-
Proc.new { true }
|
40
|
-
elsif @pattern !~ /[?*]/
|
41
|
-
lambda { |hostname| hostname.to_s.downcase == @pattern }
|
42
|
-
else
|
43
|
-
re = self.class.pattern_to_regexp @pattern
|
44
|
-
lambda { |hostname| re =~ hostname }
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def match? hostname
|
49
|
-
matcher.call hostname
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.pattern_to_regexp pattern
|
53
|
-
escaped = Regexp.escape(pattern)
|
54
|
-
escaped.gsub!('\*', '.*')
|
55
|
-
escaped.gsub!('\?', '.')
|
56
|
-
/^#{escaped}$/i
|
57
|
-
end
|
19
|
+
def get_value(host, key, &fallback)
|
20
|
+
host = host.to_s.downcase
|
21
|
+
@settings[host].fetch(key.to_sym, &fallback)
|
58
22
|
end
|
59
23
|
|
60
24
|
def parse_file file
|
61
|
-
host_patterns = [
|
25
|
+
host_patterns = %w[*]
|
62
26
|
|
63
27
|
IO.foreach(file) do |line|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
key, value = $1, $'
|
68
|
-
else
|
69
|
-
key, value = line.strip.split(/\s+/, 2)
|
70
|
-
end
|
71
|
-
|
72
|
-
next if value.nil?
|
73
|
-
key.downcase!
|
74
|
-
value = $1 if value =~ /^"(.*)"$/
|
75
|
-
value.chomp!
|
28
|
+
next unless line =~ CONFIG_RE
|
29
|
+
key, value = $1.to_sym, $'.chomp
|
30
|
+
value.gsub!(/^"|"$/, '')
|
76
31
|
|
77
|
-
if
|
78
|
-
host_patterns = value.split(/\s+/)
|
32
|
+
if :Host == key
|
33
|
+
host_patterns = value.downcase.split(/\s+/)
|
79
34
|
else
|
80
35
|
record_setting key, value, host_patterns
|
81
36
|
end
|
data/lib/hub/version.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: hub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.11.
|
5
|
+
version: 1.11.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Chris Wanstrath
|
@@ -10,40 +10,8 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-12-
|
14
|
-
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
version_requirements: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - ! '>='
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '0'
|
21
|
-
none: false
|
22
|
-
name: rake
|
23
|
-
type: :development
|
24
|
-
prerelease: false
|
25
|
-
requirement: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
30
|
-
none: false
|
31
|
-
- !ruby/object:Gem::Dependency
|
32
|
-
version_requirements: !ruby/object:Gem::Requirement
|
33
|
-
requirements:
|
34
|
-
- - ! '>='
|
35
|
-
- !ruby/object:Gem::Version
|
36
|
-
version: '0'
|
37
|
-
none: false
|
38
|
-
name: webmock
|
39
|
-
type: :development
|
40
|
-
prerelease: false
|
41
|
-
requirement: !ruby/object:Gem::Requirement
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
46
|
-
none: false
|
13
|
+
date: 2013-12-26 00:00:00.000000000 Z
|
14
|
+
dependencies: []
|
47
15
|
description: ! " `hub` is a command line utility which adds GitHub knowledge to `git`.\n\n
|
48
16
|
\ It can used on its own or as a `git` wrapper.\n\n Normal:\n\n $ hub clone
|
49
17
|
rtomayko/tilt\n\n Expands to:\n $ git clone git://github.com/rtomayko/tilt.git\n\n
|
@@ -69,23 +37,10 @@ files:
|
|
69
37
|
- lib/hub/standalone.rb
|
70
38
|
- lib/hub/version.rb
|
71
39
|
- lib/hub.rb
|
72
|
-
- bin/bench
|
73
40
|
- bin/hub
|
74
41
|
- man/hub.1
|
75
42
|
- man/hub.1.html
|
76
43
|
- man/hub.1.ronn
|
77
|
-
- script/cached-bundle
|
78
|
-
- script/s3-put
|
79
|
-
- script/test
|
80
|
-
- script/test_each
|
81
|
-
- test/context_test.rb
|
82
|
-
- test/deps.rip
|
83
|
-
- test/fakebin/git
|
84
|
-
- test/fakebin/open
|
85
|
-
- test/github_api_test.rb
|
86
|
-
- test/helper.rb
|
87
|
-
- test/hub_test.rb
|
88
|
-
- test/standalone_test.rb
|
89
44
|
homepage: http://hub.github.com/
|
90
45
|
licenses:
|
91
46
|
- MIT
|
@@ -99,17 +54,17 @@ rdoc_options: []
|
|
99
54
|
require_paths:
|
100
55
|
- lib
|
101
56
|
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
102
58
|
requirements:
|
103
59
|
- - ! '>='
|
104
60
|
- !ruby/object:Gem::Version
|
105
61
|
version: '0'
|
106
|
-
none: false
|
107
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
108
64
|
requirements:
|
109
65
|
- - ! '>='
|
110
66
|
- !ruby/object:Gem::Version
|
111
67
|
version: '0'
|
112
|
-
none: false
|
113
68
|
requirements: []
|
114
69
|
rubyforge_project:
|
115
70
|
rubygems_version: 1.8.23
|
data/bin/bench
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
set -e
|
3
|
-
|
4
|
-
iterations=20
|
5
|
-
|
6
|
-
ruby="$(rbenv which ruby)"
|
7
|
-
ruby_args="--disable-gems"
|
8
|
-
|
9
|
-
unset RUBYLIB
|
10
|
-
unset RUBYOPT
|
11
|
-
|
12
|
-
export TIMEFORMAT='%3R'
|
13
|
-
|
14
|
-
time_ruby() {
|
15
|
-
(time "$ruby" $ruby_args "$@" >/dev/null) 2>&1
|
16
|
-
}
|
17
|
-
|
18
|
-
time_plain() {
|
19
|
-
(time "$@" >/dev/null) 2>&1
|
20
|
-
}
|
21
|
-
|
22
|
-
measure() {
|
23
|
-
local count="$iterations"
|
24
|
-
echo "$@"
|
25
|
-
{ while [ "$count" -gt 0 ]; do
|
26
|
-
# time_ruby "$@"
|
27
|
-
time_plain "$@"
|
28
|
-
count=$((count - 1))
|
29
|
-
done
|
30
|
-
} | stdev
|
31
|
-
}
|
32
|
-
|
33
|
-
/usr/bin/ruby -v
|
34
|
-
measure tmp/hub-slow version
|
35
|
-
measure tmp/hub-slow browse -u
|
36
|
-
measure tmp/hub-fast version
|
37
|
-
measure tmp/hub-fast browse -u
|