kumade 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,14 +1,13 @@
1
+ require 'cocaine'
1
2
  module Kumade
2
3
  class Git < Base
3
- attr_reader :environment
4
- def initialize(pretending, environment)
4
+ def initialize
5
5
  super()
6
- @pretending = pretending
7
- @environment = environment
8
6
  end
9
7
 
10
8
  def heroku_remote?
11
- `git config --get remote.#{environment}.url`.strip =~ /^git@heroku\..+:(.+)\.git$/
9
+ remote_url = `git config --get remote.#{Kumade.configuration.environment}.url`.strip
10
+ !! remote_url.strip.match(/^git@heroku\..+:(.+)\.git$/)
12
11
  end
13
12
 
14
13
  def self.environments
@@ -21,7 +20,7 @@ module Kumade
21
20
  command << remote
22
21
  command << branch
23
22
  command = command.join(" ")
24
- run_or_error([command], "Failed to push #{branch} -> #{remote}")
23
+ run_or_error(command, "Failed to push #{branch} -> #{remote}")
25
24
  success("Pushed #{branch} -> #{remote}")
26
25
  end
27
26
 
@@ -32,12 +31,12 @@ module Kumade
32
31
  end
33
32
 
34
33
  def delete(branch_to_delete, branch_to_checkout)
35
- run_or_error(["git checkout #{branch_to_checkout}", "git branch -D #{branch_to_delete}"],
34
+ run_or_error("git checkout #{branch_to_checkout} && git branch -D #{branch_to_delete}",
36
35
  "Failed to clean up #{branch_to_delete} branch")
37
36
  end
38
37
 
39
38
  def add_and_commit_all_in(dir, branch, commit_message, success_output, error_output)
40
- run_or_error ["git checkout -b #{branch}", "git add -f #{dir}", "git commit -m '#{commit_message}'"],
39
+ run_or_error "git checkout -b #{branch} && git add -f #{dir} && git commit -m '#{commit_message}'",
41
40
  "Cannot deploy: #{error_output}"
42
41
  success success_output
43
42
  end
@@ -47,7 +46,7 @@ module Kumade
47
46
  end
48
47
 
49
48
  def remote_exists?(remote_name)
50
- if @pretending
49
+ if Kumade.configuration.pretending?
51
50
  true
52
51
  else
53
52
  `git remote` =~ /^#{remote_name}$/
@@ -55,11 +54,11 @@ module Kumade
55
54
  end
56
55
 
57
56
  def dirty?
58
- ! system("git diff --exit-code")
57
+ !run("git diff --exit-code")
59
58
  end
60
59
 
61
60
  def ensure_clean_git
62
- if ! @pretending && dirty?
61
+ if ! Kumade.configuration.pretending? && dirty?
63
62
  error("Cannot deploy: repo is not clean.")
64
63
  else
65
64
  success("Git repo is clean")
@@ -67,7 +66,7 @@ module Kumade
67
66
  end
68
67
 
69
68
  def branch_exist?(branch)
70
- system("git show-ref #{branch}")
69
+ run("git show-ref #{branch}")
71
70
  end
72
71
  end
73
72
  end
@@ -0,0 +1,46 @@
1
+ require 'cocaine'
2
+
3
+ module Kumade
4
+ class Heroku < Base
5
+ DEPLOY_BRANCH = "deploy"
6
+ attr_reader :git
7
+
8
+ def initialize
9
+ super()
10
+ @git = Git.new
11
+ @branch = @git.current_branch
12
+ end
13
+
14
+ def sync
15
+ git.create(DEPLOY_BRANCH)
16
+ git.push("#{DEPLOY_BRANCH}:master", Kumade.configuration.environment, true)
17
+ end
18
+
19
+ def migrate_database
20
+ heroku("rake db:migrate") unless Kumade.configuration.pretending?
21
+ success("Migrated #{Kumade.configuration.environment}")
22
+ end
23
+
24
+ def delete_deploy_branch
25
+ git.delete(DEPLOY_BRANCH, @branch)
26
+ end
27
+
28
+ def heroku(command)
29
+ heroku_command = if cedar?
30
+ "bundle exec heroku run"
31
+ else
32
+ "bundle exec heroku"
33
+ end
34
+ run_or_error("#{heroku_command} #{command} --remote #{Kumade.configuration.environment}",
35
+ "Failed to run #{command} on Heroku")
36
+ end
37
+
38
+ def cedar?
39
+ return @cedar unless @cedar.nil?
40
+
41
+ @cedar = Cocaine::CommandLine.new("bundle exec heroku stack --remote #{Kumade.configuration.environment}").run.split("\n").grep(/\*/).any? do |line|
42
+ line.include?("cedar")
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,94 @@
1
+ module Kumade
2
+ class Packager < Base
3
+ attr_reader :git
4
+
5
+ def initialize(git)
6
+ super()
7
+ @git = git
8
+ end
9
+
10
+ def run
11
+ invoke_custom_task if custom_task?
12
+ package_with_jammit if jammit_installed?
13
+ package_with_more if more_installed?
14
+ end
15
+
16
+ def invoke_custom_task
17
+ success "Running kumade:before_asset_compilation task"
18
+ Rake::Task["kumade:before_asset_compilation"].invoke unless Kumade.configuration.pretending?
19
+ end
20
+
21
+ def custom_task?
22
+ load("Rakefile") if File.exist?("Rakefile")
23
+ Rake::Task.task_defined?("kumade:before_asset_compilation")
24
+ end
25
+
26
+ def package_with_jammit
27
+ begin
28
+ success_message = "Packaged assets with Jammit"
29
+
30
+ if Kumade.configuration.pretending?
31
+ success(success_message)
32
+ else
33
+ Jammit.package!
34
+
35
+ success(success_message)
36
+ git_add_and_commit_all_assets_in(jammit_assets_path)
37
+ end
38
+ rescue => jammit_error
39
+ error("Error: #{jammit_error.class}: #{jammit_error.message}")
40
+ end
41
+ end
42
+
43
+ def package_with_more
44
+ success_message = "Packaged assets with More"
45
+ if Kumade.configuration.pretending?
46
+ success(success_message)
47
+ else
48
+ begin
49
+ run "bundle exec rake more:generate"
50
+ if git.dirty?
51
+ success(success_message)
52
+ git_add_and_commit_all_assets_in(more_assets_path)
53
+ end
54
+ rescue => more_error
55
+ error("Error: #{more_error.class}: #{more_error.message}")
56
+ end
57
+ end
58
+ end
59
+
60
+ def git_add_and_commit_all_assets_in(dir)
61
+ git.add_and_commit_all_in(dir, Kumade::Heroku::DEPLOY_BRANCH, 'Compiled assets', "Added and committed all assets", "couldn't commit assets")
62
+ end
63
+
64
+ def jammit_assets_path
65
+ File.join(Jammit::PUBLIC_ROOT, Jammit.package_path)
66
+ end
67
+
68
+ def more_assets_path
69
+ File.join('public', ::Less::More.destination_path)
70
+ end
71
+
72
+ def jammit_installed?
73
+ @jammit_installed ||=
74
+ (defined?(Jammit) ||
75
+ begin
76
+ require 'jammit'
77
+ true
78
+ rescue LoadError
79
+ false
80
+ end)
81
+ end
82
+
83
+ def more_installed?
84
+ @more_installed ||=
85
+ (defined?(Less::More) ||
86
+ begin
87
+ require 'less/more'
88
+ true
89
+ rescue LoadError
90
+ false
91
+ end)
92
+ end
93
+ end
94
+ end
@@ -1,3 +1,3 @@
1
1
  module Kumade
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -2,7 +2,7 @@ namespace :deploy do
2
2
  Kumade::Git.environments.each do |environment|
3
3
  desc "Deploy to #{environment} environment"
4
4
  task environment do
5
- Kumade::Runner.run([environment])
5
+ Kumade::CLI.run([environment])
6
6
  end
7
7
  end
8
8
  end
@@ -1,18 +1,99 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Kumade::Base, "#success" do
4
- it "exists" do
5
- subject.should respond_to(:success)
6
- end
4
+ it { should respond_to(:success) }
7
5
  end
8
6
 
9
7
  describe Kumade::Base, "#error" do
10
- it "exists" do
11
- subject.should respond_to(:error)
12
- end
8
+ before { STDOUT.stubs(:puts) }
9
+
10
+ it { should respond_to(:error) }
13
11
 
14
12
  it "prints its message and raises its message" do
15
- subject.should_receive(:say).with("==> ! I'm an error!", :red)
16
- lambda{ subject.error("I'm an error!") }.should raise_error(Kumade::DeploymentError)
13
+ lambda { subject.error("I'm an error!") }.should raise_error(Kumade::DeploymentError)
14
+
15
+ STDOUT.should have_received(:puts).with(regexp_matches(/I'm an error!/))
16
+ end
17
+ end
18
+
19
+ describe Kumade::Base, "#run_or_error" do
20
+ let(:command) { "dummy command" }
21
+ let(:error_message) { "dummy error message" }
22
+
23
+ before do
24
+ STDOUT.stubs(:puts)
25
+ end
26
+
27
+ context "when pretending" do
28
+ before do
29
+ Kumade.configuration.pretending = true
30
+ subject.stubs(:run)
31
+ end
32
+
33
+ it "does not run the command" do
34
+ subject.run_or_error("dummy command", "dummy error message")
35
+
36
+ subject.should_not have_received(:run)
37
+ STDOUT.should have_received(:puts).with(regexp_matches(/#{command}/))
38
+ end
39
+ end
40
+
41
+ context "when not pretending" do
42
+ context "when it runs successfully" do
43
+ before do
44
+ Cocaine::CommandLine.stubs(:new).returns(stub(:run))
45
+ end
46
+
47
+ it "does not print an error" do
48
+ subject.run_or_error(command, error_message)
49
+
50
+ STDOUT.should_not have_received(:puts).with(regexp_matches(/#{error_message}/))
51
+ end
52
+ end
53
+
54
+ context "when it does not run successfully " do
55
+ let(:failing_command_line) { stub("Failing Cocaine::CommandLine") }
56
+
57
+ before do
58
+ subject.stubs(:error)
59
+ failing_command_line.stubs(:run).raises(Cocaine::ExitStatusError)
60
+ Cocaine::CommandLine.stubs(:new).returns(failing_command_line)
61
+ end
62
+
63
+ it "prints an error message" do
64
+ subject.run_or_error(command, error_message)
65
+
66
+ subject.should have_received(:error).with(error_message)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ describe Kumade::Base, "#run" do
73
+ let(:command_line) { stub("Cocaine::CommandLine") }
74
+ let(:command) { "command" }
75
+
76
+ before do
77
+ Cocaine::CommandLine.stubs(:new).with(command).returns(command_line)
78
+ end
79
+
80
+ context "when not successful" do
81
+ before do
82
+ command_line.stubs(:run)
83
+ end
84
+
85
+ it "returns true" do
86
+ subject.run(command).should == true
87
+ end
88
+ end
89
+
90
+ context "when successful" do
91
+ before do
92
+ command_line.stubs(:run).raises(Cocaine::ExitStatusError)
93
+ end
94
+
95
+ it "returns false" do
96
+ subject.run(command).should == false
97
+ end
17
98
  end
18
99
  end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kumade::CLI do
4
+ let(:out) { StringIO.new }
5
+ let(:environment) { 'my-environment' }
6
+ let(:deployer) { stub("Deployer", :new => deployer_instance) }
7
+ let(:deployer_instance) { stub("DeployerInstance", :deploy => nil) }
8
+
9
+ before { Kumade::CLI.deployer = deployer }
10
+ after { Kumade::CLI.deployer = nil }
11
+
12
+ context "when pretending" do
13
+ %w(-p --pretend).each do |pretend_flag|
14
+ subject { Kumade::CLI.new([pretend_flag, environment], out) }
15
+
16
+ context pretend_flag do
17
+ it "sets pretending to true" do
18
+ subject
19
+ Kumade.configuration.pretending.should == true
20
+ end
21
+
22
+ it "deploys" do
23
+ subject
24
+
25
+ deployer_instance.should have_received(:deploy)
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ context "with no command-line arguments" do
32
+ subject { Kumade::CLI.new([], out) }
33
+
34
+ it "sets the environment to staging" do
35
+ Kumade.configuration.environment.should == 'staging'
36
+ end
37
+
38
+ it "sets pretending to false" do
39
+ Kumade.configuration.pretending.should == false
40
+ end
41
+ end
42
+
43
+ context "running normally" do
44
+ subject { Kumade::CLI.new([environment], out) }
45
+
46
+ it "sets pretending to false" do
47
+ subject
48
+ Kumade.configuration.pretending.should == false
49
+ end
50
+
51
+ it "deploys" do
52
+ subject
53
+
54
+ deployer_instance.should have_received(:deploy)
55
+ end
56
+ end
57
+ end
58
+
59
+ describe Kumade::CLI, ".deployer" do
60
+ after { Kumade::CLI.deployer = nil }
61
+
62
+ it "sets the deployer to the Deployer class by default" do
63
+ Kumade::CLI.deployer.should == Kumade::Deployer
64
+ end
65
+
66
+ it "can override deployer" do
67
+ Kumade::CLI.deployer = "deployer!"
68
+ Kumade::CLI.deployer.should == "deployer!"
69
+ end
70
+ end
71
+
72
+ describe Kumade::CLI, ".swapping_stdout_for" do
73
+ let(:stdout) { $stdout }
74
+ let(:output) { StringIO.new }
75
+
76
+ before do
77
+ stdout.stubs(:print => nil, :puts => nil)
78
+ end
79
+
80
+ it 'does not let anything get printed' do
81
+ Kumade::CLI.swapping_stdout_for(output) do
82
+ $stdout.puts "Hello, you can't see me."
83
+ end
84
+
85
+ stdout.should_not have_received(:print)
86
+
87
+ output.rewind
88
+ output.read.should == "Hello, you can't see me.\n"
89
+ end
90
+
91
+ it 'dumps the output stash to real stdout when an error happens' do
92
+ Kumade::CLI.swapping_stdout_for(output) do
93
+ $stdout.puts "Hello, you can see me!"
94
+ raise Kumade::DeploymentError.new("error")
95
+ end
96
+
97
+ stdout.should have_received(:print)
98
+ end
99
+
100
+ context "in print output mode" do
101
+ it 'prints everything' do
102
+ Kumade::CLI.swapping_stdout_for(output, true) do
103
+ $stdout.puts "Hello, you can see me!"
104
+ end
105
+
106
+ stdout.should have_received(:puts)
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kumade::Configuration, "by default" do
4
+ its(:environment) { should == 'staging' }
5
+ it { should_not be_pretending }
6
+ end
7
+
8
+ describe Kumade::Configuration, "#pretending" do
9
+ it "has read/write access for the pretending attribute" do
10
+ subject.pretending = true
11
+ subject.pretending.should == true
12
+ end
13
+ end
14
+
15
+ describe Kumade::Configuration, "#pretending?" do
16
+ it "returns false when not pretending" do
17
+ subject.pretending = false
18
+ subject.should_not be_pretending
19
+ end
20
+
21
+ it "returns true when pretending" do
22
+ subject.pretending = true
23
+ subject.should be_pretending
24
+ end
25
+
26
+ it "defaults to false" do
27
+ subject.pretending.should == false
28
+ end
29
+ end
30
+
31
+ describe Kumade::Configuration, "#environment" do
32
+ it "has read/write access for the environment attribute" do
33
+ subject.environment = 'new-environment'
34
+ subject.environment.should == 'new-environment'
35
+ end
36
+ end