Module: ChocTop::Appcast

Defined in:
lib/choctop/appcast.rb

Instance Method Summary collapse

Instance Method Details

#dsa_signatureObject



125
126
127
# File 'lib/choctop/appcast.rb', line 125

def dsa_signature
  @dsa_signature ||= `openssl dgst -sha1 -binary < "#{pkg}" | openssl dgst -dss1 -sign "#{private_key}" | openssl enc -base64`
end

#make_appcastObject



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/choctop/appcast.rb', line 14

def make_appcast
  app_name = File.basename(File.expand_path('.'))
  FileUtils.mkdir_p(build_path)
  appcast = File.open("#{build_path}/#{appcast_filename}", 'w') do |f|
    xml = Builder::XmlMarkup.new(:indent => 2)
    xml.instruct!
    xml_string = xml.rss('xmlns:atom' => "http://www.w3.org/2005/Atom",
            'xmlns:sparkle' => "http://www.andymatuschak.org/xml-namespaces/sparkle", 
            :version => "2.0") do
      xml.channel do
        xml.title(app_name)
        xml.description("#{app_name} updates")
        xml.link(base_url)
        xml.language('en')
        xml.pubDate( Time.now.strftime("%a, %d %b %Y %H:%M:%S %z") )
        # xml.lastBuildDate(Time.now.rfc822)
        xml.atom(:link, :href => "#{base_url}/#{appcast_filename}", 
                 :rel => "self", :type => "application/rss+xml")

        xml.item do
          xml.title("#{name} #{version}")
          xml.tag! "sparkle:releaseNotesLink", "#{base_url}/#{release_notes}"
          xml.pubDate Time.now.strftime("%a, %d %b %Y %H:%M:%S %z")
          xml.guid("#{name}-#{version}", :isPermaLink => "false")
          xml.enclosure(:url => "#{base_url}/#{pkg_name}", 
                        :length => "#{File.size(pkg)}", 
                        :type => "application/dmg",
                        :"sparkle:version" => version,
                        :"sparkle:dsaSignature" => dsa_signature)
        end
      end
    end
    f << xml_string
  end
end

#make_buildObject



2
3
4
5
6
7
8
9
10
11
12
# File 'lib/choctop/appcast.rb', line 2

def make_build
  if skip_build
    puts "Skipping build task..."
  else
    sh "xcodebuild -configuration #{build_type} #{build_opts}"
  end
  # if codesign_identity
  #   sh "codesign -v -s 'Zetetic LLC' '#{build_products}/#{target}'"
  #   sh "codesign -dv '#{build_products}/#{target}'"
  # end
end


50
51
52
53
54
55
# File 'lib/choctop/appcast.rb', line 50

def make_dmg_symlink
  FileUtils.chdir(build_path) do
    `rm '#{versionless_pkg_name}'`
    `ln -s '#{pkg_name}' '#{versionless_pkg_name}'`
  end
end

#make_index_redirectObject



57
58
59
60
61
# File 'lib/choctop/appcast.rb', line 57

def make_index_redirect
  File.open("#{build_path}/index.php", 'w') do |f|
    f << %Q{<?php header("Location: #{pkg_relative_url}"); ?>}
  end
end

#make_release_notesObject



70
71
72
73
74
75
# File 'lib/choctop/appcast.rb', line 70

def make_release_notes
  File.open("#{build_path}/#{release_notes}", "w") do |f|
    template = File.read(release_notes_template)
    f << ERB.new(template).result(binding)
  end
end

#private_keyObject

Returns a file path to the dsa_priv.pem file If private key + public key haven’t been generated yet then generate them



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/choctop/appcast.rb', line 108

def private_key
  unless File.exists?('dsa_priv.pem')
    puts "Creating new private and public keys for signing the DMG..."
    `openssl dsaparam 2048 < /dev/urandom > dsaparam.pem`
    `openssl gendsa dsaparam.pem -out dsa_priv.pem`
    `openssl dsa -in dsa_priv.pem -pubout -out dsa_pub.pem`
    `rm dsaparam.pem`
    puts <<-EOS.gsub(/^      /, '')
    
    WARNING: DO NOT PUT dsa_priv.pem IN YOUR SOURCE CONTROL
             Remember to add it to your ignore list
    
    EOS
  end
  File.expand_path('dsa_priv.pem')
end

#release_notes_contentObject



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/choctop/appcast.rb', line 77

def release_notes_content
  if File.exists?("release_notes.txt")
    File.read("release_notes.txt")
  else
    <<-TEXTILE.gsub(/^      /, '')
    h1. #{version} #{Date.today}
    
    h2. Another awesome release!
    TEXTILE
  end
end

#release_notes_htmlObject



89
90
91
# File 'lib/choctop/appcast.rb', line 89

def release_notes_html
  RedCloth.new(release_notes_content).to_html
end

#skip_buildObject



63
64
65
66
67
68
# File 'lib/choctop/appcast.rb', line 63

def skip_build
  return true if ENV['NO_BUILD']
  return false if File.exists?('Info.plist')
  return false if Dir['*.xcodeproj'].size > 0
  true
end

#upload_appcastObject



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/choctop/appcast.rb', line 93

def upload_appcast
  _host = host.nil? ? "" : host
  _user = user.nil? ? "" : "#{user}@"
  case transport
  when :scp
    # this is whack, really, work out your rsync options
    sh %{scp #{scp_args} #{build_path}/* #{_user}#{_host}:#{remote_dir}}
  else # default to rsync as per original
    sh %{rsync #{rsync_args} #{build_path}/ #{_user}#{_host}:#{remote_dir}}
  end
end