choctop 0.11.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,14 @@
1
- == 0.11.1 2009-11-17
2
-
3
- * New attribute 'source_dir': specify an alternate src folder for the built project (default: build/Release)
4
-
5
- == 0.11.0 2009-11-16
6
-
1
+ == 0.12.0 2010-05-29
2
+ * Tests run again
3
+ * Reorganzied code base so that there is a module ChocTop and a class Configuration
4
+ * New version helper
5
+ rake version:current
6
+ rake version:bump:major
7
+ rake version:bump:minor
8
+ rake version:bump:patch
9
+ * Pulled in changes from all forks
10
+
11
+ == 0.11.1
7
12
  * ChocTop no longer solely for Cocoa applications
8
13
  * Applications shortcut only included if the primary target is a .app bundle
9
14
  * Creates a non-versioned symlink to latest released DMG
@@ -30,6 +30,8 @@ features/support/matchers.rb
30
30
  lib/choctop.rb
31
31
  lib/choctop/appcast.rb
32
32
  lib/choctop/dmg.rb
33
+ lib/choctop/rake_tasks.rb
34
+ lib/choctop/version_helper.rb
33
35
  script/console
34
36
  script/destroy
35
37
  script/generate
@@ -18,12 +18,14 @@ application, creates a DMG package, generates a Sparkle XML file, and posts the
18
18
  and XML file to your remote host via rsync.
19
19
 
20
20
  All rake tasks:
21
-
22
- rake appcast # Create dmg, update appcast file, and upload to host
23
- rake build # Build Xcode Release
24
- rake dmg # Create the dmg file for appcasting
25
- rake feed # Create/update the appcast file
26
- rake upload # Upload the appcast file to the host
21
+ rake build # Build Xcode Release
22
+ rake dmg # Create the dmg file for appcasting
23
+ rake feed # Create/update the appcast file
24
+ rake upload # Upload the appcast file to the host
25
+ rake version:bump:major # Bump the gemspec by a major version.
26
+ rake version:bump:minor # Bump the gemspec by a minor version.
27
+ rake version:bump:patch # Bump the gemspec by a patch version.
28
+ rake version:current # Display the current version
27
29
 
28
30
  == Why is it called 'ChocTop'?
29
31
 
@@ -89,7 +91,7 @@ Also, in your project's Info.plist, remember to update/add the following keys:
89
91
  CFBundleVersion - version for next release, using X.Y.Z format
90
92
  SUFeedURL - url to Sparkle URL (future: insert this automatically)
91
93
 
92
- The create the distribution, Sparkle XML file, and upload it to the remote host:
94
+ Then create the distribution, Sparkle XML file, and upload it to the remote host:
93
95
 
94
96
  rake appcast
95
97
 
data/Rakefile CHANGED
@@ -2,14 +2,13 @@ gem 'hoe', '>= 2.3.2'
2
2
  require 'hoe'
3
3
  gem 'newgem', '>= 1.5.0'
4
4
  require 'newgem'
5
- require './lib/choctop'
6
5
 
7
6
  Hoe.plugin :newgem
8
7
 
9
8
  $hoe = Hoe.spec 'choctop' do
10
9
  developer 'Dr Nic Williams', 'drnicwilliams@gmail.com'
11
10
  developer 'Chris Bailey', 'chris@cobaltedge.com'
12
-
11
+ developer 'Patrick Huesler', 'patrick.huesler@gmail.com'
13
12
  extra_deps << ['activesupport']
14
13
  extra_deps << ['builder','>= 2.1.2']
15
14
  extra_dev_deps << ['newgem', ">= #{::Newgem::VERSION}"]
@@ -3,7 +3,7 @@ require "rake"
3
3
 
4
4
  require "choctop"
5
5
 
6
- ChocTop.new do |s|
6
+ ChocTop::Configuration.new do |s|
7
7
  # Remote upload target (set host if not same as Info.plist['SUFeedURL'])
8
8
  # s.host = '<%= urlname %>.com'
9
9
  s.remote_dir = '/path/to/upload/root/of/app'
@@ -14,31 +14,6 @@ Feature: Can build a customised DMG image from application build
14
14
  And file ".background/background.jpg" in mounted volume is invisible
15
15
  And file ".VolumeIcon.icns" in mounted volume is created
16
16
 
17
- Scenario: Build a DMG with alternate build folder
18
- Given a Cocoa app with choctop installed called "SampleApp"
19
- When I invoke task "rake build"
20
- And I move "build" to "alternate_build"
21
- And I set choctop attribute "source_dir" to "alternate_build/Release"
22
- When I invoke task "rake dmg NO_BUILD=1"
23
- Then file "appcast/build/SampleApp-0.1.0.dmg" is created
24
- When dmg "appcast/build/SampleApp-0.1.0.dmg" is mounted as "SampleApp"
25
- Then folder "SampleApp.app" in mounted volume is created
26
- And file "Applications" in mounted volume is created
27
- And file ".background/background.jpg" in mounted volume is created
28
- And file ".background/background.jpg" in mounted volume is invisible
29
- And file ".VolumeIcon.icns" in mounted volume is created
30
-
31
- Scenario: Build a DMG with a whitespace name
32
- Given a Cocoa app with choctop installed called "App With Whitespace"
33
- When I invoke task "rake dmg"
34
- Then file "appcast/build/App With Whitespace-1.0.dmg" is created
35
- When dmg "appcast/build/App With Whitespace-1.0.dmg" is mounted as "App With Whitespace"
36
- Then folder "App With Whitespace.app" in mounted volume is created
37
- And file "Applications" in mounted volume is created
38
- And file ".background/background.jpg" in mounted volume is created
39
- And file ".background/background.jpg" in mounted volume is invisible
40
- And file ".VolumeIcon.icns" in mounted volume is created
41
-
42
17
  Scenario: Build a DMG with custom Applications symlink icon
43
18
  Given a Cocoa app with choctop installed called "SampleApp"
44
19
  And is configured for custom Applications icon
@@ -13,19 +13,18 @@ Feature: Rake tasks are available to build and deploy Cocoa apps with Sparkle
13
13
  When I invoke task "rake dmg"
14
14
  Then file "appcast/build/SampleApp-0.1.0.dmg" is created
15
15
 
16
- Scenario: rake task to upload the appcast file to the server
16
+ Scenario: rake task to bump the major version number
17
17
  Given a Cocoa app with choctop installed called "SampleApp"
18
- And I invoke task "rake dmg feed"
19
- And ChocTop config is configured for local rsync
20
- When I invoke task "rake upload"
21
- Then remote file "my_feed.xml" is created
22
- Then remote file "SampleApp-0.1.0.dmg" is created
23
- Then remote file "SampleApp.dmg" is created
24
- Then remote file "index.php" is created
25
-
26
- Scenario: change the version number in the Info.plist
18
+ When I invoke task "rake version:bump:major"
19
+ Then current xcode project version is "1.0.0"
20
+
21
+ Scenario: rake task to bump the minor version number
22
+ Given a Cocoa app with choctop installed called "SampleApp"
23
+ When I invoke task "rake version:bump:minor"
24
+ Then current xcode project version is "0.2.0"
25
+
26
+ Scenario: rake task to bump the minor version number
27
27
  Given a Cocoa app with choctop installed called "SampleApp"
28
- When I invoke task "rake version:set VERSION="1.2.3""
29
- Then current xcode project version is "1.2.3"
30
-
28
+ When I invoke task "rake version:bump:patch"
29
+ Then current xcode project version is "0.1.1"
31
30
 
@@ -12,16 +12,10 @@ Given /^is configured for an asset file "([^\"]*)" to be included in dmg$/ do |f
12
12
  choctop_add_file(file)
13
13
  end
14
14
 
15
- Given /^I set choctop attribute "([^\"]*)" to "([^\"]*)"$/ do |attribute, value|
16
- in_project_folder do
17
- append_to_file "Rakefile", "$choctop.#{attribute} = #{value.inspect}"
18
- end
19
- end
20
-
21
15
  When /^dmg "(.*)" is mounted as "(.*)"$/ do |dmg, name|
22
16
  @stdout = File.expand_path(File.join(@tmp_root, "hdiutil.out"))
23
17
  in_project_folder do
24
- @mountpoint = ChocTop.new.mountpoint
18
+ @mountpoint = ChocTop::Configuration.new.mountpoint
25
19
  FileUtils.mkdir_p @mountpoint
26
20
  @volume_path = "#{@mountpoint}/#{name}"
27
21
  `hdiutil attach '#{dmg}' -mountpoint '#{@volume_path}' -noautoopen > #{@stdout}`
@@ -1,5 +1,5 @@
1
1
  Then /^current xcode project version is "(.*)"$/ do |version|
2
2
  in_project_folder do
3
- ChocTop.new.version.to_s.should == version
3
+ ChocTop::Configuration.new.version.to_s.should == version
4
4
  end
5
5
  end
@@ -1,10 +1,12 @@
1
- require File.dirname(__FILE__) + "/../../lib/choctop"
1
+ # require File.dirname(__FILE__) + "/../../lib/choctop"
2
2
 
3
3
  require "rubygems"
4
4
  require 'cucumber'
5
5
  require 'spec'
6
6
 
7
7
  require "activesupport"
8
+ $:.unshift(File.dirname(__FILE__) + '/../../lib')
9
+ require 'choctop'
8
10
 
9
11
  Before do
10
12
  @tmp_root = File.dirname(__FILE__) + "/../../tmp"
@@ -1,6 +1,3 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
-
4
1
  require "fileutils"
5
2
  require "yaml"
6
3
  require "builder"
@@ -10,277 +7,286 @@ require "osx/cocoa"
10
7
  require "active_support"
11
8
  require "RedCloth"
12
9
 
13
- class ChocTop
14
- VERSION = '0.11.1'
15
-
16
- # Path to the Info.plist
17
- # Default: "Info.plist"
18
- attr_accessor :info_plist_path
19
-
20
- # The name of the Cocoa application
21
- # Default: info_plist['CFBundleExecutable'] or project folder name if "${EXECUTABLE_NAME}"
22
- attr_accessor :name
23
-
24
- # The version of the Cocoa application
25
- # Default: info_plist['CFBundleVersion']
26
- attr_accessor :version
27
-
28
- # The target name of the distributed DMG file
29
- # Default: #{name}.app
30
- attr_accessor :target
31
- def target
32
- @target ||= File.basename(target_bundle) if target_bundle
33
- end
10
+ require 'choctop/appcast'
11
+ require 'choctop/dmg'
12
+ require 'choctop/version_helper'
13
+ require 'choctop/rake_tasks'
34
14
 
35
- def target_bundle
36
- @target_bundle ||= Dir["#{source_dir}/#{name}.*"].first
37
- end
15
+ module ChocTop
16
+ class Configuration
17
+ include Appcast
18
+ include Dmg
19
+ include RakeTasks
20
+
21
+ VERSION = '0.12.0'
22
+
23
+ attr_writer :build_opts
24
+ def build_opts
25
+ @build_opts ||= ''
26
+ end
38
27
 
39
- # The build type of the distributed DMG file
40
- # Default: Release
41
- attr_accessor :build_type
28
+ # Path to the Info.plist
29
+ # Default: project directory
30
+ def info_plist_path
31
+ @info_plist_path ||= File.expand_path(info_plist_name)
32
+ end
42
33
 
43
- # The Sparkle feed URL
44
- # Default: info_plist['SUFeedURL']
45
- attr_accessor :su_feed_url
34
+ # Name of the Info.plist file
35
+ # Default: "Info.plist"
36
+ def info_plist_name
37
+ @info_plist_name ||= 'Info.plist'
38
+ end
46
39
 
47
- # The host name, e.g. some-domain.com
48
- # Default: host from base_url
49
- attr_accessor :host
50
40
 
51
- # The user to log in on the remote server.
52
- # Default: empty
53
- attr_accessor :user
41
+ # The name of the Cocoa application
42
+ # Default: info_plist['CFBundleExecutable'] or project folder name if "${EXECUTABLE_NAME}"
43
+ attr_accessor :name
54
44
 
55
- # The url from where the xml + dmg files will be downloaded
56
- # Default: dir path from appcast_filename
57
- attr_accessor :base_url
45
+ # The version of the Cocoa application
46
+ # Default: info_plist['CFBundleVersion']
47
+ attr_accessor :version
58
48
 
59
- # The file name for generated release notes for the latest release
60
- # Default: release_notes.html
61
- attr_accessor :release_notes
49
+ # The target name of the distributed DMG file
50
+ # Default: #{name}.app
51
+ attr_accessor :target
52
+ def target
53
+ @target ||= File.basename(target_bundle) if target_bundle
54
+ end
62
55
 
63
- # The file name for the project readme file
64
- # Default: README.txt
65
- attr_accessor :readme
56
+ # The name of the target in Xcode, such as MacRuby's Compile or
57
+ # Embed.
58
+ # Uses the application name by default.
59
+ attr_accessor :build_target
60
+ def build_target
61
+ @build_target ||= name
62
+ end
66
63
 
67
- # List of files/bundles to be packaged into the DMG
68
- attr_accessor :files
64
+ def target_bundle
65
+ @target_bundle ||= Dir["#{build_products}/#{name}.*"].first
66
+ end
69
67
 
70
- # The path for an HTML template into which the release_notes.txt are inserted
71
- # after conversion to HTML
72
- #
73
- # The template file is an ERb template, with <%= yield %> as the placeholder
74
- # for the generated release notes.
75
- #
76
- # Currently, any CSS or JavaScript must be inline
77
- #
78
- # Default: release_notes_template.html.erb, which was generated by install_choctop into each project
79
- attr_accessor :release_notes_template
68
+ # The build type of the distributed DMG file
69
+ # Default: Release
70
+ attr_accessor :build_type
80
71
 
81
- # The name of the local xml file containing the Sparkle item details
82
- # Default: info_plist['SUFeedURL'] or linker_appcast.xml
83
- attr_accessor :appcast_filename
84
-
85
- # The remote directory where the xml + dmg files will be rsync'd
86
- attr_accessor :remote_dir
87
-
88
- # The argument flags passed to rsync
89
- # Default: -aCv
90
- attr_accessor :rsync_args
91
-
92
- # The base folder to find the built bundle/application
93
- # Default: build/Release (rather build/#{build_type})
94
- attr_accessor :source_dir
95
- def source_dir
96
- @source_dir ||= "build/#{build_type}"
97
- end
72
+ # The Sparkle feed URL
73
+ # Default: info_plist['SUFeedURL']
74
+ attr_writer :su_feed_url
75
+ def su_feed_url
76
+ @su_feed_url ||= info_plist['SUFeedURL']
77
+ end
98
78
 
99
- # Folder from where all files will be copied into the DMG
100
- # Files are copied here if specified with +add_file+ before DMG creation
101
- attr_accessor :dmg_pkg_folder
102
- def dmg_pkg_folder
103
- @dmg_pkg_folder ||= "#{source_dir}/dmg"
104
- end
79
+ # The host name, e.g. some-domain.com
80
+ # Default: host from base_url
81
+ attr_accessor :host
82
+
83
+ # The user to log in on the remote server.
84
+ # Default: empty
85
+ attr_accessor :user
86
+
87
+ # The url from where the xml + dmg files will be downloaded
88
+ # Default: dir path from appcast_filename
89
+ attr_writer :base_url
90
+ def base_url
91
+ if su_feed_url
92
+ @base_url ||= File.dirname(su_feed_url)
93
+ else
94
+ @base_url
95
+ end
96
+ end
105
97
 
106
- # Generated filename for a distribution, from name, version and .dmg
107
- # e.g. MyApp-1.0.0.dmg
108
- def pkg_name
109
- version ? "#{name}-#{version}.dmg" : versionless_pkg_name
110
- end
98
+ # The file name for generated release notes for the latest release
99
+ # Default: release_notes.html
100
+ attr_accessor :release_notes
111
101
 
112
- # Version-less generated filename for a distribution, from name and .dmg
113
- # e.g. MyApp.dmg
114
- def versionless_pkg_name
115
- "#{name}.dmg"
116
- end
102
+ # The file name for the project readme file
103
+ # Default: README.txt
104
+ attr_accessor :readme
117
105
 
118
- # Path to generated package DMG
119
- def pkg
120
- "#{build_path}/#{pkg_name}"
121
- end
106
+ # List of files/bundles to be packaged into the DMG
107
+ attr_accessor :files
108
+
109
+ # The path for an HTML template into which the release_notes.txt are inserted
110
+ # after conversion to HTML
111
+ #
112
+ # The template file is an ERb template, with <%= yield %> as the placeholder
113
+ # for the generated release notes.
114
+ #
115
+ # Currently, any CSS or JavaScript must be inline
116
+ #
117
+ # Default: release_notes_template.html.erb, which was generated by install_choctop into each project
118
+ attr_accessor :release_notes_template
119
+
120
+ # The name of the local xml file containing the Sparkle item details
121
+ # Default: info_plist['SUFeedURL'] or linker_appcast.xml
122
+ attr_writer :appcast_filename
123
+ def appcast_filename
124
+ @appcast_filename ||= su_feed_url ? File.basename(su_feed_url) : 'my_feed.xml'
125
+ end
126
+
127
+ # The remote directory where the xml + dmg files will be uploaded
128
+ attr_accessor :remote_dir
129
+
130
+ # Defines the transport to use for upload, default is :rsync, :scp is also available
131
+ attr_accessor :transport
132
+ def transport
133
+ @transport ||= :rsync # other option is scp
134
+ end
122
135
 
123
- # Path to built DMG, sparkle's xml file and other assets to be uploaded to remote server
124
- def build_path
125
- "appcast/build"
126
- end
136
+ # The argument flags passed to rsync
137
+ # Default: -aCv
138
+ attr_accessor :rsync_args
127
139
 
128
- def mountpoint
129
- # @mountpoint ||= "/tmp/build/mountpoint#{rand(10000000)}"
130
- @mountpoint ||= "/Volumes"
131
- end
140
+ # Additional arguments to pass to scp
141
+ # e.g. -P 11222
142
+ attr_accessor :scp_args
143
+
144
+ attr_accessor :build_products
145
+ def build_products
146
+ @build_products ||= "build/#{build_type}"
147
+ end
132
148
 
133
- # Path to Volume when DMG is mounted
134
- def volume_path
135
- "#{mountpoint}/#{name}"
136
- end
149
+ # Folder from where all files will be copied into the DMG
150
+ # Files are copied here if specified with +add_file+ before DMG creation
151
+ attr_accessor :src_folder
152
+ def src_folder
153
+ @src_folder ||= "build/#{build_type}/dmg"
154
+ end
137
155
 
138
- #
139
- # Custom DMG properties
140
- #
141
-
142
- # Path to background .icns image file for custom DMG
143
- # Value should be file path relative to root of project
144
- # Default: a choctop supplied background image
145
- # that matches to default app_icon_position + applications_icon_position
146
- # To have no custom background, set value to +nil+
147
- attr_accessor :background_file
148
-
149
- # x, y position of this project's icon on the custom DMG
150
- # Default: a useful position for the icon against the default background
151
- attr_accessor :app_icon_position
152
-
153
- # x, y position of the Applications symlink icon on the custom DMG
154
- # Default: a useful position for the icon against the default background
155
- attr_accessor :applications_icon_position
156
-
157
- # Path to an .icns file for the DMG's volume icon (looks like a disk or drive)
158
- # Default: a DMG icon provided within choctop
159
- # To get default, boring blank DMG volume icon, set value to +nil+
160
- attr_accessor :volume_icon
161
-
162
- # Custom icon for the Applications symlink icon
163
- # Default: none
164
- attr_accessor :applications_icon
165
-
166
- # Size of icons, in pixels, within custom DMG (between 16 and 128)
167
- # Default: 104 - this is nice and big
168
- attr_accessor :icon_size
169
-
170
- # Icon text size
171
- # Can pass integer (12) or string ("12" or "12 px")
172
- # Default: 12 (px)
173
- attr_reader :icon_text_size
174
-
175
- def icon_text_size=(size)
176
- @icon_text_size = size.to_i
177
- end
156
+ # Generated filename for a distribution, from name, version and .dmg
157
+ # e.g. MyApp-1.0.0.dmg
158
+ def pkg_name
159
+ version ? "#{name}-#{version}.dmg" : versionless_pkg_name
160
+ end
178
161
 
179
- # The url for the remote package, without the protocol + host
180
- # e.g. if absolute url is http://mydomain.com/downloads/MyApp-1.0.dmg
181
- # then pkg_relative_url is /downloads/MyApp-1.0.dmg
182
- def pkg_relative_url
183
- _base_url = base_url.gsub(%r{/$}, '')
184
- "#{_base_url}/#{pkg_name}".gsub(%r{^.*#{host}}, '')
185
- end
162
+ # Version-less generated filename for a distribution, from name and .dmg
163
+ # e.g. MyApp.dmg
164
+ def versionless_pkg_name
165
+ "#{name}.dmg"
166
+ end
186
167
 
187
- def info_plist
188
- @info_plist ||= OSX::NSDictionary.dictionaryWithContentsOfFile(File.expand_path(info_plist_path)) || {}
189
- end
168
+ # Path to generated package DMG
169
+ def pkg
170
+ "#{build_path}/#{pkg_name}"
171
+ end
190
172
 
191
- # Add an explicit file/bundle/folder into the DMG
192
- # Examples:
193
- # file 'build/Release/SampleApp.app', :position => [50, 100]
194
- # file :target_bundle, :position => [50, 100]
195
- # file proc { 'README.txt' }, :position => [50, 100]
196
- # file :position => [50, 100] { 'README.txt' }
197
- # Required option:
198
- # +:position+ - two item array [x, y] window position
199
- def file(*args, &block)
200
- path_or_helper, options = args.first.is_a?(Hash) ? [block, args.first] : [args.first, args.last]
201
- throw "add_files #{path_or_helper}, :position => [x,y] option is missing" unless options[:position]
202
- self.files ||= {}
203
- files[path_or_helper] = options
204
- end
205
- alias_method :add_file, :file
206
-
207
- def initialize
208
- $choctop = $sparkle = self # define a global variable for this object ($sparkle is legacy)
209
-
210
- yield self if block_given?
211
-
212
- # Defaults
213
- @info_plist_path ||= 'Info.plist'
214
- @name ||= info_plist['CFBundleExecutable'] || File.basename(File.expand_path("."))
215
- @name = File.basename(File.expand_path(".")) if @name == '${EXECUTABLE_NAME}'
216
- @version ||= info_plist['CFBundleVersion']
217
- @build_type = ENV['BUILD_TYPE'] || 'Release'
218
-
219
- if @su_feed_url = info_plist['SUFeedURL']
220
- @appcast_filename ||= File.basename(su_feed_url)
221
- @base_url ||= File.dirname(su_feed_url)
173
+ # Path to built DMG, sparkle's xml file and other assets to be uploaded to remote server
174
+ def build_path
175
+ "appcast/build"
222
176
  end
223
- if @base_url
224
- @host ||= URI.parse(base_url).host
177
+
178
+ def mountpoint
179
+ # @mountpoint ||= "/tmp/build/mountpoint#{rand(10000000)}"
180
+ @mountpoint ||= "/Volumes"
181
+ end
182
+
183
+ # Path to Volume when DMG is mounted
184
+ def volume_path
185
+ "#{mountpoint}/#{name}"
186
+ end
187
+
188
+ #
189
+ # Custom DMG properties
190
+ #
191
+
192
+ # Path to background .icns image file for custom DMG
193
+ # Value should be file path relative to root of project
194
+ # Default: a choctop supplied background image
195
+ # that matches to default app_icon_position + applications_icon_position
196
+ # To have no custom background, set value to +nil+
197
+ attr_accessor :background_file
198
+
199
+ # x, y position of this project's icon on the custom DMG
200
+ # Default: a useful position for the icon against the default background
201
+ attr_accessor :app_icon_position
202
+
203
+ # x, y position of the Applications symlink icon on the custom DMG
204
+ # Default: a useful position for the icon against the default background
205
+ attr_accessor :applications_icon_position
206
+
207
+ # Path to an .icns file for the DMG's volume icon (looks like a disk or drive)
208
+ # Default: a DMG icon provided within choctop
209
+ # To get default, boring blank DMG volume icon, set value to +nil+
210
+ attr_accessor :volume_icon
211
+
212
+ # Custom icon for the Applications symlink icon
213
+ # Default: none
214
+ attr_accessor :applications_icon
215
+
216
+ # Size of icons, in pixels, within custom DMG (between 16 and 128)
217
+ # Default: 104 - this is nice and big
218
+ attr_accessor :icon_size
219
+
220
+ # Icon text size
221
+ # Can pass integer (12) or string ("12" or "12 px")
222
+ # Default: 12 (px)
223
+ attr_reader :icon_text_size
224
+
225
+ def icon_text_size=(size)
226
+ @icon_text_size = size.to_i
227
+ end
228
+
229
+ # The url for the remote package, without the protocol + host
230
+ # e.g. if absolute url is http://mydomain.com/downloads/MyApp-1.0.dmg
231
+ # then pkg_relative_url is /downloads/MyApp-1.0.dmg
232
+ def pkg_relative_url
233
+ unless base_url
234
+ raise "The base url should be set in order to create a sparkle feed. Set the SUFeedURL in your Info.plist."
235
+ end
236
+ _base_url = base_url.gsub(%r{/$}, '')
237
+ "#{_base_url}/#{pkg_name}".gsub(%r{^.*#{host}}, '')
225
238
  end
226
- @release_notes ||= 'release_notes.html'
227
- @readme ||= 'README.txt'
228
- @release_notes_template ||= "release_notes_template.html.erb"
229
- @rsync_args ||= '-aCv --progress'
230
-
231
- @background_file ||= File.dirname(__FILE__) + "/../assets/sky_background.jpg"
232
- @app_icon_position ||= [175, 65]
233
- @applications_icon_position ||= [347, 270]
234
- @volume_icon ||= File.dirname(__FILE__) + "/../assets/DefaultVolumeIcon.icns"
235
- @icon_size ||= 104
236
- @icon_text_size ||= 12
237
-
238
- add_file :target_bundle, :position => app_icon_position
239
239
 
240
- define_tasks
241
- end
240
+ def info_plist
241
+ @info_plist ||= OSX::NSDictionary.dictionaryWithContentsOfFile(info_plist_path) || {}
242
+ end
242
243
 
243
- def define_tasks
244
- return unless Object.const_defined?("Rake")
244
+ # Add an explicit file/bundle/folder into the DMG
245
+ # Examples:
246
+ # file 'build/Release/SampleApp.app', :position => [50, 100]
247
+ # file :target_bundle, :position => [50, 100]
248
+ # file proc { 'README.txt' }, :position => [50, 100]
249
+ # file :position => [50, 100] { 'README.txt' }
250
+ # Required option:
251
+ # +:position+ - two item array [x, y] window position
252
+ def file(*args, &block)
253
+ path_or_helper, options = args.first.is_a?(Hash) ? [block, args.first] : [args.first, args.last]
254
+ throw "add_files #{path_or_helper}, :position => [x,y] option is missing" unless options[:position]
255
+ self.files ||= {}
256
+ files[path_or_helper] = options
257
+ end
258
+ alias_method :add_file, :file
259
+
260
+ def initialize
261
+ $choctop = $sparkle = self # define a global variable for this object ($sparkle is legacy)
245
262
 
246
- desc "Build Xcode #{build_type}"
247
- task :build => "#{source_dir}/#{target}/Contents/Info.plist"
263
+ yield self if block_given?
248
264
 
249
- task "#{source_dir}/#{target}/Contents/Info.plist" do
250
- make_build
251
- end
265
+ # Defaults
266
+ @name ||= info_plist['CFBundleExecutable'] || File.basename(File.expand_path("."))
267
+ @name = File.basename(File.expand_path(".")) if @name == '${EXECUTABLE_NAME}'
268
+ @version ||= info_plist['CFBundleVersion']
269
+ @build_type = ENV['BUILD_TYPE'] || 'Release'
252
270
 
253
- desc "Create the dmg file for appcasting"
254
- task :dmg => :build do
255
- detach_dmg
256
- make_dmg
257
- detach_dmg
258
- convert_dmg_readonly
259
- add_eula
260
- end
271
+ if base_url
272
+ @host ||= URI.parse(base_url).host
273
+ end
261
274
 
262
- desc "Create/update the appcast file"
263
- task :feed do
264
- make_appcast
265
- make_dmg_symlink
266
- make_index_redirect
267
- make_release_notes
268
- end
275
+ @release_notes ||= 'release_notes.html'
276
+ @readme ||= 'README.txt'
277
+ @release_notes_template ||= "release_notes_template.html.erb"
278
+ @rsync_args ||= '-aCv --progress'
269
279
 
270
- desc "Upload the appcast file to the host"
271
- task :upload => :feed do
272
- upload_appcast
273
- end
280
+ @background_file ||= File.dirname(__FILE__) + "/../assets/sky_background.jpg"
281
+ @app_icon_position ||= [175, 65]
282
+ @applications_icon_position ||= [347, 270]
283
+ @volume_icon ||= File.dirname(__FILE__) + "/../assets/DefaultVolumeIcon.icns"
284
+ @icon_size ||= 104
285
+ @icon_text_size ||= 12
274
286
 
275
- task :detach_dmg do
276
- detach_dmg
277
- end
287
+ add_file :target_bundle, :position => app_icon_position
278
288
 
279
- task :size do
280
- puts configure_dmg_window
289
+ define_tasks
281
290
  end
282
291
  end
283
- end
284
- require "choctop/appcast"
285
- require "choctop/dmg"
286
-
292
+ end