github_bitbucket_deployer 0.4.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +5 -0
- data/README.md +3 -5
- data/github_bitbucket_deployer.gemspec +6 -5
- data/lib/github_bitbucket_deployer/clone_logger_fix.rb +21 -0
- data/lib/github_bitbucket_deployer/git.rb +63 -61
- data/lib/github_bitbucket_deployer/version.rb +1 -1
- data/spec/lib/github_bitbucket_deployer/configuration_spec.rb +7 -9
- data/spec/lib/github_bitbucket_deployer/git_spec.rb +438 -1
- data/spec/lib/github_bitbucket_deployer_spec.rb +16 -18
- data/spec/spec_helper.rb +9 -4
- data/spec/support/fakefs.rb +9 -0
- data/spec/support/git_helpers.rb +7 -0
- data/spec/support/shared_examples/git_error_handler.rb +46 -0
- data/spec/support/shared_examples/git_ssh_wrapper.rb +59 -0
- metadata +47 -16
- data/Guardfile +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26db8331ec93b1bfcca69796b62706b44bde7df7
|
4
|
+
data.tar.gz: ab86f9d0b91833e8b4c23dc516ddab529b1f409c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd08ab565ec6cc99721f810869843ed9db8af8d9022d688fb3440f383d49913ad0467b5ca588e3352a959e2e39bf5a5993de7442ba611324d36f056adb91ac28
|
7
|
+
data.tar.gz: 2fec783ed7da9e3a094f3f71e8a9aa155156468477edbc69fe2a1dddec82ce4250fc459e47257ca07bc061e336c7b23147798976f6e7b5a84386c05e8907bf6b
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.5
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -8,14 +8,12 @@ Ruby gem to deploy public and private Github repos to Bitbucket
|
|
8
8
|
|
9
9
|
## Current Version
|
10
10
|
|
11
|
-
0.
|
12
|
-
|
11
|
+
1.0.0
|
13
12
|
|
14
13
|
## Requirements
|
15
14
|
|
16
|
-
* [
|
17
|
-
* [
|
18
|
-
|
15
|
+
* [git](https://git-scm.com/) >= 1.6.0.0
|
16
|
+
* [ruby](https://www.ruby-lang.org/) >= 2.2
|
19
17
|
|
20
18
|
## Installation
|
21
19
|
|
@@ -15,11 +15,12 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
16
|
gem.require_paths = ["lib"]
|
17
17
|
|
18
|
-
gem.add_dependency "git", "~> 1.2.
|
19
|
-
gem.add_dependency "git-ssh-wrapper", "~> 0.1
|
18
|
+
gem.add_dependency "git", "~> 1.2", ">= 1.2.9.1"
|
19
|
+
gem.add_dependency "git-ssh-wrapper", "~> 0.1"
|
20
|
+
gem.add_dependency "retriable", "~> 2.1"
|
20
21
|
|
21
22
|
gem.add_development_dependency "simplecov", "~> 0.7.1"
|
22
|
-
gem.add_development_dependency "rspec", "~>
|
23
|
-
gem.add_development_dependency "
|
24
|
-
gem.add_development_dependency "
|
23
|
+
gem.add_development_dependency "rspec", "~> 3.5"
|
24
|
+
gem.add_development_dependency "fakefs", "~> 0.9.2"
|
25
|
+
gem.add_development_dependency "pry-byebug", "~> 3.3"
|
25
26
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'git'
|
2
|
+
|
3
|
+
# Patch ruby-git to support logger for Git.clone
|
4
|
+
# See https://github.com/schacon/ruby-git/issues/208
|
5
|
+
module CloneLoggerFix
|
6
|
+
module ClassMethods
|
7
|
+
def clone(repository, name, opts = {})
|
8
|
+
lib = ::Git::Lib.new(nil, opts[:log])
|
9
|
+
clone_opts = lib.clone(repository, name, opts)
|
10
|
+
new(clone_opts.merge(log: opts[:log]))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.prepended(base)
|
15
|
+
class << base
|
16
|
+
prepend ClassMethods
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
::Git::Base.prepend(CloneLoggerFix)
|
@@ -1,8 +1,11 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'git'
|
2
|
+
require 'git-ssh-wrapper'
|
3
|
+
require 'retriable'
|
4
|
+
require 'github_bitbucket_deployer/clone_logger_fix'
|
3
5
|
|
4
6
|
module GithubBitbucketDeployer
|
5
7
|
class Git
|
8
|
+
attr_reader :bitbucket_repo_url, :git_repo_name, :id_rsa, :repo_dir, :logger
|
6
9
|
|
7
10
|
def initialize(options)
|
8
11
|
@bitbucket_repo_url = options[:bitbucket_repo_url]
|
@@ -12,92 +15,91 @@ module GithubBitbucketDeployer
|
|
12
15
|
@repo_dir = options[:repo_dir]
|
13
16
|
end
|
14
17
|
|
15
|
-
def push_app_to_bitbucket(remote=
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
yield(repo) if block_given?
|
21
|
-
@logger.info "deploying #{repo.dir} to #{repo.remote(remote).url} from branch #{branch}"
|
22
|
-
run "cd #{repo.dir}; env #{wrapper.git_ssh} git push -f #{remote} #{branch}"
|
23
|
-
ensure
|
24
|
-
wrapper.unlink
|
18
|
+
def push_app_to_bitbucket(remote = 'bitbucket', branch = 'master')
|
19
|
+
logger.info('push_app_to_bitbucket')
|
20
|
+
add_remote(remote)
|
21
|
+
with_ssh { yield(repo) } if block_given?
|
22
|
+
push(remote, branch)
|
25
23
|
end
|
26
24
|
|
27
25
|
def repo
|
28
26
|
@repo ||= setup_repo
|
29
27
|
end
|
30
28
|
|
31
|
-
def setup_repo
|
32
|
-
@logger.info "setup_repo"
|
33
|
-
clone_or_pull
|
34
|
-
open
|
35
|
-
end
|
36
|
-
|
37
29
|
def folder
|
38
30
|
@folder ||= setup_folder
|
39
31
|
end
|
40
32
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
FileUtils.mkdir_p(folder).first
|
33
|
+
def clone
|
34
|
+
logger.info("git clone: cloning #{bitbucket_repo_url} to #{folder}")
|
35
|
+
run { ::Git.clone(bitbucket_repo_url, folder, log: logger) }
|
45
36
|
end
|
46
37
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
38
|
+
def pull
|
39
|
+
logger.info("git pull: pulling from #{folder}")
|
40
|
+
run { open.pull }
|
41
|
+
open
|
50
42
|
end
|
51
43
|
|
52
|
-
def
|
53
|
-
|
44
|
+
def open
|
45
|
+
logger.info('git open')
|
46
|
+
::Git.open(folder, log: logger)
|
54
47
|
end
|
55
48
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
run "unset GIT_WORK_TREE; env #{wrapper.git_ssh} git clone #{@bitbucket_repo_url} #{folder}"
|
61
|
-
ensure
|
62
|
-
wrapper.unlink
|
49
|
+
def push(remote, branch)
|
50
|
+
logger.info("git push: deploying #{repo.dir} to " \
|
51
|
+
"#{repo.remote(remote).url} from branch #{branch}")
|
52
|
+
run { repo.push(remote, branch, force: true) }
|
63
53
|
end
|
64
54
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
@logger.info "pulling from #{folder}"
|
70
|
-
run "cd #{folder}; env #{wrapper.git_ssh} git pull; cd #{dir}"
|
71
|
-
ensure
|
72
|
-
wrapper.unlink
|
55
|
+
def add_remote(remote = 'bitbucket')
|
56
|
+
logger.info("git add_remote: #{remote}")
|
57
|
+
repo.remote(remote).remove if repo.remote(remote).url
|
58
|
+
repo.add_remote(remote, bitbucket_repo_url)
|
73
59
|
end
|
74
60
|
|
75
|
-
|
76
|
-
|
77
|
-
|
61
|
+
private
|
62
|
+
|
63
|
+
def setup_folder
|
64
|
+
logger.info('setup_folder')
|
65
|
+
folder = File.join(repo_dir, Zlib.crc32(git_repo_name).to_s)
|
66
|
+
FileUtils.mkdir_p(folder).first
|
67
|
+
end
|
68
|
+
|
69
|
+
def setup_repo
|
70
|
+
logger.info('setup_repo')
|
71
|
+
update_working_copy
|
72
|
+
open
|
78
73
|
end
|
79
74
|
|
80
|
-
def
|
81
|
-
|
75
|
+
def update_working_copy
|
76
|
+
logger.info('update_working_copy')
|
77
|
+
exists_locally? ? pull : clone
|
78
|
+
end
|
79
|
+
|
80
|
+
def exists_locally?
|
81
|
+
git_config = File.join(folder, '.git', 'config')
|
82
|
+
File.exist?(git_config)
|
82
83
|
end
|
83
84
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
85
|
+
def run
|
86
|
+
Retriable.retriable(on: ::Git::GitExecuteError, tries: 3) do
|
87
|
+
with_ssh { yield }
|
88
|
+
end
|
89
|
+
rescue ::Git::GitExecuteError => error
|
90
|
+
logger.error(error)
|
91
|
+
raise GithubBitbucketDeployer::CommandException, error
|
89
92
|
end
|
90
93
|
|
91
|
-
def
|
92
|
-
@
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
else
|
98
|
-
raise GithubBitbucketDeployer::CommandException, $?.to_s
|
94
|
+
def with_ssh
|
95
|
+
@old_git_ssh = ENV['GIT_SSH']
|
96
|
+
|
97
|
+
GitSSHWrapper.with_wrapper(private_key: id_rsa) do |wrapper|
|
98
|
+
wrapper.set_env
|
99
|
+
yield if block_given?
|
99
100
|
end
|
101
|
+
ensure
|
102
|
+
ENV['GIT_SSH'] = @old_git_ssh
|
100
103
|
end
|
101
104
|
end
|
102
105
|
end
|
103
|
-
|
@@ -1,11 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'github_bitbucket_deployer'
|
3
|
-
require 'github_bitbucket_deployer/configuration'
|
4
2
|
|
5
3
|
describe GithubBitbucketDeployer::Configuration do
|
6
|
-
it {
|
7
|
-
it {
|
8
|
-
it {
|
4
|
+
it { is_expected.to respond_to :"[]" }
|
5
|
+
it { is_expected.to respond_to :to_hash }
|
6
|
+
it { is_expected.to respond_to :merge }
|
9
7
|
|
10
8
|
it "provides default values" do
|
11
9
|
assert_config_default :id_rsa, ENV["ID_RSA"]
|
@@ -19,24 +17,24 @@ describe GithubBitbucketDeployer::Configuration do
|
|
19
17
|
config = GithubBitbucketDeployer::Configuration.new
|
20
18
|
hash = config.to_hash
|
21
19
|
GithubBitbucketDeployer::Configuration::OPTIONS.each_pair do |key, value|
|
22
|
-
config[key].
|
20
|
+
expect(config[key]).to eq(hash[key])
|
23
21
|
end
|
24
22
|
end
|
25
23
|
|
26
24
|
it "is mergable" do
|
27
25
|
config = GithubBitbucketDeployer::Configuration.new
|
28
26
|
hash = config.to_hash
|
29
|
-
config.merge(:key => 'value').
|
27
|
+
expect(config.merge(:key => 'value')).to eq(hash.merge(:key => 'value'))
|
30
28
|
end
|
31
29
|
|
32
30
|
def assert_config_default(option, default_value, config = nil)
|
33
31
|
config ||= GithubBitbucketDeployer::Configuration.new
|
34
|
-
config.send(option).
|
32
|
+
expect(config.send(option)).to eq(default_value)
|
35
33
|
end
|
36
34
|
|
37
35
|
def assert_config_overridable(option, value = 'a value')
|
38
36
|
config = GithubBitbucketDeployer::Configuration.new
|
39
37
|
config.send(:"#{option}=", value)
|
40
|
-
config.send(option).
|
38
|
+
expect(config.send(option)).to eq(value)
|
41
39
|
end
|
42
40
|
end
|
@@ -1,5 +1,442 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'github_bitbucket_deployer/git'
|
3
2
|
|
4
3
|
describe GithubBitbucketDeployer::Git do
|
4
|
+
include GitHelpers
|
5
|
+
|
6
|
+
let(:git) { described_class.new(options) }
|
7
|
+
|
8
|
+
let(:options) do
|
9
|
+
{ bitbucket_repo_url: bitbucket_repo_url,
|
10
|
+
git_repo_name: git_repo_name,
|
11
|
+
id_rsa: id_rsa,
|
12
|
+
logger: logger,
|
13
|
+
repo_dir: repo_dir }
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:bitbucket_repo_url) { 'git@bitbucket.org:g5dev/some_repo.git' }
|
17
|
+
let(:git_repo_name) { 'some_repo' }
|
18
|
+
let(:local_repo_folder) { Zlib.crc32(git_repo_name) }
|
19
|
+
let(:id_rsa) { 'this is the value of my key' }
|
20
|
+
let(:logger) { double('logger', info: true, error: true) }
|
21
|
+
let(:repo_dir) { '/my_home/projects' }
|
22
|
+
let(:working_dir) { "#{repo_dir}/#{local_repo_folder}" }
|
23
|
+
|
24
|
+
let(:git_repo) do
|
25
|
+
instance_double(::Git::Base, remote: empty_remote,
|
26
|
+
dir: git_working_dir,
|
27
|
+
add_remote: true,
|
28
|
+
pull: true,
|
29
|
+
push: true)
|
30
|
+
end
|
31
|
+
let(:empty_remote) { instance_double(::Git::Remote, url: nil) }
|
32
|
+
|
33
|
+
let(:bitbucket_remote) do
|
34
|
+
instance_double(::Git::Remote, url: bitbucket_repo_url,
|
35
|
+
remove: true)
|
36
|
+
end
|
37
|
+
before do
|
38
|
+
allow(git_repo).to receive(:remote)
|
39
|
+
.with('bitbucket').and_return(bitbucket_remote)
|
40
|
+
end
|
41
|
+
|
42
|
+
let(:git_working_dir) do
|
43
|
+
instance_double(::Git::WorkingDirectory, path: working_dir,
|
44
|
+
to_s: working_dir)
|
45
|
+
end
|
46
|
+
|
47
|
+
before do
|
48
|
+
allow(::Git).to receive(:open).and_return(git_repo)
|
49
|
+
allow(::Git).to receive(:clone).and_return(git_repo)
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#initialize' do
|
53
|
+
subject { git }
|
54
|
+
|
55
|
+
it 'sets the bitbucket_repo_url' do
|
56
|
+
expect(git.bitbucket_repo_url).to eq(bitbucket_repo_url)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'sets the git_repo_name' do
|
60
|
+
expect(git.git_repo_name).to eq(git_repo_name)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'sets the id_rsa' do
|
64
|
+
expect(git.id_rsa).to eq(id_rsa)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'sets the logger' do
|
68
|
+
expect(git.logger).to eq(logger)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'sets the repo_dir' do
|
72
|
+
expect(git.repo_dir).to eq(repo_dir)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#push_app_to_bitbucket', :fakefs do
|
77
|
+
subject { push_app }
|
78
|
+
|
79
|
+
context 'with default arguments' do
|
80
|
+
let(:push_app) { git.push_app_to_bitbucket }
|
81
|
+
|
82
|
+
context 'when local repo already exists' do
|
83
|
+
before { create_local_repo(working_dir) }
|
84
|
+
|
85
|
+
it 'pulls from the remote repo' do
|
86
|
+
expect(git_repo).to receive(:pull).and_return(true)
|
87
|
+
push_app
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'removes the existing remote' do
|
91
|
+
expect(bitbucket_remote).to receive(:remove)
|
92
|
+
push_app
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'creates the bitbucket remote anew' do
|
96
|
+
expect(git_repo).to receive(:add_remote)
|
97
|
+
.with('bitbucket', bitbucket_repo_url)
|
98
|
+
push_app
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'force pushes master to bitbucket' do
|
102
|
+
expect(git_repo).to receive(:push)
|
103
|
+
.with('bitbucket', 'master', force: true)
|
104
|
+
push_app
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'when local repo does not exist' do
|
109
|
+
before do
|
110
|
+
allow(git_repo).to receive(:remote)
|
111
|
+
.with('bitbucket').and_return(empty_remote)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'clones the bitbucket repo into the local folder' do
|
115
|
+
expect(::Git).to receive(:clone)
|
116
|
+
.with(bitbucket_repo_url, working_dir, log: logger)
|
117
|
+
.and_return(git_repo)
|
118
|
+
push_app
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'creates the bitbucket remote' do
|
122
|
+
expect(git_repo).to receive(:add_remote)
|
123
|
+
.with('bitbucket', bitbucket_repo_url)
|
124
|
+
push_app
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'force pushes master to bitbucket' do
|
128
|
+
expect(git_repo).to receive(:push)
|
129
|
+
.with('bitbucket', 'master', force: true)
|
130
|
+
push_app
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'with custom arguments' do
|
136
|
+
let(:push_app) { git.push_app_to_bitbucket(remote_name, branch) }
|
137
|
+
|
138
|
+
let(:remote_name) { 'my_git_server' }
|
139
|
+
let(:branch) { 'my_topic_branch' }
|
140
|
+
|
141
|
+
before { create_local_repo(working_dir) }
|
142
|
+
|
143
|
+
it 'pulls from the remote repo' do
|
144
|
+
expect(git_repo).to receive(:pull).and_return(true)
|
145
|
+
push_app
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'creates the new remote' do
|
149
|
+
expect(git_repo).to receive(:add_remote)
|
150
|
+
.with(remote_name, bitbucket_repo_url)
|
151
|
+
push_app
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'yields to the block' do
|
155
|
+
expect do |block|
|
156
|
+
git.push_app_to_bitbucket(remote_name, branch, &block)
|
157
|
+
end.to yield_with_args(git_repo)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'forces pushes the branch' do
|
161
|
+
expect(git_repo).to receive(:push)
|
162
|
+
.with(remote_name, branch, force: true)
|
163
|
+
push_app
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe '#repo', :fakefs do
|
169
|
+
subject(:repo) { git.repo }
|
170
|
+
|
171
|
+
context 'when repo_dir exists' do
|
172
|
+
before { FileUtils.mkdir_p(repo_dir) }
|
173
|
+
|
174
|
+
context 'with a git repo' do
|
175
|
+
before { create_local_repo(working_dir) }
|
176
|
+
|
177
|
+
it { is_expected.to eq(git_repo) }
|
178
|
+
|
179
|
+
it 'points to the local working dir' do
|
180
|
+
expect(repo.dir.path).to eq(working_dir)
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'pulls into the existing repo' do
|
184
|
+
expect(git_repo).to receive(:pull).and_return(true)
|
185
|
+
repo
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'without a git repo' do
|
190
|
+
before do
|
191
|
+
FileUtils.rm_rf(working_dir)
|
192
|
+
end
|
193
|
+
|
194
|
+
it { is_expected.to eq(git_repo) }
|
195
|
+
|
196
|
+
it 'clones the repo locally' do
|
197
|
+
expect(::Git).to receive(:clone)
|
198
|
+
.with(bitbucket_repo_url, working_dir, log: logger)
|
199
|
+
.and_return(git_repo)
|
200
|
+
repo
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context 'when repo_dir does not exist' do
|
206
|
+
before do
|
207
|
+
FileUtils.rm_rf(repo_dir)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'creates the local repo dir' do
|
211
|
+
repo
|
212
|
+
expect(File).to exist(repo_dir)
|
213
|
+
end
|
214
|
+
|
215
|
+
it { is_expected.to eq(git_repo) }
|
216
|
+
|
217
|
+
it 'clones the repo locally' do
|
218
|
+
expect(::Git).to receive(:clone)
|
219
|
+
.with(bitbucket_repo_url, working_dir, log: logger)
|
220
|
+
.and_return(git_repo)
|
221
|
+
repo
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
describe '#folder', :fakefs do
|
227
|
+
subject(:folder) { git.folder }
|
228
|
+
|
229
|
+
context 'when repo_dir exists' do
|
230
|
+
before { FileUtils.mkdir_p(repo_dir) }
|
231
|
+
|
232
|
+
it { is_expected.to eq(working_dir) }
|
233
|
+
|
234
|
+
it 'creates the local folder' do
|
235
|
+
expect(File).to exist(folder)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context 'when repo_dir does not exist' do
|
240
|
+
before { FileUtils.rm_rf(repo_dir) }
|
241
|
+
|
242
|
+
it { is_expected.to eq(working_dir) }
|
243
|
+
|
244
|
+
it 'creates the absolute path to the local folder' do
|
245
|
+
expect(File).to exist(folder)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
describe '#clone', :fakefs do
|
251
|
+
subject(:clone) { git.clone }
|
252
|
+
|
253
|
+
it { is_expected.to be(git_repo) }
|
254
|
+
|
255
|
+
it 'clones the bitbucket repo into the local folder' do
|
256
|
+
expect(::Git).to receive(:clone)
|
257
|
+
.with(bitbucket_repo_url, working_dir, log: logger)
|
258
|
+
.and_return(git_repo)
|
259
|
+
clone
|
260
|
+
end
|
261
|
+
|
262
|
+
it_behaves_like 'a git error handler' do
|
263
|
+
before { allow(::Git).to receive(:clone).and_raise(error) }
|
264
|
+
|
265
|
+
let(:retry_git_command) do
|
266
|
+
expect(::Git).to have_received(:clone).exactly(retry_limit).times
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
it_behaves_like 'a git ssh wrapper' do
|
271
|
+
def run_git_command
|
272
|
+
expect(::Git).to receive(:clone) { yield }
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
describe '#pull', :fakefs do
|
278
|
+
subject(:pull) { git.pull }
|
279
|
+
|
280
|
+
it { is_expected.to be(git_repo) }
|
281
|
+
|
282
|
+
it 'pulls from the remote server' do
|
283
|
+
expect(git_repo).to receive(:pull)
|
284
|
+
pull
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'does not change the current dir' do
|
288
|
+
expect { pull }.to_not change { Dir.pwd }
|
289
|
+
end
|
290
|
+
|
291
|
+
it_behaves_like 'a git error handler' do
|
292
|
+
before { allow(git_repo).to receive(:pull).and_raise(error) }
|
293
|
+
|
294
|
+
let(:retry_git_command) do
|
295
|
+
expect(git_repo).to have_received(:pull).exactly(retry_limit).times
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
it_behaves_like 'a git ssh wrapper' do
|
300
|
+
def run_git_command
|
301
|
+
expect(git_repo).to receive(:pull) { yield }
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
describe '#open', :fakefs do
|
307
|
+
subject(:open) { git.open }
|
308
|
+
|
309
|
+
it { is_expected.to eq(git_repo) }
|
310
|
+
|
311
|
+
it 'opens the local repo with logging' do
|
312
|
+
expect(::Git).to receive(:open)
|
313
|
+
.with(working_dir, log: logger).and_return(git_repo)
|
314
|
+
open
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
describe '#push', :fakefs do
|
319
|
+
subject(:push) { git.push(remote_name, branch) }
|
320
|
+
|
321
|
+
let(:remote_name) { 'bitbucket' }
|
322
|
+
let(:branch) { 'master' }
|
323
|
+
|
324
|
+
it 'force pushes the branch to the remote' do
|
325
|
+
expect(git_repo).to receive(:push).with(remote_name, branch, force: true)
|
326
|
+
push
|
327
|
+
end
|
328
|
+
|
329
|
+
it_behaves_like 'a git error handler' do
|
330
|
+
before { allow(git_repo).to receive(:push).and_raise(error) }
|
331
|
+
|
332
|
+
let(:retry_git_command) do
|
333
|
+
expect(git_repo).to have_received(:push).exactly(retry_limit).times
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
it_behaves_like 'a git ssh wrapper' do
|
338
|
+
def run_git_command
|
339
|
+
expect(git_repo).to receive(:push) { yield }
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
describe '#add_remote', :fakefs do
|
345
|
+
subject { add_remote }
|
346
|
+
|
347
|
+
let(:unrelated_remote) do
|
348
|
+
instance_double(::Git::Remote, url: 'git@heroku.com:my_app.git')
|
349
|
+
end
|
350
|
+
|
351
|
+
before do
|
352
|
+
allow(git_repo).to receive(:remote)
|
353
|
+
.with('heroku').and_return(unrelated_remote)
|
354
|
+
end
|
355
|
+
|
356
|
+
context 'with default remote name' do
|
357
|
+
let(:add_remote) { git.add_remote }
|
358
|
+
|
359
|
+
context 'when bitbucket remote already exists' do
|
360
|
+
it 'removes the existing remote' do
|
361
|
+
expect(bitbucket_remote).to receive(:remove)
|
362
|
+
add_remote
|
363
|
+
end
|
364
|
+
|
365
|
+
it 'does not remove the unrelated remote' do
|
366
|
+
expect(unrelated_remote).to_not receive(:remove)
|
367
|
+
add_remote
|
368
|
+
end
|
369
|
+
|
370
|
+
it 'adds the new bitbucket remote' do
|
371
|
+
expect(git_repo).to receive(:add_remote)
|
372
|
+
.with('bitbucket', bitbucket_repo_url)
|
373
|
+
add_remote
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
context 'when bitbucket remote does not exist' do
|
378
|
+
let(:bitbucket_remote) { empty_remote }
|
379
|
+
|
380
|
+
it 'does not remove any existing remotes' do
|
381
|
+
expect(empty_remote).to_not receive(:remove)
|
382
|
+
expect(unrelated_remote).to_not receive(:remove)
|
383
|
+
add_remote
|
384
|
+
end
|
385
|
+
|
386
|
+
it 'adds the new bitbucket remote' do
|
387
|
+
expect(git_repo).to receive(:add_remote)
|
388
|
+
.with('bitbucket', bitbucket_repo_url)
|
389
|
+
add_remote
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
context 'with custom remote name' do
|
395
|
+
let(:add_remote) { git.add_remote(remote_name) }
|
396
|
+
|
397
|
+
let(:custom_remote) do
|
398
|
+
instance_double(::Git::Remote, url: 'git@some_server.com:my_app.git',
|
399
|
+
remove: true)
|
400
|
+
end
|
401
|
+
let(:remote_name) { 'custom_remote' }
|
402
|
+
before do
|
403
|
+
allow(git_repo).to receive(:remote)
|
404
|
+
.with(remote_name).and_return(custom_remote)
|
405
|
+
end
|
406
|
+
|
407
|
+
context 'when custom remote already exists' do
|
408
|
+
it 'removes the existing remote' do
|
409
|
+
expect(custom_remote).to receive(:remove)
|
410
|
+
add_remote
|
411
|
+
end
|
412
|
+
|
413
|
+
it 'does not remove unrelated remotes' do
|
414
|
+
expect(unrelated_remote).to_not receive(:remove)
|
415
|
+
add_remote
|
416
|
+
end
|
417
|
+
|
418
|
+
it 'creates the new custom remote' do
|
419
|
+
expect(git_repo).to receive(:add_remote)
|
420
|
+
.with(remote_name, bitbucket_repo_url)
|
421
|
+
add_remote
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
context 'when custom remote does not already exist' do
|
426
|
+
let(:custom_remote) { empty_remote }
|
427
|
+
|
428
|
+
it 'does not remove any existing remotes' do
|
429
|
+
expect(empty_remote).to_not receive(:remove)
|
430
|
+
expect(unrelated_remote).to_not receive(:remove)
|
431
|
+
add_remote
|
432
|
+
end
|
433
|
+
|
434
|
+
it 'creates the new custom remote' do
|
435
|
+
expect(git_repo).to receive(:add_remote)
|
436
|
+
.with(remote_name, bitbucket_repo_url)
|
437
|
+
add_remote
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
5
442
|
end
|
@@ -1,33 +1,33 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'github_bitbucket_deployer'
|
3
2
|
|
4
3
|
describe GithubBitbucketDeployer do
|
5
|
-
it {
|
6
|
-
it {
|
7
|
-
it {
|
4
|
+
it { is_expected.to respond_to(:configuration) }
|
5
|
+
it { is_expected.to respond_to(:configure) }
|
6
|
+
it { is_expected.to respond_to(:deploy) }
|
7
|
+
|
8
|
+
describe ".configuration" do
|
9
|
+
subject(:config) { GithubBitbucketDeployer.configuration }
|
8
10
|
|
9
|
-
describe "::configuration" do
|
10
11
|
it "should be the configuration object" do
|
11
|
-
|
12
|
-
be_a_kind_of GithubBitbucketDeployer::Configuration)
|
12
|
+
expect(config).to be_a_kind_of(GithubBitbucketDeployer::Configuration)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "give a new instance if non defined" do
|
16
16
|
GithubBitbucketDeployer.configuration = nil
|
17
|
-
|
18
|
-
be_a_kind_of GithubBitbucketDeployer::Configuration)
|
17
|
+
expect(config).to be_a_kind_of(GithubBitbucketDeployer::Configuration)
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
22
|
-
describe "
|
21
|
+
describe ".configure" do
|
23
22
|
it "should yield the configuration object" do
|
24
23
|
GithubBitbucketDeployer.configure do |config|
|
25
|
-
config.
|
24
|
+
expect(config).to equal(GithubBitbucketDeployer.configuration)
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
29
|
describe "::deploy" do
|
30
|
+
subject(:deploy) { GithubBitbucketDeployer.deploy }
|
31
31
|
|
32
32
|
context "when unconfigured" do
|
33
33
|
before :each do
|
@@ -37,16 +37,15 @@ describe GithubBitbucketDeployer do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it "requires github_repo to be set" do
|
40
|
-
|
41
|
-
raise_error ::GithubBitbucketDeployer::ConfigurationException)
|
40
|
+
expect { deploy }.to raise_error(GithubBitbucketDeployer::ConfigurationException)
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
45
44
|
# TODO: how can I test these better?
|
46
45
|
context "when configured" do
|
47
46
|
before :each do
|
48
|
-
@deployer =
|
49
|
-
@deployer.
|
47
|
+
@deployer = double("github_bitbucket_deployer")
|
48
|
+
allow(@deployer).to receive(:deploy).and_return(true)
|
50
49
|
end
|
51
50
|
|
52
51
|
it "overrides defaults" do
|
@@ -54,9 +53,8 @@ describe GithubBitbucketDeployer do
|
|
54
53
|
config.id_rsa = ""
|
55
54
|
end
|
56
55
|
|
57
|
-
override =
|
58
|
-
override.
|
59
|
-
@deployer.deploy(id_rsa: override).should be true
|
56
|
+
override = 'override-value'
|
57
|
+
expect(@deployer.deploy(id_rsa: override)).to be true
|
60
58
|
end
|
61
59
|
|
62
60
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,12 +3,17 @@ SimpleCov.start
|
|
3
3
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'rspec'
|
6
|
-
require '
|
6
|
+
require 'pp' # See https://github.com/fakefs/fakefs/issues/99
|
7
|
+
require 'pry-byebug'
|
8
|
+
require 'fakefs/spec_helpers'
|
7
9
|
|
8
|
-
|
9
|
-
config.order = "random"
|
10
|
-
end
|
10
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f }
|
11
11
|
|
12
12
|
ENV['ID_RSA']="id_rsa"
|
13
13
|
ENV['REPO_DIR']="foo"
|
14
14
|
|
15
|
+
require 'github_bitbucket_deployer'
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.order = "random"
|
19
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
config.include FakeFS::SpecHelpers, fakefs: true
|
3
|
+
config.before(:each, fakefs: true) do
|
4
|
+
source_dir = File.join(File.dirname(__FILE__), '..', '..')
|
5
|
+
FakeFS::FileSystem.clone(source_dir)
|
6
|
+
FakeFS::FileSystem.add(Dir.tmpdir)
|
7
|
+
FakeFS::FileSystem.add('/tmp')
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Prerequisites:
|
2
|
+
# * set up any method stubs on the git repo to raise error, e.g.
|
3
|
+
# before { allow(git_repo).to receive(:pull).and raise_error(error) }
|
4
|
+
# * define a method named retry_git_command to set up retry expectations, e.g.
|
5
|
+
# let(:retry_git_command) do
|
6
|
+
# expect(git_repo).to have_received(:pull).exactly(retry_limit).times
|
7
|
+
# end
|
8
|
+
shared_examples_for 'a git error handler' do
|
9
|
+
let(:safe_subject) { subject rescue error }
|
10
|
+
|
11
|
+
context 'with Git::GitExecuteError' do
|
12
|
+
let(:error) { Git::GitExecuteError.new('some git error') }
|
13
|
+
|
14
|
+
let(:retry_limit) { 3 }
|
15
|
+
|
16
|
+
it 'retries 3 times' do
|
17
|
+
safe_subject
|
18
|
+
retry_git_command
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'logs the error' do
|
22
|
+
expect(logger).to receive(:error)
|
23
|
+
safe_subject
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'raises a GithubBitbucketDeployer::CommandException' do
|
27
|
+
expect { subject }
|
28
|
+
.to raise_error(GithubBitbucketDeployer::CommandException)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with any other type of error' do
|
33
|
+
let(:error) { ArgumentError.new('some non-git error') }
|
34
|
+
|
35
|
+
let(:retry_limit) { 1 }
|
36
|
+
|
37
|
+
it 'only tries once' do
|
38
|
+
safe_subject
|
39
|
+
retry_git_command
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'raises the original exception' do
|
43
|
+
expect { subject }.to raise_error(error)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Prerequisites:
|
2
|
+
# Must define a method names run_git_command that yields control, e.g.
|
3
|
+
# def run_git_command
|
4
|
+
# expect(git_repo).to receive(:pull) { yield }
|
5
|
+
# end
|
6
|
+
shared_examples_for 'a git ssh wrapper' do
|
7
|
+
let(:temp_files) do
|
8
|
+
Dir.glob("#{Dir.tmpdir}/git-ssh-wrapper*").sort_by { |f| File.mtime(f) }
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'constructs a wrapper with the private key' do
|
12
|
+
expect(GitSSHWrapper).to receive(:with_wrapper)
|
13
|
+
.with(private_key: id_rsa).at_least(:once)
|
14
|
+
subject
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'writes the ssh wrapper to a tempfile' do
|
18
|
+
run_git_command do
|
19
|
+
expect(temp_files).to_not be_empty
|
20
|
+
end
|
21
|
+
subject
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'sets the GIT_SSH env var during command execution' do
|
25
|
+
run_git_command do
|
26
|
+
expect(temp_files).to include(ENV['GIT_SSH'])
|
27
|
+
end
|
28
|
+
subject
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when command is successful' do
|
32
|
+
it 'resets the GIT_SSH env var after exiting' do
|
33
|
+
expect { subject }.to_not change { ENV['GIT_SSH'] }
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'unlinks the temp ssh files' do
|
37
|
+
subject
|
38
|
+
expect(temp_files).to be_empty
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when command raises an error' do
|
43
|
+
let(:safe_subject) do
|
44
|
+
run_git_command do
|
45
|
+
raise GitExecuteError, 'some git error'
|
46
|
+
end
|
47
|
+
subject rescue 'whatever'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'resets the GIT_SSH env var after exiting' do
|
51
|
+
expect { safe_subject }.to_not change { ENV['GIT_SSH'] }.from(nil)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'unlinks the temp ssh files' do
|
55
|
+
safe_subject
|
56
|
+
expect(temp_files).to be_empty
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github_bitbucket_deployer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jessica Lynn Suttles
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-11-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: git
|
@@ -17,28 +17,48 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 1.2
|
20
|
+
version: '1.2'
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.9.1
|
21
24
|
type: :runtime
|
22
25
|
prerelease: false
|
23
26
|
version_requirements: !ruby/object:Gem::Requirement
|
24
27
|
requirements:
|
25
28
|
- - "~>"
|
26
29
|
- !ruby/object:Gem::Version
|
27
|
-
version: 1.2
|
30
|
+
version: '1.2'
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.9.1
|
28
34
|
- !ruby/object:Gem::Dependency
|
29
35
|
name: git-ssh-wrapper
|
30
36
|
requirement: !ruby/object:Gem::Requirement
|
31
37
|
requirements:
|
32
38
|
- - "~>"
|
33
39
|
- !ruby/object:Gem::Version
|
34
|
-
version: 0.1
|
40
|
+
version: '0.1'
|
35
41
|
type: :runtime
|
36
42
|
prerelease: false
|
37
43
|
version_requirements: !ruby/object:Gem::Requirement
|
38
44
|
requirements:
|
39
45
|
- - "~>"
|
40
46
|
- !ruby/object:Gem::Version
|
41
|
-
version: 0.1
|
47
|
+
version: '0.1'
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: retriable
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.1'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.1'
|
42
62
|
- !ruby/object:Gem::Dependency
|
43
63
|
name: simplecov
|
44
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,42 +79,42 @@ dependencies:
|
|
59
79
|
requirements:
|
60
80
|
- - "~>"
|
61
81
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
82
|
+
version: '3.5'
|
63
83
|
type: :development
|
64
84
|
prerelease: false
|
65
85
|
version_requirements: !ruby/object:Gem::Requirement
|
66
86
|
requirements:
|
67
87
|
- - "~>"
|
68
88
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
89
|
+
version: '3.5'
|
70
90
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
91
|
+
name: fakefs
|
72
92
|
requirement: !ruby/object:Gem::Requirement
|
73
93
|
requirements:
|
74
94
|
- - "~>"
|
75
95
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
96
|
+
version: 0.9.2
|
77
97
|
type: :development
|
78
98
|
prerelease: false
|
79
99
|
version_requirements: !ruby/object:Gem::Requirement
|
80
100
|
requirements:
|
81
101
|
- - "~>"
|
82
102
|
- !ruby/object:Gem::Version
|
83
|
-
version:
|
103
|
+
version: 0.9.2
|
84
104
|
- !ruby/object:Gem::Dependency
|
85
|
-
name:
|
105
|
+
name: pry-byebug
|
86
106
|
requirement: !ruby/object:Gem::Requirement
|
87
107
|
requirements:
|
88
108
|
- - "~>"
|
89
109
|
- !ruby/object:Gem::Version
|
90
|
-
version:
|
110
|
+
version: '3.3'
|
91
111
|
type: :development
|
92
112
|
prerelease: false
|
93
113
|
version_requirements: !ruby/object:Gem::Requirement
|
94
114
|
requirements:
|
95
115
|
- - "~>"
|
96
116
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
117
|
+
version: '3.3'
|
98
118
|
description: Deploys Github repos to bitbucket
|
99
119
|
email:
|
100
120
|
- jlsuttles@gmail.com
|
@@ -104,14 +124,17 @@ extensions: []
|
|
104
124
|
extra_rdoc_files: []
|
105
125
|
files:
|
106
126
|
- ".gitignore"
|
127
|
+
- ".rspec"
|
128
|
+
- ".ruby-version"
|
107
129
|
- ".travis.yml"
|
130
|
+
- CHANGELOG.md
|
108
131
|
- Gemfile
|
109
|
-
- Guardfile
|
110
132
|
- LICENSE
|
111
133
|
- README.md
|
112
134
|
- Rakefile
|
113
135
|
- github_bitbucket_deployer.gemspec
|
114
136
|
- lib/github_bitbucket_deployer.rb
|
137
|
+
- lib/github_bitbucket_deployer/clone_logger_fix.rb
|
115
138
|
- lib/github_bitbucket_deployer/configuration.rb
|
116
139
|
- lib/github_bitbucket_deployer/exceptions.rb
|
117
140
|
- lib/github_bitbucket_deployer/git.rb
|
@@ -120,6 +143,10 @@ files:
|
|
120
143
|
- spec/lib/github_bitbucket_deployer/git_spec.rb
|
121
144
|
- spec/lib/github_bitbucket_deployer_spec.rb
|
122
145
|
- spec/spec_helper.rb
|
146
|
+
- spec/support/fakefs.rb
|
147
|
+
- spec/support/git_helpers.rb
|
148
|
+
- spec/support/shared_examples/git_error_handler.rb
|
149
|
+
- spec/support/shared_examples/git_ssh_wrapper.rb
|
123
150
|
homepage: https://github.com/G5/github_bitbucket_deployer
|
124
151
|
licenses: []
|
125
152
|
metadata: {}
|
@@ -139,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
166
|
version: '0'
|
140
167
|
requirements: []
|
141
168
|
rubyforge_project:
|
142
|
-
rubygems_version: 2.4.
|
169
|
+
rubygems_version: 2.4.8
|
143
170
|
signing_key:
|
144
171
|
specification_version: 4
|
145
172
|
summary: Deploys public and private Github repos to bitbucket
|
@@ -148,3 +175,7 @@ test_files:
|
|
148
175
|
- spec/lib/github_bitbucket_deployer/git_spec.rb
|
149
176
|
- spec/lib/github_bitbucket_deployer_spec.rb
|
150
177
|
- spec/spec_helper.rb
|
178
|
+
- spec/support/fakefs.rb
|
179
|
+
- spec/support/git_helpers.rb
|
180
|
+
- spec/support/shared_examples/git_error_handler.rb
|
181
|
+
- spec/support/shared_examples/git_ssh_wrapper.rb
|