glitter 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ bin/Glitterfile
1
2
  .DS_Store
2
3
  *.gem
3
4
  .bundle
data/README.md CHANGED
@@ -17,14 +17,12 @@ It should also be noted that Glitter uses HTTPS S3 URLs to eliminate the need fo
17
17
  3. Edit the Glitterfile
18
18
 
19
19
  # After you configure this file, deploy your app with `glitter push`
20
-
21
20
  name "My App"
22
- version "1.0.0"
21
+ version "1.0.0" # Don't forget, its ruby! This could read a version from a plist file
23
22
  archive "my_app.zip"
24
- release_notes "http://myapp.com/release_notes/"
25
23
 
26
24
  s3 {
27
- bucket "my_app"
25
+ bucket_name "my_app"
28
26
  access_key "access"
29
27
  secret_access_key "sekret"
30
28
  }
data/glitter.gemspec CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.description = %q{Glitter makes it easy to publish software updates via the Sparkle framework by using S3 buckets.}
14
14
 
15
15
  s.rubyforge_project = "glitter"
16
- s.add_dependency "aws-s3"
16
+ s.add_dependency "s3"
17
17
  s.add_dependency "haml"
18
18
  s.add_dependency "thor"
19
19
 
data/lib/glitter.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'aws/s3'
1
+ require 's3'
2
2
  require 'thor'
3
3
  require 'erb'
4
4
 
@@ -41,81 +41,114 @@ module Glitter
41
41
  end
42
42
  end
43
43
 
44
- # The configuration class that a release uses to deploy
45
- class Configuration
44
+ # The App class that a release uses to deploy
45
+ class App
46
46
  TemplatePath = File.expand_path('../glitter/templates/Glitterfile', __FILE__).to_s.freeze
47
+ RssTemplate = File.expand_path('../glitter/templates/rss.xml.erb', __FILE__).to_s.freeze
48
+ AppcastXml = 'appcast.xml'
47
49
 
48
50
  include Configurable
49
- attr_configurable :name, :version, :archive, :release_notes, :s3
51
+ attr_configurable :name, :version, :archive, :s3
50
52
 
51
53
  class S3
52
54
  include Configurable
53
- attr_configurable :bucket, :access_key, :secret_access_key
55
+ attr_configurable :bucket_name, :access_key, :secret_access_key
54
56
 
55
- def credentials
56
- {:access_key_id => access_key, :secret_access_key => secret_access_key}
57
+ def url_for(path)
58
+ "https://s3.amazonaws.com/#{bucket_name}/#{path}"
59
+ end
60
+
61
+ def service
62
+ @service ||= ::S3::Service.new(:access_key_id => access_key, :secret_access_key => secret_access_key)
63
+ end
64
+
65
+ def bucket
66
+ service.buckets.find(bucket_name)
57
67
  end
58
68
  end
59
69
 
60
70
  def s3(&block)
61
71
  @s3 ||= S3.configure(&block)
62
72
  end
63
- end
64
73
 
65
- class Release
66
- FeedTemplate = File.expand_path('../glitter/templates/rss.xml', __FILE__).to_s.freeze
74
+ class Appcast
75
+ ObjectName = 'appcast.xml'
76
+
77
+ attr_reader :app
67
78
 
68
- attr_accessor :config, :released_at
79
+ def initialize(app)
80
+ @app = app
81
+ end
69
82
 
70
- def push
71
- bucket.new_object(archive_name, file, bucket)
72
- end
83
+ def url
84
+ app.s3.url_for ObjectName
85
+ end
86
+
87
+ def push
88
+ object.content = rss
89
+ object.save
90
+ end
91
+
92
+ def rss
93
+ @rss ||= ERB.new(File.read(RssTemplate)).result(binding)
94
+ end
73
95
 
74
- def initialize(config)
75
- @config, @released_at = config, Time.now
76
- AWS::S3::Base.establish_connection! config.s3.credentials
96
+ private
97
+ def object
98
+ @object ||= app.s3.bucket.objects.build(ObjectName)
99
+ end
77
100
  end
78
101
 
79
- def name
80
- "#{config.name} #{config.version}"
102
+ def appcast
103
+ @appcast ||= Appcast.new(self)
81
104
  end
82
105
 
83
- def object_name
84
- "#{name.downcase.gsub(/\s/,'-')}#{File.extname(config.archive)}"
106
+ def head
107
+ releases[version]
85
108
  end
86
109
 
87
- def pub_date
88
- released_at.strftime("%a, %d %b %Y %H:%M:%S %z")
110
+ def releases
111
+ @releases ||= Hash.new do |hash,key|
112
+ hash[key] = Release.new do |r|
113
+ r.version = key
114
+ r.app = self
115
+ end
116
+ end
89
117
  end
118
+ end
90
119
 
91
- def appcast_url
92
- url_for 'appcast.xml'
120
+ class Release
121
+ attr_accessor :app, :version, :notes, :published_at
122
+ attr_reader :object
123
+
124
+ def initialize
125
+ @published_at = Time.now
126
+ yield self if block_given?
93
127
  end
94
128
 
95
- def url
96
- url_for object_name
129
+ def name
130
+ "#{app.name} #{version}"
97
131
  end
98
132
 
99
- def to_rss
100
- @rss ||= ERB.new(File.read(FeedTemplate)).result(binding)
133
+ def object_name
134
+ "#{name.gsub(/\s/,'-').downcase}#{File.extname(file.path)}"
101
135
  end
102
136
 
103
- def file
104
- @file ||= File.open(config.archive, 'r')
137
+ def object
138
+ @object ||= app.s3.bucket.objects.build(object_name)
105
139
  end
106
140
 
107
- def push
108
- AWS::S3::S3Object.store(object_name, File.open(config.archive), config.s3.bucket)
109
- AWS::S3::S3Object.store('appcast.xml', to_rss, config.s3.bucket)
141
+ def url
142
+ app.s3.url_for object_name
110
143
  end
111
144
 
112
- def yank
113
- AWS::S3::S3Object.store(object_name, config.s3.bucket)
145
+ def push
146
+ object.content = file
147
+ object.save
114
148
  end
115
149
 
116
- private
117
- def url_for(path)
118
- "https://s3.amazonaws.com/#{config.s3.bucket}/#{path}"
150
+ def file
151
+ File.new(app.archive)
119
152
  end
120
153
  end
121
154
 
@@ -127,24 +160,21 @@ module Glitter
127
160
  puts "Writing new Glitterfile to #{File.expand_path glitterfile_path}"
128
161
 
129
162
  File.open glitterfile_path, 'w+' do |file|
130
- file.write File.read(Configuration::TemplatePath)
131
- end
163
+ file.write File.read(App::TemplatePath)
164
+ end
132
165
  end
133
166
 
134
- desc "push", "pushes a build to S3"
135
- def push
136
- puts "Pushing #{release.object_name} to bucket #{config.s3.bucket}..."
137
- release.push
138
- puts "Pushed to #{release.url}!"
167
+ desc "push RELEASE_NOTES", "pushes a build to S3 with release notes."
168
+ def push(release_notes)
169
+ puts "Pushing #{app.head.object_name} to bucket #{app.s3.bucket_name}..."
170
+ app.head.push
171
+ app.appcast.push
172
+ puts "App pushed to #{app.head.url}"
139
173
  end
140
174
 
141
175
  private
142
- def config
143
- @config ||= Configuration.configure('./Glitterfile')
144
- end
145
-
146
- def release
147
- @release ||= Release.new(config)
176
+ def app
177
+ @config ||= App.configure('./Glitterfile')
148
178
  end
149
179
  end
150
180
  end
@@ -2,10 +2,9 @@
2
2
  name "My App"
3
3
  version "1.0.0"
4
4
  archive "my_app.zip"
5
- release_notes "http://myapp.com/release_notes/"
6
5
 
7
6
  s3 {
8
- bucket "my_app"
7
+ bucket_name "my_app"
9
8
  access_key "access"
10
9
  secret_access_key "sekret"
11
10
  }
@@ -0,0 +1,21 @@
1
+ <rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
2
+ <channel>
3
+ <title><%= app.name %></title>
4
+ <link><%= app.appcast.url %></link>
5
+ <description>Software updates for <%= app.name %></description>
6
+ <language>en</language>
7
+ <% app.releases.each do |version, release| %>
8
+ <item>
9
+ <title>Version <%= version %></title>
10
+ <description>
11
+ <![CDATA[
12
+ <h2>New Features</h2>
13
+ <p><%= release.notes %></p>
14
+ ]]>
15
+ </description>
16
+ <pubDate><%= release.published_at.strftime("%a, %d %b %Y %H:%M:%S %z") %></pubDate>
17
+ <enclosure url="<%= release.url %>" sparkle:version="2.0" length="<%= release.file.stat.size %>" type="application/octet-stream" />
18
+ </item>
19
+ <% end %>
20
+ </channel>
21
+ </rss>
@@ -1,3 +1,3 @@
1
1
  module Glitter
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,36 +1,33 @@
1
1
  require 'spec_helper'
2
2
  require 'rexml/document'
3
3
 
4
- describe Glitter::Release do
4
+ describe Glitter::App do
5
5
  before(:all) do
6
- @release = Glitter::Release.new Glitter::Configuration.configure {
6
+ @app = Glitter::App.configure do
7
7
  name "My App"
8
8
  version "1.0.0"
9
9
  archive "lib/glitter.rb"
10
- release_notes "http://myapp.com/release_notes/"
11
-
10
+
12
11
  s3 {
13
- bucket "my_app"
12
+ bucket_name "my_app"
14
13
  access_key "access"
15
14
  secret_access_key "sekret"
16
15
  }
17
- }
18
- end
16
+ end
19
17
 
20
- it "should have name" do
21
- @release.name.should eql("My App 1.0.0")
18
+ # Leave this in this order to test sorting.
19
+ @app.releases["3.0"].notes = "I'm the newest and greatest of them all. 3.0 I am!"
20
+ @app.releases["1.0"].notes = "Hi dude, 1.0"
21
+ @app.releases["2.0"].notes = "I'm way better than 2.0"
22
22
  end
23
23
 
24
- it "should generate rss entry" do
25
- REXML::Document.new(@release.to_rss).root.attributes["sparkle"].should eql('http://www.andymatuschak.org/xml-namespaces/sparkle')
24
+ it "should have head" do
25
+ @app.head.version.should eql("1.0.0")
26
26
  end
27
27
 
28
- it "should have object_name" do
29
- @release.object_name.should eql("my-app-1.0.0.rb")
28
+ it "should generate rss" do
29
+ REXML::Document.new(@app.appcast.rss).root.attributes["sparkle"].should eql('http://www.andymatuschak.org/xml-namespaces/sparkle')
30
30
  end
31
- end
32
-
33
- describe Glitter::Configuration do
34
31
 
35
32
  shared_examples_for "configuration" do
36
33
  it "should read name" do
@@ -45,13 +42,9 @@ describe Glitter::Configuration do
45
42
  @config.archive.should eql("my_app.zip")
46
43
  end
47
44
 
48
- it "should read release notes" do
49
- @config.release_notes.should eql("http://myapp.com/release_notes/")
50
- end
51
-
52
45
  context "s3" do
53
- it "should read bucket" do
54
- @config.s3.bucket.should eql("my_app")
46
+ it "should read bucket_name" do
47
+ @config.s3.bucket_name.should eql("my_app")
55
48
  end
56
49
 
57
50
  it "should read access_key" do
@@ -64,20 +57,19 @@ describe Glitter::Configuration do
64
57
  end
65
58
 
66
59
  it "should have a valid Glitterfile template path" do
67
- File.exists?(Glitter::Configuration::TemplatePath).should be_true
60
+ File.exists?(Glitter::App::TemplatePath).should be_true
68
61
  end
69
62
  end
70
-
63
+
71
64
  context "block configuration" do
72
65
  before(:all) do
73
- @config = Glitter::Configuration.configure do
66
+ @config = Glitter::App.configure do
74
67
  name "My App"
75
68
  version "1.0.0"
76
69
  archive "my_app.zip"
77
- release_notes "http://myapp.com/release_notes/"
78
70
 
79
71
  s3 {
80
- bucket "my_app"
72
+ bucket_name "my_app"
81
73
  access_key "access"
82
74
  secret_access_key "sekret"
83
75
  }
@@ -89,7 +81,7 @@ describe Glitter::Configuration do
89
81
 
90
82
  context "file configuration" do
91
83
  before(:all) do
92
- @config = Glitter::Configuration.configure File.expand_path('../../../lib/glitter/templates/Glitterfile', __FILE__)
84
+ @config = Glitter::App.configure File.expand_path('../../../lib/glitter/templates/Glitterfile', __FILE__)
93
85
  end
94
86
 
95
87
  it_should_behave_like "configuration"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glitter
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Brad Gessler
@@ -15,11 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-06-06 00:00:00 -07:00
18
+ date: 2011-06-07 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: aws-s3
22
+ name: s3
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
@@ -79,7 +79,7 @@ files:
79
79
  - glitter.gemspec
80
80
  - lib/glitter.rb
81
81
  - lib/glitter/templates/Glitterfile
82
- - lib/glitter/templates/rss.xml
82
+ - lib/glitter/templates/rss.xml.erb
83
83
  - lib/glitter/version.rb
84
84
  - spec/lib/glitter_spec.rb
85
85
  - spec/spec_helper.rb
@@ -1,14 +0,0 @@
1
- <rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
2
- <channel>
3
- <title><%= config.name %></title>
4
- <link><%= appcast_url %></link>
5
- <description>Software updates for <%= config.name %></description>
6
- <language>en</language>
7
- <item>
8
- <title><%= name %></title>
9
- <sparkle:releaseNotesLink><%= config.release_notes %></sparkle:releaseNotesLink>
10
- <pubDate><%= pub_date %></pubDate>
11
- <enclosure url="<%= url %>" sparkle:version="2.0" length="<%= file.stat.size %>" type="application/octet-stream" />
12
- </item>
13
- </channel>
14
- </rss>