motion-sparkle-sandbox 2.0.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +183 -0
- data/.ruby-version +1 -0
- data/.travis.yml +37 -0
- data/Gemfile +13 -3
- data/README.md +72 -72
- data/Rakefile +2 -7
- data/bin/bundle +114 -0
- data/bin/byebug +29 -0
- data/bin/coderay +29 -0
- data/bin/fuzzy_match +29 -0
- data/bin/htmldiff +29 -0
- data/bin/httpclient +29 -0
- data/bin/ldiff +29 -0
- data/bin/pod +29 -0
- data/bin/pry +29 -0
- data/bin/rake +29 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bin/ruby-parse +29 -0
- data/bin/ruby-rewrite +29 -0
- data/bin/sandbox-pod +29 -0
- data/bin/xcodeproj +29 -0
- data/lib/motion/project/appcast.rb +294 -111
- data/lib/motion/project/indent_string.rb +18 -0
- data/lib/motion/project/install.rb +22 -66
- data/lib/motion/project/package.rb +52 -36
- data/lib/motion/project/project.rb +42 -51
- data/lib/motion/project/rake_tasks.rb +38 -28
- data/lib/motion/project/setup.rb +67 -73
- data/lib/motion/project/sparkle.rb +317 -148
- data/lib/motion/project/templates.rb +24 -22
- data/lib/motion-sparkle-sandbox/version.rb +5 -0
- data/lib/motion-sparkle-sandbox.rb +19 -3
- data/motion-sparkle-sandbox.gemspec +26 -16
- data/sample-app/.gitignore +10 -0
- data/sample-app/Gemfile +8 -0
- data/sample-app/README.md +87 -0
- data/sample-app/Rakefile +47 -0
- data/sample-app/app/app_delegate.rb +15 -0
- data/sample-app/app/menu.rb +155 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/1024x1024.png +0 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_128x128.png +0 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_128x128@2x.png +0 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_16x16.png +0 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_16x16@2x.png +0 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_256x256.png +0 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_256x256@2x.png +0 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_32x32.png +0 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_32x32@2x.png +0 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_512x512.png +0 -0
- data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_512x512@2x.png +0 -0
- data/sample-app/resources/Assets.xcassets/Contents.json +6 -0
- data/sample-app/resources/Credits.rtf +29 -0
- data/sample-app/spec/main_spec.rb +11 -0
- data/spec/appcast_spec.rb +60 -0
- data/spec/setup_spec.rb +42 -0
- data/spec/sparkle_spec.rb +94 -73
- data/spec/spec_helper.rb +100 -27
- data/spec/spec_utils.rb +68 -0
- data/vendor/.git_keep +0 -0
- metadata +80 -14
- data/vendor/README.md +0 -34
- data/vendor/Sparkle.zip +0 -0
- data/vendor/codesign_embedded_executable +0 -46
- data/vendor/generate_appcast +0 -0
@@ -1,189 +1,358 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Motion
|
4
|
+
module Project
|
5
|
+
# rubocop:disable Metrics/ClassLength
|
6
|
+
class Sparkle
|
7
|
+
SPARKLE_ROOT = 'sparkle'
|
8
|
+
CONFIG_PATH = "#{SPARKLE_ROOT}/config"
|
9
|
+
RELEASE_PATH = "#{SPARKLE_ROOT}/release"
|
10
|
+
EDDSA_PRIV_KEY = 'eddsa_priv.key'
|
11
|
+
DSA_PRIV_KEY = 'dsa_priv.pem'
|
12
|
+
|
13
|
+
def initialize(config)
|
14
|
+
@config = config
|
15
|
+
# verify_installation
|
16
|
+
end
|
3
17
|
|
4
|
-
|
5
|
-
|
6
|
-
|
18
|
+
def after_initialize
|
19
|
+
self.feed_url = appcast.feed_url
|
20
|
+
end
|
7
21
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
install_and_embed
|
12
|
-
end
|
22
|
+
def appcast
|
23
|
+
@appcast ||= Appcast.new(self)
|
24
|
+
end
|
13
25
|
|
14
|
-
|
15
|
-
|
16
|
-
end
|
26
|
+
def publish(key, value)
|
27
|
+
return if appcast.process_option(key, value)
|
17
28
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
appcast.feed_base_url = value
|
27
|
-
feed_url appcast.feed_url
|
28
|
-
when :feed_filename
|
29
|
-
appcast.feed_filename = value
|
30
|
-
feed_url appcast.feed_url
|
31
|
-
when :version
|
32
|
-
version value
|
33
|
-
when :notes_base_url, :package_base_url, :notes_filename, :package_filename
|
34
|
-
appcast.send "#{key}=", value
|
35
|
-
when :archive_folder
|
36
|
-
appcast.archive_folder = value
|
37
|
-
else
|
38
|
-
raise "Unknown Sparkle config option #{key}"
|
29
|
+
case key
|
30
|
+
when :public_key
|
31
|
+
self.public_ed_dsa_key = value
|
32
|
+
when :version
|
33
|
+
version(value)
|
34
|
+
else
|
35
|
+
raise "Unknown Sparkle config option #{key}"
|
36
|
+
end
|
39
37
|
end
|
40
|
-
|
41
|
-
alias_method :release, :publish
|
38
|
+
alias release publish
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
40
|
+
def version(vstring)
|
41
|
+
@config.version = vstring.to_s
|
42
|
+
@config.short_version = vstring.to_s
|
43
|
+
end
|
47
44
|
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
def version_string
|
46
|
+
"#{@config.short_version} (#{@config.version})"
|
47
|
+
end
|
51
48
|
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
def feed_url
|
50
|
+
@config.info_plist['SUFeedURL']
|
51
|
+
end
|
55
52
|
|
56
|
-
|
57
|
-
|
58
|
-
|
53
|
+
def feed_url=(url)
|
54
|
+
@config.info_plist['SUFeedURL'] = url
|
55
|
+
end
|
59
56
|
|
60
|
-
|
57
|
+
def public_ed_dsa_key
|
58
|
+
@config.info_plist['SUPublicEDKey']
|
59
|
+
end
|
60
|
+
|
61
|
+
def public_ed_dsa_key=(key)
|
62
|
+
@config.info_plist['SUPublicEDKey'] = key
|
63
|
+
end
|
64
|
+
|
65
|
+
# File manipulation and certificates
|
61
66
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
67
|
+
def add_to_gitignore
|
68
|
+
@ignorable = ['sparkle/release', 'sparkle/release/*', private_key_path]
|
69
|
+
return unless File.exist?(gitignore_path)
|
70
|
+
|
71
|
+
File.open(gitignore_path, 'r') do |f|
|
72
|
+
f.each_line do |line|
|
73
|
+
@ignorable.delete(line) if @ignorable.include?(line)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
if @ignorable.any?
|
77
|
+
File.open(gitignore_path, 'a') do |f|
|
78
|
+
@ignorable.each do |i|
|
79
|
+
f << "#{i}\n"
|
80
|
+
end
|
81
|
+
end
|
68
82
|
end
|
83
|
+
`cat #{gitignore_path}`
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_sparkle_folder
|
87
|
+
create_config_folder
|
88
|
+
create_release_folder
|
89
|
+
end
|
90
|
+
|
91
|
+
def generate_keys_app
|
92
|
+
"#{vendored_sparkle_path}/bin/generate_keys"
|
69
93
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
94
|
+
|
95
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
96
|
+
def generate_keys
|
97
|
+
return false unless config_ok?
|
98
|
+
|
99
|
+
FileUtils.mkdir_p sparkle_config_path unless File.exist?(sparkle_config_path)
|
100
|
+
|
101
|
+
if appcast.use_exported_private_key && File.exist?(private_key_path)
|
102
|
+
App.info 'Sparkle', "Private key already exported at `#{private_key_path}` and will be used."
|
103
|
+
if public_ed_dsa_key.present?
|
104
|
+
App.info '', <<~EXISTS
|
105
|
+
SUPublicEDKey already set
|
106
|
+
|
107
|
+
Be careful not to override or lose your certificates.
|
108
|
+
Delete this file if you're sure.
|
109
|
+
Aborting (no action performed)
|
110
|
+
EXISTS
|
111
|
+
.indent(11, skip_first_line: true)
|
112
|
+
else
|
113
|
+
App.info '', <<~EXISTS
|
114
|
+
SUPublicEDKey NOT SET
|
115
|
+
|
116
|
+
You can easily add the `SUPublicEDKey` by publishing the key in your Rakefile:
|
117
|
+
|
118
|
+
app.sparkle do
|
119
|
+
...
|
120
|
+
publish :public_key, 'PUBLIC_KEY'
|
121
|
+
end
|
122
|
+
|
123
|
+
Be careful not to override or lose your certificates.
|
124
|
+
Delete this file if you're sure.
|
125
|
+
Aborting (no action performed)
|
126
|
+
EXISTS
|
127
|
+
.indent(11, skip_first_line: true)
|
128
|
+
end
|
129
|
+
|
130
|
+
return
|
73
131
|
end
|
74
|
-
end if @ignorable.any?
|
75
|
-
`cat #{gitignore_path}`
|
76
|
-
end
|
77
132
|
|
78
|
-
|
79
|
-
create_config_folder
|
80
|
-
create_release_folder
|
81
|
-
end
|
133
|
+
results, status = Open3.capture2e(generate_keys_app, '-p', '--account', appcast.cli_options[:account])
|
82
134
|
|
83
|
-
|
84
|
-
|
85
|
-
end
|
135
|
+
if status.success?
|
136
|
+
App.info 'Sparkle', "Public/private keys found in the keychain for account #{appcast.cli_options[:account]}"
|
86
137
|
|
87
|
-
|
88
|
-
|
89
|
-
|
138
|
+
if results.strip == public_ed_dsa_key
|
139
|
+
App.info 'Sparkle', 'Keychain public key matches `SUPublicEDKey`'
|
140
|
+
|
141
|
+
if appcast.use_exported_private_key && !File.exist?(private_key_path)
|
142
|
+
# export the private key from the keychain
|
143
|
+
end
|
144
|
+
else
|
145
|
+
App.fail <<~NOT_MATCHED
|
146
|
+
Keychain public key DOES NOT match `SUPublicEDKey`
|
147
|
+
|
148
|
+
Keychain public key: #{results.strip}
|
149
|
+
SUPublicEDKey public key: #{public_ed_dsa_key}
|
150
|
+
|
151
|
+
NOT_MATCHED
|
152
|
+
.indent(11, skip_first_line: true)
|
153
|
+
end
|
90
154
|
|
91
|
-
def generate_keys
|
92
|
-
return false unless config_ok?
|
93
|
-
unless File.exist?(sparkle_config_path)
|
94
|
-
FileUtils.mkdir_p sparkle_config_path
|
95
|
-
end
|
96
|
-
[dsa_param_path, private_key_path, public_key_path].each do |file|
|
97
|
-
if File.exist? file
|
98
|
-
App.info "Sparkle", "Error: file exists.
|
99
|
-
There's already a '#{file}'. Be careful not to override or lose your certificates. \n
|
100
|
-
Delete this file if you're sure. \n
|
101
|
-
Aborting (no action performed)
|
102
|
-
"
|
103
155
|
return
|
104
156
|
end
|
157
|
+
|
158
|
+
create_private_key
|
159
|
+
export_private_key if appcast.use_exported_private_key
|
105
160
|
end
|
106
|
-
|
107
|
-
`#{openssl} gendsa #{dsa_param_path} -out #{private_key_path}`
|
108
|
-
generate_public_key
|
109
|
-
`rm #{dsa_param_path}`
|
110
|
-
App.info "Sparkle", "Generated private and public certificates.
|
111
|
-
Details:
|
112
|
-
* Private certificate: ./#{private_key_path}
|
113
|
-
* Public certificate: ./#{public_key_path}
|
114
|
-
Warning:
|
115
|
-
ADD YOUR PRIVATE CERTIFICATE TO YOUR `.gitignore` OR EQUIVALENT AND BACK IT UP!
|
116
|
-
KEEP IT PRIVATE AND SAFE!
|
117
|
-
If you lose it, your users will be unable to upgrade.
|
118
|
-
"
|
119
|
-
end
|
161
|
+
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
120
162
|
|
121
|
-
|
122
|
-
|
123
|
-
|
163
|
+
# Create the private key in the keychain
|
164
|
+
def create_private_key
|
165
|
+
App.info 'Sparkle',
|
166
|
+
'Generating a new signing key into the Keychain. This may take a moment, depending on your machine.'
|
167
|
+
results, status = Open3.capture2e(generate_keys_app, '--account', appcast.cli_options[:account])
|
124
168
|
|
125
|
-
|
169
|
+
App.fail 'Sparkle could not generate keys' unless status.success?
|
126
170
|
|
127
|
-
|
128
|
-
|
129
|
-
end
|
171
|
+
puts
|
172
|
+
puts results.lines[1..].join.indent(11)
|
130
173
|
|
131
|
-
|
132
|
-
|
133
|
-
end
|
174
|
+
# Extract the public key so we can use it in message
|
175
|
+
results, status = Open3.capture2e(generate_keys_app, '-p', '--account', appcast.cli_options[:account])
|
134
176
|
|
135
|
-
|
136
|
-
@vendor_path ||= Pathname.new(project_path + 'vendor/')
|
137
|
-
end
|
177
|
+
App.fail 'Unable to read public key' unless status.success?
|
138
178
|
|
139
|
-
|
140
|
-
|
141
|
-
end
|
179
|
+
puts <<~KEYS
|
180
|
+
You can easily add the `SUPublicEDKey` by publishing the key in your Rakefile:
|
142
181
|
|
143
|
-
|
144
|
-
|
145
|
-
|
182
|
+
app.sparkle do
|
183
|
+
...
|
184
|
+
publish :public_key, '#{results.strip}'
|
185
|
+
end
|
146
186
|
|
147
|
-
|
148
|
-
|
149
|
-
|
187
|
+
KEYS
|
188
|
+
.indent(11)
|
189
|
+
end
|
150
190
|
|
151
|
-
|
152
|
-
|
153
|
-
|
191
|
+
# Export the private key from the keychain
|
192
|
+
def export_private_key
|
193
|
+
_results, status = Open3.capture2e(generate_keys_app, '-x', private_key_path.to_s, '--account', appcast.cli_options[:account])
|
154
194
|
|
155
|
-
|
156
|
-
sparkle_config_path + "dsa_priv.pem"
|
157
|
-
end
|
195
|
+
App.fail 'Unable to export private key' unless status.success?
|
158
196
|
|
159
|
-
|
160
|
-
|
161
|
-
project_path + "resources/#{pub_key_file}"
|
162
|
-
end
|
197
|
+
App.info 'Sparkle', 'Private key has been exported from the keychain into the file:'
|
198
|
+
puts <<~KEYS
|
163
199
|
|
164
|
-
|
165
|
-
Pathname.new @config.app_bundle_raw('MacOSX')
|
166
|
-
end
|
200
|
+
./#{private_key_path}
|
167
201
|
|
168
|
-
|
169
|
-
|
170
|
-
|
202
|
+
ADD THIS PRIVATE KEY TO YOUR `.gitignore` OR EQUIVALENT AND BACK IT UP!
|
203
|
+
KEEP IT PRIVATE AND SAFE!
|
204
|
+
If you lose it, your users will be unable to upgrade, unless you used Apple code signing.
|
205
|
+
See https://sparkle-project.org/documentation/ for details
|
206
|
+
KEYS
|
207
|
+
.indent(11)
|
208
|
+
end
|
171
209
|
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
175
215
|
|
176
|
-
|
177
|
-
|
178
|
-
|
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
|
179
221
|
|
180
|
-
|
181
|
-
|
182
|
-
|
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
|
183
230
|
|
184
|
-
|
185
|
-
|
186
|
-
|
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)
|
187
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
|
+
|
296
|
+
# A few helpers
|
297
|
+
|
298
|
+
def project_path
|
299
|
+
@project_path ||= Pathname.new(@config.project_dir)
|
300
|
+
end
|
301
|
+
|
302
|
+
def vendor_path
|
303
|
+
@vendor_path ||= project_path.join('vendor')
|
304
|
+
end
|
305
|
+
|
306
|
+
def gitignore_path
|
307
|
+
project_path.join('.gitignore')
|
308
|
+
end
|
309
|
+
|
310
|
+
def sparkle_release_path
|
311
|
+
project_path.join(RELEASE_PATH)
|
312
|
+
end
|
313
|
+
|
314
|
+
def sparkle_config_path
|
315
|
+
project_path.join(CONFIG_PATH)
|
316
|
+
end
|
317
|
+
|
318
|
+
def private_key_path
|
319
|
+
sparkle_config_path.join(EDDSA_PRIV_KEY)
|
320
|
+
end
|
321
|
+
|
322
|
+
def app_bundle_path
|
323
|
+
Pathname.new(@config.app_bundle_raw('MacOSX'))
|
324
|
+
end
|
325
|
+
|
326
|
+
def app_release_path
|
327
|
+
app_bundle_path.parent.to_s
|
328
|
+
end
|
329
|
+
|
330
|
+
def app_name
|
331
|
+
File.basename(app_bundle_path, '.app')
|
332
|
+
end
|
333
|
+
|
334
|
+
def zip_file
|
335
|
+
appcast.package_filename || "#{app_name}.#{@config.short_version}.zip"
|
336
|
+
end
|
337
|
+
|
338
|
+
def releases_folder
|
339
|
+
appcast.releases_folder
|
340
|
+
end
|
341
|
+
|
342
|
+
def app_file
|
343
|
+
"#{app_name}.app"
|
344
|
+
end
|
345
|
+
|
346
|
+
private
|
347
|
+
|
348
|
+
def create_config_folder
|
349
|
+
FileUtils.mkdir_p(sparkle_config_path) unless File.exist?(sparkle_config_path)
|
350
|
+
end
|
351
|
+
|
352
|
+
def create_release_folder
|
353
|
+
FileUtils.mkdir_p(sparkle_release_path) unless File.exist?(sparkle_release_path)
|
354
|
+
end
|
355
|
+
end
|
356
|
+
# rubocop:enable Metrics/ClassLength
|
188
357
|
end
|
189
358
|
end
|
@@ -1,34 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'erb'
|
2
4
|
require 'rexml/document'
|
3
5
|
|
4
|
-
module Motion
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
module Motion
|
7
|
+
module Project
|
8
|
+
class Sparkle
|
9
|
+
TEMPLATE_PATHS = [
|
10
|
+
File.expand_path(File.join(__FILE__, '../appcast'))
|
11
|
+
].freeze
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
def all_templates
|
14
|
+
@all_templates ||= begin
|
15
|
+
templates = {}
|
16
|
+
TEMPLATE_PATHS.map { |path| Dir.glob("#{path}/*") }.flatten.each do |template_path|
|
17
|
+
templates[File.basename(template_path)] = template_path
|
18
|
+
end
|
19
|
+
templates
|
16
20
|
end
|
17
|
-
templates
|
18
21
|
end
|
19
|
-
end
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
def copy_templates(force = false)
|
24
|
+
all_templates.each_pair do |tmpl, path|
|
25
|
+
result = "#{sparkle_config_path}/#{tmpl}"
|
26
|
+
if File.exist?(result) && !force
|
27
|
+
App.info 'Exists', result
|
28
|
+
else
|
29
|
+
FileUtils.cp(path, "#{sparkle_config_path}/")
|
30
|
+
App.info 'Create', "./#{sparkle_config_path}/#{tmpl}"
|
31
|
+
end
|
29
32
|
end
|
30
33
|
end
|
31
34
|
end
|
32
|
-
|
33
35
|
end
|
34
36
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
raise 'This file must be required within a RubyMotion project Rakefile.' unless defined?(Motion::Project::Config)
|
4
|
+
|
5
|
+
require 'motion-cocoapods'
|
4
6
|
|
5
7
|
require 'motion/project/sparkle'
|
6
8
|
require 'motion/project/install'
|
@@ -10,3 +12,17 @@ require 'motion/project/templates'
|
|
10
12
|
require 'motion/project/appcast'
|
11
13
|
require 'motion/project/project'
|
12
14
|
require 'motion/project/rake_tasks'
|
15
|
+
require 'motion/project/indent_string'
|
16
|
+
|
17
|
+
lib_dir_path = File.dirname(File.expand_path(__FILE__))
|
18
|
+
|
19
|
+
POD_VERSION = '~> 2.1.0'
|
20
|
+
|
21
|
+
unless @running_specs
|
22
|
+
Motion::Project::App.setup do |app|
|
23
|
+
app.files.unshift(Dir.glob(File.join(lib_dir_path, 'motion-sparkle-sandbox/**/*.rb')))
|
24
|
+
app.pods do
|
25
|
+
pod 'Sparkle', POD_VERSION
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,21 +1,31 @@
|
|
1
|
-
#
|
2
|
-
module ::Motion; module Project; class Config
|
3
|
-
def self.variable(*); end
|
4
|
-
end; end; end
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
7
|
-
|
3
|
+
module Motion
|
4
|
+
module Project
|
5
|
+
# This is just so that the source file can be loaded
|
6
|
+
class Config
|
7
|
+
def self.variable(*); end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# require 'date'
|
13
|
+
# $:.unshift File.expand_path('../lib', __FILE__)
|
14
|
+
require File.expand_path('lib/motion-sparkle-sandbox/version.rb', __dir__)
|
8
15
|
|
9
16
|
Gem::Specification.new do |spec|
|
10
|
-
spec.name
|
11
|
-
spec.version
|
12
|
-
spec.
|
13
|
-
spec.
|
14
|
-
spec.
|
15
|
-
spec.
|
16
|
-
spec.
|
17
|
-
spec.
|
18
|
-
|
19
|
-
spec.files
|
17
|
+
spec.name = 'motion-sparkle-sandbox'
|
18
|
+
spec.version = MotionSparkleSandbox::VERSION
|
19
|
+
spec.authors = ['Brett Walker', 'Alexandre L. Solleiro']
|
20
|
+
spec.email = ['github@digitalmoksha.com', 'alex@webcracy.org']
|
21
|
+
spec.summary = 'Sparkle (sandboxed) integration for Rubymotion projects'
|
22
|
+
spec.description = 'motion-sparkle-sandbox makes it easy to use the sandboxed version of Sparkle in your RubyMotion macOS apps'
|
23
|
+
spec.homepage = 'https://github.com/digitalmoksha/motion-sparkle-sandbox'
|
24
|
+
spec.license = 'MIT'
|
25
|
+
|
26
|
+
spec.files = `git ls-files`.split("\n")
|
27
|
+
spec.test_files = Dir.glob('spec/**/*.rb')
|
20
28
|
spec.require_paths = ['lib']
|
29
|
+
|
30
|
+
spec.add_dependency 'motion-cocoapods'
|
21
31
|
end
|