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/script/cached-bundle
DELETED
@@ -1,46 +0,0 @@
|
|
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
DELETED
@@ -1,71 +0,0 @@
|
|
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
DELETED
@@ -1,41 +0,0 @@
|
|
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
DELETED
data/test/context_test.rb
DELETED
@@ -1,79 +0,0 @@
|
|
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/deps.rip
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
webmock 1.3.0
|
data/test/fakebin/git
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
#!/bin/sh
|
2
|
-
if [ "$1" = "--version" ] || [ "$1" = "version" ]; then
|
3
|
-
echo "git version 1.7.0.4"
|
4
|
-
elif [ "$1" = "--exec-path" ]; then
|
5
|
-
echo "/usr/lib/git-core"
|
6
|
-
elif [ "$1" = "--html-path" ]; then
|
7
|
-
echo "/usr/share/doc/git-doc"
|
8
|
-
else
|
9
|
-
echo "ERROR: git was called, but wasn't supposed to:" git $* >&2
|
10
|
-
exit 1
|
11
|
-
fi
|
data/test/fakebin/open
DELETED
data/test/github_api_test.rb
DELETED
@@ -1,79 +0,0 @@
|
|
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
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'hub'
|
3
|
-
|
4
|
-
# We're checking for `open` in our tests
|
5
|
-
ENV['BROWSER'] = 'open'
|
6
|
-
|
7
|
-
# Setup path with fake executables in case a test hits them
|
8
|
-
fakebin_dir = File.expand_path('../fakebin', __FILE__)
|
9
|
-
ENV['PATH'] = "#{fakebin_dir}:#{ENV['PATH']}"
|
10
|
-
|
11
|
-
# Use an isolated config file in testing
|
12
|
-
tmp_dir = ENV['TMPDIR'] || ENV['TEMP'] || '/tmp'
|
13
|
-
ENV['HUB_CONFIG'] = File.join(tmp_dir, 'hub-test-config')
|
14
|
-
|
15
|
-
# Disable `abort` and `exit` in the main test process, but allow it in
|
16
|
-
# subprocesses where we need to test does a command properly bail out.
|
17
|
-
Hub::Commands.extend Module.new {
|
18
|
-
main_pid = Process.pid
|
19
|
-
|
20
|
-
[:abort, :exit].each do |method|
|
21
|
-
define_method method do |*args|
|
22
|
-
if Process.pid == main_pid
|
23
|
-
raise "#{method} is disabled"
|
24
|
-
else
|
25
|
-
super(*args)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
}
|
30
|
-
|
31
|
-
class Minitest::Test
|
32
|
-
# Shortcut for creating a `Hub` instance. Pass it what you would
|
33
|
-
# normally pass `hub` on the command line, e.g.
|
34
|
-
#
|
35
|
-
# shell: hub clone rtomayko/tilt
|
36
|
-
# test: Hub("clone rtomayko/tilt")
|
37
|
-
def Hub(args)
|
38
|
-
runner = Hub::Runner.new(*args.split(' ').map {|a| a.freeze })
|
39
|
-
runner.args.commands.each do |cmd|
|
40
|
-
if Array === cmd and invalid = cmd.find {|c| !c.respond_to? :to_str }
|
41
|
-
raise "#{invalid.inspect} is not a string (in #{cmd.join(' ').inspect})"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
runner
|
45
|
-
end
|
46
|
-
|
47
|
-
# Shortcut for running the `hub` command in a subprocess. Returns
|
48
|
-
# STDOUT as a string. Pass it what you would normally pass `hub` on
|
49
|
-
# the command line, e.g.
|
50
|
-
#
|
51
|
-
# shell: hub clone rtomayko/tilt
|
52
|
-
# test: hub("clone rtomayko/tilt")
|
53
|
-
#
|
54
|
-
# If a block is given it will be run in the child process before
|
55
|
-
# execution begins. You can use this to monkeypatch or fudge the
|
56
|
-
# environment before running hub.
|
57
|
-
def hub(args, input = nil)
|
58
|
-
parent_read, child_write = IO.pipe
|
59
|
-
child_read, parent_write = IO.pipe if input
|
60
|
-
|
61
|
-
fork do
|
62
|
-
yield if block_given?
|
63
|
-
$stdin.reopen(child_read) if input
|
64
|
-
$stdout.reopen(child_write)
|
65
|
-
$stderr.reopen(child_write)
|
66
|
-
Hub(args).execute
|
67
|
-
end
|
68
|
-
|
69
|
-
if input
|
70
|
-
parent_write.write input
|
71
|
-
parent_write.close
|
72
|
-
end
|
73
|
-
child_write.close
|
74
|
-
parent_read.read
|
75
|
-
end
|
76
|
-
|
77
|
-
# Asserts that `hub` will run a specific git command based on
|
78
|
-
# certain input.
|
79
|
-
#
|
80
|
-
# e.g.
|
81
|
-
# assert_command "clone git/hub", "git clone git://github.com/git/hub.git"
|
82
|
-
#
|
83
|
-
# Here we are saying that this:
|
84
|
-
# $ hub clone git/hub
|
85
|
-
# Should in turn execute this:
|
86
|
-
# $ git clone git://github.com/git/hub.git
|
87
|
-
def assert_command(input, expected)
|
88
|
-
assert_equal expected, Hub(input).command, "$ git #{input}"
|
89
|
-
end
|
90
|
-
|
91
|
-
def assert_commands(*expected)
|
92
|
-
input = expected.pop
|
93
|
-
assert_equal expected, Hub(input).commands
|
94
|
-
end
|
95
|
-
|
96
|
-
# Asserts that the command will be forwarded to git without changes
|
97
|
-
def assert_forwarded(input)
|
98
|
-
cmd = Hub(input)
|
99
|
-
assert !cmd.args.changed?, "arguments were not supposed to change: #{cmd.args.inspect}"
|
100
|
-
end
|
101
|
-
|
102
|
-
# Asserts that `haystack` includes `needle`.
|
103
|
-
def assert_includes(needle, haystack)
|
104
|
-
assert haystack.include?(needle),
|
105
|
-
"expected #{needle.inspect} in #{haystack.inspect}"
|
106
|
-
end
|
107
|
-
|
108
|
-
# Asserts that `haystack` does not include `needle`.
|
109
|
-
def assert_not_includes(needle, haystack)
|
110
|
-
assert !haystack.include?(needle),
|
111
|
-
"didn't expect #{needle.inspect} in #{haystack.inspect}"
|
112
|
-
end
|
113
|
-
|
114
|
-
# Version of assert_equal tailored for big output
|
115
|
-
def assert_output(expected, command)
|
116
|
-
output = hub(command) { ENV['GIT'] = 'echo' }
|
117
|
-
assert expected == output,
|
118
|
-
"expected:\n#{expected}\ngot:\n#{output}"
|
119
|
-
end
|
120
|
-
|
121
|
-
def edit_hub_config
|
122
|
-
config = ENV['HUB_CONFIG']
|
123
|
-
if File.exist? config
|
124
|
-
data = YAML.load File.read(config)
|
125
|
-
else
|
126
|
-
data = {}
|
127
|
-
end
|
128
|
-
yield data
|
129
|
-
File.open(config, 'w') { |cfg| cfg << YAML.dump(data) }
|
130
|
-
end
|
131
|
-
end
|