kumade 0.3.0 → 0.4.0

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.
@@ -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