hub 1.10.6 → 1.11.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/man/hub.1.ronn CHANGED
@@ -25,9 +25,10 @@ hub(1) -- git + hub = github
25
25
 
26
26
  `git create` [<NAME>] [`-p`] [`-d` <DESCRIPTION>] [`-h` <HOMEPAGE>]
27
27
  `git browse` [`-u`] [[<USER>`/`]<REPOSITORY>] [SUBPAGE]
28
- `git compare` [`-u`] [<USER>] [<START>...]<END>
28
+ `git compare` [`-u`] [<USER>] [[<START>...]<END>]
29
29
  `git fork` [`--no-remote`]
30
- `git pull-request` [`-f`] [<TITLE>|`-i` <ISSUE>] [`-b` <BASE>] [`-h` <HEAD>]
30
+ `git pull-request` [`-f`] [`-m` <MESSAGE>|`-F` <FILE>|`-i` <ISSUE>|<ISSUE-URL>] [`-b` <BASE>] [`-h` <HEAD>]
31
+ `git ci-status` [`-v`] [<COMMIT>]
31
32
 
32
33
  ## DESCRIPTION
33
34
 
@@ -50,8 +51,12 @@ hub enhances various git commands to ease most common workflows with GitHub.
50
51
  * `git clone` [`-p`] <OPTIONS> [<USER>`/`]<REPOSITORY> <DIRECTORY>:
51
52
  Clone repository "git://github.com/<USER>/<REPOSITORY>.git" into
52
53
  <DIRECTORY> as with git-clone(1). When <USER>/ is omitted, assumes
53
- your GitHub login. With `-p`, clone private repositories over SSH.
54
- For repositories under your GitHub login, `-p` is implicit.
54
+ your GitHub login.
55
+
56
+ If the repository is private or the current user has push access to the
57
+ repository, hub will use the ssh protocol for cloning. Use `-p` to select
58
+ the ssh protocol unconditionally. HTTPS protocol can be used instead by
59
+ setting "hub.protocol" (see <CONFIGURATION>).
55
60
 
56
61
  * `git remote add` [`-p`] <OPTIONS> <USER>[`/`<REPOSITORY>]:
57
62
  Add remote "git://github.com/<USER>/<REPOSITORY>.git" as with
@@ -122,20 +127,22 @@ hub also adds some custom commands that are otherwise not present in git:
122
127
  specified, `browse` opens the page of the repository found in the current
123
128
  directory. If SUBPAGE is specified, the browser will open on the specified
124
129
  subpage: one of "wiki", "commits", "issues" or other (the default is
125
- "tree").
130
+ "tree"). With `-u`, outputs the URL rather than opening the browser.
126
131
 
127
- * `git compare` [`-u`] [<USER>] [<START>...]<END>:
132
+ * `git compare` [`-u`] [<USER>] [[<START>...]<END>]:
128
133
  Open a GitHub compare view page in the system's default web browser.
129
134
  <START> to <END> are branch names, tag names, or commit SHA1s specifying
130
135
  the range of history to compare. If a range with two dots (`a..b`) is given,
131
136
  it will be transformed into one with three dots. If <START> is omitted,
132
137
  GitHub will compare against the base branch (the default is "master").
138
+ If <END> is omitted, GitHub compare view is opened for the current branch.
139
+ With `-u`, outputs the URL rather than opening the browser.
133
140
 
134
141
  * `git fork` [`--no-remote`]:
135
142
  Forks the original project (referenced by "origin" remote) on GitHub and
136
143
  adds a new remote for it under your username.
137
144
 
138
- * `git pull-request` [`-f`] [<TITLE>|`-i` <ISSUE>|<ISSUE-URL>] [`-b` <BASE>] [`-h` <HEAD>]:
145
+ * `git pull-request` [`-f`] [`-m` <MESSAGE>|`-F` <FILE>|`-i` <ISSUE>|<ISSUE-URL>] [`-b` <BASE>] [`-h` <HEAD>]:
139
146
  Opens a pull request on GitHub for the project that the "origin" remote
140
147
  points to. The default head of the pull request is the current branch.
141
148
  Both base and head of the pull request can be explicitly given in one of
@@ -144,12 +151,20 @@ hub also adds some custom commands that are otherwise not present in git:
144
151
  branch has local commits that are not yet pushed to its upstream branch
145
152
  on the remote. To skip this check, use `-f`.
146
153
 
147
- If <TITLE> is omitted, a text editor will open in which title and body of
148
- the pull request can be entered in the same manner as git commit message.
154
+ Without <MESSAGE> or <FILE>, a text editor will open in which title and body
155
+ of the pull request can be entered in the same manner as git commit message.
156
+ Pull request message can also be passed via stdin with `-F -`.
157
+
158
+ Issue to pull request conversion via `-i <ISSUE>` or <ISSUE-URL>
159
+ arguments is deprecated and will likely be removed from the future versions
160
+ of both hub and GitHub API.
161
+
162
+ * `git ci-status` [`-v`] [<COMMIT>]:
163
+ Looks up the SHA for <COMMIT> in GitHub Status API and displays the latest
164
+ status. Exits with one of:
165
+ success (0), error (1), failure (1), pending (2), no status (3)
149
166
 
150
- If instead of normal <TITLE> an issue number is given with `-i`, the pull
151
- request will be attached to an existing GitHub issue. Alternatively, instead
152
- of title you can paste a full URL to an issue on GitHub.
167
+ If `-v` is given, additionally print the URL to CI build results.
153
168
 
154
169
  ## CONFIGURATION
155
170
 
@@ -186,14 +201,14 @@ variable:
186
201
 
187
202
  ## BUGS
188
203
 
189
- <https://github.com/defunkt/hub/issues>
204
+ <https://github.com/github/hub/issues>
190
205
 
191
206
  ## AUTHORS
192
207
 
193
- <https://github.com/defunkt/hub/contributors>
208
+ <https://github.com/github/hub/contributors>
194
209
 
195
210
  ## SEE ALSO
196
211
 
197
212
  git(1), git-clone(1), git-remote(1), git-init(1),
198
213
  <http://github.com>,
199
- <https://github.com/defunkt/hub>
214
+ <https://github.com/github/hub>
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env bash
2
+ # Usage: cached-bundle install --deployment
3
+ #
4
+ # After running `bundle`, caches the `vendor/bundle` directory to S3.
5
+ # On the next run, restores the cached directory before running `bundle`.
6
+ # When `Gemfile.lock` changes, the cache gets rebuilt.
7
+ #
8
+ # Requirements:
9
+ # - Gemfile.lock
10
+ # - TRAVIS_REPO_SLUG
11
+ # - TRAVIS_RUBY_VERSION
12
+ # - AMAZON_S3_BUCKET
13
+ # - script/s3-put
14
+ # - bundle
15
+ # - curl
16
+ #
17
+ # Author: Mislav Marohnić
18
+
19
+ set -e
20
+
21
+ compute_md5() {
22
+ local output="$(openssl md5)"
23
+ echo "${output##* }"
24
+ }
25
+
26
+ download() {
27
+ curl --tcp-nodelay -qsfL "$1" -o "$2"
28
+ }
29
+
30
+ bundle_path="vendor/bundle"
31
+ gemfile_hash="$(compute_md5 <"${BUNDLE_GEMFILE:-Gemfile}.lock")"
32
+ cache_name="${TRAVIS_RUBY_VERSION}-${gemfile_hash}.tgz"
33
+ fetch_url="http://${AMAZON_S3_BUCKET}.s3.amazonaws.com/${TRAVIS_REPO_SLUG}/${cache_name}"
34
+
35
+ if download "$fetch_url" "$cache_name"; then
36
+ echo "Reusing cached bundle ${cache_name}"
37
+ tar xzf "$cache_name"
38
+ fi
39
+
40
+ bundle "$@"
41
+
42
+ if [ ! -f "$cache_name" ]; then
43
+ echo "Caching \`${bundle_path}' to S3"
44
+ tar czf "$cache_name" "$bundle_path"
45
+ script/s3-put "$cache_name" "${AMAZON_S3_BUCKET}:${TRAVIS_REPO_SLUG}/${cache_name}"
46
+ fi
data/script/s3-put ADDED
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env bash
2
+ # Usage: s3-put <FILE> <S3_BUCKET>[:<PATH>] [<CONTENT_TYPE>]
3
+ #
4
+ # Uploads a file to the Amazon S3 service.
5
+ # Outputs the URL for the newly uploaded file.
6
+ #
7
+ # Requirements:
8
+ # - AMAZON_ACCESS_KEY_ID
9
+ # - AMAZON_SECRET_ACCESS_KEY
10
+ # - openssl
11
+ # - curl
12
+ #
13
+ # Author: Mislav Marohnić
14
+
15
+ set -e
16
+
17
+ authorization() {
18
+ local signature="$(string_to_sign | hmac_sha1 | base64)"
19
+ echo "AWS ${AMAZON_ACCESS_KEY_ID?}:${signature}"
20
+ }
21
+
22
+ hmac_sha1() {
23
+ openssl dgst -binary -sha1 -hmac "${AMAZON_SECRET_ACCESS_KEY?}"
24
+ }
25
+
26
+ base64() {
27
+ openssl enc -base64
28
+ }
29
+
30
+ bin_md5() {
31
+ openssl dgst -binary -md5
32
+ }
33
+
34
+ string_to_sign() {
35
+ echo "$http_method"
36
+ echo "$content_md5"
37
+ echo "$content_type"
38
+ echo "$date"
39
+ echo "x-amz-acl:$acl"
40
+ printf "/$bucket/$remote_path"
41
+ }
42
+
43
+ date_string() {
44
+ LC_TIME=C date "+%a, %d %h %Y %T %z"
45
+ }
46
+
47
+ file="$1"
48
+ bucket="${2%%:*}"
49
+ remote_path="${2#*:}"
50
+ content_type="$3"
51
+
52
+ if [ -z "$remote_path" ] || [ "$remote_path" = "$bucket" ]; then
53
+ remote_path="${file##*/}"
54
+ fi
55
+
56
+ http_method=PUT
57
+ acl="public-read"
58
+ content_md5="$(bin_md5 < "$file" | base64)"
59
+ date="$(date_string)"
60
+
61
+ url="https://$bucket.s3.amazonaws.com/$remote_path"
62
+
63
+ curl -qsSf -T "$file" \
64
+ -H "Authorization: $(authorization)" \
65
+ -H "x-amz-acl: $acl" \
66
+ -H "Date: $date" \
67
+ -H "Content-MD5: $content_md5" \
68
+ -H "Content-Type: $content_type" \
69
+ "$url"
70
+
71
+ echo "$url"
data/script/test ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ STATUS=0
5
+ warnings="${TMPDIR:-/tmp}/hub-warnings.$$"
6
+
7
+ run() {
8
+ # Save warnings on stderr to a separate file
9
+ RUBYOPT="$RUBYOPT -w" bundle exec "$@" \
10
+ 2> >(tee >(grep 'warning:' >>"$warnings") | grep -v 'warning:') || STATUS=$?
11
+ }
12
+
13
+ check_warnings() {
14
+ # Display Ruby warnings from this project's source files. Abort if any were found.
15
+ num="$(grep -F "$PWD" "$warnings" | grep -v "${PWD}/vendor/bundle" | sort | uniq -c | sort -rn | tee /dev/stderr | wc -l)"
16
+ rm -f "$warnings"
17
+ if [ "$num" -gt 0 ]; then
18
+ echo "FAILED: this test suite doesn't tolerate Ruby syntax warnings!" >&2
19
+ exit 1
20
+ fi
21
+ }
22
+
23
+ if tmux -V; then
24
+ if [ -n "$CI" ]; then
25
+ git --version
26
+ bash --version | head -1
27
+ zsh --version
28
+ echo
29
+ fi
30
+ profile="all"
31
+ else
32
+ echo "warning: skipping shell completion tests (install tmux to enable)" >&2
33
+ profile="default"
34
+ fi
35
+
36
+ run rake test
37
+ run cucumber -p "$profile"
38
+
39
+ check_warnings
40
+
41
+ exit $STATUS
data/script/test_each ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # 1.8.6-p420 ??
5
+ for RBENV_VERSION in 1.8.7-p374 1.9.3-p194 2.0.0-p247; do
6
+ export RBENV_VERSION
7
+ bundle install
8
+ script/test
9
+ done
@@ -0,0 +1,79 @@
1
+ require 'helper'
2
+
3
+ class ContextTest < Minitest::Test
4
+ class Context
5
+ include Hub::Context
6
+
7
+ def initialize(&block)
8
+ @git_reader = Hub::Context::GitReader.new('git', &block)
9
+ end
10
+
11
+ public :git_editor
12
+ end
13
+
14
+ attr_reader :context
15
+
16
+ def setup
17
+ super
18
+ @stubs = {}
19
+ @context = Context.new do |_, cmd|
20
+ @stubs.fetch(cmd)
21
+ end
22
+ end
23
+
24
+ def test_editor
25
+ stub_command_output 'var GIT_EDITOR', 'vim'
26
+ assert_equal %w'vim', context.git_editor
27
+ end
28
+
29
+ def test_editor_with_argument
30
+ stub_command_output 'var GIT_EDITOR', 'subl -w'
31
+ assert_equal %w'subl -w', context.git_editor
32
+ end
33
+
34
+ def test_editor_with_spaces
35
+ stub_command_output 'var GIT_EDITOR', '"my editor" -w arg2'
36
+ assert_equal %w'my\ editor -w arg2', context.git_editor
37
+ end
38
+
39
+ def test_editor_with_tilde
40
+ stub_command_output 'var GIT_EDITOR', '~/bin/vi'
41
+ with_env('HOME', '/home/mislav') do
42
+ assert_equal %w'/home/mislav/bin/vi', context.git_editor
43
+ end
44
+ end
45
+
46
+ def test_editor_with_env_variable
47
+ stub_command_output 'var GIT_EDITOR', '$EDITOR'
48
+ with_env('EDITOR', 'subl -w') do
49
+ assert_equal %w'subl -w', context.git_editor
50
+ end
51
+ end
52
+
53
+ def test_editor_with_embedded_env_variable
54
+ stub_command_output 'var GIT_EDITOR', '$EDITOR -w'
55
+ with_env('EDITOR', 'subl') do
56
+ assert_equal %w'subl -w', context.git_editor
57
+ end
58
+ end
59
+
60
+ def test_editor_with_curly_brackets_embedded_env_variable
61
+ stub_command_output 'var GIT_EDITOR', 'my${EDITOR}2 -w'
62
+ with_env('EDITOR', 'subl') do
63
+ assert_equal %w'mysubl2 -w', context.git_editor
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ def stub_command_output(cmd, value)
70
+ @stubs[cmd] = value.nil? ? nil : value.to_s
71
+ end
72
+
73
+ def with_env(name, value)
74
+ dir, ENV[name] = ENV[name], value
75
+ yield
76
+ ensure
77
+ ENV[name] = dir
78
+ end
79
+ end
data/test/fakebin/git CHANGED
@@ -6,6 +6,6 @@ elif [ "$1" = "--exec-path" ]; then
6
6
  elif [ "$1" = "--html-path" ]; then
7
7
  echo "/usr/share/doc/git-doc"
8
8
  else
9
- echo "ERROR: git was called, but wasn't supposed to:" git $*
9
+ echo "ERROR: git was called, but wasn't supposed to:" git $* >&2
10
10
  exit 1
11
11
  fi
data/test/fakebin/open CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/bin/sh
2
- echo "ERROR: open was called, but wasn't supposed to:" open $*
3
- exit 1
2
+ echo "ERROR: open was called, but wasn't supposed to:" open $* >&2
3
+ exit 1
@@ -0,0 +1,79 @@
1
+ require 'helper'
2
+ require 'hub/github_api'
3
+ require 'forwardable'
4
+ require 'delegate'
5
+
6
+ class FileStoreTest < Minitest::Test
7
+ extend Forwardable
8
+ def_delegators :@store, :yaml_dump, :yaml_load
9
+
10
+ def setup
11
+ @store = Hub::GitHubAPI::FileStore.new('')
12
+ end
13
+
14
+ class OrderedHash < DelegateClass(::Hash)
15
+ def self.[](*args)
16
+ hash = new
17
+ while args.any?
18
+ key, value = args.shift, args.shift
19
+ hash[key] = value
20
+ end
21
+ hash
22
+ end
23
+
24
+ def initialize(hash = {})
25
+ @keys = hash.keys
26
+ super(hash)
27
+ end
28
+
29
+ def []=(key, value) @keys << key; super end
30
+
31
+ def each
32
+ @keys.each { |key| yield(key, self[key]) }
33
+ end
34
+ end
35
+
36
+ def test_yaml_dump
37
+ output = yaml_dump("github.com" => [
38
+ OrderedHash['user', 'mislav', 'oauth_token', 'OTOKEN'],
39
+ OrderedHash['user', 'tpw', 'oauth_token', 'POKEN'],
40
+ ])
41
+
42
+ assert_equal <<-YAML.chomp, output
43
+ ---
44
+ github.com:
45
+ - user: mislav
46
+ oauth_token: OTOKEN
47
+ - user: tpw
48
+ oauth_token: POKEN
49
+ YAML
50
+ end
51
+
52
+ def test_yaml_load
53
+ data = yaml_load <<-YAML
54
+ ---
55
+ github.com:
56
+ - user: mislav
57
+ oauth_token: OTOKEN
58
+ - user: tpw
59
+ oauth_token: POKEN
60
+ YAML
61
+
62
+ assert_equal 'mislav', data['github.com'][0]['user']
63
+ assert_equal 'OTOKEN', data['github.com'][0]['oauth_token']
64
+ assert_equal 'tpw', data['github.com'][1]['user']
65
+ assert_equal 'POKEN', data['github.com'][1]['oauth_token']
66
+ end
67
+
68
+ def test_yaml_load_quoted
69
+ data = yaml_load <<-YAML
70
+ ---
71
+ github.com:
72
+ - user: 'true'
73
+ oauth_token: '1234'
74
+ YAML
75
+
76
+ assert_equal 'true', data['github.com'][0]['user']
77
+ assert_equal '1234', data['github.com'][0]['oauth_token']
78
+ end
79
+ end
data/test/helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'test/unit'
1
+ require 'minitest/autorun'
2
2
  require 'hub'
3
3
 
4
4
  # We're checking for `open` in our tests
@@ -28,7 +28,7 @@ Hub::Commands.extend Module.new {
28
28
  end
29
29
  }
30
30
 
31
- class Test::Unit::TestCase
31
+ class Minitest::Test
32
32
  # Shortcut for creating a `Hub` instance. Pass it what you would
33
33
  # normally pass `hub` on the command line, e.g.
34
34
  #