Module: ChocTop::Appcast

Included in:
Configuration
Defined in:
lib/choctop/appcast.rb

Instance Method Summary collapse

Instance Method Details

#dsa_signatureObject



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

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

#make_appcastObject



11
12
13
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
# File 'lib/choctop/appcast.rb', line 11

def make_appcast
  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(@name)
        xml.description("#{@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



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

def make_build
  if skip_xcode_build
    puts "Skipping build task..."
  else
    sh "xcodebuild -configuration #{build_type} -target #{build_target} #{build_opts}"
  end
end


46
47
48
49
50
51
52
53
# File 'lib/choctop/appcast.rb', line 46

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

#make_index_redirectObject



55
56
57
58
59
# File 'lib/choctop/appcast.rb', line 55

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



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

def make_release_notes
  if File.exist?(release_notes_template)
    File.open("#{build_path}/#{release_notes}", "w") do |f|
      template = File.read(release_notes_template)
      f << ERB.new(template).result(binding)
    end
  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



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

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



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

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



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

def release_notes_html
  RedCloth.new(release_notes_content).to_html
end

#skip_xcode_buildObject



61
62
63
64
65
# File 'lib/choctop/appcast.rb', line 61

def skip_xcode_build
  return true if ENV['NO_BUILD']
  return false if Dir['*.xcodeproj'].size > 0
  true
end

#upload_appcastObject



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

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