harpoon 0.0.4 → 0.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 67816218225a067d3f8b66c9673338f17204fd3d
4
- data.tar.gz: 75ba5ab88e915ad54987f0518a620ba4bbeb19b8
3
+ metadata.gz: 785a0b17a5308ada400cdcdcbb89add7f665446d
4
+ data.tar.gz: b752390ed81dca7ab9c8d4391c2beb1e628a1651
5
5
  SHA512:
6
- metadata.gz: 5f61d684a67f40527bc41396e63d3a5115ae2d02ca4677b315890b33cb6202f90ea50bfab68022ab3bd6895ed51ab86fd3574a8a52c3d4fff8005b3c2158e6f3
7
- data.tar.gz: d1af82d8c71e92dcdabf854a91cdbc451413dc169f2e4498dfb59f0418aeb768e30fde4bcc560b3ec25f082060b1daac800d4e92f393219afea5e9c65be5a302
6
+ metadata.gz: 38b0d89349672d7067ae295ba17df1f0f2260bb7daad15dc9c2a5e4d7dbdadaab5a2854ae1857e5e1f5948d057aee3991abffd1a0e46853368d813724ff238ca
7
+ data.tar.gz: 87d9b4359c0ba94fbeed1810700d3fcef3846bf9b7a1c6d10166e6e9061a98537472238babf11f1319f3990a4f20d590d2706085ce5f1404e8e20de2ed04d3d0
data/harpoon.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'harpoon'
3
- s.version = '0.0.4'
3
+ s.version = '0.0.5'
4
4
  s.date = '2014-08-20'
5
5
  s.summary = "A single page app deployer for amazon s3"
6
6
  s.description = "Deploy small server-less webapps to amazon s3, including buckets, dns and permissions"
@@ -9,11 +9,12 @@ Gem::Specification.new do |s|
9
9
  s.licenses = ["MIT"]
10
10
  s.files = `git ls-files -z`.split("\x0")
11
11
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
12
- s.add_dependency "thor", "~> 0.19.1"
13
- s.add_dependency "netrc", "~> 0.7.7"
14
- s.add_dependency "aws-sdk", "~> 1.51.0"
15
- s.add_dependency "public_suffix", "~> 1.4.5"
16
- s.add_dependency 'colorize', '~> 0.7.3'
17
- s.add_dependency 'activesupport', "~> 4.1.5"
12
+ s.add_runtime_dependency 'thor', '~> 0.19', '>= 0.19.1'
13
+ s.add_runtime_dependency 'netrc', '~> 0.7', '>= 0.7.7'
14
+ s.add_runtime_dependency 'aws-sdk', '~> 1.51', '>= 1.51.0'
15
+ s.add_runtime_dependency 'bitballoon', '~> 0.2', '>= 0.2.5'
16
+ s.add_runtime_dependency 'public_suffix', '~> 1.4', '>= 1.4.5'
17
+ s.add_runtime_dependency 'colorize', '~> 0.7', '>= 0.7.3'
18
+ s.add_runtime_dependency 'activesupport', '~> 4.1', '>= 4.1.5'
18
19
  s.homepage = 'http://www.getharpoon.com'
19
20
  end
data/lib/harpoon/auth.rb CHANGED
@@ -37,13 +37,19 @@ module Harpoon
37
37
  end
38
38
  end
39
39
 
40
- def get_or_ask(key, mes1 = "Private Key", mes2 = "Public Key")
40
+ def get_or_ask(key, mes1 = nil, mes2 = nil)
41
41
  values = get(key)
42
42
  return values if values
43
- puts "Enter your #{mes1}:"
44
- val1 = $stdin.gets.to_s.strip
45
- puts "Enter your #{mes2}:"
46
- val2 = $stdin.gets.to_s.strip
43
+ val1 = nil
44
+ val2 = nil
45
+ if mes1
46
+ puts "Enter your #{mes1}:"
47
+ val1 = $stdin.gets.to_s.strip
48
+ end
49
+ if mes2
50
+ puts "Enter your #{mes2}:"
51
+ val2 = $stdin.gets.to_s.strip
52
+ end
47
53
  set(key, val1, val2)
48
54
  return [val1, val2]
49
55
  end
@@ -52,7 +58,7 @@ module Harpoon
52
58
 
53
59
  #netrc doesn't like nil values
54
60
  def netrc_nil(value = nil)
55
- if value
61
+ if value && value != ""
56
62
  if value == "nothing-here"
57
63
  return nil
58
64
  else
@@ -42,10 +42,10 @@ module Harpoon
42
42
  runner.list
43
43
  end
44
44
 
45
- desc "rollback", "Rollback to previous release"
46
- def rollback
45
+ desc "rollback VERSION", "Rollback to previous release"
46
+ def rollback(version)
47
47
  runner = Harpoon::Runner.new(options)
48
- runner.rollback
48
+ runner.rollback(version)
49
49
  end
50
50
  end
51
51
  end
@@ -38,6 +38,7 @@ module Harpoon
38
38
  def initialize(config, auth, logger)
39
39
  @logger = logger
40
40
  @auth = {}
41
+ @config = config
41
42
  @options = self.class.default_options.dup
42
43
 
43
44
  @options.deep_merge!(config.hosting_options || {})
@@ -0,0 +1,104 @@
1
+ require "bitballoon"
2
+ module Harpoon
3
+ module Services
4
+ class Bitballoon
5
+ include Harpoon::Service
6
+
7
+ auth :secret, "Access Token"
8
+
9
+ def setup
10
+ #setup for future deploys
11
+ if site
12
+ @logger.pass "Site already configured"
13
+ else
14
+ bitballoon.sites.create(:name => @config.name)
15
+ @logger.pass "Site configured as #{@config.name}"
16
+ end
17
+ if @options.primary_domain
18
+ site.update(custom_domain: @options.primary_domain)
19
+ @logger.pass "Custom Domain configured"
20
+ end
21
+ @logger.suggest "You should run `harpoon doctor` to confirm setup"
22
+ end
23
+
24
+ def deploy
25
+ #deploy new code
26
+ if site
27
+ if @config.directory
28
+ @logger.info "Deploying #{@config.directory}"
29
+ deploy = site.deploys.create(dir: @config.directory)
30
+ site.wait_for_ready
31
+ @logger.pass "Deployed."
32
+ else
33
+ @logger.fatal "We don't know what to deploy!"
34
+ end
35
+ else
36
+ @logger.fatal "Uh oh, please run `harpoon doctor`"
37
+ end
38
+ end
39
+
40
+ def list
41
+ #list available rollbacks
42
+ if site
43
+ @logger.info "The following rollbacks are available"
44
+ site.deploys.each_with_index do |deploy, index|
45
+ @logger.info "#{index} - #{deploy.created_at}"
46
+ end
47
+ @logger.info "To Rollback, type `harpoon rollback {{deploy-number}}`"
48
+ else
49
+ @logger.fatal "Uh oh, please run `harpoon doctor`"
50
+ end
51
+ end
52
+
53
+ def rollback(version)
54
+ #rollback to {{version}}
55
+ deploy = site.deploys.all[version.to_i]
56
+ if deploy
57
+ @logger.info "Publishing version #{deploy.id} created at #{deploy.created_at}"
58
+ deploy.publish
59
+ @logger.pass "Published."
60
+ end
61
+ end
62
+
63
+ def doctor
64
+ #check to see if we're ready for a deploy
65
+ if site
66
+ @logger.pass "Site configured with BitBalloon"
67
+ else
68
+ @logger.fail "Site not configured"
69
+ @logger.suggest "Run `harpoon setup`"
70
+ exit
71
+ end
72
+
73
+ if @config[:primary_domain]
74
+ if site.custom_domain == @config[:primary_domain]
75
+ @logger.pass "Custom domain configured"
76
+ else
77
+ @logger.fail "Custom domain not setup"
78
+ @logger.suggest "Run `harpoon setup`"
79
+ exit
80
+ end
81
+ end
82
+
83
+ @logger.suggest "Make sure you have your DNS settings configured"
84
+ @logger.suggest "Learn more at https://www.bitballoon.com/docs/custom_domains/"
85
+ end
86
+
87
+ private
88
+
89
+ def bitballoon
90
+ @bitballoon ||= ::BitBalloon::Client.new(:access_token => @auth[:secret])
91
+ end
92
+
93
+ def site
94
+ return @site if defined? @site
95
+ bitballoon.sites.each do |s|
96
+ return @site = s if s.name == @config.name
97
+ end
98
+ @logger.fatal "Site could not be found"
99
+ @logger.suggest "Try running `harpoon doctor`"
100
+ return nil
101
+ end
102
+ end
103
+ end
104
+ end
@@ -34,7 +34,7 @@ module Harpoon
34
34
  bucket.policy = policy
35
35
 
36
36
 
37
- history = setup_bucket(rollback_bucket(@options.primary_domain))
37
+ history = setup_bucket(rollback_bucket_name(@options.primary_domain))
38
38
  @logger.info "Created rollback bucket"
39
39
 
40
40
  setup_dns_alias(@options.primary_domain, bucket)
@@ -43,7 +43,6 @@ module Harpoon
43
43
  if @options.forwarded_domain
44
44
  #we also want to forward some domains
45
45
  #make sure we have an array
46
- #TODO : Move all of this nonsense to the config object, it should be validating this stuff
47
46
  forwarded = @options.forwarded_domain.is_a?(Array) ? @options.forwarded_domain : [@options.forwarded_domain]
48
47
  forwarded.each do |f|
49
48
  bucket = setup_bucket(f)
@@ -61,28 +60,33 @@ module Harpoon
61
60
 
62
61
  def deploy
63
62
  raise Harpoon::Errors::InvalidConfiguration, "Missing list of files" unless @options.files && @options.directory && @options.primary_domain
64
- move_existing_to_history!
65
- current_bucket = s3.buckets[@options.primary_domain]
66
- raise Harpoon::Errors::MissingSetup, "Required s3 buckets are not created. Run harpoon doctor to test." unless current_bucket.exists?
67
- @logger.info "Copying new release to s3"
68
- @options.files.each do |f|
69
- @logger.debug "Path: #{f}"
70
- relative_path = Pathname.new(f).relative_path_from(Pathname.new(@options.directory)).to_s
71
- @logger.debug "s3 key: #{relative_path}"
72
- current_bucket.objects[relative_path].write(Pathname.new(f))
63
+ if primary_bucket
64
+ move_existing_to_history!
65
+ @logger.info "Copying new release to s3"
66
+ @options.files.each do |f|
67
+ @logger.debug "Path: #{f}"
68
+ relative_path = Pathname.new(f).relative_path_from(Pathname.new(@options.directory)).to_s
69
+ @logger.debug "s3 key: #{relative_path}"
70
+ primary_bucket.objects[relative_path].write(Pathname.new(f))
71
+ end
72
+ @logger.info "...done"
73
+ else
74
+ raise Harpoon::Errors::MissingSetup, "Required s3 buckets are not created. Run harpoon doctor to test."
73
75
  end
74
- @logger.info "...done"
75
76
  end
76
77
 
77
78
  def list
78
79
  @logger.info "The following rollbacks are available:"
79
- if @options.primary_domain
80
- tree = s3.buckets[rollback_bucket(@options.primary_domain)].as_tree
80
+ if rollback_bucket
81
+ tree = rollback_bucket.as_tree
81
82
  rollbacks = tree.children.collect {|i| i.prefix.gsub(/\/$/, "").to_i }
82
83
  rollbacks.sort!.reverse!
83
84
  rollbacks.each_with_index do |r, index|
84
85
  @logger.info Time.at(r).strftime("#{index + 1} - %F %r")
85
86
  end
87
+ else
88
+ @logger.warn "Rollback bucket not yet created"
89
+ @logger.suggest "Run harpoon setup to create one"
86
90
  end
87
91
  end
88
92
 
@@ -142,10 +146,15 @@ module Harpoon
142
146
  @logger.info "...done"
143
147
  end
144
148
 
145
- def rollback
149
+ def rollback(version)
146
150
  @logger.info "Not yet implemented!"
147
151
  @logger.info "Your rollbacks ARE safe on s3 #{rollback_bucket(@options.primary_domain)}"
148
- self.list
152
+ if rollback_bucket && primary_bucket
153
+ @logger.debug "Rollback bucket found, ensuring version exists"
154
+ else
155
+ @logger.warn "Buckets not yet configured"
156
+ @logger.suggest "Setup a primary domain in your configuration and run harpoon setup"
157
+ end
149
158
  end
150
159
 
151
160
  private
@@ -235,10 +244,6 @@ module Harpoon
235
244
  @logger.suggest "=============================="
236
245
  end
237
246
 
238
- def rollback_bucket(domain)
239
- "#{domain}-history"
240
- end
241
-
242
247
  def move_existing_to_history!
243
248
  raise Harpoon::Errors::InvalidConfiguration, "Must have a primary domain defined" unless @options.primary_domain
244
249
  @logger.info "Moving existing deploy to history"
@@ -257,9 +262,31 @@ module Harpoon
257
262
  end
258
263
  @logger.debug "Moved to history, deleting files from current bucket"
259
264
  #delete the current objects
260
- current.objects.delete_all
265
+ bucket.objects.delete_all
261
266
  @logger.debug "Files deleted"
262
267
  end
268
+
269
+ def primary_bucket
270
+ return @primary_bucket if defined? @primary_bucket
271
+ if @options.primary_domain && s3.buckets[@options.primary_domain].exists?
272
+ return @primary_bucket = s3.buckets[@options.primary_domain]
273
+ else
274
+ return false
275
+ end
276
+ end
277
+
278
+ def rollback_bucket
279
+ return @rollback_bucket if defined? @rollback_bucket
280
+ if @options.primary_domain && s3.buckets[rollback_bucket_name(@options.primary_domain)].exists?
281
+ return @rollback_bucket = s3.buckets[rollback_bucket_name(@options.primary_domain)]
282
+ else
283
+ return false
284
+ end
285
+ end
286
+
287
+ def rollback_bucket_name(domain)
288
+ "#{domain}-history"
289
+ end
263
290
  end
264
291
  end
265
292
  end
data/lib/harpoon.rb CHANGED
@@ -10,4 +10,5 @@ module Harpoon
10
10
  require_relative "harpoon/service"
11
11
  require_relative "harpoon/services/test"
12
12
  require_relative "harpoon/services/s3"
13
+ require_relative "harpoon/services/bitballoon"
13
14
  end
@@ -0,0 +1,19 @@
1
+ require "helper"
2
+
3
+ describe "Logger" do
4
+ before do
5
+ @logger = Harpoon::Logger.new(STDOUT)
6
+ end
7
+
8
+ it "Should understand how to record a pass" do
9
+ assert defined?(@logger.pass), "Should have a pass method"
10
+ end
11
+
12
+ it "Should understand how to record a fail" do
13
+ assert defined?(@logger.fail), "Should have a fail method"
14
+ end
15
+
16
+ it "Should understand how to record a suggestion" do
17
+ assert defined?(@logger.suggest), "Should have a suggest method"
18
+ end
19
+ end
@@ -27,6 +27,7 @@ describe "Service Base" do
27
27
  @mock_auth = MiniTest::Mock.new
28
28
  @mock_logger = MiniTest::Mock.new
29
29
  d = {
30
+ name: "test-app",
30
31
  hosting: :test,
31
32
  hosting_options: {default_option: "one", new_option: true, default_option_required: true}
32
33
  }
@@ -49,6 +50,11 @@ describe "Service Base" do
49
50
  assert_equal true, @service.instance_eval {@options.new_option}
50
51
  end
51
52
 
53
+ it "Should give us access to the root config object" do
54
+ @service = Harpoon::Services::TestBase.new(@mock_options, @mock_auth, @mock_logger)
55
+ assert_equal "test-app", @service.instance_eval {@config.name}
56
+ end
57
+
52
58
  it "Should raise an error if required options aren't included" do
53
59
  @mock_options = Harpoon::Config.new({hosting: :test})
54
60
  assert_raises Harpoon::Errors::InvalidConfiguration do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: harpoon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Quinn
@@ -15,6 +15,9 @@ dependencies:
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.19'
20
+ - - ">="
18
21
  - !ruby/object:Gem::Version
19
22
  version: 0.19.1
20
23
  type: :runtime
@@ -22,6 +25,9 @@ dependencies:
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.19'
30
+ - - ">="
25
31
  - !ruby/object:Gem::Version
26
32
  version: 0.19.1
27
33
  - !ruby/object:Gem::Dependency
@@ -29,6 +35,9 @@ dependencies:
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.7'
40
+ - - ">="
32
41
  - !ruby/object:Gem::Version
33
42
  version: 0.7.7
34
43
  type: :runtime
@@ -36,6 +45,9 @@ dependencies:
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
47
  - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.7'
50
+ - - ">="
39
51
  - !ruby/object:Gem::Version
40
52
  version: 0.7.7
41
53
  - !ruby/object:Gem::Dependency
@@ -43,6 +55,9 @@ dependencies:
43
55
  requirement: !ruby/object:Gem::Requirement
44
56
  requirements:
45
57
  - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.51'
60
+ - - ">="
46
61
  - !ruby/object:Gem::Version
47
62
  version: 1.51.0
48
63
  type: :runtime
@@ -50,13 +65,39 @@ dependencies:
50
65
  version_requirements: !ruby/object:Gem::Requirement
51
66
  requirements:
52
67
  - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.51'
70
+ - - ">="
53
71
  - !ruby/object:Gem::Version
54
72
  version: 1.51.0
73
+ - !ruby/object:Gem::Dependency
74
+ name: bitballoon
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '0.2'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 0.2.5
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.2'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 0.2.5
55
93
  - !ruby/object:Gem::Dependency
56
94
  name: public_suffix
57
95
  requirement: !ruby/object:Gem::Requirement
58
96
  requirements:
59
97
  - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '1.4'
100
+ - - ">="
60
101
  - !ruby/object:Gem::Version
61
102
  version: 1.4.5
62
103
  type: :runtime
@@ -64,6 +105,9 @@ dependencies:
64
105
  version_requirements: !ruby/object:Gem::Requirement
65
106
  requirements:
66
107
  - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.4'
110
+ - - ">="
67
111
  - !ruby/object:Gem::Version
68
112
  version: 1.4.5
69
113
  - !ruby/object:Gem::Dependency
@@ -71,6 +115,9 @@ dependencies:
71
115
  requirement: !ruby/object:Gem::Requirement
72
116
  requirements:
73
117
  - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '0.7'
120
+ - - ">="
74
121
  - !ruby/object:Gem::Version
75
122
  version: 0.7.3
76
123
  type: :runtime
@@ -78,6 +125,9 @@ dependencies:
78
125
  version_requirements: !ruby/object:Gem::Requirement
79
126
  requirements:
80
127
  - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '0.7'
130
+ - - ">="
81
131
  - !ruby/object:Gem::Version
82
132
  version: 0.7.3
83
133
  - !ruby/object:Gem::Dependency
@@ -85,6 +135,9 @@ dependencies:
85
135
  requirement: !ruby/object:Gem::Requirement
86
136
  requirements:
87
137
  - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '4.1'
140
+ - - ">="
88
141
  - !ruby/object:Gem::Version
89
142
  version: 4.1.5
90
143
  type: :runtime
@@ -92,6 +145,9 @@ dependencies:
92
145
  version_requirements: !ruby/object:Gem::Requirement
93
146
  requirements:
94
147
  - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '4.1'
150
+ - - ">="
95
151
  - !ruby/object:Gem::Version
96
152
  version: 4.1.5
97
153
  description: Deploy small server-less webapps to amazon s3, including buckets, dns
@@ -117,6 +173,7 @@ files:
117
173
  - lib/harpoon/logger.rb
118
174
  - lib/harpoon/runner.rb
119
175
  - lib/harpoon/service.rb
176
+ - lib/harpoon/services/bitballoon.rb
120
177
  - lib/harpoon/services/s3.rb
121
178
  - lib/harpoon/services/test.rb
122
179
  - lib/harpoon/templates/harpoon.json
@@ -133,6 +190,7 @@ files:
133
190
  - test/test_directory/unnested_files/nested/test2.txt
134
191
  - test/test_directory/unnested_files/test.txt
135
192
  - test/test_hosting.rb
193
+ - test/test_logger.rb
136
194
  - test/test_runner.rb
137
195
  - test/test_service_base.rb
138
196
  - test/test_services.rb