git_reflow 0.8.6 → 0.8.7
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/.gitignore +1 -0
- data/CHANGELOG.md +348 -348
- data/Gemfile.lock +13 -15
- data/LICENSE +20 -20
- data/README.rdoc +461 -461
- data/Rakefile +8 -8
- data/bin/console +7 -7
- data/bin/setup +6 -6
- data/circle.yml +5 -5
- data/exe/git-reflow +36 -36
- data/git_reflow.gemspec +1 -1
- data/lib/git_reflow/commands/deliver.rb +10 -10
- data/lib/git_reflow/commands/refresh.rb +20 -20
- data/lib/git_reflow/commands/review.rb +13 -13
- data/lib/git_reflow/commands/setup.rb +11 -11
- data/lib/git_reflow/commands/stage.rb +9 -9
- data/lib/git_reflow/commands/start.rb +22 -22
- data/lib/git_reflow/commands/status.rb +7 -7
- data/lib/git_reflow/config.rb +9 -9
- data/lib/git_reflow/git_server/base.rb +68 -68
- data/lib/git_reflow/git_server/bit_bucket/pull_request.rb +84 -84
- data/lib/git_reflow/git_server/bit_bucket.rb +101 -101
- data/lib/git_reflow/git_server/git_hub/pull_request.rb +4 -1
- data/lib/git_reflow/git_server/pull_request.rb +11 -2
- data/lib/git_reflow/git_server.rb +63 -63
- data/lib/git_reflow/logger.rb +49 -0
- data/lib/git_reflow/merge_error.rb +9 -9
- data/lib/git_reflow/os_detector.rb +23 -23
- data/lib/git_reflow/rspec/command_line_helpers.rb +12 -8
- data/lib/git_reflow/rspec/stub_helpers.rb +13 -13
- data/lib/git_reflow/rspec.rb +2 -2
- data/lib/git_reflow/sandbox.rb +11 -6
- data/lib/git_reflow/version.rb +1 -1
- data/lib/git_reflow/workflow.rb +59 -59
- data/lib/git_reflow/workflows/core.rb +238 -238
- data/lib/git_reflow/workflows/flat_merge.rb +10 -10
- data/lib/git_reflow.rb +11 -0
- data/spec/fixtures/awesome_workflow.rb +7 -0
- data/spec/fixtures/git/git_config +7 -0
- data/spec/fixtures/issues/comment.json.erb +27 -0
- data/spec/fixtures/issues/comments.json +29 -0
- data/spec/fixtures/issues/comments.json.erb +15 -0
- data/spec/fixtures/pull_requests/comment.json.erb +45 -0
- data/spec/fixtures/pull_requests/comments.json +47 -0
- data/spec/fixtures/pull_requests/comments.json.erb +15 -0
- data/spec/fixtures/pull_requests/commits.json +29 -0
- data/spec/fixtures/pull_requests/external_pull_request.json +145 -0
- data/spec/fixtures/pull_requests/pull_request.json +142 -0
- data/spec/fixtures/pull_requests/pull_request.json.erb +142 -0
- data/spec/fixtures/pull_requests/pull_request_exists_error.json +32 -0
- data/spec/fixtures/pull_requests/pull_requests.json +136 -0
- data/spec/fixtures/repositories/commit.json +53 -0
- data/spec/fixtures/repositories/commit.json.erb +53 -0
- data/spec/fixtures/repositories/commits.json.erb +13 -0
- data/spec/fixtures/repositories/statuses.json +31 -0
- data/spec/fixtures/workflow_with_super.rb +8 -0
- data/spec/lib/git_reflow/config_spec.rb +74 -0
- data/spec/lib/git_reflow/git_helpers_spec.rb +182 -0
- data/spec/lib/git_reflow/git_server/bit_bucket_spec.rb +81 -0
- data/spec/lib/git_reflow/git_server/git_hub/pull_request_spec.rb +587 -0
- data/spec/lib/git_reflow/git_server/git_hub_spec.rb +221 -0
- data/spec/lib/git_reflow/git_server/pull_request_spec.rb +524 -0
- data/spec/lib/git_reflow/git_server_spec.rb +101 -0
- data/spec/lib/git_reflow/logger_spec.rb +18 -0
- data/spec/lib/git_reflow/sandbox_spec.rb +15 -0
- data/spec/lib/git_reflow/workflow_spec.rb +59 -0
- data/spec/lib/git_reflow/workflows/core_spec.rb +665 -0
- data/spec/lib/git_reflow/workflows/flat_merge_spec.rb +59 -0
- data/spec/lib/git_reflow_spec.rb +75 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/fake_github.rb +128 -0
- data/spec/support/fixtures.rb +54 -0
- data/spec/support/github_helpers.rb +109 -0
- data/spec/support/mock_pull_request.rb +17 -0
- data/spec/support/web_mocks.rb +39 -0
- metadata +83 -6
@@ -0,0 +1,221 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GitReflow::GitServer::GitHub do
|
4
|
+
let(:user) { 'reenhanced' }
|
5
|
+
let(:password) { 'shazam' }
|
6
|
+
let(:repo) { 'repo' }
|
7
|
+
let(:oauth_token_hash) { Hashie::Mash.new({ token: 'a1b2c3d4e5f6g7h8i9j0'}) }
|
8
|
+
let(:hostname) { 'hostname.local' }
|
9
|
+
let(:github_site) { 'https://github.com' }
|
10
|
+
let(:github_api_endpoint) { 'https://api.github.com' }
|
11
|
+
let(:enterprise_site) { 'https://github.gittyup.com' }
|
12
|
+
let(:enterprise_api) { 'https://github.gittyup.com/api/v3' }
|
13
|
+
let(:github) { stub_github_with(pull: existing_pull_request) }
|
14
|
+
let!(:github_api) { github.connection }
|
15
|
+
let(:existing_pull_request) { Fixture.new('pull_requests/pull_request.json').to_json_hashie }
|
16
|
+
let(:existing_pull_requests) { Fixture.new('pull_requests/pull_requests.json').to_json_hashie }
|
17
|
+
|
18
|
+
before do
|
19
|
+
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
20
|
+
values = {
|
21
|
+
"Please enter your GitHub username: " => user,
|
22
|
+
"Please enter your GitHub password (we do NOT store this): " => password,
|
23
|
+
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
24
|
+
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api
|
25
|
+
}
|
26
|
+
return_value = values[question]
|
27
|
+
question = ""
|
28
|
+
return_value
|
29
|
+
end
|
30
|
+
|
31
|
+
allow(github.class).to receive(:remote_user).and_return(user)
|
32
|
+
allow(github.class).to receive(:remote_repo_name).and_return(repo)
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#initialize(options)' do
|
36
|
+
subject { GitReflow::GitServer::GitHub.new({}) }
|
37
|
+
|
38
|
+
it 'sets the reflow git server provider to GitHub in the git config' do
|
39
|
+
expect(GitReflow::Config).to receive(:set).once.with('github.site', github_site, local: false)
|
40
|
+
expect(GitReflow::Config).to receive(:set).once.with('github.endpoint', github_api_endpoint, local: false)
|
41
|
+
expect(GitReflow::Config).to receive(:set).once.with('reflow.git-server', 'GitHub', local: false)
|
42
|
+
subject
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'using enterprise' do
|
46
|
+
subject { GitReflow::GitServer::GitHub.new(enterprise: true) }
|
47
|
+
|
48
|
+
it 'sets the enterprise site and api as the site and api endpoints for the GitHub provider in the git config' do
|
49
|
+
expect(GitReflow::Config).to receive(:set).once.with('github.site', enterprise_site, local: false)
|
50
|
+
expect(GitReflow::Config).to receive(:set).once.with('github.endpoint', enterprise_api, local: false)
|
51
|
+
expect(GitReflow::Config).to receive(:set).once.with('reflow.git-server', 'GitHub', local: false)
|
52
|
+
subject
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'storing git config settings only for this project' do
|
58
|
+
subject { GitReflow::GitServer::GitHub.new(project_only: true) }
|
59
|
+
|
60
|
+
before do
|
61
|
+
expect(GitReflow::Config).to receive(:get).twice.with('reflow.local-projects', all: true).and_return("#{user}/#{repo}")
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'sets the enterprise site and api as the site and api endpoints for the GitHub provider in the git config' do
|
65
|
+
expect(GitReflow::Config).to receive(:set).once.with('github.site', github_site, local: true).and_call_original
|
66
|
+
expect(GitReflow::Config).to receive(:set).once.with('github.endpoint', github_api_endpoint, local: true)
|
67
|
+
expect(GitReflow::Config).to receive(:set).once.with('reflow.git-server', 'GitHub', local: true)
|
68
|
+
subject
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#authenticate' do
|
75
|
+
let(:github) { GitReflow::GitServer::GitHub.new({}) }
|
76
|
+
let!(:github_api) { Github::Client.new }
|
77
|
+
let(:github_authorizations) { Github::Client::Authorizations.new }
|
78
|
+
subject { github.authenticate }
|
79
|
+
|
80
|
+
before do
|
81
|
+
allow(GitReflow::GitServer::GitHub).to receive(:user).and_return('reenhanced')
|
82
|
+
allow(github_api).to receive(:oauth).and_return(github_authorizations)
|
83
|
+
allow(github_api).to receive_message_chain(:oauth, :all).and_return([])
|
84
|
+
allow(github).to receive(:run).with('hostname', loud: false).and_return(hostname)
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'not yet authenticated' do
|
88
|
+
context 'with valid GitHub credentials' do
|
89
|
+
|
90
|
+
before do
|
91
|
+
allow(Github::Client).to receive(:new).and_return(github_api)
|
92
|
+
allow(github_authorizations).to receive(:authenticated?).and_return(true)
|
93
|
+
allow(github_api.oauth).to receive(:create).with({ scopes: ['repo'], note: "git-reflow (#{hostname})" }).and_return(oauth_token_hash)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "notifies the user of successful setup" do
|
97
|
+
expect { subject }.to have_said "Your GitHub account was successfully setup!", :success
|
98
|
+
end
|
99
|
+
|
100
|
+
it "creates a new GitHub oauth token" do
|
101
|
+
expect(github_api.oauth).to receive(:create).and_return(oauth_token_hash)
|
102
|
+
subject
|
103
|
+
end
|
104
|
+
|
105
|
+
it "creates git config keys for github connections" do
|
106
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.site \"#{GitReflow::GitServer::GitHub.site_url}\"", blocking: false
|
107
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.endpoint \"#{GitReflow::GitServer::GitHub.api_endpoint}\"", blocking: false
|
108
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.oauth-token \"#{oauth_token_hash[:token]}\"", blocking: false
|
109
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all reflow.git-server \"GitHub\"", blocking: false
|
110
|
+
end
|
111
|
+
|
112
|
+
context "exclusive to project" do
|
113
|
+
let(:github) do
|
114
|
+
allow(GitReflow::GitServer::GitHub).to receive(:project_only?).and_return(true)
|
115
|
+
allow(GitReflow::GitServer::GitHub).to receive(:remote_user).and_return(user)
|
116
|
+
allow(GitReflow::GitServer::GitHub).to receive(:remote_repo_name).and_return(repo)
|
117
|
+
GitReflow::GitServer::GitHub.new(project_only: true)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "creates _local_ git config keys for github connections" do
|
121
|
+
expect{ subject }.to_not have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.site \"#{GitReflow::GitServer::GitHub.site_url}\"", blocking: false
|
122
|
+
expect{ subject }.to_not have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.endpoint \"#{GitReflow::GitServer::GitHub.api_endpoint}\"", blocking: false
|
123
|
+
expect{ subject }.to_not have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.oauth-token \"#{oauth_token_hash[:token]}\"", blocking: false
|
124
|
+
expect{ subject }.to_not have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all reflow.git-server \"GitHub\"", blocking: false
|
125
|
+
|
126
|
+
expect{ subject }.to have_run_command_silently "git config --replace-all github.site \"#{GitReflow::GitServer::GitHub.site_url}\"", blocking: false
|
127
|
+
expect{ subject }.to have_run_command_silently "git config --replace-all github.endpoint \"#{GitReflow::GitServer::GitHub.api_endpoint}\"", blocking: false
|
128
|
+
expect{ subject }.to have_run_command_silently "git config --replace-all github.oauth-token \"#{oauth_token_hash[:token]}\"", blocking: false
|
129
|
+
expect{ subject }.to have_run_command_silently "git config --replace-all reflow.git-server \"GitHub\"", blocking: false
|
130
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --add reflow.local-projects \"#{user}/#{repo}\"", blocking: false
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "use GitHub enterprise account" do
|
135
|
+
let(:github) { GitReflow::GitServer::GitHub.new(enterprise: true) }
|
136
|
+
before { allow(GitReflow::GitServer::GitHub).to receive(:@using_enterprise).and_return(true) }
|
137
|
+
it "creates git config keys for github connections" do
|
138
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.site \"#{enterprise_site}\"", blocking: false
|
139
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.endpoint \"#{enterprise_api}\"", blocking: false
|
140
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.oauth-token \"#{oauth_token_hash[:token]}\"", blocking: false
|
141
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all reflow.git-server \"GitHub\"", blocking: false
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "with invalid GitHub credentials" do
|
147
|
+
let(:unauthorized_error_response) {{
|
148
|
+
response_headers: {'content-type' => 'application/json; charset=utf-8', status: 'Unauthorized'},
|
149
|
+
method: 'GET',
|
150
|
+
status: '401',
|
151
|
+
body: { error: "GET https://api.github.com/authorizations: 401 Bad credentials" }
|
152
|
+
}}
|
153
|
+
|
154
|
+
before do
|
155
|
+
allow(Github::Client).to receive(:new).and_raise Github::Error::Unauthorized.new(unauthorized_error_response)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "notifies user of invalid login details" do
|
159
|
+
expect { subject }.to have_said "Github Authentication Error: #{Github::Error::Unauthorized.new(unauthorized_error_response).inspect}", :error
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe '#create_pull_request(options)' do
|
166
|
+
let(:title) { 'Fresh title' }
|
167
|
+
let(:body) { 'Funky body' }
|
168
|
+
let(:current_branch) { 'new-feature' }
|
169
|
+
|
170
|
+
subject { github.create_pull_request({ title: title, body: body, base: 'master' }) }
|
171
|
+
|
172
|
+
before do
|
173
|
+
allow(github.class).to receive(:current_branch).and_return(current_branch)
|
174
|
+
allow(GitReflow).to receive(:git_server).and_return(github)
|
175
|
+
stub_request(:post, %r{/repos/#{user}/#{repo}/pulls}).
|
176
|
+
to_return(body: Fixture.new('pull_requests/pull_request.json').to_s, status: 201, headers: {content_type: "application/json; charset=utf-8"})
|
177
|
+
end
|
178
|
+
|
179
|
+
specify { expect(subject.class.to_s).to eq('GitReflow::GitServer::GitHub::PullRequest') }
|
180
|
+
|
181
|
+
it 'creates a pull request using the remote user and repo' do
|
182
|
+
allow(github_api).to receive(:pull_requests)
|
183
|
+
expect(github_api.pull_requests).to receive(:create).with(user, repo, title: title, body: body, head: "#{user}:#{current_branch}", base: 'master').and_return(existing_pull_request)
|
184
|
+
subject
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe '#find_open_pull_request(from, to)' do
|
189
|
+
subject { github.find_open_pull_request({ from: 'new-feature', to: 'master'}) }
|
190
|
+
|
191
|
+
it 'looks for an open pull request matching the remote user/repo' do
|
192
|
+
expect(subject.number).to eq(existing_pull_requests.first.number)
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'no pull request exists' do
|
196
|
+
before do
|
197
|
+
allow(github_api).to receive(:pull_requests)
|
198
|
+
expect(github_api.pull_requests).to receive(:all).and_return([])
|
199
|
+
end
|
200
|
+
it { is_expected.to eq(nil) }
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe '#get_build_status(sha)' do
|
205
|
+
let(:sha) { '6dcb09b5b57875f334f61aebed695e2e4193db5e' }
|
206
|
+
subject { github.get_build_status(sha) }
|
207
|
+
before { allow(github_api).to receive_message_chain(:repos, :statuses) }
|
208
|
+
|
209
|
+
it 'gets the latest build status for the given commit hash' do
|
210
|
+
expect(github_api.repos.statuses).to receive(:all).with(user, repo, sha).and_return([{ state: 'success'}])
|
211
|
+
subject
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe '#comment_authors_for_pull_request(pull_request, options = {})' do
|
216
|
+
end
|
217
|
+
|
218
|
+
describe '#get_committed_time(commit_sha)' do
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|