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.
@@ -2,7 +2,6 @@ rvm:
2
2
  - 1.9.2
3
3
  - 1.8.7
4
4
  - ree-1.8.7
5
- - 1.8.7-p249
6
5
  # branches:
7
6
  # only:
8
7
  # - master
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Kumade 熊手 [![Build Status](https://secure.travis-ci.org/thoughtbot/kumade.png)](http://travis-ci.org/thoughtbot/kumade)
2
- Kumade is a set of basic Rake tasks for deploying to Heroku. It aims to
2
+ Kumade is a command-line program for deploying to Heroku. It aims to
3
3
  provide most of what you want. Unlike other Heroku deploy gems, it is
4
4
  well-tested.
5
5
 
@@ -9,11 +9,11 @@ public API is constant (e.g. `kumade production` will work), but you may have to
9
9
  rebase against master a couple times before your pull request can be merged.
10
10
 
11
11
  ## What does Kumade do?
12
- Before deploying, Kumade ensures the git repo is clean and that all tests pass.
12
+ Before deploying, Kumade ensures the git repo is clean.
13
13
  After that, it packages assets using
14
14
  [Jammit](http://documentcloud.github.com/jammit/) and/or
15
15
  [More](https://github.com/cloudhead/more), commits them, and pushes to origin.
16
- Then it force pushes to the correct remote and runs `rake db:migrate` on the
16
+ Then it force pushes to the correct Heroku remote and runs `rake db:migrate` on the
17
17
  Heroku app.
18
18
 
19
19
  If any step fails, it immediately prints an error and stops the deploy
@@ -29,36 +29,34 @@ gem 'kumade'
29
29
  ## Usage
30
30
 
31
31
  kumade will deploy to any Heroku remote in the repo.
32
- For example, if you have a remote named "bamboo":
32
+ For example, if you have a remote named "staging":
33
33
 
34
- $ bundle exec kumade bamboo
34
+ $ bundle exec kumade staging
35
35
 
36
- or
36
+ To run in pretend mode, which prints what would be done without actually doing
37
+ any of it:
37
38
 
38
- # in your Rakefile:
39
- require 'kumade'
39
+ $ bundle exec kumade staging -p
40
40
 
41
- # kumade auto-generates a deploy:ENV task for every Heroku environment
42
- $ rake deploy:bamboo
41
+ The default is to deploy to staging:
43
42
 
44
- which will autodetect the name of the Heroku app that the bamboo remote points
45
- to and deploy to it.
43
+ # equivalent to "bundle exec kumade staging"
44
+ $ bundle exec kumade
46
45
 
47
- To run in pretend mode, which prints what would be done without actually doing
48
- any of it:
46
+ ## Rake
49
47
 
50
- $ bundle exec kumade bamboo -p
48
+ Kumade auto-generates a deploy:ENV task for every Heroku environment.
51
49
 
52
- The default is to deploy to staging:
50
+ # in your Rakefile:
51
+ require 'kumade'
53
52
 
54
- $ bundle exec kumade # equivalent to "bundle exec kumade staging"
53
+ $ rake deploy:staging
55
54
 
55
+ If you use rake tasks, you can't pass in options (like -p/--pretend).
56
56
 
57
57
  ## Does it support the Cedar stack?
58
58
 
59
- Yes. To indicate that a particular app is using Cedar, run with the -c flag:
60
-
61
- bundle exec kumade bamboo -c
59
+ Yes. Kumade will automatically detect if your app is running on Cedar.
62
60
 
63
61
  ## Compatibility
64
62
 
@@ -68,7 +66,7 @@ Tested against:
68
66
  * MRI 1.9.2
69
67
  * REE 1.8.7
70
68
 
71
- ## Misc Features
69
+ ## Miscellaneous Features
72
70
 
73
71
  Want to run a task before bundling your assets on deploy? In your Rails app's rake tasks, drop in:
74
72
 
data/bin/kumade CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'kumade'
4
4
 
5
- Kumade::Runner.run
5
+ Kumade::CLI.new
@@ -19,10 +19,12 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency('heroku', '~> 2.0')
20
20
  s.add_dependency('thor', '~> 0.14')
21
21
  s.add_dependency('rake', '>= 0.8.7')
22
+ s.add_dependency('cocaine', '>= 0.2.0')
22
23
 
23
24
  s.add_development_dependency('rake', '>= 0.8.7')
24
25
  s.add_development_dependency('rspec', '~> 2.6.0')
25
26
  s.add_development_dependency('cucumber', '~> 1.0.2')
26
27
  s.add_development_dependency('aruba', '~> 0.4.3')
27
28
  s.add_development_dependency('jammit', '~> 0.6.3')
29
+ s.add_development_dependency('bourne')
28
30
  end
@@ -1,13 +1,19 @@
1
- require 'rake'
2
- require 'thor'
3
- require 'stringio'
1
+ module Kumade
2
+ autoload :Base, "kumade/base"
3
+ autoload :Git, "kumade/git"
4
+ autoload :Deployer, "kumade/deployer"
5
+ autoload :CLI, "kumade/cli"
6
+ autoload :Railtie, "kumade/railtie"
7
+ autoload :DeploymentError, "kumade/deployment_error"
8
+ autoload :Configuration, "kumade/configuration"
9
+ autoload :Heroku, "kumade/heroku"
10
+ autoload :Packager, "kumade/packager"
4
11
 
5
- require 'kumade/base'
6
- require 'kumade/git'
7
- require 'kumade/deployer'
8
- require 'kumade/runner'
9
- require 'kumade/railtie'
10
- require 'kumade/deployment_error'
12
+ def self.configuration
13
+ @@configuration ||= Configuration.new
14
+ end
11
15
 
12
- module Kumade
16
+ def self.configuration=(new_configuration)
17
+ @@configuration = new_configuration
18
+ end
13
19
  end
@@ -1,21 +1,26 @@
1
+ require "thor"
2
+
1
3
  module Kumade
2
4
  class Base < Thor::Shell::Color
3
5
  def initialize
4
6
  super()
5
7
  end
6
8
 
7
- def run_or_error(commands, error_message)
8
- all_commands = [commands].flatten.join(' && ')
9
- if @pretending
10
- say_status(:run, all_commands)
11
- else
12
- error(error_message) unless run(all_commands)
9
+ def run_or_error(command, error_message)
10
+ say_status(:run, command)
11
+ if ! Kumade.configuration.pretending?
12
+ error(error_message) unless run(command)
13
13
  end
14
14
  end
15
15
 
16
- def run(command, config = {})
17
- say_status :run, command
18
- config[:capture] ? `#{command}` : system("#{command}")
16
+ def run(command)
17
+ line = Cocaine::CommandLine.new(command)
18
+ begin
19
+ line.run
20
+ true
21
+ rescue Cocaine::ExitStatusError => e
22
+ false
23
+ end
19
24
  end
20
25
 
21
26
  def error(message)
@@ -0,0 +1,86 @@
1
+ require 'optparse'
2
+ require 'stringio'
3
+
4
+ module Kumade
5
+ class CLI
6
+ class << self
7
+ attr_writer :deployer
8
+
9
+ def deployer
10
+ @deployer || Kumade::Deployer
11
+ end
12
+ end
13
+
14
+ def initialize(args = ARGV, out = StringIO.new)
15
+ @options = {}
16
+ parse_arguments!(args)
17
+
18
+ Kumade.configuration.pretending = !!@options[:pretend]
19
+ Kumade.configuration.environment = args.shift || 'staging'
20
+
21
+ self.class.swapping_stdout_for(out, print_output?) do
22
+ deploy
23
+ end
24
+ end
25
+
26
+ def self.swapping_stdout_for(io, print_output = false)
27
+ if print_output
28
+ yield
29
+ else
30
+ begin
31
+ real_stdout = $stdout
32
+ $stdout = io
33
+ yield
34
+ rescue Kumade::DeploymentError
35
+ io.rewind
36
+ real_stdout.print(io.read)
37
+ ensure
38
+ $stdout = real_stdout
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def deploy
46
+ if Kumade.configuration.pretending?
47
+ puts "==> In Pretend Mode"
48
+ end
49
+ puts "==> Deploying to: #{Kumade.configuration.environment}"
50
+ self.class.deployer.new.deploy
51
+ puts "==> Deployed to: #{Kumade.configuration.environment}"
52
+ end
53
+
54
+ def parse_arguments!(args)
55
+ OptionParser.new do |opts|
56
+ opts.banner = "Usage: kumade <environment> [options]"
57
+
58
+ opts.on("-p", "--pretend", "Pretend mode: print what kumade would do") do |p|
59
+ @options[:pretend] = true
60
+ end
61
+
62
+ opts.on_tail("-v", "--verbose", "Print what kumade is doing") do
63
+ @options[:verbose] = true
64
+ end
65
+
66
+ opts.on_tail('--version', 'Show version') do
67
+ puts "kumade #{Kumade::VERSION}"
68
+ exit
69
+ end
70
+
71
+ opts.on_tail('-h', '--help', 'Show this message') do
72
+ puts opts
73
+ exit
74
+ end
75
+ end.parse!(args)
76
+ end
77
+
78
+ def verbose?
79
+ @options[:verbose]
80
+ end
81
+
82
+ def print_output?
83
+ Kumade.configuration.pretending? || verbose?
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,14 @@
1
+ module Kumade
2
+ class Configuration
3
+ def initialize(environment = 'staging', pretending = false )
4
+ @environment = environment
5
+ @pretending = pretending
6
+ end
7
+
8
+ def pretending?
9
+ @pretending
10
+ end
11
+
12
+ attr_accessor :pretending, :environment
13
+ end
14
+ end
@@ -1,22 +1,28 @@
1
+ require "rake"
2
+ require 'cocaine'
3
+
1
4
  module Kumade
2
5
  class Deployer < Base
3
- DEPLOY_BRANCH = "deploy"
4
- attr_reader :environment, :pretending, :git
6
+ attr_reader :git, :heroku, :packager
5
7
 
6
- def initialize(environment = 'staging', pretending = false)
8
+ def initialize
7
9
  super()
8
- @environment = environment
9
- @pretending = pretending
10
- @git = Git.new(pretending, environment)
11
- @branch = @git.current_branch
10
+ @git = Git.new
11
+ @heroku = Heroku.new
12
+ @branch = @git.current_branch
13
+ @packager = Packager.new(@git)
12
14
  end
13
15
 
14
16
  def deploy
15
- ensure_heroku_remote_exists
16
- pre_deploy
17
- sync_heroku
18
- heroku_migrate
19
- post_deploy
17
+ begin
18
+ ensure_heroku_remote_exists
19
+ pre_deploy
20
+ heroku.sync
21
+ heroku.migrate_database
22
+ rescue
23
+ ensure
24
+ post_deploy
25
+ end
20
26
  end
21
27
 
22
28
  def pre_deploy
@@ -25,138 +31,31 @@ module Kumade
25
31
  sync_github
26
32
  end
27
33
 
28
- def sync_github
29
- git.push(@branch)
30
- end
31
-
32
- def sync_heroku
33
- git.create(DEPLOY_BRANCH)
34
- git.push("#{DEPLOY_BRANCH}:master", environment, true)
34
+ def package_assets
35
+ packager.run
35
36
  end
36
37
 
37
- def heroku_migrate
38
- heroku("rake db:migrate") unless pretending
39
- success("Migrated #{environment}")
38
+ def sync_github
39
+ git.push(@branch)
40
40
  end
41
41
 
42
42
  def post_deploy
43
- git.delete(DEPLOY_BRANCH, @branch)
44
- end
45
-
46
- def heroku(command)
47
- heroku_command = if cedar?
48
- "bundle exec heroku run"
49
- else
50
- "bundle exec heroku"
51
- end
52
- run_or_error("#{heroku_command} #{command} --remote #{environment}",
53
- "Failed to run #{command} on Heroku")
54
- end
55
-
56
- def cedar?
57
- return @cedar unless @cedar.nil?
58
- @cedar = heroku("stack").split("\n").grep(/\*/).any? do |line|
59
- line.include?("cedar")
60
- end
43
+ heroku.delete_deploy_branch
61
44
  end
62
45
 
63
46
  def ensure_clean_git
64
47
  git.ensure_clean_git
65
48
  end
66
49
 
67
- def package_assets
68
- invoke_custom_task if custom_task?
69
- package_with_jammit if jammit_installed?
70
- package_with_more if more_installed?
71
- end
72
-
73
- def package_with_jammit
74
- begin
75
- success_message = "Packaged assets with Jammit"
76
-
77
- if pretending
78
- success(success_message)
79
- else
80
- Jammit.package!
81
-
82
- success(success_message)
83
- git_add_and_commit_all_assets_in(jammit_assets_path)
84
- end
85
- rescue => jammit_error
86
- error("Error: #{jammit_error.class}: #{jammit_error.message}")
87
- end
88
- end
89
-
90
- def package_with_more
91
- success_message = "Packaged assets with More"
92
- if pretending
93
- success(success_message)
94
- else
95
- begin
96
- run "bundle exec rake more:generate"
97
- if git.dirty?
98
- success(success_message)
99
- git_add_and_commit_all_assets_in(more_assets_path)
100
- end
101
- rescue => more_error
102
- error("Error: #{more_error.class}: #{more_error.message}")
103
- end
104
- end
105
- end
106
-
107
- def invoke_custom_task
108
- success "Running kumade:before_asset_compilation task"
109
- Rake::Task["kumade:before_asset_compilation"].invoke unless pretending
110
- end
111
-
112
- def git_add_and_commit_all_assets_in(dir)
113
- git.add_and_commit_all_in(dir, DEPLOY_BRANCH, 'Compiled assets', "Added and committed all assets", "couldn't commit assets")
114
- end
115
-
116
- def jammit_assets_path
117
- File.join(Jammit::PUBLIC_ROOT, Jammit.package_path)
118
- end
119
-
120
- def more_assets_path
121
- File.join('public', ::Less::More.destination_path)
122
- end
123
-
124
- def jammit_installed?
125
- @jammit_installed ||=
126
- (defined?(Jammit) ||
127
- begin
128
- require 'jammit'
129
- true
130
- rescue LoadError
131
- false
132
- end)
133
- end
134
-
135
- def more_installed?
136
- @more_installed ||=
137
- (defined?(Less::More) ||
138
- begin
139
- require 'less/more'
140
- true
141
- rescue LoadError
142
- false
143
- end)
144
- end
145
-
146
- def custom_task?
147
- load("Rakefile") if File.exist?("Rakefile")
148
- Rake::Task.task_defined?("kumade:before_asset_compilation")
149
- end
150
-
151
50
  def ensure_heroku_remote_exists
152
- if git.remote_exists?(environment)
51
+ if git.remote_exists?(Kumade.configuration.environment)
153
52
  if git.heroku_remote?
154
- success("#{environment} is a Heroku remote")
53
+ success("#{Kumade.configuration.environment} is a Heroku remote")
155
54
  else
156
- error(%{Cannot deploy: "#{environment}" remote does not point to Heroku})
55
+ error(%{Cannot deploy: "#{Kumade.configuration.environment}" remote does not point to Heroku})
157
56
  end
158
57
  else
159
- error(%{Cannot deploy: "#{environment}" remote does not exist})
58
+ error(%{Cannot deploy: "#{Kumade.configuration.environment}" remote does not exist})
160
59
  end
161
60
  end
162
61
  end