hub 1.9.0 → 1.10.0

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/HISTORY.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## master
2
+
3
+ * fix GitHub username prompt in `create` command
4
+ * make `fetch` command work with private repos too
5
+ * add `merge` command to merge pull requests
6
+
7
+ ## 1.9.0 (2012-05-04)
8
+
9
+ * internal refactoring and code reorganization
10
+ * switch to GitHub API v3 and authenticate via OAuth
11
+ * auth info is now stored in ~/.config/hub instead of ~/.gitconfig
12
+
1
13
  ## 1.8.4 (2012-03-20)
2
14
 
3
15
  * add bash, zsh completion
data/README.md CHANGED
@@ -206,11 +206,17 @@ superpowers:
206
206
 
207
207
  ### git checkout
208
208
 
209
- # $ git checkout https://github.com/defunkt/hub/pull/73
210
- # > git remote add -f -t feature git://github:com/mislav/hub.git
211
- # > git checkout --track -B mislav-feature mislav/feature
209
+ $ git checkout https://github.com/defunkt/hub/pull/73
210
+ > git remote add -f -t feature git://github:com/mislav/hub.git
211
+ > git checkout --track -B mislav-feature mislav/feature
212
212
 
213
- # $ git checkout https://github.com/defunkt/hub/pull/73 custom-branch-name
213
+ $ git checkout https://github.com/defunkt/hub/pull/73 custom-branch-name
214
+
215
+ ### git merge
216
+
217
+ $ git merge https://github.com/defunkt/hub/pull/73
218
+ > git fetch git://github.com/mislav/hub.git +refs/heads/feature:refs/remotes/mislav/feature
219
+ > git merge mislav/feature --no-ff -m 'Merge pull request #73 from mislav/feature...'
214
220
 
215
221
  ### git create
216
222
 
@@ -307,7 +313,7 @@ Configuration
307
313
  Hub will prompt for GitHub username & password the first time it needs to access
308
314
  the API and exchange it for an OAuth token, which it saves in "~/.config/hub".
309
315
 
310
- ### HTTPS insted of git protocol
316
+ ### HTTPS instead of git protocol
311
317
 
312
318
  If you prefer using the HTTPS protocol for GitHub repositories instead of the git
313
319
  protocol for read and ssh for write, you can set "hub.protocol" to "https".
data/lib/hub/commands.rb CHANGED
@@ -55,7 +55,7 @@ module Hub
55
55
  respect_help_flags(expanded_args || args) if custom_command? cmd
56
56
 
57
57
  # git commands can have dashes
58
- cmd = cmd.sub(/(\w)-/, '\1_')
58
+ cmd = cmd.gsub(/(\w)-/, '\1_')
59
59
  if method_defined?(cmd) and cmd != 'run'
60
60
  args.replace expanded_args if expanded_args
61
61
  send(cmd, args)
@@ -213,12 +213,10 @@ module Hub
213
213
  # $ hub clone rtomayko/tilt
214
214
  # $ hub clone tilt
215
215
  if arg =~ NAME_WITH_OWNER_RE and !File.directory?(arg)
216
- # FIXME: this logic shouldn't be duplicated here!
217
216
  name, owner = arg, nil
218
217
  owner, name = name.split('/', 2) if name.index('/')
219
- host = ENV['GITHUB_HOST'] || 'github.com'
220
- project = Context::GithubProject.new(nil, owner || github_user(host), name, host)
221
- ssh ||= args[0] != 'submodule' && project.owner == github_user(host) || host != 'github.com'
218
+ project = github_project(name, owner || github_user)
219
+ ssh ||= args[0] != 'submodule' && project.owner == github_user(project.host) { }
222
220
  args[idx] = project.git_url(:private => ssh, :https => https_protocol?)
223
221
  end
224
222
  break
@@ -321,7 +319,11 @@ module Hub
321
319
  projects = names.map { |name|
322
320
  unless name =~ /\W/ or remotes.include?(name) or remotes_group(name)
323
321
  project = github_project(nil, name)
324
- project if api_client.repo_exists?(project)
322
+ repo_info = api_client.repo_info(project)
323
+ if repo_info.success?
324
+ project.repo_data = repo_info.data
325
+ project
326
+ end
325
327
  end
326
328
  }.compact
327
329
 
@@ -360,6 +362,31 @@ module Hub
360
362
  end
361
363
  end
362
364
 
365
+ # $ git merge https://github.com/defunkt/hub/pull/73
366
+ # > git fetch git://github.com/mislav/hub.git +refs/heads/feature:refs/remotes/mislav/feature
367
+ # > git merge mislav/feature --no-ff -m 'Merge pull request #73 from mislav/feature...'
368
+ def merge(args)
369
+ _, url_arg = args.words
370
+ if url = resolve_github_url(url_arg) and url.project_path =~ /^pull\/(\d+)/
371
+ pull_id = $1
372
+ pull_data = api_client.pullrequest_info(url.project, pull_id)
373
+
374
+ user, branch = pull_data['head']['label'].split(':', 2)
375
+ abort "Error: #{user}'s fork is not available anymore" unless pull_data['head']['repo']
376
+
377
+ url = github_project(url.project_name, user).git_url(:private => pull_data['head']['repo']['private'],
378
+ :https => https_protocol?)
379
+
380
+ merge_head = "#{user}/#{branch}"
381
+ args.before ['fetch', url, "+refs/heads/#{branch}:refs/remotes/#{merge_head}"]
382
+
383
+ idx = args.index url_arg
384
+ args.delete_at idx
385
+ args.insert idx, merge_head, '--no-ff', '-m',
386
+ "Merge pull request ##{pull_id} from #{merge_head}\n\n#{pull_data['title']}"
387
+ end
388
+ end
389
+
363
390
  # $ git cherry-pick http://github.com/mislav/hub/commit/a319d88#comments
364
391
  # > git remote add -f mislav git://github.com/mislav/hub.git
365
392
  # > git cherry-pick a319d88
@@ -423,10 +450,7 @@ module Hub
423
450
  # > git remote add origin git@github.com:USER/REPO.git
424
451
  def init(args)
425
452
  if args.delete('-g')
426
- # can't use default_host because there is no local_repo yet
427
- # FIXME: this shouldn't be here!
428
- host = ENV['GITHUB_HOST'] || 'github.com'
429
- project = Context::GithubProject.new(nil, github_user(host), File.basename(current_dir), host)
453
+ project = github_project(File.basename(current_dir))
430
454
  url = project.git_url(:private => true, :https => https_protocol?)
431
455
  args.after ['remote', 'add', 'origin', url]
432
456
  end
@@ -466,7 +490,8 @@ module Hub
466
490
  def create(args)
467
491
  if !is_repo?
468
492
  abort "'create' must be run from inside a git repository"
469
- elsif owner = github_user
493
+ else
494
+ owner = github_user
470
495
  args.shift
471
496
  options = {}
472
497
  options[:private] = true if args.delete('-p')
@@ -702,10 +727,9 @@ module Hub
702
727
  end
703
728
  end
704
729
 
705
- def github_user host = nil
706
- host ||= local_repo(false) && local_repo.main_host
707
- return nil if host.nil?
708
- api_client.config.username(host) { }
730
+ def github_user host = nil, &block
731
+ host ||= (local_repo(false) || Context::LocalRepo).default_host
732
+ api_client.config.username(host, &block)
709
733
  end
710
734
 
711
735
  def custom_command? cmd
@@ -768,12 +792,19 @@ Remote Commands:
768
792
  push Upload data, tags and branches to a remote repository
769
793
  remote View and manage a set of remote repositories
770
794
 
771
- Advanced commands:
795
+ Advanced Commands:
772
796
  reset Reset your staging area or working directory to another point
773
797
  rebase Re-apply a series of patches in one branch onto another
774
798
  bisect Find by binary search the change that introduced a bug
775
799
  grep Print files with lines matching a pattern in your codebase
776
800
 
801
+ GitHub Commands:
802
+ pull-request Open a pull request on GitHub
803
+ fork Make a fork of a remote repository on GitHub and add as remote
804
+ create Create this repository on GitHub and add GitHub as origin
805
+ browse Open a GitHub page in the default browser
806
+ compare Open a compare page on GitHub
807
+
777
808
  See 'git help <command>' for more information on a specific command.
778
809
  help
779
810
  end
@@ -944,7 +975,7 @@ help
944
975
  title.tr!("\n", ' ')
945
976
  title.strip!
946
977
  body.strip!
947
-
978
+
948
979
  [title =~ /\S/ ? title : nil, body =~ /\S/ ? body : nil]
949
980
  end
950
981
 
data/lib/hub/context.rb CHANGED
@@ -179,14 +179,17 @@ module Hub
179
179
  git_config('hub.host', :all).to_s.split("\n") + [default_host]
180
180
  end
181
181
 
182
- def default_host
182
+ def self.default_host
183
183
  ENV['GITHUB_HOST'] || main_host
184
184
  end
185
185
 
186
- def main_host
186
+ def self.main_host
187
187
  'github.com'
188
188
  end
189
189
 
190
+ extend Forwardable
191
+ def_delegators :'self.class', :default_host, :main_host
192
+
190
193
  def ssh_config
191
194
  @ssh_config ||= SshConfig.new
192
195
  end
@@ -200,13 +203,16 @@ module Hub
200
203
  end
201
204
  end
202
205
 
206
+ attr_accessor :repo_data
207
+
203
208
  def initialize(*args)
204
209
  super
205
- self.host ||= local_repo.default_host
210
+ self.host ||= (local_repo || LocalRepo).default_host
206
211
  end
207
212
 
208
213
  def private?
209
- local_repo and host != local_repo.main_host
214
+ repo_data ? repo_data.fetch('private') :
215
+ host != (local_repo || LocalRepo).main_host
210
216
  end
211
217
 
212
218
  def owned_by(new_owner)
@@ -357,7 +363,7 @@ module Hub
357
363
  project.name = name
358
364
  project
359
365
  else
360
- GithubProject.new(local_repo, owner, name)
366
+ GithubProject.new(local_repo(false), owner, name)
361
367
  end
362
368
  end
363
369
 
@@ -46,11 +46,15 @@ module Hub
46
46
  'github.com' == host ? 'api.github.com' : host
47
47
  end
48
48
 
49
- # Public: Determine whether a specific repo already exists.
50
- def repo_exists? project
51
- res = get "https://%s/repos/%s/%s" %
49
+ # Public: Fetch data for a specific repo.
50
+ def repo_info project
51
+ get "https://%s/repos/%s/%s" %
52
52
  [api_host(project.host), project.owner, project.name]
53
- res.success?
53
+ end
54
+
55
+ # Public: Determine whether a specific repo exists.
56
+ def repo_exists? project
57
+ repo_info(project).success?
54
58
  end
55
59
 
56
60
  # Public: Fork the specified repo.
@@ -147,11 +151,14 @@ module Hub
147
151
  end
148
152
 
149
153
  def perform_request url, type
150
- url = URI.parse url unless url.respond_to? :hostname
154
+ url = URI.parse url unless url.respond_to? :host
151
155
 
152
156
  require 'net/https'
153
157
  req = Net::HTTP.const_get(type).new(url.request_uri)
154
- http = create_connection(url)
158
+ # TODO: better naming?
159
+ http = configure_connection(req, url) do |host_url|
160
+ create_connection host_url
161
+ end
155
162
 
156
163
  apply_authentication(req, url)
157
164
  yield req if block_given?
@@ -162,6 +169,17 @@ module Hub
162
169
  raise Context::FatalError, "error with #{type.to_s.upcase} #{url} (#{err.message})"
163
170
  end
164
171
 
172
+ def configure_connection req, url
173
+ if ENV['HUB_TEST_HOST']
174
+ req['Host'] = url.host
175
+ url = url.dup
176
+ url.scheme = 'http'
177
+ url.host, test_port = ENV['HUB_TEST_HOST'].split(':')
178
+ url.port = test_port.to_i if test_port
179
+ end
180
+ yield url
181
+ end
182
+
165
183
  def apply_authentication req, url
166
184
  user = url.user || config.username(url.host)
167
185
  pass = config.password(url.host, user)
@@ -325,9 +343,14 @@ module Hub
325
343
  # special prompt that has hidden input
326
344
  def prompt_password host, user
327
345
  print "#{host} password for #{user} (never stored): "
328
- password = askpass
329
- puts ''
330
- password
346
+ if $stdin.tty?
347
+ password = askpass
348
+ puts ''
349
+ password
350
+ else
351
+ # in testing
352
+ $stdin.gets.chomp
353
+ end
331
354
  end
332
355
 
333
356
  # FIXME: probably not cross-platform
@@ -349,7 +372,7 @@ module Hub
349
372
 
350
373
  def proxy_uri(with_ssl)
351
374
  env_name = "HTTP#{with_ssl ? 'S' : ''}_PROXY"
352
- if proxy = ENV[env_name] || ENV[env_name.downcase]
375
+ if proxy = ENV[env_name] || ENV[env_name.downcase] and !proxy.empty?
353
376
  proxy = "http://#{proxy}" unless proxy.include? '://'
354
377
  URI.parse proxy
355
378
  end
data/lib/hub/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Hub
2
- Version = VERSION = '1.9.0'
2
+ Version = VERSION = '1.10.0'
3
3
  end
data/man/hub.1 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "HUB" "1" "April 2012" "DEFUNKT" "Git Manual"
4
+ .TH "HUB" "1" "May 2012" "DEFUNKT" "Git Manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBhub\fR \- git + hub = github
@@ -31,6 +31,9 @@
31
31
  \fBgit checkout\fR \fIPULLREQ\-URL\fR [\fIBRANCH\fR]
32
32
  .
33
33
  .br
34
+ \fBgit merge\fR \fIPULLREQ\-URL\fR
35
+ .
36
+ .br
34
37
  \fBgit cherry\-pick\fR \fIGITHUB\-REF\fR
35
38
  .
36
39
  .br
@@ -96,6 +99,10 @@ Adds missing remote(s) with \fBgit remote add\fR prior to fetching\. New remotes
96
99
  Checks out the head of the pull request as a local branch, to allow for reviewing, rebasing and otherwise cleaning up the commits in the pull request before merging\. The name of the local branch can explicitly be set with \fIBRANCH\fR\.
97
100
  .
98
101
  .TP
102
+ \fBgit merge\fR \fIPULLREQ\-URL\fR
103
+ Merge the pull request with a commit message that includes the pull request ID and title, similar to the GitHub Merge Button\.
104
+ .
105
+ .TP
99
106
  \fBgit cherry\-pick\fR \fIGITHUB\-REF\fR
100
107
  Cherry\-pick a commit from a fork using either full URL to the commit or GitHub\-flavored Markdown notation, which is \fBuser@sha\fR\. If the remote doesn\'t yet exist, it will be added\. A \fBgit fetch <user>\fR is issued prior to the cherry\-pick attempt\.
101
108
  .
@@ -300,11 +307,21 @@ $ git pull\-request \-i 123
300
307
  .
301
308
  .nf
302
309
 
303
- # $ git checkout https://github\.com/defunkt/hub/pull/73
304
- # > git remote add \-f \-t feature git://github:com/mislav/hub\.git
305
- # > git checkout \-\-track \-B mislav\-feature mislav/feature
310
+ $ git checkout https://github\.com/defunkt/hub/pull/73
311
+ > git remote add \-f \-t feature git://github:com/mislav/hub\.git
312
+ > git checkout \-\-track \-B mislav\-feature mislav/feature
313
+
314
+ $ git checkout https://github\.com/defunkt/hub/pull/73 custom\-branch\-name
315
+ .
316
+ .fi
317
+ .
318
+ .SS "git merge"
319
+ .
320
+ .nf
306
321
 
307
- # $ git checkout https://github\.com/defunkt/hub/pull/73 custom\-branch\-name
322
+ $ git merge https://github\.com/defunkt/hub/pull/73
323
+ > git fetch git://github\.com/mislav/hub\.git +refs/heads/feature:refs/remotes/mislav/feature
324
+ > git merge mislav/feature \-\-no\-ff \-m \'Merge pull request #73 from mislav/feature\.\.\.\'
308
325
  .
309
326
  .fi
310
327
  .
data/man/hub.1.html CHANGED
@@ -87,6 +87,7 @@
87
87
  <code>git remote set-url</code> [<code>-p</code>] <var>OPTIONS</var> <var>REMOTE-NAME</var> <var>USER</var>[/<var>REPOSITORY</var>]<br />
88
88
  <code>git fetch</code> <var>USER-1</var>,[<var>USER-2</var>,...]<br />
89
89
  <code>git checkout</code> <var>PULLREQ-URL</var> [<var>BRANCH</var>]<br />
90
+ <code>git merge</code> <var>PULLREQ-URL</var><br />
90
91
  <code>git cherry-pick</code> <var>GITHUB-REF</var><br />
91
92
  <code>git am</code> <var>GITHUB-URL</var><br />
92
93
  <code>git apply</code> <var>GITHUB-URL</var><br />
@@ -131,6 +132,8 @@ remotes are only added if they correspond to valid forks on GitHub.</p></dd>
131
132
  reviewing, rebasing and otherwise cleaning up the commits in the pull
132
133
  request before merging. The name of the local branch can explicitly be
133
134
  set with <var>BRANCH</var>.</p></dd>
135
+ <dt><code>git merge</code> <var>PULLREQ-URL</var></dt><dd><p>Merge the pull request with a commit message that includes the pull request
136
+ ID and title, similar to the GitHub Merge Button.</p></dd>
134
137
  <dt><code>git cherry-pick</code> <var>GITHUB-REF</var></dt><dd><p>Cherry-pick a commit from a fork using either full URL to the commit
135
138
  or GitHub-flavored Markdown notation, which is <code>user@sha</code>. If the remote
136
139
  doesn't yet exist, it will be added. A <code>git fetch &lt;user></code> is issued
@@ -311,11 +314,18 @@ $ git pull-request -i 123
311
314
 
312
315
  <h3 id="git-checkout">git checkout</h3>
313
316
 
314
- <pre><code># $ git checkout https://github.com/defunkt/hub/pull/73
315
- # &gt; git remote add -f -t feature git://github:com/mislav/hub.git
316
- # &gt; git checkout --track -B mislav-feature mislav/feature
317
+ <pre><code>$ git checkout https://github.com/defunkt/hub/pull/73
318
+ &gt; git remote add -f -t feature git://github:com/mislav/hub.git
319
+ &gt; git checkout --track -B mislav-feature mislav/feature
317
320
 
318
- # $ git checkout https://github.com/defunkt/hub/pull/73 custom-branch-name
321
+ $ git checkout https://github.com/defunkt/hub/pull/73 custom-branch-name
322
+ </code></pre>
323
+
324
+ <h3 id="git-merge">git merge</h3>
325
+
326
+ <pre><code>$ git merge https://github.com/defunkt/hub/pull/73
327
+ &gt; git fetch git://github.com/mislav/hub.git +refs/heads/feature:refs/remotes/mislav/feature
328
+ &gt; git merge mislav/feature --no-ff -m 'Merge pull request #73 from mislav/feature...'
319
329
  </code></pre>
320
330
 
321
331
  <h3 id="git-create">git create</h3>
@@ -427,7 +437,7 @@ $ git help hub
427
437
 
428
438
  <ol class='man-decor man-foot man foot'>
429
439
  <li class='tl'>DEFUNKT</li>
430
- <li class='tc'>April 2012</li>
440
+ <li class='tc'>May 2012</li>
431
441
  <li class='tr'>hub(1)</li>
432
442
  </ol>
433
443
 
data/man/hub.1.ronn CHANGED
@@ -14,6 +14,7 @@ hub(1) -- git + hub = github
14
14
  `git remote set-url` [`-p`] <OPTIONS> <REMOTE-NAME> <USER>[/<REPOSITORY>]
15
15
  `git fetch` <USER-1>,[<USER-2>,...]
16
16
  `git checkout` <PULLREQ-URL> [<BRANCH>]
17
+ `git merge` <PULLREQ-URL>
17
18
  `git cherry-pick` <GITHUB-REF>
18
19
  `git am` <GITHUB-URL>
19
20
  `git apply` <GITHUB-URL>
@@ -73,6 +74,10 @@ hub enhances various git commands to ease most common workflows with GitHub.
73
74
  request before merging. The name of the local branch can explicitly be
74
75
  set with <BRANCH>.
75
76
 
77
+ * `git merge` <PULLREQ-URL>:
78
+ Merge the pull request with a commit message that includes the pull request
79
+ ID and title, similar to the GitHub Merge Button.
80
+
76
81
  * `git cherry-pick` <GITHUB-REF>:
77
82
  Cherry-pick a commit from a fork using either full URL to the commit
78
83
  or GitHub-flavored Markdown notation, which is `user@sha`. If the remote
data/test/hub_test.rb CHANGED
@@ -82,79 +82,6 @@ class HubTest < Test::Unit::TestCase
82
82
  'rev-parse -q --git-dir' => '.git'
83
83
  end
84
84
 
85
- def test_fetch_existing_remote
86
- assert_forwarded "fetch mislav"
87
- end
88
-
89
- def test_fetch_new_remote
90
- stub_remotes_group('xoebus', nil)
91
- stub_existing_fork('xoebus')
92
-
93
- assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
94
- "git fetch xoebus",
95
- "fetch xoebus"
96
- end
97
-
98
- def test_fetch_new_remote_https_protocol
99
- stub_remotes_group('xoebus', nil)
100
- stub_existing_fork('xoebus')
101
- stub_https_is_preferred
102
-
103
- assert_commands "git remote add xoebus https://github.com/xoebus/hub.git",
104
- "git fetch xoebus",
105
- "fetch xoebus"
106
- end
107
-
108
- def test_fetch_new_remote_with_options
109
- stub_remotes_group('xoebus', nil)
110
- stub_existing_fork('xoebus')
111
-
112
- assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
113
- "git fetch --depth=1 --prune xoebus",
114
- "fetch --depth=1 --prune xoebus"
115
- end
116
-
117
- def test_fetch_multiple_new_remotes
118
- stub_remotes_group('xoebus', nil)
119
- stub_remotes_group('rtomayko', nil)
120
- stub_existing_fork('xoebus')
121
- stub_existing_fork('rtomayko')
122
-
123
- assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
124
- "git remote add rtomayko git://github.com/rtomayko/hub.git",
125
- "git fetch --multiple xoebus rtomayko",
126
- "fetch --multiple xoebus rtomayko"
127
- end
128
-
129
- def test_fetch_multiple_comma_separated_remotes
130
- stub_remotes_group('xoebus', nil)
131
- stub_remotes_group('rtomayko', nil)
132
- stub_existing_fork('xoebus')
133
- stub_existing_fork('rtomayko')
134
-
135
- assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
136
- "git remote add rtomayko git://github.com/rtomayko/hub.git",
137
- "git fetch --multiple xoebus rtomayko",
138
- "fetch xoebus,rtomayko"
139
- end
140
-
141
- def test_fetch_multiple_new_remotes_with_filtering
142
- stub_remotes_group('xoebus', nil)
143
- stub_remotes_group('mygrp', 'one two')
144
- stub_remotes_group('typo', nil)
145
- stub_existing_fork('xoebus')
146
- stub_nonexisting_fork('typo')
147
-
148
- # mislav: existing remote; skipped
149
- # xoebus: new remote, fork exists; added
150
- # mygrp: a remotes group; skipped
151
- # URL: can't be a username; skipped
152
- # typo: fork doesn't exist; skipped
153
- assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
154
- "git fetch --multiple mislav xoebus mygrp git://example.com typo",
155
- "fetch --multiple mislav xoebus mygrp git://example.com typo"
156
- end
157
-
158
85
  def test_cherry_pick
159
86
  assert_forwarded "cherry-pick a319d88"
160
87
  end
@@ -317,192 +244,6 @@ class HubTest < Test::Unit::TestCase
317
244
  "push origin,staging,qa cool-feature"
318
245
  end
319
246
 
320
- def test_create
321
- stub_no_remotes
322
- stub_nonexisting_fork('tpw')
323
- stub_request(:post, "https://api.github.com/user/repos").
324
- with(:body => { 'name' => 'hub', 'private' => false })
325
-
326
- expected = "remote add -f origin git@github.com:tpw/hub.git\n"
327
- expected << "created repository: tpw/hub\n"
328
- assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
329
- end
330
-
331
- def test_create_custom_name
332
- stub_no_remotes
333
- stub_nonexisting_fork('tpw', 'hubbub')
334
- stub_request(:post, "https://api.github.com/user/repos").
335
- with(:body => { 'name' => 'hubbub', 'private' => false })
336
-
337
- expected = "remote add -f origin git@github.com:tpw/hubbub.git\n"
338
- expected << "created repository: tpw/hubbub\n"
339
- assert_equal expected, hub("create hubbub") { ENV['GIT'] = 'echo' }
340
- end
341
-
342
- def test_create_in_organization
343
- stub_no_remotes
344
- stub_nonexisting_fork('acme', 'hubbub')
345
- stub_request(:post, "https://api.github.com/orgs/acme/repos").
346
- with(:body => { 'name' => 'hubbub', 'private' => false })
347
-
348
- expected = "remote add -f origin git@github.com:acme/hubbub.git\n"
349
- expected << "created repository: acme/hubbub\n"
350
- assert_equal expected, hub("create acme/hubbub") { ENV['GIT'] = 'echo' }
351
- end
352
-
353
- def test_create_failed
354
- stub_no_remotes
355
- stub_nonexisting_fork('tpw')
356
- stub_request(:post, "https://api.github.com/user/repos").
357
- to_return(:status => [401, "Your token is fail"])
358
-
359
- expected = "Error creating repository: Your token is fail (HTTP 401)\n"
360
- assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
361
- end
362
-
363
- def test_create_private_repository
364
- stub_no_remotes
365
- stub_nonexisting_fork('tpw')
366
- stub_request(:post, "https://api.github.com/user/repos").
367
- with(:body => { 'name' => 'hub', 'private' => true })
368
-
369
- expected = "remote add -f origin git@github.com:tpw/hub.git\n"
370
- expected << "created repository: tpw/hub\n"
371
- assert_equal expected, hub("create -p") { ENV['GIT'] = 'echo' }
372
- end
373
-
374
- def test_create_private_repository_fails
375
- stub_no_remotes
376
- stub_nonexisting_fork('tpw')
377
- stub_request(:post, "https://api.github.com/user/repos").
378
- to_return(:status => [422, "Unprocessable Entity"],
379
- :headers => {"Content-type" => "application/json"},
380
- :body => %({"message":"repository creation failed: You are over your quota."}))
381
-
382
- expected = "Error creating repository: Unprocessable Entity (HTTP 422)\n"
383
- expected << "repository creation failed: You are over your quota.\n"
384
- assert_equal expected, hub("create -p") { ENV['GIT'] = 'echo' }
385
- end
386
-
387
- def test_create_with_description_and_homepage
388
- stub_no_remotes
389
- stub_nonexisting_fork('tpw')
390
- stub_request(:post, "https://api.github.com/user/repos").with(:body => {
391
- 'name' => 'hub', 'private' => false,
392
- 'description' => 'toyproject', 'homepage' => 'http://example.com'
393
- })
394
-
395
- expected = "remote add -f origin git@github.com:tpw/hub.git\n"
396
- expected << "created repository: tpw/hub\n"
397
- assert_equal expected, hub("create -d toyproject -h http://example.com") { ENV['GIT'] = 'echo' }
398
- end
399
-
400
- def test_create_with_invalid_arguments
401
- assert_equal "invalid argument: -a\n", hub("create -a blah") { ENV['GIT'] = 'echo' }
402
- assert_equal "invalid argument: bleh\n", hub("create blah bleh") { ENV['GIT'] = 'echo' }
403
- end
404
-
405
- def test_create_with_existing_repository
406
- stub_no_remotes
407
- stub_existing_fork('tpw')
408
-
409
- expected = "tpw/hub already exists on github.com\n"
410
- expected << "remote add -f origin git@github.com:tpw/hub.git\n"
411
- expected << "set remote origin: tpw/hub\n"
412
- assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
413
- end
414
-
415
- def test_create_https_protocol
416
- stub_no_remotes
417
- stub_existing_fork('tpw')
418
- stub_https_is_preferred
419
-
420
- expected = "tpw/hub already exists on github.com\n"
421
- expected << "remote add -f origin https://github.com/tpw/hub.git\n"
422
- expected << "set remote origin: tpw/hub\n"
423
- assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
424
- end
425
-
426
- def test_create_outside_git_repo
427
- stub_no_git_repo
428
- assert_equal "'create' must be run from inside a git repository\n", hub("create")
429
- end
430
-
431
- def test_create_origin_already_exists
432
- stub_nonexisting_fork('tpw')
433
- stub_request(:post, "https://api.github.com/user/repos").
434
- with(:body => { 'name' => 'hub', 'private' => false })
435
-
436
- expected = "remote -v\ncreated repository: tpw/hub\n"
437
- assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
438
- end
439
-
440
- def test_fork
441
- stub_nonexisting_fork('tpw')
442
- stub_request(:post, "https://api.github.com/repos/defunkt/hub/forks").
443
- with { |req| req.headers['Content-Length'] == 0 }
444
-
445
- expected = "remote add -f tpw git@github.com:tpw/hub.git\n"
446
- expected << "new remote: tpw\n"
447
- assert_output expected, "fork"
448
- end
449
-
450
- def test_fork_https_protocol
451
- stub_https_is_preferred
452
- stub_nonexisting_fork('tpw')
453
- stub_request(:post, "https://api.github.com/repos/defunkt/hub/forks")
454
-
455
- expected = "remote add -f tpw https://github.com/tpw/hub.git\n"
456
- expected << "new remote: tpw\n"
457
- assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
458
- end
459
-
460
- def test_fork_not_in_repo
461
- stub_no_git_repo
462
- expected = "fatal: Not a git repository\n"
463
- assert_output expected, "fork"
464
- end
465
-
466
- def test_fork_enterprise
467
- stub_hub_host('git.my.org')
468
- stub_repo_url('git@git.my.org:defunkt/hub.git')
469
- edit_hub_config do |data|
470
- data['git.my.org'] = [{'user'=>'myfiname', 'oauth_token' => 'FITOKEN'}]
471
- end
472
-
473
- stub_request(:get, "https://git.my.org/repos/myfiname/hub").
474
- to_return(:status => 404)
475
- stub_request(:post, "https://git.my.org/repos/defunkt/hub/forks").
476
- with(:headers => {"Authorization" => "token FITOKEN"})
477
-
478
- expected = "remote add -f myfiname git@git.my.org:myfiname/hub.git\n"
479
- expected << "new remote: myfiname\n"
480
- assert_output expected, "fork"
481
- end
482
-
483
- def test_fork_failed
484
- stub_nonexisting_fork('tpw')
485
- stub_request(:post, "https://api.github.com/repos/defunkt/hub/forks").
486
- to_return(:status => [500, "Your fork is fail"])
487
-
488
- expected = "Error creating fork: Your fork is fail (HTTP 500)\n"
489
- assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
490
- end
491
-
492
- def test_fork_no_remote
493
- stub_nonexisting_fork('tpw')
494
- stub_request(:post, "https://api.github.com/repos/defunkt/hub/forks")
495
-
496
- assert_equal "", hub("fork --no-remote") { ENV['GIT'] = 'echo' }
497
- end
498
-
499
- def test_fork_already_exists
500
- stub_existing_fork('tpw')
501
-
502
- expected = "Error creating fork: tpw/hub already exists on github.com\n"
503
- assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
504
- end
505
-
506
247
  def test_pullrequest
507
248
  expected = "Aborted: head branch is the same as base (\"master\")\n" <<
508
249
  "(use `-h <branch>` to specify an explicit pull request head)\n"
@@ -743,7 +484,7 @@ class HubTest < Test::Unit::TestCase
743
484
  def test_help_hub
744
485
  help_manpage = hub("help hub")
745
486
  assert_includes "git + hub = github", help_manpage
746
- assert_includes "Hub will prompt for GitHub username & password", help_manpage
487
+ assert_includes "Hub will prompt for GitHub username & password", help_manpage.gsub(/ {2,}/, ' ')
747
488
  end
748
489
 
749
490
  def test_help_flag_on_command
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hub
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-05-04 00:00:00.000000000 Z
13
+ date: 2012-05-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
17
- requirement: &70352271416600 !ruby/object:Gem::Requirement
17
+ requirement: &70214831337220 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *70352271416600
25
+ version_requirements: *70214831337220
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: webmock
28
- requirement: &70352271431980 !ruby/object:Gem::Requirement
28
+ requirement: &70214831336720 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70352271431980
36
+ version_requirements: *70214831336720
37
37
  description: ! " `hub` is a command line utility which adds GitHub knowledge to `git`.\n\n
38
38
  \ It can used on its own or as a `git` wrapper.\n\n Normal:\n\n $ hub clone
39
39
  rtomayko/tilt\n\n Expands to:\n $ git clone git://github.com/rtomayko/tilt.git\n\n
@@ -63,7 +63,6 @@ files:
63
63
  - man/hub.1
64
64
  - man/hub.1.html
65
65
  - man/hub.1.ronn
66
- - test/alias_test.rb
67
66
  - test/deps.rip
68
67
  - test/fakebin/git
69
68
  - test/fakebin/open
data/test/alias_test.rb DELETED
@@ -1,59 +0,0 @@
1
- require 'helper'
2
-
3
- class AliasTest < Test::Unit::TestCase
4
- def test_alias_instructions
5
- expected = "# Wrap git automatically by adding the following to your profile:\n"
6
- expected << "\n"
7
- expected << 'eval "$(hub alias -s)"' << "\n"
8
- assert_equal expected, hub("alias sh")
9
- end
10
-
11
- def test_alias_instructions_bash
12
- with_shell('bash') do
13
- assert_includes '~/.bash_profile', hub("alias")
14
- end
15
- end
16
-
17
- def test_alias_instructions_zsh
18
- with_shell('zsh') do
19
- assert_includes '~/.zshrc', hub("alias")
20
- end
21
- end
22
-
23
- def test_alias_script_bash
24
- with_shell('bash') do
25
- assert_equal "alias git=hub\n", hub("alias -s")
26
- end
27
- end
28
-
29
- def test_alias_script_zsh
30
- with_shell('zsh') do
31
- script = hub("alias -s")
32
- assert_includes "alias git=hub\n", script
33
- assert_includes "compdef hub=git\n", script
34
- end
35
- end
36
-
37
- def test_unknown_shell
38
- with_shell(nil) do
39
- assert_equal "hub alias: unknown shell\n", hub("alias -s")
40
- end
41
- end
42
-
43
- def test_unsupported_shell
44
- with_shell('foosh') do
45
- expected = "hub alias: unsupported shell\n"
46
- expected << "supported shells: bash zsh sh ksh csh fish\n"
47
- assert_equal expected, hub("alias -s")
48
- end
49
- end
50
-
51
- private
52
-
53
- def with_shell(shell)
54
- old_shell, ENV['SHELL'] = ENV['SHELL'], shell
55
- yield
56
- ensure
57
- ENV['SHELL'] = old_shell
58
- end
59
- end