harrison 0.3.0 → 0.4.0.b1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5a7a1e571b53bc0460cdfafd012a454a12a7abd7
4
+ data.tar.gz: 5b3899d0745b0a0cf49a7cb8babc02b88288cc4a
5
+ SHA512:
6
+ metadata.gz: 62ab8175825b9102916f4a59cfc46ee8c22faf787ed66e753b1e8df31261b8c98e0267058ddab68ea6010fee6c333546e345f340733ff6ee9d51b94cf9dbbd9a
7
+ data.tar.gz: fee23a513d98d677e458448e2491e26086cd0199667fce84ca6240f1461f7110349ee0758badb7de9b83eb78bd061cd6b5b73e016aab664313431346da0c349b
@@ -19,15 +19,16 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.required_ruby_version = '>= 1.9.3'
21
21
 
22
- spec.add_runtime_dependency "trollop"
23
- spec.add_runtime_dependency "net-ssh"
24
- spec.add_runtime_dependency "net-scp"
22
+ spec.add_runtime_dependency "trollop", "~> 2.1.2"
23
+ spec.add_runtime_dependency "net-ssh", "~> 2.9.1"
24
+ spec.add_runtime_dependency "net-scp", "~> 1.2.1"
25
+ spec.add_runtime_dependency "highline", "~> 1.7.8"
25
26
 
26
27
  spec.add_development_dependency "bundler", "~> 1.6"
27
28
  spec.add_development_dependency "rake"
28
29
  spec.add_development_dependency "rspec", "~> 3.0"
29
30
  spec.add_development_dependency "simplecov"
30
- spec.add_development_dependency "debugger" if RUBY_VERSION < "2.0.0"
31
- spec.add_development_dependency "byebug" if RUBY_VERSION >= "2.0.0"
31
+ spec.add_development_dependency "pry-debugger" if RUBY_VERSION < "2.0.0"
32
+ spec.add_development_dependency "pry-byebug" if RUBY_VERSION >= "2.0.0"
32
33
  spec.add_development_dependency "sourcify"
33
34
  end
@@ -7,6 +7,11 @@ require "harrison/package"
7
7
  require "harrison/deploy"
8
8
  require "harrison/deploy/phase"
9
9
 
10
+ begin
11
+ require "pry"
12
+ rescue LoadError
13
+ end
14
+
10
15
  module Harrison
11
16
 
12
17
  def self.invoke(args)
@@ -23,12 +23,10 @@ module Harrison
23
23
  end
24
24
  end
25
25
 
26
- # Find config from Harrison.config if it's not on this class.
27
- def method_missing(meth, *args, &block)
28
- if Harrison.config.respond_to?(meth)
29
- Harrison.config.send(meth, *args, &block)
30
- else
31
- super
26
+ # Add config getter methods from Harrison.config to this class.
27
+ Harrison::Config.config_keys.each do |key|
28
+ define_method(key) do
29
+ Harrison.config.send(key)
32
30
  end
33
31
  end
34
32
 
@@ -1,9 +1,16 @@
1
1
  module Harrison
2
2
  class Config
3
- attr_accessor :project
4
- attr_accessor :git_src
5
-
6
3
  def initialize(opts={})
4
+ self.class.config_keys.each do |key|
5
+ self.class.send(:attr_accessor, key)
6
+ end
7
+ end
8
+
9
+ def self.config_keys
10
+ [
11
+ :project,
12
+ :git_src,
13
+ ]
7
14
  end
8
15
  end
9
16
  end
@@ -1,3 +1,5 @@
1
+ require 'highline'
2
+
1
3
  module Harrison
2
4
  class Deploy < Base
3
5
  attr_accessor :artifact
@@ -17,12 +19,14 @@ module Harrison
17
19
  self.class.option_helper(:base_dir)
18
20
  self.class.option_helper(:deploy_via)
19
21
  self.class.option_helper(:keep)
22
+ self.class.option_helper(:confirm)
20
23
 
21
24
  # Command line opts for this action. Will be merged with common opts.
22
25
  arg_opts = [
23
26
  [ :hosts, "List of remote hosts to deploy to. Can also be specified in Harrisonfile.", :type => :strings ],
24
27
  [ :env, "Environment to deploy to. This can be examined in your Harrisonfile to calculate target hosts.", :type => :string ],
25
28
  [ :keep, "Number of recent deploys to keep after a successful deploy. (Including the most recent deploy.) Defaults to keeping all deploys forever.", :type => :integer ],
29
+ [ :confirm, "Whether to interactively confirm the list of target hosts for deployment.", :type => :flag, :default => true ],
26
30
  ]
27
31
 
28
32
  super(arg_opts, opts)
@@ -59,7 +63,8 @@ module Harrison
59
63
  end
60
64
 
61
65
  def update_current_symlink
62
- @_old_current = self.remote_exec("if [ -L #{current_symlink} ]; then readlink -vn #{current_symlink}; fi")
66
+ # Conditional assignment here makes this idempotent.
67
+ @_old_current ||= self.remote_exec("if [ -L #{current_symlink} ]; then readlink -vn #{current_symlink}; fi")
63
68
  @_old_current = nil if @_old_current.empty?
64
69
 
65
70
  # Symlink current to new deploy.
@@ -77,11 +82,24 @@ module Harrison
77
82
  # Override Harrisonfile hosts if it was passed on argv.
78
83
  self.hosts = @_argv_hosts if @_argv_hosts
79
84
 
85
+ if self.hosts.respond_to?(:call)
86
+ resolved_hosts = self.hosts.call(self)
87
+ self.hosts = resolved_hosts
88
+ end
89
+
80
90
  # Require at least one host.
81
91
  if !self.hosts || self.hosts.empty?
82
92
  abort("ERROR: You must specify one or more hosts to deploy/rollback on, either in your Harrisonfile or via --hosts.")
83
93
  end
84
94
 
95
+ if self.confirm
96
+ self.hosts.each { |h| puts " - #{h}" }
97
+
98
+ exit unless HighLine.new.agree("\nProceed with above-listed hosts?")
99
+
100
+ puts ""
101
+ end
102
+
85
103
  # Default to just built in deployment phases.
86
104
  self.phases ||= [ :upload, :extract, :link, :cleanup ]
87
105
 
@@ -7,6 +7,10 @@ module Harrison
7
7
 
8
8
  @conditions = Array.new
9
9
 
10
+ @limit = nil
11
+ @_run_count = 0
12
+ @_fail_count = 0
13
+
10
14
  yield self if block_given?
11
15
  end
12
16
 
@@ -14,7 +18,12 @@ module Harrison
14
18
  @conditions << block
15
19
  end
16
20
 
17
- # Ensure all conditions eval to true for this context.
21
+ # Limit the number of times this phase is invoked per deployment.
22
+ def set_limit(n)
23
+ @limit = n
24
+ end
25
+
26
+ # Check if all conditions eval to true for this context.
18
27
  def matches_context?(context)
19
28
  @conditions.all? { |cblock| cblock.call(context) }
20
29
  end
@@ -29,21 +38,30 @@ module Harrison
29
38
 
30
39
  # These should only be invoked by the deploy action.
31
40
  def _run(context)
41
+ # Ensure limit has not been met.
42
+ return unless @limit.nil? || @_run_count < @limit
43
+
44
+ # Ensure all conditions eval to true for this context.
32
45
  return unless matches_context?(context)
33
46
 
34
47
  if @run_block
35
48
  puts "[#{context.host}] Executing \"#{self.name}\"..."
36
49
  @run_block.call(context)
50
+ @_run_count += 1
37
51
  end
38
52
  end
39
53
 
40
54
  def _fail(context)
55
+ # Ensure limit has not been met.
56
+ return unless @limit.nil? || @_fail_count < @limit
57
+
41
58
  # Ensure all conditions eval to true for this context.
42
59
  return unless matches_context?(context)
43
60
 
44
61
  if @fail_block
45
62
  puts "[#{context.host}] Reverting \"#{self.name}\"..."
46
63
  @fail_block.call(context)
64
+ @_fail_count += 1
47
65
  end
48
66
 
49
67
  end
@@ -1,3 +1,3 @@
1
1
  module Harrison
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0.b1"
3
3
  end
@@ -1,6 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Harrison::Deploy do
4
+ before(:all) do
5
+ Harrison.class_variable_set(:@@config, Harrison::Config.new)
6
+ Harrison.config.project = 'test_project'
7
+ end
8
+
4
9
  let(:instance) do
5
10
  Harrison::Deploy.new.tap do |d|
6
11
  d.hosts = [ 'hf_host' ]
@@ -71,7 +76,6 @@ describe Harrison::Deploy do
71
76
  describe '#remote_exec' do
72
77
  before(:each) do
73
78
  instance.base_dir = '/opt'
74
- instance.project = 'test_project'
75
79
 
76
80
  @mock_ssh = double(:ssh)
77
81
  expect(instance).to receive(:ssh).and_return(@mock_ssh)
@@ -157,7 +161,6 @@ describe Harrison::Deploy do
157
161
  describe '#run' do
158
162
  before(:each) do
159
163
  instance.artifact = 'test_artifact.tar.gz'
160
- instance.project = 'test_project'
161
164
 
162
165
  @mock_ssh = double(:ssh, host: 'test_host1', exec: '', upload: true, download: true)
163
166
  allow(instance).to receive(:ssh).and_return(@mock_ssh)
@@ -254,8 +257,6 @@ describe Harrison::Deploy do
254
257
  before(:each) do
255
258
  instance.rollback = true
256
259
 
257
- instance.project = 'test_project'
258
-
259
260
  @mock_ssh = double(:ssh, host: 'test_host1', exec: '', upload: true, download: true)
260
261
  allow(instance).to receive(:ssh).and_return(@mock_ssh)
261
262
  end
@@ -389,7 +390,6 @@ describe Harrison::Deploy do
389
390
  describe '#remote_project_dir' do
390
391
  it 'should combine base_dir and project name' do
391
392
  instance.base_dir = '/test_base_dir'
392
- instance.project = 'test_project'
393
393
 
394
394
  expect(instance.send(:remote_project_dir)).to include('/test_base_dir', 'test_project')
395
395
  end
@@ -1,9 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Harrison::Package do
4
+ before(:all) do
5
+ Harrison.class_variable_set(:@@config, Harrison::Config.new)
6
+ Harrison.config.project = 'test_project'
7
+ end
8
+
4
9
  let(:instance) do
5
10
  Harrison::Package.new.tap do |p|
6
- p.project = 'test_project'
7
11
  p.host = 'hf_host'
8
12
  p.commit = 'HEAD'
9
13
  end
@@ -43,7 +47,6 @@ describe Harrison::Package do
43
47
 
44
48
  it 'should prepend remote build dir onto passed command' do
45
49
  instance.remote_dir = '~/.harrison'
46
- instance.project = 'test_project'
47
50
 
48
51
  expect(@mock_ssh).to receive(:exec).with("cd ~/.harrison/test_project/package && test_command").and_return('')
49
52
 
@@ -89,7 +92,6 @@ describe Harrison::Package do
89
92
  describe '#remote_project_dir' do
90
93
  it 'should combine remote dir and project name' do
91
94
  instance.remote_dir = '~/.harrison'
92
- instance.project = 'test_project'
93
95
 
94
96
  expect(instance.send(:remote_project_dir)).to include('~/.harrison', 'test_project')
95
97
  end
metadata CHANGED
@@ -1,158 +1,153 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: harrison
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
5
- prerelease:
4
+ version: 0.4.0.b1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jesse Scott
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-10-20 00:00:00.000000000 Z
11
+ date: 2016-07-12 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: trollop
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: '0'
19
+ version: 2.1.2
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '0'
26
+ version: 2.1.2
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: net-ssh
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
- version: '0'
33
+ version: 2.9.1
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
- version: '0'
40
+ version: 2.9.1
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: net-scp
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
- version: '0'
47
+ version: 1.2.1
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
- version: '0'
54
+ version: 1.2.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: highline
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.7.8
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.7.8
62
69
  - !ruby/object:Gem::Dependency
63
70
  name: bundler
64
71
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
72
  requirements:
67
- - - ~>
73
+ - - "~>"
68
74
  - !ruby/object:Gem::Version
69
75
  version: '1.6'
70
76
  type: :development
71
77
  prerelease: false
72
78
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
79
  requirements:
75
- - - ~>
80
+ - - "~>"
76
81
  - !ruby/object:Gem::Version
77
82
  version: '1.6'
78
83
  - !ruby/object:Gem::Dependency
79
84
  name: rake
80
85
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
86
  requirements:
83
- - - ! '>='
87
+ - - ">="
84
88
  - !ruby/object:Gem::Version
85
89
  version: '0'
86
90
  type: :development
87
91
  prerelease: false
88
92
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
93
  requirements:
91
- - - ! '>='
94
+ - - ">="
92
95
  - !ruby/object:Gem::Version
93
96
  version: '0'
94
97
  - !ruby/object:Gem::Dependency
95
98
  name: rspec
96
99
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
100
  requirements:
99
- - - ~>
101
+ - - "~>"
100
102
  - !ruby/object:Gem::Version
101
103
  version: '3.0'
102
104
  type: :development
103
105
  prerelease: false
104
106
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
107
  requirements:
107
- - - ~>
108
+ - - "~>"
108
109
  - !ruby/object:Gem::Version
109
110
  version: '3.0'
110
111
  - !ruby/object:Gem::Dependency
111
112
  name: simplecov
112
113
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
114
  requirements:
115
- - - ! '>='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
121
  requirements:
123
- - - ! '>='
122
+ - - ">="
124
123
  - !ruby/object:Gem::Version
125
124
  version: '0'
126
125
  - !ruby/object:Gem::Dependency
127
- name: debugger
126
+ name: pry-byebug
128
127
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
128
  requirements:
131
- - - ! '>='
129
+ - - ">="
132
130
  - !ruby/object:Gem::Version
133
131
  version: '0'
134
132
  type: :development
135
133
  prerelease: false
136
134
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
135
  requirements:
139
- - - ! '>='
136
+ - - ">="
140
137
  - !ruby/object:Gem::Version
141
138
  version: '0'
142
139
  - !ruby/object:Gem::Dependency
143
140
  name: sourcify
144
141
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
142
  requirements:
147
- - - ! '>='
143
+ - - ">="
148
144
  - !ruby/object:Gem::Version
149
145
  version: '0'
150
146
  type: :development
151
147
  prerelease: false
152
148
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
149
  requirements:
155
- - - ! '>='
150
+ - - ">="
156
151
  - !ruby/object:Gem::Version
157
152
  version: '0'
158
153
  description:
@@ -163,9 +158,9 @@ executables:
163
158
  extensions: []
164
159
  extra_rdoc_files: []
165
160
  files:
166
- - .gitignore
167
- - .rspec
168
- - .travis.yml
161
+ - ".gitignore"
162
+ - ".rspec"
163
+ - ".travis.yml"
169
164
  - CHANGELOG
170
165
  - Gemfile
171
166
  - IDEAS
@@ -195,30 +190,26 @@ files:
195
190
  homepage: https://github.com/puppetlabs/harrison
196
191
  licenses:
197
192
  - Apache 2.0
193
+ metadata: {}
198
194
  post_install_message:
199
195
  rdoc_options: []
200
196
  require_paths:
201
197
  - lib
202
198
  required_ruby_version: !ruby/object:Gem::Requirement
203
- none: false
204
199
  requirements:
205
- - - ! '>='
200
+ - - ">="
206
201
  - !ruby/object:Gem::Version
207
202
  version: 1.9.3
208
203
  required_rubygems_version: !ruby/object:Gem::Requirement
209
- none: false
210
204
  requirements:
211
- - - ! '>='
205
+ - - ">"
212
206
  - !ruby/object:Gem::Version
213
- version: '0'
214
- segments:
215
- - 0
216
- hash: 2429299049933717858
207
+ version: 1.3.1
217
208
  requirements: []
218
209
  rubyforge_project:
219
- rubygems_version: 1.8.29
210
+ rubygems_version: 2.4.5.1
220
211
  signing_key:
221
- specification_version: 3
212
+ specification_version: 4
222
213
  summary: Simple artifact-based deployment for web applications.
223
214
  test_files:
224
215
  - spec/fixtures/Harrisonfile