paratrooper 0.0.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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: