diff --git a/lib/kumade.rb b/lib/kumade.rb index b1175f3..7314bc9 100644 --- a/lib/kumade.rb +++ b/lib/kumade.rb @@ -7,6 +7,7 @@ module Kumade autoload :DeploymentError, "kumade/deployment_error" autoload :Configuration, "kumade/configuration" autoload :Heroku, "kumade/heroku" + autoload :Packager, "kumade/packager" def self.configuration @@configuration ||= Configuration.new diff --git a/lib/kumade/deployer.rb b/lib/kumade/deployer.rb index b35df06..2a231cc 100644 --- a/lib/kumade/deployer.rb +++ b/lib/kumade/deployer.rb @@ -3,13 +3,14 @@ module Kumade class Deployer < Base - attr_reader :git, :heroku + attr_reader :git, :heroku, :packager def initialize super() - @git = Git.new - @heroku = Heroku.new - @branch = @git.current_branch + @git = Git.new + @heroku = Heroku.new + @branch = @git.current_branch + @packager = Packager.new(@git) end def deploy @@ -30,6 +31,10 @@ def pre_deploy sync_github end + def package_assets + packager.run + end + def sync_github git.push(@branch) end @@ -42,90 +47,6 @@ def ensure_clean_git git.ensure_clean_git end - def package_assets - invoke_custom_task if custom_task? - package_with_jammit if jammit_installed? - package_with_more if more_installed? - end - - def package_with_jammit - begin - success_message = "Packaged assets with Jammit" - - if Kumade.configuration.pretending? - success(success_message) - else - Jammit.package! - - success(success_message) - git_add_and_commit_all_assets_in(jammit_assets_path) - end - rescue => jammit_error - error("Error: #{jammit_error.class}: #{jammit_error.message}") - end - end - - def package_with_more - success_message = "Packaged assets with More" - if Kumade.configuration.pretending? - success(success_message) - else - begin - run "bundle exec rake more:generate" - if git.dirty? - success(success_message) - git_add_and_commit_all_assets_in(more_assets_path) - end - rescue => more_error - error("Error: #{more_error.class}: #{more_error.message}") - end - end - end - - def invoke_custom_task - success("Running kumade:before_asset_compilation task") - Rake::Task["kumade:before_asset_compilation"].invoke unless Kumade.configuration.pretending? - end - - def git_add_and_commit_all_assets_in(dir) - git.add_and_commit_all_in(dir, Kumade::Heroku::DEPLOY_BRANCH, 'Compiled assets', "Added and committed all assets", "couldn't commit assets") - end - - def jammit_assets_path - File.join(Jammit::PUBLIC_ROOT, Jammit.package_path) - end - - def more_assets_path - File.join('public', ::Less::More.destination_path) - end - - def jammit_installed? - @jammit_installed ||= - (defined?(Jammit) || - begin - require 'jammit' - true - rescue LoadError - false - end) - end - - def more_installed? - @more_installed ||= - (defined?(Less::More) || - begin - require 'less/more' - true - rescue LoadError - false - end) - end - - def custom_task? - load("Rakefile") if File.exist?("Rakefile") - Rake::Task.task_defined?("kumade:before_asset_compilation") - end - def ensure_heroku_remote_exists if git.remote_exists?(Kumade.configuration.environment) if git.heroku_remote? diff --git a/lib/kumade/packager.rb b/lib/kumade/packager.rb new file mode 100644 index 0000000..8a7438c --- /dev/null +++ b/lib/kumade/packager.rb @@ -0,0 +1,94 @@ +module Kumade + class Packager < Base + attr_reader :git + + def initialize(git) + super() + @git = git + end + + def run + invoke_custom_task if custom_task? + package_with_jammit if jammit_installed? + package_with_more if more_installed? + end + + def invoke_custom_task + success "Running kumade:before_asset_compilation task" + Rake::Task["kumade:before_asset_compilation"].invoke unless Kumade.configuration.pretending? + end + + def custom_task? + load("Rakefile") if File.exist?("Rakefile") + Rake::Task.task_defined?("kumade:before_asset_compilation") + end + + def package_with_jammit + begin + success_message = "Packaged assets with Jammit" + + if Kumade.configuration.pretending? + success(success_message) + else + Jammit.package! + + success(success_message) + git_add_and_commit_all_assets_in(jammit_assets_path) + end + rescue => jammit_error + error("Error: #{jammit_error.class}: #{jammit_error.message}") + end + end + + def package_with_more + success_message = "Packaged assets with More" + if Kumade.configuration.pretending? + success(success_message) + else + begin + run "bundle exec rake more:generate" + if git.dirty? + success(success_message) + git_add_and_commit_all_assets_in(more_assets_path) + end + rescue => more_error + error("Error: #{more_error.class}: #{more_error.message}") + end + end + end + + def git_add_and_commit_all_assets_in(dir) + git.add_and_commit_all_in(dir, Kumade::Heroku::DEPLOY_BRANCH, 'Compiled assets', "Added and committed all assets", "couldn't commit assets") + end + + def jammit_assets_path + File.join(Jammit::PUBLIC_ROOT, Jammit.package_path) + end + + def more_assets_path + File.join('public', ::Less::More.destination_path) + end + + def jammit_installed? + @jammit_installed ||= + (defined?(Jammit) || + begin + require 'jammit' + true + rescue LoadError + false + end) + end + + def more_installed? + @more_installed ||= + (defined?(Less::More) || + begin + require 'less/more' + true + rescue LoadError + false + end) + end + end +end diff --git a/spec/kumade/deployer_spec.rb b/spec/kumade/deployer_spec.rb index e6855c2..1600b2f 100644 --- a/spec/kumade/deployer_spec.rb +++ b/spec/kumade/deployer_spec.rb @@ -54,282 +54,39 @@ end end - -describe Kumade::Deployer, "#ensure_clean_git" do - it "calls git.ensure_clean_git" do - subject.git.should_receive(:ensure_clean_git) - subject.ensure_clean_git - end -end - -describe Kumade::Deployer, "#package_assets" do - context "with Jammit installed" do - it "calls package_with_jammit" do - subject.should_receive(:package_with_jammit) - subject.package_assets - end - end - - context "with Jammit not installed" do - before { subject.stub(:jammit_installed? => false) } - - it "does not call package_with_jammit" do - subject.should_not_receive(:package_with_jammit) - subject.package_assets - end - end - - context "with More installed" do - before do - subject.stub(:jammit_installed? => false) - subject.stub(:more_installed? => true) - end - - it "calls package_with_more" do - subject.should_receive(:package_with_more) - subject.package_assets - end - end - - context "with More not installed" do - before do - subject.stub(:jammit_installed? => false) - subject.stub(:more_installed? => false) - end - - it "does not call package_with_more" do - subject.should_not_receive(:package_with_more) - subject.package_assets - end - end - - context "with custom rake task installed" do - before do - Rake::Task.stub(:task_defined?). - with("kumade:before_asset_compilation"). - and_return(true) - - subject.stub(:jammit_installed? => false, - :more_installed? => false) - end - - it "invokes the custom task" do - subject.should_receive(:invoke_custom_task) - subject.package_assets - end - end - - context "with custom rake task not installed" do - before do - Rake::Task.stub(:task_defined?). - with("kumade:before_asset_compilation"). - and_return(false) - - subject.stub(:jammit_installed? => false, - :more_installed? => false) - end - - it "does not invoke custom task" do - subject.should_not_receive(:invoke_custom_task) - subject.package_assets - end - end -end - -describe Kumade::Deployer, "#package_with_jammit" do - before do - subject.stub(:git_add_and_commit_all_assets_in) - Jammit.stub(:package!) - end - - it "calls Jammit.package!" do - Jammit.should_receive(:package!) - subject.package_with_jammit - end - - context "with updated assets" do - before { subject.git.stub(:dirty?).and_return(true) } - - it "prints the correct message" do - STDOUT.should_receive(:puts).with(/Packaged assets with Jammit/) - - subject.package_with_jammit - end - - it "calls git_add_and_commit_all_assets_in" do - subject.stub(:jammit_assets_path).and_return('jammit-assets') - subject.should_receive(:git_add_and_commit_all_assets_in). - with('jammit-assets') - - subject.package_with_jammit - end - end - - it "prints an error if packaging failed" do - Jammit.stub(:package!).and_raise(Jammit::MissingConfiguration.new("random Jammit error")) - subject.should_receive(:error).with("Error: Jammit::MissingConfiguration: random Jammit error") - - subject.package_with_jammit - end -end - -describe Kumade::Deployer, "#invoke_custom_task" do - let(:task) { stub('task', :invoke => nil) } - - before do - subject.stub(:say) - Rake::Task.stub(:[] => task) - end - - it "calls deploy task" do - Rake::Task.should_receive(:[]).with("kumade:before_asset_compilation") - task.should_receive(:invoke) - subject.invoke_custom_task - end -end - -describe Kumade::Deployer, "#package_with_more" do - before do - subject.stub(:git_add_and_commit_all_assets_in => true, - :more_assets_path => 'assets') - subject.stub(:say) - end - - it "calls the more:generate task" do - subject.should_receive(:run).with("bundle exec rake more:generate") - subject.package_with_more - end - - context "with changed assets" do - it "prints a success message" do - subject.stub(:run).with("bundle exec rake more:generate") - subject.stub(:git => mock(:dirty? => true)) - subject.should_receive(:success).with("Packaged assets with More") - - subject.package_with_more - end - - it "calls git_add_and_commit_all_assets_in if assets were added" do - subject.stub(:git => mock(:dirty? => true), - :more_assets_path => 'blerg') - subject.stub(:run).with("bundle exec rake more:generate") - subject.should_receive(:git_add_and_commit_all_assets_in). - with('blerg'). - and_return(true) - - subject.package_with_more - end - end - - context "with no changed assets" do - before { subject.stub(:git => stub(:dirty? => false)) } - - it "prints no message" do - subject.stub(:run).with("bundle exec rake more:generate") - subject.should_not_receive(:say) - - subject.package_with_more - end - - it "does not call git_add_and_commit_all_assets_in" do - subject.stub(:run).with("bundle exec rake more:generate") - subject.should_not_receive(:git_add_and_commit_all_assets_in) - - subject.package_with_more - end - end - - it "prints an error if packaging failed" do - subject.should_receive(:run).with("bundle exec rake more:generate").and_raise(RuntimeError.new("blerg")) - - subject.should_receive(:error).with("Error: RuntimeError: blerg") - - subject.package_with_more - end -end - -describe Kumade::Deployer, "#git_add_and_commit_all_assets_in" do +describe Kumade::Deployer, "#sync_heroku" do + let(:environment) { 'my-env' } + subject { Kumade::Deployer.new(environment) } let(:git_mock) { mock() } - before { subject.stub(:git => git_mock) } - - it "calls git.add_and_commit_all_in" do - git_mock.should_receive(:add_and_commit_all_in).with("dir", 'deploy', 'Compiled assets', "Added and committed all assets", "couldn't commit assets") - subject.git_add_and_commit_all_assets_in("dir") + it "should call git.create and git.push" do + git_mock.should_receive(:create).with("deploy") + git_mock.should_receive(:push).with("deploy:master", environment, true) + subject.sync_heroku end end -describe Kumade::Deployer, "#jammit_assets_path" do - before do - Jammit.stub(:package_path).and_return('blerg') - end - its(:jammit_assets_path) { should == File.join(Jammit::PUBLIC_ROOT, 'blerg') } -end - -describe Kumade::Deployer, "#more_assets_path" do - before do - module ::Less - class More - def self.destination_path - 'blerg' - end - end - end - end - - its(:more_assets_path) { should == 'public/blerg' } -end - -describe Kumade::Deployer, "#jammit_installed?" do - it "returns true because it's loaded by the Gemfile" do - subject.jammit_installed?.should be_true +describe Kumade::Deployer, "#ensure_clean_git" do + it "calls git.ensure_clean_git" do + subject.git.should_receive(:ensure_clean_git) + subject.ensure_clean_git end end -describe Kumade::Deployer, "#more_installed?" do - before do - if defined?(Less) - Object.send(:remove_const, :Less) - end - end - - it "returns false if it does not find Less::More" do - subject.more_installed?.should be_false - end - - it "returns true if it finds Less::More" do - module Less - class More - end - end - - subject.more_installed?.should be_true - end -end +describe Kumade::Deployer, "#heroku_migrate" do + let(:environment){ 'staging' } -describe Kumade::Deployer, "#custom_task?" do before do - Rake::Task.clear - end - - it "returns true if the task exists" do - namespace :kumade do - task :before_asset_compilation do - end - end - - subject.custom_task?.should be_true - end - - it "returns false if task not found" do - subject.custom_task?.should be_false + subject.stub(:say) + force_add_heroku_remote(environment) end -end -describe Kumade::Deployer, "#post_deploy" do - it "deletes the deploy branch" do - Kumade::Git.any_instance.should_receive(:delete).with('deploy', 'master') + it "runs db:migrate with the correct app" do + subject.stub(:run => true) + subject.should_receive(:heroku). + with("rake db:migrate") + subject.should_receive(:success).with("Migrated staging") subject.post_deploy end @@ -384,4 +141,3 @@ class More end end end - diff --git a/spec/kumade/packager_spec.rb b/spec/kumade/packager_spec.rb new file mode 100644 index 0000000..3eb7141 --- /dev/null +++ b/spec/kumade/packager_spec.rb @@ -0,0 +1,291 @@ +require 'spec_helper' + +describe Kumade::Packager, "#run" do + let(:git_mock) { mock() } + subject { Kumade::Packager.new(git_mock) } + + context "with Jammit installed" do + it "calls package_with_jammit" do + subject.should_receive(:package_with_jammit) + subject.run + end + end + + context "with Jammit not installed" do + before { subject.stub(:jammit_installed? => false) } + it "does not call package_with_jammit" do + subject.should_not_receive(:package_with_jammit) + subject.run + end + end + + context "with More installed" do + before do + subject.stub(:jammit_installed? => false) + subject.stub(:more_installed? => true) + end + + it "calls package_with_more" do + subject.should_receive(:package_with_more) + subject.run + end + end + + context "with More not installed" do + before do + subject.stub(:jammit_installed? => false) + subject.stub(:more_installed? => false) + end + + it "does not call package_with_more" do + subject.should_not_receive(:package_with_more) + subject.run + end + end + + context "with custom rake task installed" do + before do + subject.stub(:jammit_installed? => false, + :more_installed? => false, + :invoke_custom_task => nil, + :custom_task? => true) + end + + it "invokes custom task" do + subject.should_receive(:invoke_custom_task) + subject.run + end + end + + context "with custom rake task not installed" do + before do + subject.stub(:jammit_installed? => false, + :more_installed? => false, + :invoke_custom_task => nil, + :custom_task? => false) + end + + it "does not invoke custom task" do + subject.should_not_receive(:invoke_custom_task) + subject.run + end + end +end + +describe Kumade::Packager, "#invoke_custom_task" do + let(:git_mock) { mock() } + subject { Kumade::Packager.new(git_mock) } + before do + subject.stub(:say) + Rake::Task.stub(:[] => task) + end + + let(:task) { stub('task', :invoke => nil) } + + it "calls deploy task" do + Rake::Task.should_receive(:[]).with("kumade:before_asset_compilation") + task.should_receive(:invoke) + subject.invoke_custom_task + end +end + +describe Kumade::Packager, "#custom_task?" do + let(:git_mock) { mock() } + subject { Kumade::Packager.new(git_mock) } + before do + Rake::Task.clear + end + + it "returns true if it task found" do + namespace :kumade do + task :before_asset_compilation do + + end + end + subject.custom_task?.should be_true + end + + it "returns false if task not found" do + subject.custom_task?.should be_false + end +end + +describe Kumade::Packager, "#package_with_jammit" do + let(:git_mock) { mock() } + subject { Kumade::Packager.new(git_mock) } + before do + subject.stub(:git_add_and_commit_all_assets_in) + subject.stub(:say) + Jammit.stub(:package!) + end + + it "calls Jammit.package!" do + Jammit.should_receive(:package!).once + subject.package_with_jammit + end + + context "with updated assets" do + before { subject.stub(:git => mock(:dirty? => true)) } + + it "prints the correct message" do + subject.should_receive(:success).with("Packaged assets with Jammit") + + subject.package_with_jammit + end + + it "calls git_add_and_commit_all_assets_in" do + subject.stub(:jammit_assets_path => 'jammit-assets') + subject.should_receive(:git_add_and_commit_all_assets_in). + with('jammit-assets'). + and_return(true) + + subject.package_with_jammit + end + end + + it "prints an error if packaging failed" do + Jammit.stub(:package!) do + raise Jammit::MissingConfiguration.new("random Jammit error") + end + subject.should_receive(:error).with("Error: Jammit::MissingConfiguration: random Jammit error") + + subject.package_with_jammit + end +end + +describe Kumade::Packager, "#package_with_more" do + let(:git_mock) { mock() } + subject { Kumade::Packager.new(git_mock) } + before do + subject.stub(:git_add_and_commit_all_assets_in => true, + :more_assets_path => 'assets') + subject.stub(:say) + end + + it "calls the more:generate task" do + git_mock.should_receive(:dirty?).and_return(true) + subject.should_receive(:run).with("bundle exec rake more:generate") + subject.package_with_more + end + + context "with changed assets" do + it "prints a success message" do + subject.stub(:run).with("bundle exec rake more:generate") + subject.stub(:git => mock(:dirty? => true)) + subject.should_receive(:success).with("Packaged assets with More") + + subject.package_with_more + end + + it "calls git_add_and_commit_all_assets_in if assets were added" do + subject.stub(:git => mock(:dirty? => true), + :more_assets_path => 'blerg') + subject.stub(:run).with("bundle exec rake more:generate") + subject.should_receive(:git_add_and_commit_all_assets_in). + with('blerg'). + and_return(true) + + subject.package_with_more + end + end + + context "with no changed assets" do + it "prints no message" do + subject.stub(:run).with("bundle exec rake more:generate") + subject.stub(:git => mock(:dirty? => false)) + subject.should_not_receive(:say) + + subject.package_with_more + end + + it "does not call git_add_and_commit_all_more_assets" do + subject.stub(:run).with("bundle exec rake more:generate") + subject.stub(:git => mock(:dirty? => false)) + subject.should_not_receive(:git_add_and_commit_all_assets_in) + + subject.package_with_more + end + end + + it "prints an error if packaging failed" do + subject.stub(:run) do |arg| + if arg == "bundle exec rake more:generate" + raise "blerg" + end + end + + subject.should_receive(:error).with("Error: RuntimeError: blerg") + + subject.package_with_more + end +end + +describe Kumade::Packager, "#git_add_and_commit_all_assets_in" do + let(:git_mock) { mock() } + subject { Kumade::Packager.new(git_mock) } + before { subject.stub(:git => git_mock) } + + it "should call git.add_and_commit_all_in" do + git_mock.should_receive(:add_and_commit_all_in).with("dir", 'deploy', 'Compiled assets', "Added and committed all assets", "couldn't commit assets") + subject.git_add_and_commit_all_assets_in("dir") + end +end + +describe Kumade::Packager, "#jammit_assets_path" do + let(:git_mock) { mock() } + subject { Kumade::Packager.new(git_mock) } + it "returns the correct asset path" do + Jammit.stub(:package_path => 'blerg') + current_dir = File.expand_path(Dir.pwd) + subject.jammit_assets_path.should == File.join(current_dir, 'public', 'blerg') + end +end + +describe Kumade::Packager, "#more_assets_path" do + let(:git_mock) { mock() } + subject { Kumade::Packager.new(git_mock) } + it "returns the correct asset path" do + module ::Less + class More + def self.destination_path + 'blerg' + end + end + end + subject.more_assets_path.should == 'public/blerg' + end +end + +describe Kumade::Packager, "#jammit_installed?" do + let(:git_mock) { mock() } + subject { Kumade::Packager.new(git_mock) } + it "returns true because it's loaded by the Gemfile" do + subject.jammit_installed?.should be_true + end + + it "returns false if jammit is not installed" do + subject.jammit_installed?.should be_true + end +end + +describe Kumade::Packager, "#more_installed?" do + let(:git_mock) { mock() } + subject { Kumade::Packager.new(git_mock) } + before do + if defined?(Less) + Object.send(:remove_const, :Less) + end + end + + it "returns false if it does not find Less::More" do + subject.more_installed?.should be_false + end + + it "returns true if it finds Less::More" do + module Less + class More + end + end + subject.more_installed?.should be_true + end +end