motion-rubygems 0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ motion-rubygems adds (primitive and broken) support for (one or two) Rubygems to RubyMotion
2
+
3
+ Installation
4
+ ------------
5
+
6
+ WARNING: By typing `--pre` you admit that *everything is broken*. Please don't even try using this if you want anything to work at all.
7
+
8
+ ```
9
+ $ gem install motion-rubygems --pre
10
+ ```
11
+
12
+ Usage
13
+ -----
14
+
15
+ To use motion-rubygems, first add `require 'motion-rubygems'` to the top of your Rakefile:
16
+
17
+ ```ruby
18
+ $:.unshift("/Library/RubyMotion/lib")
19
+ require 'motion/project'
20
+
21
+ require 'motion-rubygems'
22
+ ```
23
+
24
+ And then add gems to your app in the setup block:
25
+
26
+ ```ruby
27
+
28
+ Motion::Project::App.setup do |app|
29
+ # ...
30
+ app.gems = %w(andand)
31
+ end
32
+ ```
33
+
34
+ Making gems motion-rubygems compatible
35
+ --------------------------------------
36
+
37
+ This is quite hard at the moment (see under "How does this even work?!!" for details).
38
+
39
+ Essentially your gem will be required with the constant `RUBYMOTION_VERSION="1.6"` or similar.
40
+
41
+ At compile time, you should `require` all the files that you need (note that at runtime, `require`s will be deferred to the end of the current file; so don't do anything that needs the result of the require later on in the current file). The `requires` are fully evaluated, so if you require a file from inside another file, that's fine.
42
+
43
+ At runtime you should then run RubyMotion compatible ruby. There are a few restrictions (like, no `eval`, or `define_method`), and a few random strange quirks of the runtime. Good luck!
44
+
45
+ (There's no way to tell the difference between compile time and run time yet, it's coming...)
46
+
47
+ Snake Oil Warning
48
+ -----------------
49
+
50
+ Warning, most gems *do not work* with motion-rubygems. This is for a few reasons:
51
+
52
+ 1. The gem uses features of ruby that RubyMotion doesn't yet support (eval, define_method, autoload, etc.)
53
+ 2. The gem uses a C extension.
54
+ 3. The gem is highly load-order dependent.
55
+ 4. It just randomly segfaults and I don't know why.
56
+
57
+ Success cases
58
+ -------------
59
+
60
+ Gems I've tested and seem to at least compile include:
61
+
62
+ * andand, custom_boolean
63
+
64
+ Uh, yeah, that's it. Sorry folks :(.
65
+
66
+ How does this even work!?
67
+ -------------------------
68
+
69
+ As you'll know, RubyMotion doesn't support `require`, but Rubygems require it.
70
+
71
+ To get round this we (at compile time) load the gem and write down all the files it requires. We then add all of these files to the app; and make RubyMotion compile them.
72
+
73
+ At *runtime*, we temporarily override require to do nothing, hope that none of the bad things listed above happen, and then let RubyMotion load all the files in order.
74
+
75
+ TODO
76
+ ----
77
+
78
+ * Come up with conventions for writing RubyMotion gems so that they look like normal RubyGems. (not actually technically hard, but requires some people-skills!)
79
+
80
+ * Work out how to include shared libraries. (In theory this is doable, but I need to talk to someone from the RubyMotion team about how to actually do it; I guess the main hard bit is supporting the ruby C API?).
81
+
82
+ * Find common problems that stop lots of rubygems from working on RubyMotion, and work out sweeping solutions. (yeah, *dream on*)
83
+
84
+ If everything doesn't work, Why did you do this?
85
+ ------------------------------------------------
86
+
87
+ At the moment you can't use rubygems with RubyMotion at all, and that makes me really sad.
88
+
89
+ The ideas being thrown around about packaging ruby motion gems make them totally incompatible with other ruby platforms, and that makes me quite sad too.
90
+
91
+ Obviously there are going to be RubyMotion specific gems, and gems that RubyMotion doesn't support; however I assert that gems which work everywhere are *the most important*.
92
+
93
+ It's incredibly awesome to be able to run the same code on the JVM and on an iPhone, and even (with mruby) on your dishwasher.
94
+
95
+ Meta-fu
96
+ -------
97
+
98
+ This is released under the MIT license, pull-requests are very very welcome!
99
+
100
+
101
+
@@ -0,0 +1,70 @@
1
+ module Motion::Project
2
+
3
+ class Config
4
+ # Allow the user to do 'app.gems = %w(andand)'
5
+ variable :gems
6
+ end
7
+
8
+ class << App
9
+ # Override the original setup so that we can put gems before the user's own
10
+ # files.
11
+ def setup_with_motion_rubygems
12
+ setup_without_motion_rubygems do |app|
13
+ yield app
14
+
15
+ unless app.gems == []
16
+ app.files = MotionRubyGems.files(app.gems) + app.files
17
+ end
18
+ end
19
+ end
20
+
21
+ alias setup_without_motion_rubygems setup
22
+ alias setup setup_with_motion_rubygems
23
+ end
24
+
25
+ class MotionRubyGems
26
+ # Get a list of files that are required for the given gems.
27
+ #
28
+ # This includes a few meta-files to ensure that gems have a better
29
+ # chance of working.
30
+ def self.files(gems)
31
+ gem_files = []
32
+ gem_files << MotionRubyGems.version_file
33
+ gem_files << File.expand_path("../remove_require.rb", __FILE__)
34
+
35
+ gems.each do |gem|
36
+ gem_files += MotionRubyGems.files_for(gem)
37
+ end
38
+
39
+ gem_files << File.expand_path("../restore_require.rb", __FILE__)
40
+ end
41
+
42
+ # Get the files required by a given gem.
43
+ #
44
+ # At the moment this runs the gem with an overridden 'require'; it would be
45
+ # nice to add support for a `<gemname>.motion.rb` that can be used instead.
46
+ def self.files_for(gem)
47
+ require version_file
48
+ before = $".dup
49
+ require gem
50
+ files = $" - before
51
+
52
+ if (non_ruby = files - files.grep(/\.rb$/)) != []
53
+ raise "gem: #{gem} is not pure ruby: #{non_ruby.inspect}"
54
+ end
55
+
56
+ files
57
+ end
58
+
59
+ # This is a file that sets the RUBYMOTION_VERSION constant so that gems
60
+ # can alter their behaviour for Ruby Motion if necessary.
61
+ def self.version_file
62
+ File.expand_path("~/.motion-rubygems.version.rb").tap do |file|
63
+ File.open(file, 'w') do |f|
64
+ f.puts "RUBYMOTION_VERSION = #{Motion::Version.inspect}"
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+
@@ -0,0 +1,6 @@
1
+ # We want require to be a no-op when running gem code as that is full of
2
+ # requires. Luckily RubyMotion will take care of requiring everything for us!
3
+ module Kernel
4
+ alias require_without_motion_rubygems require
5
+ def require(*); end
6
+ end
@@ -0,0 +1,6 @@
1
+ # Now that all the rubygems are loaded, re-instate the version of require that
2
+ # raises an exception to the user.
3
+ module Kernel
4
+ alias require require_without_motion_rubygems
5
+ undef require_without_motion_rubygems
6
+ end
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "motion-rubygems"
3
+ s.version = "0.1.pre"
4
+ s.platform = Gem::Platform::RUBY
5
+ s.author = "Conrad Irwin"
6
+ s.email = "conrad.irwin@gmail.com"
7
+ s.homepage = "http://github.com/ConradIrwin/motion-rubygems"
8
+ s.summary = "Provides primitive support for requiring some rubygems into RubyMotion"
9
+ s.description = "Not all (or even many) gems will work out of the box on RubyMotion. However some do, so it'd be nice to be able to use them."
10
+ s.files = `git ls-files`.lines.map(&:strip)
11
+ s.require_path = "lib"
12
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: motion-rubygems
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.pre
5
+ prerelease: 4
6
+ platform: ruby
7
+ authors:
8
+ - Conrad Irwin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-24 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Not all (or even many) gems will work out of the box on RubyMotion. However
15
+ some do, so it'd be nice to be able to use them.
16
+ email: conrad.irwin@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - README.md
22
+ - lib/motion-rubygems.rb
23
+ - lib/remove_require.rb
24
+ - lib/restore_require.rb
25
+ - motion-rubygems.gemspec
26
+ homepage: http://github.com/ConradIrwin/motion-rubygems
27
+ licenses: []
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>'
42
+ - !ruby/object:Gem::Version
43
+ version: 1.3.1
44
+ requirements: []
45
+ rubyforge_project:
46
+ rubygems_version: 1.8.19
47
+ signing_key:
48
+ specification_version: 3
49
+ summary: Provides primitive support for requiring some rubygems into RubyMotion
50
+ test_files: []