Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updated a bunch of internals

  • Loading branch information...
commit 4f8c0c99421701018c18dec31a5b6ebfbb58a847 1 parent bebcf8c
Brad Gessler authored
View
1  .gitignore
@@ -1,3 +1,4 @@
+bin/Glitterfile
.DS_Store
*.gem
.bundle
View
6 README.md
@@ -17,14 +17,12 @@ It should also be noted that Glitter uses HTTPS S3 URLs to eliminate the need fo
3. Edit the Glitterfile
# After you configure this file, deploy your app with `glitter push`
-
name "My App"
- version "1.0.0"
+ version "1.0.0" # Don't forget, its ruby! This could read a version from a plist file
archive "my_app.zip"
- release_notes "http://myapp.com/release_notes/"
s3 {
- bucket "my_app"
+ bucket_name "my_app"
access_key "access"
secret_access_key "sekret"
}
View
2  glitter.gemspec
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
s.description = %q{Glitter makes it easy to publish software updates via the Sparkle framework by using S3 buckets.}
s.rubyforge_project = "glitter"
- s.add_dependency "aws-s3"
+ s.add_dependency "s3"
s.add_dependency "haml"
s.add_dependency "thor"
View
134 lib/glitter.rb
@@ -1,4 +1,4 @@
-require 'aws/s3'
+require 's3'
require 'thor'
require 'erb'
@@ -41,81 +41,114 @@ def configure(*args, &block)
end
end
- # The configuration class that a release uses to deploy
- class Configuration
+ # The App class that a release uses to deploy
+ class App
TemplatePath = File.expand_path('../glitter/templates/Glitterfile', __FILE__).to_s.freeze
+ RssTemplate = File.expand_path('../glitter/templates/rss.xml.erb', __FILE__).to_s.freeze
+ AppcastXml = 'appcast.xml'
include Configurable
- attr_configurable :name, :version, :archive, :release_notes, :s3
+ attr_configurable :name, :version, :archive, :s3
class S3
include Configurable
- attr_configurable :bucket, :access_key, :secret_access_key
+ attr_configurable :bucket_name, :access_key, :secret_access_key
- def credentials
- {:access_key_id => access_key, :secret_access_key => secret_access_key}
+ def url_for(path)
+ "https://s3.amazonaws.com/#{bucket_name}/#{path}"
+ end
+
+ def service
+ @service ||= ::S3::Service.new(:access_key_id => access_key, :secret_access_key => secret_access_key)
+ end
+
+ def bucket
+ service.buckets.find(bucket_name)
end
end
def s3(&block)
@s3 ||= S3.configure(&block)
end
- end
- class Release
- FeedTemplate = File.expand_path('../glitter/templates/rss.xml', __FILE__).to_s.freeze
+ class Appcast
+ ObjectName = 'appcast.xml'
+
+ attr_reader :app
- attr_accessor :config, :released_at
+ def initialize(app)
+ @app = app
+ end
- def push
- bucket.new_object(archive_name, file, bucket)
- end
+ def url
+ app.s3.url_for ObjectName
+ end
+
+ def push
+ object.content = rss
+ object.save
+ end
+
+ def rss
+ @rss ||= ERB.new(File.read(RssTemplate)).result(binding)
+ end
- def initialize(config)
- @config, @released_at = config, Time.now
- AWS::S3::Base.establish_connection! config.s3.credentials
+ private
+ def object
+ @object ||= app.s3.bucket.objects.build(ObjectName)
+ end
end
- def name
- "#{config.name} #{config.version}"
+ def appcast
+ @appcast ||= Appcast.new(self)
end
- def object_name
- "#{name.downcase.gsub(/\s/,'-')}#{File.extname(config.archive)}"
+ def head
+ releases[version]
end
- def pub_date
- released_at.strftime("%a, %d %b %Y %H:%M:%S %z")
+ def releases
+ @releases ||= Hash.new do |hash,key|
+ hash[key] = Release.new do |r|
+ r.version = key
+ r.app = self
+ end
+ end
end
+ end
- def appcast_url
- url_for 'appcast.xml'
+ class Release
+ attr_accessor :app, :version, :notes, :published_at
+ attr_reader :object
+
+ def initialize
+ @published_at = Time.now
+ yield self if block_given?
end
- def url
- url_for object_name
+ def name
+ "#{app.name} #{version}"
end
- def to_rss
- @rss ||= ERB.new(File.read(FeedTemplate)).result(binding)
+ def object_name
+ "#{name.gsub(/\s/,'-').downcase}#{File.extname(file.path)}"
end
- def file
- @file ||= File.open(config.archive, 'r')
+ def object
+ @object ||= app.s3.bucket.objects.build(object_name)
end
- def push
- AWS::S3::S3Object.store(object_name, File.open(config.archive), config.s3.bucket)
- AWS::S3::S3Object.store('appcast.xml', to_rss, config.s3.bucket)
+ def url
+ app.s3.url_for object_name
end
- def yank
- AWS::S3::S3Object.store(object_name, config.s3.bucket)
+ def push
+ object.content = file
+ object.save
end
- private
- def url_for(path)
- "https://s3.amazonaws.com/#{config.s3.bucket}/#{path}"
+ def file
+ File.new(app.archive)
end
end
@@ -127,24 +160,21 @@ def init(path)
puts "Writing new Glitterfile to #{File.expand_path glitterfile_path}"
File.open glitterfile_path, 'w+' do |file|
- file.write File.read(Configuration::TemplatePath)
- end
+ file.write File.read(App::TemplatePath)
+ end
end
- desc "push", "pushes a build to S3"
- def push
- puts "Pushing #{release.object_name} to bucket #{config.s3.bucket}..."
- release.push
- puts "Pushed to #{release.url}!"
+ desc "push RELEASE_NOTES", "pushes a build to S3 with release notes."
+ def push(release_notes)
+ puts "Pushing #{app.head.object_name} to bucket #{app.s3.bucket_name}..."
+ app.head.push
+ app.appcast.push
+ puts "App pushed to #{app.head.url}"
end
private
- def config
- @config ||= Configuration.configure('./Glitterfile')
- end
-
- def release
- @release ||= Release.new(config)
+ def app
+ @config ||= App.configure('./Glitterfile')
end
end
end
View
3  lib/glitter/templates/Glitterfile
@@ -2,10 +2,9 @@
name "My App"
version "1.0.0"
archive "my_app.zip"
-release_notes "http://myapp.com/release_notes/"
s3 {
- bucket "my_app"
+ bucket_name "my_app"
access_key "access"
secret_access_key "sekret"
}
View
14 lib/glitter/templates/rss.xml
@@ -1,14 +0,0 @@
-<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
-<channel>
-<title><%= config.name %></title>
-<link><%= appcast_url %></link>
-<description>Software updates for <%= config.name %></description>
-<language>en</language>
-<item>
- <title><%= name %></title>
- <sparkle:releaseNotesLink><%= config.release_notes %></sparkle:releaseNotesLink>
- <pubDate><%= pub_date %></pubDate>
- <enclosure url="<%= url %>" sparkle:version="2.0" length="<%= file.stat.size %>" type="application/octet-stream" />
-</item>
-</channel>
-</rss>
View
21 lib/glitter/templates/rss.xml.erb
@@ -0,0 +1,21 @@
+<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
+<channel>
+<title><%= app.name %></title>
+<link><%= app.appcast.url %></link>
+<description>Software updates for <%= app.name %></description>
+<language>en</language>
+<% app.releases.each do |version, release| %>
+<item>
+ <title>Version <%= version %></title>
+ <description>
+ <![CDATA[
+ <h2>New Features</h2>
+ <p><%= release.notes %></p>
+ ]]>
+ </description>
+ <pubDate><%= release.published_at.strftime("%a, %d %b %Y %H:%M:%S %z") %></pubDate>
+ <enclosure url="<%= release.url %>" sparkle:version="2.0" length="<%= release.file.stat.size %>" type="application/octet-stream" />
+</item>
+<% end %>
+</channel>
+</rss>
View
50 spec/lib/glitter_spec.rb
@@ -1,36 +1,33 @@
require 'spec_helper'
require 'rexml/document'
-describe Glitter::Release do
+describe Glitter::App do
before(:all) do
- @release = Glitter::Release.new Glitter::Configuration.configure {
+ @app = Glitter::App.configure do
name "My App"
version "1.0.0"
archive "lib/glitter.rb"
- release_notes "http://myapp.com/release_notes/"
-
+
s3 {
- bucket "my_app"
+ bucket_name "my_app"
access_key "access"
secret_access_key "sekret"
}
- }
- end
+ end
- it "should have name" do
- @release.name.should eql("My App 1.0.0")
+ # Leave this in this order to test sorting.
+ @app.releases["3.0"].notes = "I'm the newest and greatest of them all. 3.0 I am!"
+ @app.releases["1.0"].notes = "Hi dude, 1.0"
+ @app.releases["2.0"].notes = "I'm way better than 2.0"
end
- it "should generate rss entry" do
- REXML::Document.new(@release.to_rss).root.attributes["sparkle"].should eql('http://www.andymatuschak.org/xml-namespaces/sparkle')
+ it "should have head" do
+ @app.head.version.should eql("1.0.0")
end
- it "should have object_name" do
- @release.object_name.should eql("my-app-1.0.0.rb")
+ it "should generate rss" do
+ REXML::Document.new(@app.appcast.rss).root.attributes["sparkle"].should eql('http://www.andymatuschak.org/xml-namespaces/sparkle')
end
-end
-
-describe Glitter::Configuration do
shared_examples_for "configuration" do
it "should read name" do
@@ -44,14 +41,10 @@
it "should read archive" do
@config.archive.should eql("my_app.zip")
end
-
- it "should read release notes" do
- @config.release_notes.should eql("http://myapp.com/release_notes/")
- end
-
+
context "s3" do
- it "should read bucket" do
- @config.s3.bucket.should eql("my_app")
+ it "should read bucket_name" do
+ @config.s3.bucket_name.should eql("my_app")
end
it "should read access_key" do
@@ -64,20 +57,19 @@
end
it "should have a valid Glitterfile template path" do
- File.exists?(Glitter::Configuration::TemplatePath).should be_true
+ File.exists?(Glitter::App::TemplatePath).should be_true
end
end
-
+
context "block configuration" do
before(:all) do
- @config = Glitter::Configuration.configure do
+ @config = Glitter::App.configure do
name "My App"
version "1.0.0"
archive "my_app.zip"
- release_notes "http://myapp.com/release_notes/"
s3 {
- bucket "my_app"
+ bucket_name "my_app"
access_key "access"
secret_access_key "sekret"
}
@@ -89,7 +81,7 @@
context "file configuration" do
before(:all) do
- @config = Glitter::Configuration.configure File.expand_path('../../../lib/glitter/templates/Glitterfile', __FILE__)
+ @config = Glitter::App.configure File.expand_path('../../../lib/glitter/templates/Glitterfile', __FILE__)
end
it_should_behave_like "configuration"
Please sign in to comment.
Something went wrong with that request. Please try again.