thegarage-gitx 2.4.2 → 2.5.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/thegarage/gitx/cli/integrate_command.rb +44 -19
- data/lib/thegarage/gitx/cli/start_command.rb +1 -1
- data/lib/thegarage/gitx/{extensions/string.rb → string_extensions.rb} +0 -0
- data/lib/thegarage/gitx/{extensions/thor.rb → thor_extensions.rb} +0 -0
- data/lib/thegarage/gitx/version.rb +1 -1
- data/lib/thegarage/gitx.rb +2 -2
- data/spec/spec_helper.rb +1 -4
- data/spec/support/stub_execution.rb +4 -10
- data/spec/thegarage/gitx/cli/integrate_command_spec.rb +58 -29
- data/spec/thegarage/gitx/cli/nuke_command_spec.rb +0 -60
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52a815b1f180eb401a49be082d797c8048500eba
|
4
|
+
data.tar.gz: 0fffe93eea6027c24774d152b3a7ce02f36c3021
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44d73575489db418bf94747b9318061d9f5939d9fff7ee7ebd1efe9242814b487cd857ef7bcfa9c8181d315a1f1241ba1c911dfade1f8016f3949c1c0ec35d2e
|
7
|
+
data.tar.gz: 3e9f8275982afa713d5f553e5ffb3653ee6b7e2a6a40c26cb23fcba9bee95aaa300e21f8115b52aca8194e5a6cf49192a4d1a281b5a050f51edf4404d1d0ef4a
|
@@ -3,49 +3,74 @@ require 'thegarage/gitx'
|
|
3
3
|
require 'thegarage/gitx/cli/base_command'
|
4
4
|
require 'thegarage/gitx/cli/update_command'
|
5
5
|
|
6
|
+
|
6
7
|
module Thegarage
|
7
8
|
module Gitx
|
8
9
|
module Cli
|
9
10
|
class IntegrateCommand < BaseCommand
|
10
11
|
desc 'integrate', 'integrate the current branch into one of the aggregate development branches (default = staging)'
|
12
|
+
method_option :resume, :type => :string, :aliases => '-r', :desc => 'resume merging of feature-branch'
|
11
13
|
def integrate(target_branch = 'staging')
|
12
14
|
branch = current_branch.name
|
13
|
-
|
15
|
+
if options[:resume]
|
16
|
+
resume
|
17
|
+
else
|
18
|
+
assert_integratable_branch!(branch, target_branch)
|
14
19
|
|
15
|
-
|
20
|
+
UpdateCommand.new.update
|
16
21
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
say "Integrating "
|
23
|
+
say "#{branch} ", :green
|
24
|
+
say "into "
|
25
|
+
say target_branch, :green
|
21
26
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
+
refresh_branch_from_remote target_branch
|
28
|
+
merge_feature_branch branch
|
29
|
+
run_cmd "git push origin HEAD"
|
30
|
+
checkout_branch branch
|
31
|
+
end
|
27
32
|
end
|
28
33
|
|
29
34
|
private
|
30
35
|
|
31
|
-
def
|
32
|
-
|
36
|
+
def assert_integratable_branch!(branch, target_branch)
|
37
|
+
assert_not_protected_branch!(branch, 'integrate') unless aggregate_branch?(target_branch)
|
38
|
+
raise "Only aggregate branches are allowed for integration: #{AGGREGATE_BRANCHES}" unless aggregate_branch?(target_branch) || target_branch == Thegarage::Gitx::BASE_BRANCH
|
33
39
|
end
|
34
40
|
|
35
41
|
# nuke local branch and pull fresh version from remote repo
|
36
42
|
def refresh_branch_from_remote(target_branch)
|
37
|
-
run_cmd "git fetch origin"
|
38
43
|
run_cmd "git branch -D #{target_branch}", :allow_failure => true
|
44
|
+
run_cmd "git fetch origin"
|
39
45
|
checkout_branch target_branch
|
40
46
|
end
|
41
47
|
|
42
|
-
def
|
43
|
-
|
48
|
+
def merge_feature_branch(branch)
|
49
|
+
begin
|
50
|
+
run_cmd "git merge #{branch}"
|
51
|
+
rescue
|
52
|
+
raise "Merge Conflict Occurred. Please fix merge conflict and rerun command with --resume #{branch} flag"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def resume
|
57
|
+
feature_branch = options[:resume]
|
58
|
+
say "Resuming Integration of "
|
59
|
+
say "#{feature_branch}", :green
|
60
|
+
|
61
|
+
run_cmd "git push origin HEAD"
|
62
|
+
until check_if_branch_exists? feature_branch
|
63
|
+
raise "#{feature_branch} does not exist please make sure you typed the correct branch and run command again"
|
64
|
+
end
|
65
|
+
checkout_branch feature_branch
|
66
|
+
end
|
67
|
+
|
68
|
+
def check_if_branch_exists?(branch)
|
69
|
+
return true if local_branches.include?(branch)
|
44
70
|
end
|
45
71
|
|
46
|
-
def
|
47
|
-
repo.
|
48
|
-
run_cmd "git push origin #{target_branch}:#{target_branch}"
|
72
|
+
def local_branches
|
73
|
+
@local_branches ||= repo.branches.each_name(:local).to_a.map { |branch| branch }
|
49
74
|
end
|
50
75
|
end
|
51
76
|
end
|
File without changes
|
File without changes
|
data/lib/thegarage/gitx.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,6 @@
|
|
1
1
|
# protip to prevent execution of shell commands during testsuite
|
2
2
|
# see http://stackoverflow.com/questions/1628586/mock-system-call-in-ruby
|
3
|
-
module
|
4
|
-
def included(base)
|
5
|
-
base.class_eval do
|
6
|
-
alias_method :execute_without_stub, :`
|
7
|
-
alias_method :`, :execute_with_stub
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
3
|
+
module Kernel
|
11
4
|
def execute_with_stub(cmd)
|
12
5
|
if cmd.include?('git')
|
13
6
|
puts "WARNING: stubbing command execution within tests of command: #{cmd}", :red
|
@@ -15,6 +8,7 @@ module ShellExecutionStub
|
|
15
8
|
execute_without_stub(cmd)
|
16
9
|
end
|
17
10
|
end
|
18
|
-
end
|
19
11
|
|
20
|
-
|
12
|
+
alias_method :execute_without_stub, :`
|
13
|
+
alias_method :`, :execute_with_stub
|
14
|
+
end
|
@@ -10,13 +10,10 @@ describe Thegarage::Gitx::Cli::IntegrateCommand do
|
|
10
10
|
}
|
11
11
|
end
|
12
12
|
let(:cli) { Thegarage::Gitx::Cli::IntegrateCommand.new(args, options, config) }
|
13
|
-
let(:
|
14
|
-
let(:repo) { cli.send(:repo) }
|
15
|
-
let(:remote_branch_names) { [] }
|
13
|
+
let(:branch) { double('fake branch', name: 'feature-branch') }
|
16
14
|
|
17
15
|
before do
|
18
|
-
allow(cli).to receive(:current_branch).and_return(
|
19
|
-
allow(repo).to receive(:branches).and_return(double(each_name: remote_branch_names))
|
16
|
+
allow(cli).to receive(:current_branch).and_return(branch)
|
20
17
|
end
|
21
18
|
|
22
19
|
describe '#integrate' do
|
@@ -24,13 +21,12 @@ describe Thegarage::Gitx::Cli::IntegrateCommand do
|
|
24
21
|
before do
|
25
22
|
allow(Thegarage::Gitx::Cli::UpdateCommand).to receive(:new).and_return(fake_update_command)
|
26
23
|
end
|
27
|
-
context 'when target branch is ommitted
|
28
|
-
let(:remote_branch_names) { ['origin/staging'] }
|
24
|
+
context 'when target branch is ommitted' do
|
29
25
|
before do
|
30
26
|
expect(fake_update_command).to receive(:update)
|
31
27
|
|
32
|
-
expect(cli).to receive(:run_cmd).with("git fetch origin").ordered
|
33
28
|
expect(cli).to receive(:run_cmd).with("git branch -D staging", allow_failure: true).ordered
|
29
|
+
expect(cli).to receive(:run_cmd).with("git fetch origin").ordered
|
34
30
|
expect(cli).to receive(:run_cmd).with("git checkout staging").ordered
|
35
31
|
expect(cli).to receive(:run_cmd).with("git merge feature-branch").ordered
|
36
32
|
expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
|
@@ -42,49 +38,82 @@ describe Thegarage::Gitx::Cli::IntegrateCommand do
|
|
42
38
|
should meet_expectations
|
43
39
|
end
|
44
40
|
end
|
45
|
-
context 'when
|
46
|
-
let(:remote_branch_names) { [] }
|
41
|
+
context 'when target branch == prototype' do
|
47
42
|
before do
|
48
43
|
expect(fake_update_command).to receive(:update)
|
49
44
|
|
50
|
-
expect(
|
51
|
-
|
52
|
-
expect(cli).to receive(:run_cmd).with('git push origin staging:staging').ordered
|
53
|
-
|
45
|
+
expect(cli).to receive(:run_cmd).with("git branch -D prototype", allow_failure: true).ordered
|
54
46
|
expect(cli).to receive(:run_cmd).with("git fetch origin").ordered
|
55
|
-
expect(cli).to receive(:run_cmd).with("git
|
56
|
-
expect(cli).to receive(:run_cmd).with("git checkout staging").ordered
|
47
|
+
expect(cli).to receive(:run_cmd).with("git checkout prototype").ordered
|
57
48
|
expect(cli).to receive(:run_cmd).with("git merge feature-branch").ordered
|
58
49
|
expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
|
59
50
|
expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered
|
60
51
|
|
61
|
-
cli.integrate
|
52
|
+
cli.integrate 'prototype'
|
62
53
|
end
|
63
|
-
it '
|
54
|
+
it 'runs expected commands' do
|
64
55
|
should meet_expectations
|
65
56
|
end
|
66
57
|
end
|
67
|
-
context 'when target branch
|
68
|
-
|
58
|
+
context 'when target branch != staging || prototype' do
|
59
|
+
it 'raises an error' do
|
60
|
+
|
61
|
+
expect { cli.integrate('some-other-branch') }.to raise_error(/Only aggregate branches are allowed for integration/)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
context 'when merge conflicts occur' do
|
69
65
|
before do
|
70
66
|
expect(fake_update_command).to receive(:update)
|
71
67
|
|
68
|
+
expect(cli).to receive(:run_cmd).with("git branch -D staging", allow_failure: true).ordered
|
72
69
|
expect(cli).to receive(:run_cmd).with("git fetch origin").ordered
|
73
|
-
expect(cli).to receive(:run_cmd).with("git
|
74
|
-
expect(cli).to receive(:run_cmd).with("git
|
75
|
-
|
70
|
+
expect(cli).to receive(:run_cmd).with("git checkout staging").ordered
|
71
|
+
expect(cli).to receive(:run_cmd).with("git merge feature-branch").and_raise('git merge feature-branch failed').ordered
|
72
|
+
|
73
|
+
expect { cli.integrate }.to raise_error("Merge Conflict Occurred. Please fix merge conflict and rerun command with --resume feature-branch flag")
|
74
|
+
end
|
75
|
+
it 'raises a helpful error' do
|
76
|
+
should meet_expectations
|
77
|
+
end
|
78
|
+
end
|
79
|
+
context 'with --resume "feature-branch" flag when feature-branch exists' do
|
80
|
+
let(:options) do
|
81
|
+
{
|
82
|
+
resume: 'feature-branch'
|
83
|
+
}
|
84
|
+
end
|
85
|
+
let(:repo) { cli.send(:repo) }
|
86
|
+
let(:branches) { double(each_name: ['feature-branch']) }
|
87
|
+
before do
|
88
|
+
expect(repo).to receive(:branches).and_return(branches)
|
89
|
+
|
90
|
+
expect(cli).not_to receive(:run_cmd).with("git branch -D staging")
|
76
91
|
expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
|
77
|
-
expect(
|
92
|
+
expect(options[:resume]).to match("feature-branch")
|
93
|
+
expect(cli).to receive(:run_cmd).with("git checkout feature-branch")
|
78
94
|
|
79
|
-
cli.integrate
|
95
|
+
cli.integrate
|
80
96
|
end
|
81
|
-
it '
|
97
|
+
it 'does not delete local staging branch' do
|
82
98
|
should meet_expectations
|
83
99
|
end
|
84
100
|
end
|
85
|
-
context '
|
86
|
-
|
87
|
-
|
101
|
+
context 'with --resume "feature-branch" flag when feature-branch does not exist' do
|
102
|
+
let(:options) do
|
103
|
+
{
|
104
|
+
resume: 'feature-branch'
|
105
|
+
}
|
106
|
+
end
|
107
|
+
before do
|
108
|
+
expect(cli).not_to receive(:run_cmd).with("git branch -D staging")
|
109
|
+
expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
|
110
|
+
expect(options[:resume]).to match("feature-branch")
|
111
|
+
expect(cli).not_to receive(:run_cmd).with("git checkout feature-branch").and_raise('some error').ordered
|
112
|
+
|
113
|
+
expect { cli.integrate }.to raise_error("#{options[:resume]} does not exist please make sure you typed the correct branch and run command again")
|
114
|
+
end
|
115
|
+
it 'raises error' do
|
116
|
+
should meet_expectations
|
88
117
|
end
|
89
118
|
end
|
90
119
|
end
|
@@ -101,65 +101,5 @@ describe Thegarage::Gitx::Cli::NukeCommand do
|
|
101
101
|
expect { cli.nuke('prototype') }.to raise_error(/No known good tag found for branch/)
|
102
102
|
end
|
103
103
|
end
|
104
|
-
context 'when database migrations exist and user cancels operation' do
|
105
|
-
let(:buildtag) { 'build-master-2013-10-01-01' }
|
106
|
-
let(:good_branch) { 'master' }
|
107
|
-
let(:bad_branch) { 'prototype' }
|
108
|
-
let(:migrations) do
|
109
|
-
%w( db/migrate/20140715194946_create_users.rb db/migrate/20140730063034_update_user_account.rb ).join("\n")
|
110
|
-
end
|
111
|
-
before do
|
112
|
-
FileUtils.mkdir_p('db/migrate')
|
113
|
-
|
114
|
-
expect(cli).to receive(:current_build_tag).with(good_branch).and_return(buildtag)
|
115
|
-
|
116
|
-
expect(cli).to receive(:ask).and_return(good_branch)
|
117
|
-
expect(cli).to receive(:yes?).with('Reset prototype to build-master-2013-10-01-01? (y/n)', :green).and_return(true)
|
118
|
-
expect(cli).to receive(:run_cmd).with("git diff build-master-2013-10-01-01...prototype --name-only db/migrate").and_return(migrations)
|
119
|
-
expect(cli).to receive(:yes?).with('Are you sure you want to nuke prototype? (y/n) ', :green).and_return(false)
|
120
|
-
|
121
|
-
cli.nuke 'prototype'
|
122
|
-
end
|
123
|
-
after do
|
124
|
-
FileUtils.rm_rf('db/migrate')
|
125
|
-
end
|
126
|
-
it 'prompts for nuke confirmation' do
|
127
|
-
should meet_expectations
|
128
|
-
end
|
129
|
-
end
|
130
|
-
context 'when database migrations exist and user approves operation' do
|
131
|
-
let(:buildtag) { 'build-master-2013-10-01-01' }
|
132
|
-
let(:good_branch) { 'master' }
|
133
|
-
let(:bad_branch) { 'prototype' }
|
134
|
-
let(:migrations) do
|
135
|
-
%w( db/migrate/20140715194946_create_users.rb db/migrate/20140730063034_update_user_account.rb ).join("\n")
|
136
|
-
end
|
137
|
-
before do
|
138
|
-
FileUtils.mkdir_p('db/migrate')
|
139
|
-
|
140
|
-
expect(cli).to receive(:current_build_tag).with(good_branch).and_return(buildtag)
|
141
|
-
|
142
|
-
expect(cli).to receive(:ask).and_return(good_branch)
|
143
|
-
expect(cli).to receive(:yes?).with('Reset prototype to build-master-2013-10-01-01? (y/n)', :green).and_return(true)
|
144
|
-
expect(cli).to receive(:run_cmd).with("git diff build-master-2013-10-01-01...prototype --name-only db/migrate").and_return(migrations)
|
145
|
-
expect(cli).to receive(:yes?).with('Are you sure you want to nuke prototype? (y/n) ', :green).and_return(true)
|
146
|
-
|
147
|
-
expect(cli).to receive(:run_cmd).with("git checkout master").ordered
|
148
|
-
expect(cli).to receive(:run_cmd).with("git branch -D prototype", allow_failure: true).ordered
|
149
|
-
expect(cli).to receive(:run_cmd).with("git push origin --delete prototype", allow_failure: true).ordered
|
150
|
-
expect(cli).to receive(:run_cmd).with("git checkout -b prototype build-master-2013-10-01-01").ordered
|
151
|
-
expect(cli).to receive(:run_cmd).with("git push origin prototype").ordered
|
152
|
-
expect(cli).to receive(:run_cmd).with("git branch --set-upstream-to origin/prototype").ordered
|
153
|
-
expect(cli).to receive(:run_cmd).with("git checkout master").ordered
|
154
|
-
|
155
|
-
cli.nuke 'prototype'
|
156
|
-
end
|
157
|
-
after do
|
158
|
-
FileUtils.rm_rf('db/migrate')
|
159
|
-
end
|
160
|
-
it 'prompts for nuke confirmation' do
|
161
|
-
should meet_expectations
|
162
|
-
end
|
163
|
-
end
|
164
104
|
end
|
165
105
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thegarage-gitx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0.alpha1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Sonnek
|
@@ -271,8 +271,8 @@ files:
|
|
271
271
|
- lib/thegarage/gitx/cli/start_command.rb
|
272
272
|
- lib/thegarage/gitx/cli/track_command.rb
|
273
273
|
- lib/thegarage/gitx/cli/update_command.rb
|
274
|
-
- lib/thegarage/gitx/
|
275
|
-
- lib/thegarage/gitx/
|
274
|
+
- lib/thegarage/gitx/string_extensions.rb
|
275
|
+
- lib/thegarage/gitx/thor_extensions.rb
|
276
276
|
- lib/thegarage/gitx/version.rb
|
277
277
|
- spec/fixtures/vcr_cassettes/pull_request_does_exist.yml
|
278
278
|
- spec/fixtures/vcr_cassettes/pull_request_does_not_exist.yml
|
@@ -309,9 +309,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
309
309
|
version: '0'
|
310
310
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
311
311
|
requirements:
|
312
|
-
- - "
|
312
|
+
- - ">"
|
313
313
|
- !ruby/object:Gem::Version
|
314
|
-
version:
|
314
|
+
version: 1.3.1
|
315
315
|
requirements: []
|
316
316
|
rubyforge_project:
|
317
317
|
rubygems_version: 2.2.2
|