From 74937587f571de8654787138f4ea9d70b8bfe586 Mon Sep 17 00:00:00 2001 From: cgullick Date: Mon, 22 Sep 2014 10:56:45 -0500 Subject: [PATCH] fixed merge conflicts and added red to error * fixed merge conflicts from master * added red color to merge conflict error * changed version to 2.5.0.beta3 --- lib/thegarage/gitx.rb | 4 +- lib/thegarage/gitx/cli/integrate_command.rb | 23 +++++-- lib/thegarage/gitx/cli/start_command.rb | 2 +- .../string.rb} | 0 .../thor.rb} | 0 lib/thegarage/gitx/version.rb | 2 +- spec/spec_helper.rb | 5 +- .../gitx/cli/integrate_command_spec.rb | 64 +++++++++++-------- spec/thegarage/gitx/cli/nuke_command_spec.rb | 60 +++++++++++++++++ 9 files changed, 121 insertions(+), 39 deletions(-) rename lib/thegarage/gitx/{string_extensions.rb => extensions/string.rb} (100%) rename lib/thegarage/gitx/{thor_extensions.rb => extensions/thor.rb} (100%) diff --git a/lib/thegarage/gitx.rb b/lib/thegarage/gitx.rb index 84bbee1..094a9b5 100644 --- a/lib/thegarage/gitx.rb +++ b/lib/thegarage/gitx.rb @@ -1,6 +1,6 @@ require 'thegarage/gitx/version' -require 'thegarage/gitx/string_extensions' -require 'thegarage/gitx/thor_extensions' +require 'thegarage/gitx/extensions/string' +require 'thegarage/gitx/extensions/thor' module Thegarage module Gitx diff --git a/lib/thegarage/gitx/cli/integrate_command.rb b/lib/thegarage/gitx/cli/integrate_command.rb index 764bb56..8ddfbf1 100644 --- a/lib/thegarage/gitx/cli/integrate_command.rb +++ b/lib/thegarage/gitx/cli/integrate_command.rb @@ -15,7 +15,7 @@ def integrate(target_branch = 'staging') if options[:resume] resume else - assert_integratable_branch!(branch, target_branch) + assert_aggregate_branch!(target_branch) UpdateCommand.new.update @@ -24,7 +24,8 @@ def integrate(target_branch = 'staging') say "into " say target_branch, :green - refresh_branch_from_remote target_branch + create_remote_branch(target_branch) unless remote_branch_exists?(target_branch) + refresh_branch_from_remote(target_branch) merge_feature_branch branch run_cmd "git push origin HEAD" checkout_branch branch @@ -33,15 +34,14 @@ def integrate(target_branch = 'staging') private - def assert_integratable_branch!(branch, target_branch) - assert_not_protected_branch!(branch, 'integrate') unless aggregate_branch?(target_branch) - raise "Only aggregate branches are allowed for integration: #{AGGREGATE_BRANCHES}" unless aggregate_branch?(target_branch) || target_branch == Thegarage::Gitx::BASE_BRANCH + def assert_aggregate_branch!(target_branch) + fail "Invalid aggregate branch: #{target_branch} must be one of supported aggregate branches #{AGGREGATE_BRANCHES}" unless aggregate_branch?(target_branch) end # nuke local branch and pull fresh version from remote repo def refresh_branch_from_remote(target_branch) - run_cmd "git branch -D #{target_branch}", :allow_failure => true run_cmd "git fetch origin" + run_cmd "git branch -D #{target_branch}", :allow_failure => true checkout_branch target_branch end @@ -49,7 +49,7 @@ def merge_feature_branch(branch) begin run_cmd "git merge #{branch}" rescue - say "Merge Conflict Occurred. Please fix merge conflict and rerun command with --resume #{branch} flag" + say "Merge Conflict Occurred. Please fix merge conflict and rerun command with --resume #{branch} flag", :red exit end end @@ -73,6 +73,15 @@ def check_if_branch_exists?(branch) def local_branches @local_branches ||= repo.branches.each_name(:local).map { |branch| branch } end + + def remote_branch_exists?(target_branch) + repo.branches.each_name(:remote).include?("origin/#{target_branch}") + end + + def create_remote_branch(target_branch) + repo.create_branch(target_branch, Thegarage::Gitx::BASE_BRANCH) + run_cmd "git push origin #{target_branch}:#{target_branch}" + end end end end diff --git a/lib/thegarage/gitx/cli/start_command.rb b/lib/thegarage/gitx/cli/start_command.rb index 24e062e..c41ea26 100644 --- a/lib/thegarage/gitx/cli/start_command.rb +++ b/lib/thegarage/gitx/cli/start_command.rb @@ -17,7 +17,7 @@ def start(branch_name = nil) checkout_branch Thegarage::Gitx::BASE_BRANCH run_cmd 'git pull' - repo.create_branch branch_name, 'master' + repo.create_branch branch_name, Thegarage::Gitx::BASE_BRANCH checkout_branch branch_name end diff --git a/lib/thegarage/gitx/string_extensions.rb b/lib/thegarage/gitx/extensions/string.rb similarity index 100% rename from lib/thegarage/gitx/string_extensions.rb rename to lib/thegarage/gitx/extensions/string.rb diff --git a/lib/thegarage/gitx/thor_extensions.rb b/lib/thegarage/gitx/extensions/thor.rb similarity index 100% rename from lib/thegarage/gitx/thor_extensions.rb rename to lib/thegarage/gitx/extensions/thor.rb diff --git a/lib/thegarage/gitx/version.rb b/lib/thegarage/gitx/version.rb index daa4bf1..f791bc2 100644 --- a/lib/thegarage/gitx/version.rb +++ b/lib/thegarage/gitx/version.rb @@ -1,5 +1,5 @@ module Thegarage module Gitx - VERSION = '2.5.0.beta2' + VERSION = '2.5.0.beta3' end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index bd5a16a..835e053 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,8 @@ require 'coveralls' -Coveralls.wear! +Coveralls.wear! do + ::SimpleCov.add_filter 'spec' + ::SimpleCov.add_filter 'lib/thegarage/gitx/extensions' +end require 'rubygems' require 'bundler/setup' diff --git a/spec/thegarage/gitx/cli/integrate_command_spec.rb b/spec/thegarage/gitx/cli/integrate_command_spec.rb index b974db9..ee5167f 100644 --- a/spec/thegarage/gitx/cli/integrate_command_spec.rb +++ b/spec/thegarage/gitx/cli/integrate_command_spec.rb @@ -10,10 +10,13 @@ } end let(:cli) { Thegarage::Gitx::Cli::IntegrateCommand.new(args, options, config) } - let(:branch) { double('fake branch', name: 'feature-branch') } + let(:current_branch) { double('fake branch', name: 'feature-branch', head?: true) } + let(:repo) { cli.send(:repo) } + let(:remote_branch_names) { [] } before do - allow(cli).to receive(:current_branch).and_return(branch) + allow(cli).to receive(:current_branch).and_return(current_branch) + allow(repo).to receive(:branches).and_return(double(each_name: remote_branch_names)) end describe '#integrate' do @@ -21,12 +24,13 @@ before do allow(Thegarage::Gitx::Cli::UpdateCommand).to receive(:new).and_return(fake_update_command) end - context 'when target branch is ommitted' do + context 'when target branch is ommitted and remote branch exists' do + let(:remote_branch_names) { ['origin/staging'] } before do expect(fake_update_command).to receive(:update) - expect(cli).to receive(:run_cmd).with("git branch -D staging", allow_failure: true).ordered expect(cli).to receive(:run_cmd).with("git fetch origin").ordered + expect(cli).to receive(:run_cmd).with("git branch -D staging", allow_failure: true).ordered expect(cli).to receive(:run_cmd).with("git checkout staging").ordered expect(cli).to receive(:run_cmd).with("git merge feature-branch").ordered expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered @@ -38,12 +42,35 @@ should meet_expectations end end - context 'when target branch == prototype' do + context 'when staging branch does not exist remotely' do + let(:remote_branch_names) { [] } + before do + expect(fake_update_command).to receive(:update) + + expect(repo).to receive(:create_branch).with('staging', 'master') + + expect(cli).to receive(:run_cmd).with('git push origin staging:staging').ordered + + expect(cli).to receive(:run_cmd).with("git fetch origin").ordered + expect(cli).to receive(:run_cmd).with("git branch -D staging", allow_failure: true).ordered + expect(cli).to receive(:run_cmd).with("git checkout staging").ordered + expect(cli).to receive(:run_cmd).with("git merge feature-branch").ordered + expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered + expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered + + cli.integrate + end + it 'creates remote aggregate branch' do + should meet_expectations + end + end + context 'when target branch == prototype and remote branch exists' do + let(:remote_branch_names) { ['origin/prototype'] } before do expect(fake_update_command).to receive(:update) - expect(cli).to receive(:run_cmd).with("git branch -D prototype", allow_failure: true).ordered expect(cli).to receive(:run_cmd).with("git fetch origin").ordered + expect(cli).to receive(:run_cmd).with("git branch -D prototype", allow_failure: true).ordered expect(cli).to receive(:run_cmd).with("git checkout prototype").ordered expect(cli).to receive(:run_cmd).with("git merge feature-branch").ordered expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered @@ -55,18 +82,18 @@ should meet_expectations end end - context 'when target branch != staging || prototype' do + context 'when target branch is not an aggregate branch' do it 'raises an error' do - - expect { cli.integrate('some-other-branch') }.to raise_error(/Only aggregate branches are allowed for integration/) + expect { cli.integrate('some-other-branch') }.to raise_error(/Invalid aggregate branch: some-other-branch must be one of supported aggregate branches/) end end context 'when merge conflicts occur' do + let(:remote_branch_names) { ['origin/staging'] } before do expect(fake_update_command).to receive(:update) - expect(cli).to receive(:run_cmd).with("git branch -D staging", allow_failure: true).ordered expect(cli).to receive(:run_cmd).with("git fetch origin").ordered + expect(cli).to receive(:run_cmd).with("git branch -D staging", allow_failure: true).ordered expect(cli).to receive(:run_cmd).with("git checkout staging").ordered expect(cli).to receive(:run_cmd).with("git merge feature-branch").and_raise('git merge feature-branch failed').ordered expect(cli).to receive(:exit).and_raise(SystemExit) @@ -122,22 +149,5 @@ should meet_expectations end end - context 'with --resume flag with no feature branch passed' do - let(:options) do - { - resume:'' - } - end - let(:repo) { cli.send(:repo) } - let(:branches) { double(each_name: ['my-feature-branch'])} - before do - expect(repo).to receive(:branches).and_return(branches) - - cli.integrate - end - it 'raises error' do - should meet_expectations - end - end end end diff --git a/spec/thegarage/gitx/cli/nuke_command_spec.rb b/spec/thegarage/gitx/cli/nuke_command_spec.rb index d2910b0..9d53ee8 100644 --- a/spec/thegarage/gitx/cli/nuke_command_spec.rb +++ b/spec/thegarage/gitx/cli/nuke_command_spec.rb @@ -101,5 +101,65 @@ expect { cli.nuke('prototype') }.to raise_error(/No known good tag found for branch/) end end + context 'when database migrations exist and user cancels operation' do + let(:buildtag) { 'build-master-2013-10-01-01' } + let(:good_branch) { 'master' } + let(:bad_branch) { 'prototype' } + let(:migrations) do + %w( db/migrate/20140715194946_create_users.rb db/migrate/20140730063034_update_user_account.rb ).join("\n") + end + before do + FileUtils.mkdir_p('db/migrate') + + expect(cli).to receive(:current_build_tag).with(good_branch).and_return(buildtag) + + expect(cli).to receive(:ask).and_return(good_branch) + expect(cli).to receive(:yes?).with('Reset prototype to build-master-2013-10-01-01? (y/n)', :green).and_return(true) + expect(cli).to receive(:run_cmd).with("git diff build-master-2013-10-01-01...prototype --name-only db/migrate").and_return(migrations) + expect(cli).to receive(:yes?).with('Are you sure you want to nuke prototype? (y/n) ', :green).and_return(false) + + cli.nuke 'prototype' + end + after do + FileUtils.rm_rf('db/migrate') + end + it 'prompts for nuke confirmation' do + should meet_expectations + end + end + context 'when database migrations exist and user approves operation' do + let(:buildtag) { 'build-master-2013-10-01-01' } + let(:good_branch) { 'master' } + let(:bad_branch) { 'prototype' } + let(:migrations) do + %w( db/migrate/20140715194946_create_users.rb db/migrate/20140730063034_update_user_account.rb ).join("\n") + end + before do + FileUtils.mkdir_p('db/migrate') + + expect(cli).to receive(:current_build_tag).with(good_branch).and_return(buildtag) + + expect(cli).to receive(:ask).and_return(good_branch) + expect(cli).to receive(:yes?).with('Reset prototype to build-master-2013-10-01-01? (y/n)', :green).and_return(true) + expect(cli).to receive(:run_cmd).with("git diff build-master-2013-10-01-01...prototype --name-only db/migrate").and_return(migrations) + expect(cli).to receive(:yes?).with('Are you sure you want to nuke prototype? (y/n) ', :green).and_return(true) + + expect(cli).to receive(:run_cmd).with("git checkout master").ordered + expect(cli).to receive(:run_cmd).with("git branch -D prototype", allow_failure: true).ordered + expect(cli).to receive(:run_cmd).with("git push origin --delete prototype", allow_failure: true).ordered + expect(cli).to receive(:run_cmd).with("git checkout -b prototype build-master-2013-10-01-01").ordered + expect(cli).to receive(:run_cmd).with("git push origin prototype").ordered + expect(cli).to receive(:run_cmd).with("git branch --set-upstream-to origin/prototype").ordered + expect(cli).to receive(:run_cmd).with("git checkout master").ordered + + cli.nuke 'prototype' + end + after do + FileUtils.rm_rf('db/migrate') + end + it 'prompts for nuke confirmation' do + should meet_expectations + end + end end end