motion-sparkle-sandbox 0.8.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +7 -0
  5. data/.rubocop_todo.yml +183 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +37 -0
  8. data/Gemfile +13 -3
  9. data/LICENSE +1 -0
  10. data/README.md +72 -72
  11. data/Rakefile +2 -7
  12. data/bin/bundle +105 -0
  13. data/bin/byebug +29 -0
  14. data/bin/coderay +29 -0
  15. data/bin/fuzzy_match +29 -0
  16. data/bin/htmldiff +29 -0
  17. data/bin/httpclient +29 -0
  18. data/bin/ldiff +29 -0
  19. data/bin/pod +29 -0
  20. data/bin/pry +29 -0
  21. data/bin/rake +29 -0
  22. data/bin/rspec +29 -0
  23. data/bin/rubocop +29 -0
  24. data/bin/ruby-parse +29 -0
  25. data/bin/ruby-rewrite +29 -0
  26. data/bin/sandbox-pod +29 -0
  27. data/bin/xcodeproj +29 -0
  28. data/lib/motion/project/appcast.rb +177 -104
  29. data/lib/motion/project/indent_string.rb +18 -0
  30. data/lib/motion/project/install.rb +22 -66
  31. data/lib/motion/project/package.rb +52 -36
  32. data/lib/motion/project/project.rb +41 -51
  33. data/lib/motion/project/rake_tasks.rb +28 -32
  34. data/lib/motion/project/setup.rb +67 -73
  35. data/lib/motion/project/sparkle.rb +244 -148
  36. data/lib/motion/project/templates.rb +24 -22
  37. data/lib/motion-sparkle-sandbox/version.rb +5 -0
  38. data/lib/motion-sparkle-sandbox.rb +20 -3
  39. data/motion-sparkle-sandbox.gemspec +26 -16
  40. data/sample-app/.gitignore +9 -0
  41. data/sample-app/Gemfile +8 -0
  42. data/sample-app/README.md +87 -0
  43. data/sample-app/Rakefile +44 -0
  44. data/sample-app/app/app_delegate.rb +15 -0
  45. data/sample-app/app/menu.rb +155 -0
  46. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/1024x1024.png +0 -0
  47. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
  48. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_128x128.png +0 -0
  49. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_128x128@2x.png +0 -0
  50. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_16x16.png +0 -0
  51. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_16x16@2x.png +0 -0
  52. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_256x256.png +0 -0
  53. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_256x256@2x.png +0 -0
  54. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_32x32.png +0 -0
  55. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_32x32@2x.png +0 -0
  56. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_512x512.png +0 -0
  57. data/sample-app/resources/Assets.xcassets/AppIcon.appiconset/Icon_512x512@2x.png +0 -0
  58. data/sample-app/resources/Assets.xcassets/Contents.json +6 -0
  59. data/sample-app/resources/Credits.rtf +29 -0
  60. data/sample-app/spec/main_spec.rb +11 -0
  61. data/spec/setup_spec.rb +42 -0
  62. data/spec/sparkle_spec.rb +92 -73
  63. data/spec/spec_helper.rb +100 -27
  64. data/spec/spec_utils.rb +68 -0
  65. data/vendor/.git_keep +0 -0
  66. metadata +78 -15
  67. data/vendor/README.md +0 -24
  68. data/vendor/Sparkle.zip +0 -0
  69. data/vendor/codesign_xpc +0 -46
  70. data/vendor/generate_appcast +0 -0
@@ -1,189 +1,285 @@
1
- module Motion::Project
2
- class Sparkle
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
- SPARKLE_ROOT = "sparkle"
5
- CONFIG_PATH = "#{SPARKLE_ROOT}/config"
6
- RELEASE_PATH = "#{SPARKLE_ROOT}/release"
18
+ def appcast
19
+ @appcast ||= Appcast.new
20
+ end
7
21
 
8
- def initialize(config)
9
- @config = config
10
- publish :public_key, 'dsa_pub.pem'
11
- install_and_embed
12
- end
22
+ def publish(key, value)
23
+ case key
24
+ 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
35
+ 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
41
+ else
42
+ raise "Unknown Sparkle config option #{key}"
43
+ end
44
+ end
45
+ alias release publish
13
46
 
14
- def appcast
15
- @appcast ||= Appcast.new
16
- end
47
+ def version(vstring)
48
+ @config.version = vstring.to_s
49
+ @config.short_version = vstring.to_s
50
+ end
17
51
 
18
- def publish(key, value)
19
- case key
20
- when :public_key
21
- public_key value
22
- when :base_url
23
- appcast.base_url = value
24
- feed_url appcast.feed_url
25
- when :feed_base_url
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}"
52
+ def version_string
53
+ "#{@config.short_version} (#{@config.version})"
39
54
  end
40
- end
41
- alias_method :release, :publish
42
55
 
43
- def version(vstring)
44
- @config.version = vstring.to_s
45
- @config.short_version = vstring.to_s
46
- end
56
+ def feed_url
57
+ @config.info_plist['SUFeedURL']
58
+ end
47
59
 
48
- def version_string
49
- "#{@config.short_version} (#{@config.version})"
50
- end
60
+ def feed_url=(url)
61
+ @config.info_plist['SUFeedURL'] = url
62
+ end
51
63
 
52
- def feed_url(url)
53
- @config.info_plist['SUFeedURL'] = url
54
- end
64
+ # rubocop:disable Naming/MethodName
65
+ def public_EdDSA_key
66
+ @config.info_plist['SUPublicEDKey']
67
+ end
55
68
 
56
- def public_key(path_in_resources_folder)
57
- @config.info_plist['SUPublicDSAKeyFile'] = path_in_resources_folder
58
- end
69
+ def public_EdDSA_key=(key)
70
+ @config.info_plist['SUPublicEDKey'] = key
71
+ end
72
+ # rubocop:enable Naming/MethodName
73
+
74
+ # File manipulation and certificates
59
75
 
60
- # File manipulation and certificates
76
+ def add_to_gitignore
77
+ @ignorable = ['sparkle/release', 'sparkle/release/*', private_key_path]
78
+ return unless File.exist?(gitignore_path)
61
79
 
62
- def add_to_gitignore
63
- @ignorable = ['sparkle/release','sparkle/release/*','sparkle/config/dsa_priv.pem']
64
- return unless File.exist?(gitignore_path)
65
- File.open(gitignore_path, 'r') do |f|
66
- f.each_line do |line|
67
- @ignorable.delete(line) if @ignorable.include?(line)
80
+ File.open(gitignore_path, 'r') do |f|
81
+ f.each_line do |line|
82
+ @ignorable.delete(line) if @ignorable.include?(line)
83
+ end
84
+ end
85
+ if @ignorable.any?
86
+ File.open(gitignore_path, 'a') do |f|
87
+ @ignorable.each do |i|
88
+ f << "#{i}\n"
89
+ end
90
+ end
68
91
  end
92
+ `cat #{gitignore_path}`
93
+ end
94
+
95
+ def create_sparkle_folder
96
+ create_config_folder
97
+ create_release_folder
69
98
  end
70
- File.open(gitignore_path, 'a') do |f|
71
- @ignorable.each do |i|
72
- f << "#{i}\n"
99
+
100
+ def generate_keys_app
101
+ "#{vendored_sparkle_path}/bin/generate_keys"
102
+ end
103
+
104
+ # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength
105
+ def generate_keys
106
+ return false unless config_ok?
107
+
108
+ FileUtils.mkdir_p sparkle_config_path unless File.exist?(sparkle_config_path)
109
+
110
+ if appcast.use_exported_private_key && File.exist?(private_key_path)
111
+ App.info 'Sparkle', "Private key already exported at `#{private_key_path}` and will be used."
112
+ if public_EdDSA_key.present?
113
+ App.info '', <<~EXISTS
114
+ SUPublicEDKey already set
115
+
116
+ Be careful not to override or lose your certificates.
117
+ Delete this file if you're sure.
118
+ Aborting (no action performed)
119
+ EXISTS
120
+ .indent(11, skip_first_line: true)
121
+ else
122
+ App.info '', <<~EXISTS
123
+ SUPublicEDKey NOT SET
124
+
125
+ You can easily add the `SUPublicEDKey` by publishing the key in your Rakefile:
126
+
127
+ app.sparkle do
128
+ ...
129
+ publish :public_key, 'PUBLIC_KEY'
130
+ end
131
+
132
+ Be careful not to override or lose your certificates.
133
+ Delete this file if you're sure.
134
+ Aborting (no action performed)
135
+ EXISTS
136
+ .indent(11, skip_first_line: true)
137
+ end
138
+
139
+ return
73
140
  end
74
- end if @ignorable.any?
75
- `cat #{gitignore_path}`
76
- end
77
141
 
78
- def create_sparkle_folder
79
- create_config_folder
80
- create_release_folder
81
- end
142
+ results, status = Open3.capture2e(generate_keys_app, '-p')
82
143
 
83
- def create_config_folder
84
- FileUtils.mkdir_p(sparkle_config_path) unless File.exist?(sparkle_config_path)
85
- end
144
+ if status.success?
145
+ App.info 'Sparkle', 'Public/private keys found in the keychain'
86
146
 
87
- def create_release_folder
88
- FileUtils.mkdir_p(sparkle_release_path) unless File.exist?(sparkle_release_path)
89
- end
147
+ if results.strip == public_EdDSA_key
148
+ App.info 'Sparkle', 'Keychain public key matches `SUPublicEDKey`'
149
+
150
+ if appcast.use_exported_private_key && !File.exist?(private_key_path)
151
+ # export the private key from the keychain
152
+ end
153
+ else
154
+ App.fail <<~NOT_MATCHED
155
+ Keychain public key DOES NOT match `SUPublicEDKey`
156
+
157
+ Keychain public key: #{results.strip}
158
+ SUPublicEDKey public key: #{public_EdDSA_key}
159
+
160
+ NOT_MATCHED
161
+ .indent(11, skip_first_line: true)
162
+ end
90
163
 
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
164
  return
104
165
  end
166
+
167
+ create_private_key
168
+ export_private_key if appcast.use_exported_private_key
105
169
  end
106
- `#{openssl} dsaparam 2048 < /dev/urandom > #{dsa_param_path}`
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
170
+ # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength
120
171
 
121
- def generate_public_key
122
- `#{openssl} dsa -in #{private_key_path} -pubout -out #{public_key_path}`
123
- end
172
+ # Create the private key in the keychain
173
+ def create_private_key
174
+ App.info 'Sparkle',
175
+ '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)
124
177
 
125
- # A few helpers
178
+ App.fail 'Sparkle could not generate keys' unless status.success?
126
179
 
127
- def openssl
128
- "/usr/bin/openssl"
129
- end
180
+ puts
181
+ puts results.lines[1..].join.indent(11)
130
182
 
131
- def project_path
132
- @project_path ||= Pathname.new(@config.project_dir)
133
- end
183
+ # Extract the public key so we can use it in message
184
+ results, status = Open3.capture2e(generate_keys_app, '-p')
134
185
 
135
- def vendor_path
136
- @vendor_path ||= Pathname.new(project_path + 'vendor/')
137
- end
186
+ App.fail 'Unable to read public key' unless status.success?
138
187
 
139
- def gitignore_path
140
- project_path + ".gitignore"
141
- end
188
+ puts <<~KEYS
189
+ You can easily add the `SUPublicEDKey` by publishing the key in your Rakefile:
142
190
 
143
- def sparkle_release_path
144
- project_path + RELEASE_PATH
145
- end
191
+ app.sparkle do
192
+ ...
193
+ publish :public_key, '#{results.strip}'
194
+ end
146
195
 
147
- def sparkle_config_path
148
- project_path + CONFIG_PATH
149
- end
196
+ KEYS
197
+ .indent(11)
198
+ end
150
199
 
151
- def dsa_param_path
152
- sparkle_config_path + "dsaparam.pem"
153
- end
200
+ # Export the private key from the keychain
201
+ def export_private_key
202
+ _results, status = Open3.capture2e(generate_keys_app, '-x', private_key_path.to_s)
154
203
 
155
- def private_key_path
156
- sparkle_config_path + "dsa_priv.pem"
157
- end
204
+ App.fail 'Unable to export private key' unless status.success?
158
205
 
159
- def public_key_path
160
- pub_key_file = @config.info_plist['SUPublicDSAKeyFile']
161
- project_path + "resources/#{pub_key_file}"
162
- end
206
+ App.info 'Sparkle', 'Private key has been exported from the keychain into the file:'
207
+ puts <<~KEYS
163
208
 
164
- def app_bundle_path
165
- Pathname.new @config.app_bundle_raw('MacOSX')
166
- end
209
+ ./#{private_key_path}
167
210
 
168
- def app_release_path
169
- app_bundle_path.parent.to_s
170
- end
211
+ ADD THIS PRIVATE KEY TO YOUR `.gitignore` OR EQUIVALENT AND BACK IT UP!
212
+ KEEP IT PRIVATE AND SAFE!
213
+ If you lose it, your users will be unable to upgrade, unless you used Apple code signing.
214
+ See https://sparkle-project.org/documentation/ for details
215
+ KEYS
216
+ .indent(11)
217
+ end
171
218
 
172
- def app_name
173
- File.basename(app_bundle_path, '.app')
174
- end
219
+ # A few helpers
175
220
 
176
- def zip_file
177
- appcast.package_filename || "#{app_name}.zip"
178
- end
221
+ def project_path
222
+ @project_path ||= Pathname.new(@config.project_dir)
223
+ end
179
224
 
180
- def archive_folder
181
- appcast.archive_folder
182
- end
225
+ def vendor_path
226
+ @vendor_path ||= project_path.join('vendor')
227
+ end
183
228
 
184
- def app_file
185
- "#{app_name}.app"
186
- end
229
+ def gitignore_path
230
+ project_path.join('.gitignore')
231
+ end
232
+
233
+ def sparkle_release_path
234
+ project_path.join(RELEASE_PATH)
235
+ end
236
+
237
+ def sparkle_config_path
238
+ project_path.join(CONFIG_PATH)
239
+ end
240
+
241
+ def private_key_path
242
+ sparkle_config_path.join(EDDSA_PRIV_KEY)
243
+ end
244
+
245
+ def legacy_private_key_path
246
+ sparkle_config_path.join(DSA_PRIV_KEY)
247
+ end
248
+
249
+ def app_bundle_path
250
+ Pathname.new(@config.app_bundle_raw('MacOSX'))
251
+ end
252
+
253
+ def app_release_path
254
+ app_bundle_path.parent.to_s
255
+ end
256
+
257
+ def app_name
258
+ File.basename(app_bundle_path, '.app')
259
+ end
260
+
261
+ def zip_file
262
+ appcast.package_filename || "#{app_name}.#{@config.short_version}.zip"
263
+ end
264
+
265
+ def archive_folder
266
+ appcast.archive_folder
267
+ end
268
+
269
+ def app_file
270
+ "#{app_name}.app"
271
+ end
187
272
 
273
+ private
274
+
275
+ def create_config_folder
276
+ FileUtils.mkdir_p(sparkle_config_path) unless File.exist?(sparkle_config_path)
277
+ end
278
+
279
+ def create_release_folder
280
+ FileUtils.mkdir_p(sparkle_release_path) unless File.exist?(sparkle_release_path)
281
+ end
282
+ end
283
+ # rubocop:enable Metrics/ClassLength
188
284
  end
189
285
  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::Project
5
- class Sparkle
6
-
7
- TEMPLATE_PATHS = [
8
- File.expand_path(File.join(__FILE__, '../appcast'))
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
- def all_templates
12
- @all_templates ||= begin
13
- templates = {}
14
- TEMPLATE_PATHS.map { |path| Dir.glob(path + '/*') }.flatten.each do |template_path|
15
- templates[File.basename(template_path)] = template_path
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
- def copy_templates(force=false)
22
- all_templates.each_pair do |tmpl, path|
23
- result = "#{sparkle_config_path}/#{tmpl}"
24
- if File.exist?(result) and !force
25
- App.info 'Exists', result
26
- else
27
- FileUtils.cp(path, "#{sparkle_config_path}/")
28
- App.info 'Create', "./#{sparkle_config_path}/#{tmpl.to_s}"
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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MotionSparkleSandbox
4
+ VERSION = '2.1.0'
5
+ end
@@ -1,6 +1,9 @@
1
- unless defined?(Motion::Project::Config)
2
- raise "This file must be required within a RubyMotion project Rakefile."
3
- end
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'
6
+
4
7
  require 'motion/project/sparkle'
5
8
  require 'motion/project/install'
6
9
  require 'motion/project/setup'
@@ -9,3 +12,17 @@ require 'motion/project/templates'
9
12
  require 'motion/project/appcast'
10
13
  require 'motion/project/project'
11
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
- # This is just so that the source file can be loaded.
2
- module ::Motion; module Project; class Config
3
- def self.variable(*); end
4
- end; end; end
1
+ # frozen_string_literal: true
5
2
 
6
- require 'date'
7
- $:.unshift File.expand_path('../lib', __FILE__)
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 = 'motion-sparkle-sandbox'
11
- spec.version = '0.8.0'
12
- spec.date = Date.today
13
- spec.summary = 'Sparkle (sandboxed) integration for Rubymotion projects'
14
- spec.description = "motion-sparkle-sandbox makes it easy to use the sandboxed version of Sparkle in your RubyMotion OS X apps"
15
- spec.author = 'Brett Walker'
16
- spec.email = 'github@digitalmoksha.com'
17
- spec.homepage = 'https://github.com/digitalmoksha/motion-sparkle-sandbox'
18
- spec.license = 'MIT'
19
- spec.files = `git ls-files`.split("\n")
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
@@ -0,0 +1,9 @@
1
+ .DS_Store
2
+ .bundle
3
+ .repl_history
4
+ build
5
+ build-log
6
+ vendor
7
+
8
+ sparkle/release
9
+ sparkle/config
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+
5
+ gem 'motion-sparkle-sandbox', path: '..'
6
+
7
+ gem 'pry-byebug', '~> 3.9.0', platform: :mri
8
+ gem 'binding_of_caller'