paratrooper 0.0.5 → 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.
data/Gemfile.lock CHANGED
@@ -1,22 +1,25 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- paratrooper (0.0.2)
5
- heroku-api
4
+ paratrooper (0.3.0)
5
+ heroku-api (~> 0.3)
6
+ netrc (~> 0.7)
6
7
 
7
8
  GEM
8
9
  remote: http://rubygems.org/
9
10
  specs:
10
11
  coderay (1.0.8)
11
12
  diff-lcs (1.1.3)
12
- excon (0.16.7)
13
- heroku-api (0.3.6)
14
- excon (~> 0.16.7)
13
+ excon (0.16.10)
14
+ heroku-api (0.3.7)
15
+ excon (~> 0.16.10)
15
16
  method_source (0.8.1)
17
+ netrc (0.7.7)
16
18
  pry (0.9.10)
17
19
  coderay (~> 1.0.5)
18
20
  method_source (~> 0.8)
19
21
  slop (~> 3.3.1)
22
+ rake (10.0.3)
20
23
  rspec (2.12.0)
21
24
  rspec-core (~> 2.12.0)
22
25
  rspec-expectations (~> 2.12.0)
@@ -33,4 +36,5 @@ PLATFORMS
33
36
  DEPENDENCIES
34
37
  paratrooper!
35
38
  pry
39
+ rake
36
40
  rspec (~> 2.12)
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Library for handling common tasks when deploying to [Heroku](http://heroku.com)
4
4
 
5
+ [![Build Status](https://travis-ci.org/mattpolito/paratrooper.png?branch=master)](https://travis-ci.org/mattpolito/paratrooper)
6
+
5
7
  ## Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
@@ -1,11 +1,19 @@
1
+ require 'stringio'
2
+
1
3
  module Paratrooper
2
4
  class DefaultFormatter
5
+ attr_reader :output
6
+
7
+ def initialize(output = StringIO.new)
8
+ @output = output
9
+ end
10
+
3
11
  def display(message)
4
- puts
5
- puts "=" * 80
6
- puts ">> #{message}"
7
- puts "=" * 80
8
- puts
12
+ output.puts
13
+ output.puts "=" * 80
14
+ output.puts ">> #{message}"
15
+ output.puts "=" * 80
16
+ output.puts
9
17
  end
10
18
  end
11
19
  end
@@ -1,4 +1,4 @@
1
- require 'heroku-api'
1
+ require 'paratrooper/heroku_wrapper'
2
2
  require 'paratrooper/default_formatter'
3
3
  require 'paratrooper/system_caller'
4
4
 
@@ -9,19 +9,19 @@ module Paratrooper
9
9
  def initialize(app_name, options = {})
10
10
  @app_name = app_name
11
11
  @formatter = options[:formatter] || DefaultFormatter.new
12
- @heroku = options[:heroku_auth] || Heroku::API.new(api_key: ENV['HEROKU_API_KEY'])
12
+ @heroku = options[:heroku] || HerokuWrapper.new(app_name, options)
13
13
  @tag_name = options[:tag]
14
14
  @system_caller = options[:system_caller] || SystemCaller.new
15
15
  end
16
16
 
17
17
  def activate_maintenance_mode
18
18
  notify_screen("Activating Maintenance Mode")
19
- app_maintenance_on
19
+ heroku.app_maintenance_on
20
20
  end
21
21
 
22
22
  def deactivate_maintenance_mode
23
23
  notify_screen("Deactivating Maintenance Mode")
24
- app_maintenance_off
24
+ heroku.app_maintenance_off
25
25
  end
26
26
 
27
27
  def update_repo_tag
@@ -44,7 +44,7 @@ module Paratrooper
44
44
 
45
45
  def app_restart
46
46
  notify_screen("Restarting application")
47
- _app_restart
47
+ heroku.app_restart
48
48
  end
49
49
 
50
50
  def warm_instance(wait_time = 3)
@@ -65,28 +65,8 @@ module Paratrooper
65
65
  alias_method :deploy, :default_deploy
66
66
 
67
67
  private
68
- def _app_maintenance(flag)
69
- heroku.post_app_maintenance(app_name, flag)
70
- end
71
-
72
- def _app_restart
73
- heroku.post_ps_restart(app_name)
74
- end
75
-
76
- def _app_domain_name
77
- heroku.get_domains(app_name).body.last['domain']
78
- end
79
-
80
- def app_maintenance_off
81
- _app_maintenance('0')
82
- end
83
-
84
- def app_maintenance_on
85
- _app_maintenance('1')
86
- end
87
-
88
68
  def app_url
89
- _app_domain_name
69
+ heroku.app_url
90
70
  end
91
71
 
92
72
  def git_remote
@@ -0,0 +1,40 @@
1
+ require 'heroku-api'
2
+ require 'paratrooper/local_api_key_extractor'
3
+
4
+ module Paratrooper
5
+ class HerokuWrapper
6
+ attr_reader :api_key, :app_name, :heroku_api, :key_extractor
7
+
8
+ def initialize(app_name, options = {})
9
+ @app_name = app_name
10
+ @key_extractor = options[:key_extractor] || LocalApiKeyExtractor
11
+ @api_key = options[:api_key] || key_extractor.get_credentials
12
+ @heroku_api = options[:heroku_api] || Heroku::API.new(api_key: api_key)
13
+ end
14
+
15
+ def app_restart
16
+ heroku_api.post_ps_restart(app_name)
17
+ end
18
+
19
+ def app_maintenance_off
20
+ app_maintenance('0')
21
+ end
22
+
23
+ def app_maintenance_on
24
+ app_maintenance('1')
25
+ end
26
+
27
+ def app_url
28
+ app_domain_name
29
+ end
30
+
31
+ private
32
+ def app_domain_name
33
+ heroku_api.get_domains(app_name).body.last['domain']
34
+ end
35
+
36
+ def app_maintenance(flag)
37
+ heroku_api.post_app_maintenance(app_name, flag)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ require 'netrc'
2
+
3
+ module Paratrooper
4
+ class LocalApiKeyExtractor
5
+ attr_reader :file_path, :netrc_klass
6
+
7
+ def self.get_credentials
8
+ new.read_credentials
9
+ end
10
+
11
+ def initialize(options = {})
12
+ @netrc_klass = options[:netrc_klass] || Netrc
13
+ @file_path = options[:file_path] || netrc_klass.default_path
14
+ end
15
+
16
+ def read_credentials
17
+ ENV['HEROKU_API_KEY'] || read_credentials_for('api.heroku.com')
18
+ end
19
+
20
+ private
21
+ def netrc
22
+ @netrc ||= begin
23
+ File.exists?(file_path) && Netrc.read(file_path)
24
+ rescue => error
25
+ raise error
26
+ end
27
+ end
28
+
29
+ def read_credentials_for(domain)
30
+ netrc[domain][1]
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module Paratrooper
2
- VERSION = "0.0.5"
2
+ VERSION = "0.4.0"
3
3
  end
data/paratrooper.gemspec CHANGED
@@ -10,14 +10,16 @@ Gem::Specification.new do |gem|
10
10
  gem.email = ['matt.polito@gmail.com', 'bthesorceror@gmail.com']
11
11
  gem.description = %q{Library to create task for deployment to Heroku}
12
12
  gem.summary = %q{Library to create task for deployment to Heroku}
13
- gem.homepage = "http://github.com/hashrocket/paratrooper"
13
+ gem.homepage = "http://github.com/mattpolito/paratrooper"
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
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 'rake'
20
21
  gem.add_development_dependency 'rspec', '~> 2.12'
21
22
  gem.add_development_dependency 'pry'
22
- gem.add_dependency 'heroku-api'
23
+ gem.add_dependency 'heroku-api', '~> 0.3'
24
+ gem.add_dependency 'netrc', '~> 0.7'
23
25
  end
@@ -0,0 +1,6 @@
1
+ machine api.heroku.com
2
+ login mattman@example.com
3
+ password LOCAL_API_KEY
4
+ machine code.heroku.com
5
+ login mattman@example.com
6
+ password LOCAL_API_KEY
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'paratrooper/default_formatter'
3
+
4
+ describe Paratrooper::DefaultFormatter do
5
+ let(:formatter) { described_class.new(output_stub) }
6
+ let(:output_stub) { StringIO.new }
7
+
8
+ describe "#display(message)" do
9
+ it "outputs _message_ to screen" do
10
+ expected_output = <<-EXPECTED_OUTPUT.gsub(/^ {8}/, '')
11
+
12
+ #{'=' * 80}
13
+ >> MESSAGE
14
+ #{'=' * 80}
15
+
16
+ EXPECTED_OUTPUT
17
+
18
+ formatter.display('MESSAGE')
19
+ output_stub.seek(0)
20
+
21
+ expect(output_stub.read).to eq(expected_output)
22
+ end
23
+ end
24
+ end
@@ -8,7 +8,7 @@ describe Paratrooper::Deploy do
8
8
  let(:app_name) { 'app' }
9
9
  let(:default_options) do
10
10
  {
11
- heroku_auth: heroku,
11
+ heroku: heroku,
12
12
  formatter: formatter,
13
13
  system_caller: system_caller
14
14
  }
@@ -16,9 +16,10 @@ describe Paratrooper::Deploy do
16
16
  let(:options) { Hash.new }
17
17
  let(:heroku) do
18
18
  double(:heroku,
19
- post_app_maintenance: true,
20
- post_ps_restart: true,
21
- get_domains: domain_response
19
+ app_url: 'application_url',
20
+ app_restart: true,
21
+ app_maintenance_on: true,
22
+ app_maintenance_off: true,
22
23
  )
23
24
  end
24
25
  let(:formatter) { double(:formatter, puts: '') }
@@ -69,7 +70,7 @@ describe Paratrooper::Deploy do
69
70
  end
70
71
 
71
72
  it "makes call to heroku to turn on maintenance mode" do
72
- heroku.should_receive(:post_app_maintenance).with(app_name, '1')
73
+ heroku.should_receive(:app_maintenance_on)
73
74
  deployer.activate_maintenance_mode
74
75
  end
75
76
  end
@@ -85,7 +86,7 @@ describe Paratrooper::Deploy do
85
86
  end
86
87
 
87
88
  it "makes call to heroku to turn on maintenance mode" do
88
- heroku.should_receive(:post_app_maintenance).with(app_name, '0')
89
+ heroku.should_receive(:app_maintenance_off)
89
90
  deployer.deactivate_maintenance_mode
90
91
  end
91
92
  end
@@ -172,7 +173,7 @@ describe Paratrooper::Deploy do
172
173
  end
173
174
 
174
175
  it 'restarts your heroku instance' do
175
- heroku.should_receive(:post_ps_restart).with(app_name)
176
+ heroku.should_receive(:app_restart)
176
177
  deployer.app_restart
177
178
  end
178
179
  end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+ require 'paratrooper/heroku_wrapper'
3
+
4
+ describe Paratrooper::HerokuWrapper do
5
+ let(:wrapper) do
6
+ described_class.new(app_name, default_options.merge(options))
7
+ end
8
+ let(:app_name) { 'app_name' }
9
+ let(:options) { Hash.new }
10
+ let(:default_options) do
11
+ {
12
+ heroku_api: heroku_api
13
+ }
14
+ end
15
+ let(:heroku_api) { double(:heroku_api) }
16
+
17
+ describe '#api_key' do
18
+ context 'when api_key is provided as an option' do
19
+ let(:options) do
20
+ {
21
+ api_key: 'PROVIDED_API_KEY'
22
+ }
23
+ end
24
+
25
+ it 'returns provided api key' do
26
+ expect(wrapper.api_key).to eq('PROVIDED_API_KEY')
27
+ end
28
+ end
29
+
30
+ context 'when no key is provided' do
31
+ let(:options) do
32
+ {
33
+ key_extractor: double(:key_extractor, get_credentials: 'NETRC_API_KEY')
34
+ }
35
+ end
36
+
37
+ it 'returns api key from locally stored file' do
38
+ expect(wrapper.api_key).to eq('NETRC_API_KEY')
39
+ end
40
+ end
41
+ end
42
+
43
+ describe '#app_restart' do
44
+ it "calls down to heroku api" do
45
+ heroku_api.should_receive(:post_ps_restart).with(app_name)
46
+ wrapper.app_restart
47
+ end
48
+ end
49
+
50
+ describe '#app_maintenance_off' do
51
+ it "calls down to heroku api" do
52
+ heroku_api.should_receive(:post_app_maintenance).with(app_name, '0')
53
+ wrapper.app_maintenance_off
54
+ end
55
+ end
56
+
57
+ describe '#app_maintenance_on' do
58
+ it "calls down to heroku api" do
59
+ heroku_api.should_receive(:post_app_maintenance).with(app_name, '1')
60
+ wrapper.app_maintenance_on
61
+ end
62
+ end
63
+
64
+ describe '#app_domain_name' do
65
+ let(:response) { double(:response, body: [{'domain' => 'APP_URL'}]) }
66
+ it "calls down to heroku api" do
67
+ heroku_api.should_receive(:get_domains).with(app_name).and_return(response)
68
+ wrapper.app_url
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'paratrooper/local_api_key_extractor'
3
+
4
+ describe Paratrooper::LocalApiKeyExtractor do
5
+ let(:netrc_klass) { double(:netrc_klass, default_path: fixture_file_path) }
6
+ let(:fixture_file_path) { fixture_path('netrc') }
7
+
8
+ describe 'file association' do
9
+ context 'when file path is provided' do
10
+ let(:extractor) { described_class.new(file_path: fixture_file_path) }
11
+
12
+ it 'uses provided file path' do
13
+ expect(extractor.file_path).to eq(fixture_file_path)
14
+ end
15
+ end
16
+
17
+ context 'when file path is not provided' do
18
+ let(:extractor) { described_class.new(netrc_klass: netrc_klass) }
19
+
20
+ it 'uses default path' do
21
+ expect(extractor.file_path).to eq(netrc_klass.default_path)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe '#read_credentials' do
27
+ let(:extractor) { described_class.new(netrc_klass: netrc_klass) }
28
+
29
+ context 'when environment variable is set' do
30
+ before do
31
+ ENV.stub(:[]).with('HEROKU_API_KEY').and_return('ENV_API_KEY')
32
+ end
33
+
34
+ it 'returns credentials' do
35
+ expect(extractor.read_credentials).to eq('ENV_API_KEY')
36
+ end
37
+ end
38
+
39
+ context 'when environment variable is not set' do
40
+ before do
41
+ ENV.stub(:[]).with('HEROKU_API_KEY').and_return(nil)
42
+ end
43
+ it 'returns credentials from local file' do
44
+ expect(extractor.read_credentials).to eq('LOCAL_API_KEY')
45
+ end
46
+ end
47
+ end
48
+ end
data/spec/spec_helper.rb CHANGED
@@ -1 +1,5 @@
1
1
  require 'rspec'
2
+
3
+ def fixture_path(file)
4
+ File.expand_path("../fixtures/#{file}", __FILE__)
5
+ end
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.5
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,8 +10,24 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-24 00:00:00.000000000 Z
13
+ date: 2013-02-05 00:00:00.000000000 Z
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
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: '0'
15
31
  - !ruby/object:Gem::Dependency
16
32
  name: rspec
17
33
  requirement: !ruby/object:Gem::Requirement
@@ -49,17 +65,33 @@ dependencies:
49
65
  requirement: !ruby/object:Gem::Requirement
50
66
  none: false
51
67
  requirements:
52
- - - ! '>='
68
+ - - ~>
53
69
  - !ruby/object:Gem::Version
54
- version: '0'
70
+ version: '0.3'
55
71
  type: :runtime
56
72
  prerelease: false
57
73
  version_requirements: !ruby/object:Gem::Requirement
58
74
  none: false
59
75
  requirements:
60
- - - ! '>='
76
+ - - ~>
61
77
  - !ruby/object:Gem::Version
62
- version: '0'
78
+ version: '0.3'
79
+ - !ruby/object:Gem::Dependency
80
+ name: netrc
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ~>
85
+ - !ruby/object:Gem::Version
86
+ version: '0.7'
87
+ type: :runtime
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: '0.7'
63
95
  description: Library to create task for deployment to Heroku
64
96
  email:
65
97
  - matt.polito@gmail.com
@@ -77,12 +109,18 @@ files:
77
109
  - lib/paratrooper.rb
78
110
  - lib/paratrooper/default_formatter.rb
79
111
  - lib/paratrooper/deploy.rb
112
+ - lib/paratrooper/heroku_wrapper.rb
113
+ - lib/paratrooper/local_api_key_extractor.rb
80
114
  - lib/paratrooper/system_caller.rb
81
115
  - lib/paratrooper/version.rb
82
116
  - paratrooper.gemspec
117
+ - spec/fixtures/netrc
118
+ - spec/paratrooper/default_formatter_spec.rb
83
119
  - spec/paratrooper/deploy_spec.rb
120
+ - spec/paratrooper/heroku_wrapper_spec.rb
121
+ - spec/paratrooper/local_api_key_extractor_spec.rb
84
122
  - spec/spec_helper.rb
85
- homepage: http://github.com/hashrocket/paratrooper
123
+ homepage: http://github.com/mattpolito/paratrooper
86
124
  licenses: []
87
125
  post_install_message:
88
126
  rdoc_options: []
@@ -107,5 +145,10 @@ signing_key:
107
145
  specification_version: 3
108
146
  summary: Library to create task for deployment to Heroku
109
147
  test_files:
148
+ - spec/fixtures/netrc
149
+ - spec/paratrooper/default_formatter_spec.rb
110
150
  - spec/paratrooper/deploy_spec.rb
151
+ - spec/paratrooper/heroku_wrapper_spec.rb
152
+ - spec/paratrooper/local_api_key_extractor_spec.rb
111
153
  - spec/spec_helper.rb
154
+ has_rdoc: