harpoon 0.0.4 → 0.0.5

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