paratrooper 0.0.2 → 0.0.3

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,18 +1,36 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- paratrooper (0.0.1)
4
+ paratrooper (0.0.2)
5
5
  heroku-api
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- excon (0.16.10)
11
- heroku-api (0.3.7)
12
- excon (~> 0.16.10)
10
+ coderay (1.0.8)
11
+ diff-lcs (1.1.3)
12
+ excon (0.16.7)
13
+ heroku-api (0.3.6)
14
+ excon (~> 0.16.7)
15
+ method_source (0.8.1)
16
+ pry (0.9.10)
17
+ coderay (~> 1.0.5)
18
+ method_source (~> 0.8)
19
+ slop (~> 3.3.1)
20
+ rspec (2.12.0)
21
+ rspec-core (~> 2.12.0)
22
+ rspec-expectations (~> 2.12.0)
23
+ rspec-mocks (~> 2.12.0)
24
+ rspec-core (2.12.2)
25
+ rspec-expectations (2.12.1)
26
+ diff-lcs (~> 1.1.3)
27
+ rspec-mocks (2.12.1)
28
+ slop (3.3.3)
13
29
 
14
30
  PLATFORMS
15
31
  ruby
16
32
 
17
33
  DEPENDENCIES
18
34
  paratrooper!
35
+ pry
36
+ rspec (~> 2.12)
data/README.md CHANGED
@@ -18,16 +18,18 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
+ >> Note: Before getting started, ensure that `ENV['HEROKU_API_KEY']` is set. If you do not know your api key, you can `cat ~/.netrc`. Your api key will be listed as password in that file. This is necessary until reading your crendentials out of the `.netrc` file is implemented.
22
+
21
23
  Instantiate Paratrooper with the name of your heroku application
22
24
 
23
25
  ```ruby
24
- Paratrooper.new('amazing-app')
26
+ Paratrooper::Deploy.new('amazing-app')
25
27
  ```
26
28
 
27
29
  also you can provide a tag name for repository use
28
30
 
29
31
  ```ruby
30
- Paratrooper.new('amazing-app', tag: 'staging')
32
+ Paratrooper::Deploy.new('amazing-app', tag: 'staging')
31
33
  ```
32
34
 
33
35
  Then there are methods available to perform common tasks like creating git tags, running migrations, and warming your application instance.
@@ -54,14 +56,14 @@ require 'paratrooper'
54
56
  namespace :deploy do
55
57
  desc 'Deploy app in staging environment'
56
58
  task :staging do
57
- deployment = Paratrooper.new("amazing-staging-app", tag: 'staging')
59
+ deployment = Paratrooper::Deploy.new("amazing-staging-app", tag: 'staging')
58
60
 
59
61
  deployment.deploy
60
62
  end
61
63
 
62
64
  desc 'Deploy app in production environment'
63
65
  task :production do
64
- deployment = Paratrooper.new("amazing-production-app", tag: 'production')
66
+ deployment = Paratrooper::Deploy.new("amazing-production-app", tag: 'production')
65
67
 
66
68
  deployment.deploy
67
69
  end
@@ -1,6 +1,5 @@
1
- require "paratrooper/version"
1
+ require 'paratrooper/version'
2
2
  require 'paratrooper/deploy'
3
3
 
4
4
  module Paratrooper
5
-
6
5
  end
@@ -0,0 +1,11 @@
1
+ module Paratrooper
2
+ class DefaultFormatter
3
+ def puts(message)
4
+ puts
5
+ puts "=" * 80
6
+ puts ">> #{message}"
7
+ puts "=" * 80
8
+ puts
9
+ end
10
+ end
11
+ end
@@ -1,51 +1,55 @@
1
1
  require 'heroku-api'
2
+ require 'paratrooper/default_formatter'
2
3
 
3
4
  module Paratrooper
4
5
  class Deploy
5
- attr_reader :app_name, :heroku, :tag_name
6
+ attr_reader :app_name, :formatter, :system_caller, :heroku, :tag_name
6
7
 
7
8
  def initialize(app_name, options = {})
8
- @app_name = app_name
9
- @heroku = options[:heroku_auth] || Heroku::API.new(api_key: ENV['HEROKU_API_KEY'])
10
- @tag_name = options[:tag]
9
+ @app_name = app_name
10
+ @formatter = options[:formatter] || DefaultFormatter.new
11
+ @heroku = options[:heroku_auth] || Heroku::API.new(api_key: ENV['HEROKU_API_KEY'])
12
+ @tag_name = options[:tag]
13
+ @system_caller = options[:system_caller] || SystemCaller.new
11
14
  end
12
15
 
13
16
  def activate_maintenance_mode
14
17
  notify_screen("Activating Maintenance Mode")
15
- heroku.post_app_maintenance(app_name, '1')
18
+ app_maintenance_on
16
19
  end
17
20
 
18
21
  def deactivate_maintenance_mode
19
22
  notify_screen("Deactivating Maintenance Mode")
20
- heroku.post_app_maintenance(app_name, '0')
23
+ app_maintenance_off
21
24
  end
22
25
 
23
26
  def update_repo_tag
24
- unless tag_name.empty?
27
+ unless tag_name.nil? || tag_name.empty?
25
28
  notify_screen("Updating Repo Tag: #{tag_name}")
26
- system "git tag #{tag_name} -f"
27
- system "git push origin #{tag_name}"
29
+ system_call "git tag #{tag_name} -f"
30
+ system_call "git push origin #{tag_name}"
28
31
  end
29
32
  end
30
33
 
31
34
  def push_repo(branch = 'master')
32
35
  notify_screen("Pushing #{branch} to Heroku")
33
- system "git push -f #{git_remote} #{branch}"
36
+ system_call "git push -f #{git_remote} #{branch}"
34
37
  end
35
38
 
36
39
  def run_migrations
37
40
  notify_screen("Running database migrations")
38
- system "heroku run rake db:migrate --app #{app_name}"
41
+ system_call "heroku run rake db:migrate --app #{app_name}"
39
42
  end
40
43
 
41
44
  def app_restart
42
- heroku.post_ps_restart(app_name)
45
+ notify_screen("Restarting application")
46
+ _app_restart
43
47
  end
44
48
 
45
- def warm_instance(wait_time = 5)
49
+ def warm_instance(wait_time = 3)
46
50
  sleep wait_time
47
51
  notify_screen("Accessing #{app_url} to warm up your application")
48
- system "curl -Il http://#{app_url}"
52
+ system_call "curl -Il http://#{app_url}"
49
53
  end
50
54
 
51
55
  def default_deploy
@@ -60,20 +64,46 @@ module Paratrooper
60
64
  alias_method :deploy, :default_deploy
61
65
 
62
66
  private
63
- def git_remote
64
- "git@heroku.com:#{app_name}.git"
67
+ def _app_maintenance(flag)
68
+ heroku.post_app_maintenance(app_name, flag)
65
69
  end
66
70
 
67
- def app_url
71
+ def _app_restart
72
+ heroku.post_ps_restart(app_name)
73
+ end
74
+
75
+ def _app_domain_name
68
76
  heroku.get_domains(app_name).body.last['domain']
69
77
  end
70
78
 
79
+ def app_maintenance_off
80
+ _app_maintenance('0')
81
+ end
82
+
83
+ def app_maintenance_on
84
+ _app_maintenance('1')
85
+ end
86
+
87
+ def app_url
88
+ _app_domain_name
89
+ end
90
+
91
+ def git_remote
92
+ "git@heroku.com:#{app_name}.git"
93
+ end
94
+
71
95
  def notify_screen(message)
72
- puts
73
- puts "=" * 80
74
- puts ">> #{message}"
75
- puts "=" * 80
76
- puts
96
+ formatter.puts(message)
97
+ end
98
+
99
+ def system_call(call)
100
+ system_caller.execute(call)
101
+ end
102
+ end
103
+
104
+ SystemCaller = Struct.new(:call) do
105
+ def execute
106
+ system(call)
77
107
  end
78
108
  end
79
109
  end
@@ -0,0 +1,5 @@
1
+ SystemCaller = Struct.new(:call) do
2
+ def execute
3
+ system(call)
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module Paratrooper
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -17,5 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
19
 
20
+ gem.add_development_dependency 'rspec', '~> 2.12'
21
+ gem.add_development_dependency 'pry'
20
22
  gem.add_dependency 'heroku-api'
21
23
  end
@@ -0,0 +1,182 @@
1
+ require 'spec_helper'
2
+ require 'paratrooper/deploy'
3
+
4
+ describe Paratrooper::Deploy do
5
+ let(:deployer) do
6
+ described_class.new(app_name, default_options.merge(options))
7
+ end
8
+ let(:app_name) { 'app' }
9
+ let(:default_options) do
10
+ {
11
+ heroku_auth: heroku,
12
+ formatter: formatter,
13
+ system_caller: system_caller
14
+ }
15
+ end
16
+ let(:options) { Hash.new }
17
+ let(:heroku) do
18
+ double(:heroku,
19
+ post_app_maintenance: true,
20
+ post_ps_restart: true,
21
+ get_domains: domain_response
22
+ )
23
+ end
24
+ let(:formatter) { double(:formatter, puts: '') }
25
+ let(:system_caller) { double(:system_caller) }
26
+ let(:domain_response) do
27
+ double(:domain_response, body: [{'domain' => 'application_url'}])
28
+ end
29
+
30
+ describe "options" do
31
+ context "accepts :tag" do
32
+ let(:options) { { tag: 'tag_name' } }
33
+
34
+ it "and responds to #tag_name" do
35
+ expect(deployer.tag_name).to eq('tag_name')
36
+ end
37
+ end
38
+
39
+ context "accepts :heroku_auth" do
40
+ let(:options) { { heroku_auth: heroku } }
41
+ let(:heroku) { double(:heroku) }
42
+
43
+ it "and responds to #heroku" do
44
+ expect(deployer.heroku).to eq(heroku)
45
+ end
46
+ end
47
+
48
+ context "accepts :formatter" do
49
+ let(:options) { { formatter: formatter } }
50
+ let(:formatter) { double(:formatter) }
51
+
52
+ it "and responds to #formatter" do
53
+ expect(deployer.formatter).to eq(formatter)
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#activate_maintenance_mode" do
59
+ let(:options) { { formatter: formatter } }
60
+ let(:formatter) { double(:formatter, puts: true) }
61
+
62
+ it "displays message" do
63
+ formatter.should_receive(:puts).with('Activating Maintenance Mode')
64
+ deployer.activate_maintenance_mode
65
+ end
66
+
67
+ it "makes call to heroku to turn on maintenance mode" do
68
+ heroku.should_receive(:post_app_maintenance).with(app_name, '1')
69
+ deployer.activate_maintenance_mode
70
+ end
71
+ end
72
+
73
+ describe "#deactivate_maintenance_mode" do
74
+ it "displays message" do
75
+ formatter.should_receive(:puts).with('Deactivating Maintenance Mode')
76
+ deployer.deactivate_maintenance_mode
77
+ end
78
+
79
+ it "makes call to heroku to turn on maintenance mode" do
80
+ heroku.should_receive(:post_app_maintenance).with(app_name, '0')
81
+ deployer.deactivate_maintenance_mode
82
+ end
83
+ end
84
+
85
+ describe "#update_repo_tag" do
86
+ context "when a tag_name is available" do
87
+ let(:options) { { tag: 'awesome' } }
88
+
89
+ before do
90
+ system_caller.stub(:execute)
91
+ end
92
+
93
+ it 'displays message' do
94
+ formatter.should_receive(:puts).with('Updating Repo Tag: awesome')
95
+ deployer.update_repo_tag
96
+ end
97
+
98
+ it 'creates a git tag' do
99
+ system_caller.should_receive(:execute).with('git tag awesome -f')
100
+ deployer.update_repo_tag
101
+ end
102
+
103
+ it 'pushes git tag' do
104
+ system_caller.should_receive(:execute).with('git push origin awesome')
105
+ deployer.update_repo_tag
106
+ end
107
+ end
108
+
109
+ context "when a tag_name is unavailable" do
110
+ let(:options) { Hash.new }
111
+
112
+ it 'no repo tags are created' do
113
+ system_caller.should_not_receive(:execute)
114
+ deployer.update_repo_tag
115
+ end
116
+ end
117
+ end
118
+
119
+ describe "#push_repo" do
120
+ before do
121
+ system_caller.stub(:execute)
122
+ end
123
+
124
+ it 'displays message' do
125
+ formatter.should_receive(:puts).with('Pushing master to Heroku')
126
+ deployer.push_repo
127
+ end
128
+
129
+ it 'pushes repo to heroku' do
130
+ expected_call = 'git push -f git@heroku.com:app.git master'
131
+ system_caller.should_receive(:execute).with(expected_call)
132
+ deployer.push_repo
133
+ end
134
+ end
135
+
136
+ describe "#run_migrations" do
137
+ before do
138
+ system_caller.stub(:execute)
139
+ end
140
+
141
+ it 'displays message' do
142
+ formatter.should_receive(:puts).with('Running database migrations')
143
+ deployer.run_migrations
144
+ end
145
+
146
+ it 'pushes repo to heroku' do
147
+ expected_call = 'heroku run rake db:migrate --app app'
148
+ system_caller.should_receive(:execute).with(expected_call)
149
+ deployer.run_migrations
150
+ end
151
+ end
152
+
153
+ describe "#app_restart" do
154
+ it 'displays message' do
155
+ formatter.should_receive(:puts).with('Restarting application')
156
+ deployer.app_restart
157
+ end
158
+
159
+ it 'restarts your heroku instance' do
160
+ heroku.should_receive(:post_ps_restart).with(app_name)
161
+ deployer.app_restart
162
+ end
163
+ end
164
+
165
+ describe "#warm_instance" do
166
+ before do
167
+ system_caller.stub(:execute)
168
+ end
169
+
170
+ it 'displays message' do
171
+ expected_notice = 'Accessing application_url to warm up your application'
172
+ formatter.should_receive(:puts).with(expected_notice)
173
+ deployer.warm_instance(0)
174
+ end
175
+
176
+ it 'pings application url' do
177
+ expected_call = 'curl -Il http://application_url'
178
+ system_caller.should_receive(:execute).with(expected_call)
179
+ deployer.warm_instance(0)
180
+ end
181
+ end
182
+ end
@@ -0,0 +1 @@
1
+ require 'rspec'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paratrooper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,8 +10,40 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-15 00:00:00.000000000 Z
13
+ date: 2013-01-23 00:00:00.000000000 Z
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '2.12'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '2.12'
31
+ - !ruby/object:Gem::Dependency
32
+ name: pry
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
15
47
  - !ruby/object:Gem::Dependency
16
48
  name: heroku-api
17
49
  requirement: !ruby/object:Gem::Requirement
@@ -43,9 +75,13 @@ files:
43
75
  - README.md
44
76
  - Rakefile
45
77
  - lib/paratrooper.rb
78
+ - lib/paratrooper/default_formatter.rb
46
79
  - lib/paratrooper/deploy.rb
80
+ - lib/paratrooper/system_caller.rb
47
81
  - lib/paratrooper/version.rb
48
82
  - paratrooper.gemspec
83
+ - spec/paratrooper/deploy_spec.rb
84
+ - spec/spec_helper.rb
49
85
  homepage: http://github.com/hashrocket/paratrooper
50
86
  licenses: []
51
87
  post_install_message:
@@ -70,4 +106,6 @@ rubygems_version: 1.8.24
70
106
  signing_key:
71
107
  specification_version: 3
72
108
  summary: Library to create task for deployment to Heroku
73
- test_files: []
109
+ test_files:
110
+ - spec/paratrooper/deploy_spec.rb
111
+ - spec/spec_helper.rb