harrison 0.3.0 → 0.4.0.b1

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.
@@ -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