@@ -15,29 +15,22 @@ def initialize(config)
15
15
# verify_installation
16
16
end
17
17
18
+ def after_initialize
19
+ self . feed_url = appcast . feed_url
20
+ end
21
+
18
22
def appcast
19
- @appcast ||= Appcast . new
23
+ @appcast ||= Appcast . new ( self )
20
24
end
21
25
22
26
def publish ( key , value )
27
+ return if appcast . process_option ( key , value )
28
+
23
29
case key
24
30
when :public_key
25
- self . public_EdDSA_key = value
26
- when :base_url
27
- appcast . base_url = value
28
- self . feed_url = appcast . feed_url
29
- when :feed_base_url
30
- appcast . feed_base_url = value
31
- self . feed_url = appcast . feed_url
32
- when :feed_filename
33
- appcast . feed_filename = value
34
- self . feed_url = appcast . feed_url
31
+ self . public_ed_dsa_key = value
35
32
when :version
36
- version value
37
- when :package_base_url , :package_filename , :notes_base_url , :notes_filename , :use_exported_private_key
38
- appcast . send "#{ key } =" , value
39
- when :archive_folder
40
- appcast . archive_folder = value
33
+ version ( value )
41
34
else
42
35
raise "Unknown Sparkle config option #{ key } "
43
36
end
@@ -61,15 +54,13 @@ def feed_url=(url)
61
54
@config . info_plist [ 'SUFeedURL' ] = url
62
55
end
63
56
64
- # rubocop:disable Naming/MethodName
65
- def public_EdDSA_key
57
+ def public_ed_dsa_key
66
58
@config . info_plist [ 'SUPublicEDKey' ]
67
59
end
68
60
69
- def public_EdDSA_key = ( key )
61
+ def public_ed_dsa_key = ( key )
70
62
@config . info_plist [ 'SUPublicEDKey' ] = key
71
63
end
72
- # rubocop:enable Naming/MethodName
73
64
74
65
# File manipulation and certificates
75
66
@@ -109,7 +100,7 @@ def generate_keys
109
100
110
101
if appcast . use_exported_private_key && File . exist? ( private_key_path )
111
102
App . info 'Sparkle' , "Private key already exported at `#{ private_key_path } ` and will be used."
112
- if public_EdDSA_key . present?
103
+ if public_ed_dsa_key . present?
113
104
App . info '' , <<~EXISTS
114
105
SUPublicEDKey already set
115
106
@@ -139,12 +130,12 @@ def generate_keys
139
130
return
140
131
end
141
132
142
- results , status = Open3 . capture2e ( generate_keys_app , '-p' )
133
+ results , status = Open3 . capture2e ( generate_keys_app , '-p' , '--account' , appcast . cli_options [ :account ] )
143
134
144
135
if status . success?
145
- App . info 'Sparkle' , ' Public/private keys found in the keychain'
136
+ App . info 'Sparkle' , " Public/private keys found in the keychain for account #{ appcast . cli_options [ :account ] } "
146
137
147
- if results . strip == public_EdDSA_key
138
+ if results . strip == public_ed_dsa_key
148
139
App . info 'Sparkle' , 'Keychain public key matches `SUPublicEDKey`'
149
140
150
141
if appcast . use_exported_private_key && !File . exist? ( private_key_path )
@@ -155,7 +146,7 @@ def generate_keys
155
146
Keychain public key DOES NOT match `SUPublicEDKey`
156
147
157
148
Keychain public key: #{ results . strip }
158
- SUPublicEDKey public key: #{ public_EdDSA_key }
149
+ SUPublicEDKey public key: #{ public_ed_dsa_key }
159
150
160
151
NOT_MATCHED
161
152
. indent ( 11 , skip_first_line : true )
@@ -173,15 +164,15 @@ def generate_keys
173
164
def create_private_key
174
165
App . info 'Sparkle' ,
175
166
'Generating a new signing key into the Keychain. This may take a moment, depending on your machine.'
176
- results , status = Open3 . capture2e ( generate_keys_app )
167
+ results , status = Open3 . capture2e ( generate_keys_app , '--account' , appcast . cli_options [ :account ] )
177
168
178
169
App . fail 'Sparkle could not generate keys' unless status . success?
179
170
180
171
puts
181
172
puts results . lines [ 1 ..] . join . indent ( 11 )
182
173
183
174
# Extract the public key so we can use it in message
184
- results , status = Open3 . capture2e ( generate_keys_app , '-p' )
175
+ results , status = Open3 . capture2e ( generate_keys_app , '-p' , '--account' , appcast . cli_options [ :account ] )
185
176
186
177
App . fail 'Unable to read public key' unless status . success?
187
178
@@ -199,7 +190,7 @@ def create_private_key
199
190
200
191
# Export the private key from the keychain
201
192
def export_private_key
202
- _results , status = Open3 . capture2e ( generate_keys_app , '-x' , private_key_path . to_s )
193
+ _results , status = Open3 . capture2e ( generate_keys_app , '-x' , private_key_path . to_s , '--account' , appcast . cli_options [ :account ] )
203
194
204
195
App . fail 'Unable to export private key' unless status . success?
205
196
@@ -216,6 +207,92 @@ def export_private_key
216
207
. indent ( 11 )
217
208
end
218
209
210
+ # copy the release notes and zip archive into the releases_folder,
211
+ # where the appcast will get built
212
+ def copy_to_release
213
+ path = ( project_path + releases_folder ) . realpath
214
+ zip_file_path = ( sparkle_release_path + zip_file ) . realpath
215
+
216
+ [ release_notes_path , zip_file_path ] . each do |file |
217
+ FileUtils . cp ( file , "#{ path } /" )
218
+ App . info 'Copied' , "./#{ path } /#{ file } "
219
+ end
220
+ end
221
+
222
+ # Generate the appcast.
223
+ # Note: We do not support the old DSA keys, only the newer EdDSA keys.
224
+ # See https://sparkle-project.org/documentation/eddsa-migration
225
+ def generate_appcast
226
+ generate_appcast_app = "#{ vendored_sparkle_path } /bin/generate_appcast"
227
+ path = ( project_path + releases_folder ) . realpath
228
+ appcast_filename = ( path + appcast . feed_filename )
229
+ appcast . cli_options [ :output_path ] = appcast_filename
230
+
231
+ FileUtils . mkdir_p ( path ) unless File . exist? ( path )
232
+
233
+ App . info ( 'Sparkle' , "Generating appcast using `#{ generate_appcast_app } `" )
234
+ puts "from files in `#{ path } `..." . indent ( 11 )
235
+
236
+ args = appcast . prepare_args
237
+
238
+ App . info 'Executing' , [ generate_appcast_app , *args , path . to_s ] . join ( ' ' )
239
+
240
+ results , status = Open3 . capture2e ( generate_appcast_app , *args , path . to_s )
241
+
242
+ App . info ( 'Sparkle' , "Saved appcast to `#{ appcast_filename } `" ) if status . success?
243
+ puts results . indent ( 11 )
244
+
245
+ return unless status . success?
246
+
247
+ puts
248
+ puts "SUFeedURL : #{ feed_url } " . indent ( 11 )
249
+ puts "SUPublicEDKey : #{ public_ed_dsa_key } " . indent ( 11 )
250
+ end
251
+
252
+ def generate_appcast_help
253
+ generate_appcast_app = "#{ vendored_sparkle_path } /bin/generate_appcast"
254
+ results , _status = Open3 . capture2e ( generate_appcast_app , '--help' )
255
+
256
+ puts results
257
+ end
258
+
259
+ def create_release_notes
260
+ App . fail "Release notes template not found as expected at ./#{ release_notes_template_path } " unless File . exist? ( release_notes_template_path )
261
+
262
+ create_release_folder
263
+
264
+ File . open ( release_notes_path . to_s , 'w' ) do |f |
265
+ template = File . read ( release_notes_template_path )
266
+ f << ERB . new ( template ) . result ( binding )
267
+ end
268
+
269
+ App . info 'Create' , "./#{ release_notes_path } "
270
+ end
271
+
272
+ def release_notes_template_path
273
+ sparkle_config_path . join ( 'release_notes.template.erb' )
274
+ end
275
+
276
+ def release_notes_content_path
277
+ sparkle_config_path . join ( 'release_notes.content.html' )
278
+ end
279
+
280
+ def release_notes_path
281
+ sparkle_release_path + ( appcast . notes_filename || "#{ app_name } .#{ @config . short_version } .html" )
282
+ end
283
+
284
+ def release_notes_content
285
+ if File . exist? ( release_notes_content_path )
286
+ File . read ( release_notes_content_path )
287
+ else
288
+ App . fail "Missing #{ release_notes_content_path } "
289
+ end
290
+ end
291
+
292
+ def release_notes_html
293
+ release_notes_content
294
+ end
295
+
219
296
# A few helpers
220
297
221
298
def project_path
@@ -242,10 +319,6 @@ def private_key_path
242
319
sparkle_config_path . join ( EDDSA_PRIV_KEY )
243
320
end
244
321
245
- def legacy_private_key_path
246
- sparkle_config_path . join ( DSA_PRIV_KEY )
247
- end
248
-
249
322
def app_bundle_path
250
323
Pathname . new ( @config . app_bundle_raw ( 'MacOSX' ) )
251
324
end
@@ -262,8 +335,8 @@ def zip_file
262
335
appcast . package_filename || "#{ app_name } .#{ @config . short_version } .zip"
263
336
end
264
337
265
- def archive_folder
266
- appcast . archive_folder
338
+ def releases_folder
339
+ appcast . releases_folder
267
340
end
268
341
269
342
def app_file
0 commit comments