rubygems-compile 0.0.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +28 -22
- data/Rakefile +41 -0
- data/lib/rubygems-compile/common_methods.rb +22 -0
- data/lib/rubygems-compile/compile.rb +70 -0
- data/lib/rubygems-compile/decompile.rb +52 -0
- data/lib/rubygems-compile/monkey_patches.rb +11 -0
- data/lib/rubygems_plugin.rb +3 -16
- data/test/helper.rb +16 -0
- data/test/test_find_files_to_compile.rb +44 -0
- data/test/test_get_specs_for_gems.rb +19 -0
- metadata +30 -8
data/README.rdoc
CHANGED
@@ -1,39 +1,45 @@
|
|
1
1
|
= rubygems-compile
|
2
2
|
|
3
|
-
A
|
4
|
-
when you install them.
|
3
|
+
A compile command for `macgem` to install and compile gems using the MacRuby compiler.
|
5
4
|
|
6
5
|
All you need to do is:
|
7
6
|
|
8
7
|
gem install rubygems-compile
|
9
8
|
|
10
|
-
And then you're off to the races! When you install gems
|
9
|
+
And then you're off to the races! When you install gems using `macgem compile` the gem will also be compiled.
|
11
10
|
|
12
|
-
==
|
13
|
-
|
14
|
-
Right now, all you need to do is install the gem and it will be used every time you install a new gem (or reinstall an existing gem).
|
11
|
+
== Description
|
15
12
|
|
16
|
-
|
13
|
+
`rubygems-compile` provides two additional commands for `macgem`. The first is `compile`; you can now say `macgem compile nokogiri` and the `nokogiri` gem will be installed and compiled. Then, whenever you use `nokogiri`, the compiled version of the gem files will be loaded instead of the uncompiled version of the gem files.
|
17
14
|
|
18
|
-
|
19
|
-
* spec.compile_for_macruby = true
|
20
|
-
* A gem command
|
21
|
-
* gem compile nokogiri
|
22
|
-
* gem compile --remove-original-files nokogiri
|
23
|
-
* I can't remove the original .rb files and leave *.rbo files because of how rubygems identifies gems (unless I modify gemspec files)
|
24
|
-
* A gem install option
|
25
|
-
* gem install --compile nokogiri
|
15
|
+
`macgem compile` is a superset of the `gem install` command, so you can still use all the options you would normally use. `macgem compile` has one extra option to delete all the original .rb files after the .rbo is generated; use this option with caution.
|
26
16
|
|
27
|
-
|
17
|
+
Some gems work perfectly when compiled, and some do not (for various reasons), so you should try a gem non-compiled first. If you dove head first into using compiled gems and you need to back-peddle, you will have to uninstall and then reinstall the gem (NOTE: a `macgem decompile` to remove the .rbo files and, if needed, reinstall the gem all in one step is included but only works for normal cases (no dependency decompiling, no custom install directories)).
|
28
18
|
|
29
19
|
== Caveats
|
30
20
|
|
31
|
-
* Large gems will take a long time to compile
|
32
|
-
* This has only been tested on a few gems, but should not break existing gems since we leave the original files around
|
33
|
-
*
|
21
|
+
* Large gems will take a long time to compile, but these are the gems that will benefit the most from being compiled
|
22
|
+
* This has only been tested on a few gems, but should not break existing gems since we leave the original files around by default
|
23
|
+
* As of MacRuby 0.9, you cannot get usable backtrace data for compiled ruby files
|
24
|
+
* This may be fixed for MacRuby 0.10
|
25
|
+
* The 1-to-1 correlation of .rb files to .rbo files can make gems quite a bit bigger on disk
|
34
26
|
|
35
|
-
==
|
27
|
+
== Known Reasons A Compiled Gem Will Not Work
|
28
|
+
|
29
|
+
* Using non-standard file suffixes (e.g. `mime-types` has a `.rb.data` file)
|
30
|
+
* This will be addressed in a later release
|
31
|
+
* Gems that explicitly require a file with the file suffix (e.g. `require 'nokogiri.rb'`)
|
32
|
+
* This should be addressable in a future release
|
36
33
|
|
37
|
-
|
38
|
-
|
34
|
+
== TODO
|
35
|
+
|
36
|
+
* A gem install option would be most natural instead of compile command
|
37
|
+
* gem install --compile nokogiri
|
38
|
+
* Code parsing to WARN about gems that will not work when compiled
|
39
|
+
* Compile multiple .rb files to a single .rbo binary (instead of an .rbo for each .rb)
|
40
|
+
* A naive implementation will not work for gems that are loaded modularly
|
41
|
+
* Files in bin/ usually don't include the file extension and are not compiled
|
42
|
+
|
43
|
+
== Copyright
|
39
44
|
|
45
|
+
Copyright (c) 2011 Mark Rada. See LICENSE.txt for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
require 'rake/testtask'
|
5
|
+
Rake::TestTask.new(:test) do |test|
|
6
|
+
test.libs << 'lib' << 'test'
|
7
|
+
test.pattern = 'test/**/test_*.rb'
|
8
|
+
test.verbose = true
|
9
|
+
end
|
10
|
+
|
11
|
+
task :default => :'gem:build'
|
12
|
+
|
13
|
+
namespace :macruby do
|
14
|
+
desc 'AOT compile'
|
15
|
+
task :compile do
|
16
|
+
FileList["lib/**/*.rb"].each do |source|
|
17
|
+
name = File.basename source
|
18
|
+
puts "#{name} => #{name}o"
|
19
|
+
`macrubyc --arch x86_64 -C '#{source}' -o '#{source}o'`
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'Clean MacRuby binaries'
|
24
|
+
task :clean do
|
25
|
+
FileList["lib/**/*.rbo"].each do |bin|
|
26
|
+
rm bin
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
namespace :gem do
|
32
|
+
desc 'Build the gem'
|
33
|
+
task :build do
|
34
|
+
puts `gem build -v rubygems-compile.gemspec`
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'Build the gem and install it'
|
38
|
+
task :install => :build do
|
39
|
+
puts `gem install #{Dir.glob('rubygems-compile*.gem').sort.reverse.first}`
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Gem
|
2
|
+
module Compile
|
3
|
+
module Methods
|
4
|
+
|
5
|
+
MACRUBYC = File.join(RbConfig::CONFIG['bindir'], 'macrubyc')
|
6
|
+
|
7
|
+
def get_specs_for_gems gem_names # :nodoc:
|
8
|
+
gem_names.flatten.map { |gem|
|
9
|
+
Gem.source_index.find_name gem
|
10
|
+
}.flatten.compact
|
11
|
+
end
|
12
|
+
|
13
|
+
def find_files_to_compile gem # :nodoc:
|
14
|
+
files = gem.files - gem.test_files - gem.extra_rdoc_files
|
15
|
+
files = files.reject do |file| file.match /^(?:test|spec)/ end
|
16
|
+
# this cuts out the .rb.data file in the mime-types gem
|
17
|
+
files.select do |file| file.match /\.rb$/ end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'rubygems/command'
|
4
|
+
require 'rubygems/commands/install_command'
|
5
|
+
require 'rubygems-compile/common_methods'
|
6
|
+
|
7
|
+
##
|
8
|
+
# Use the MacRuby compiler to compile gems at install time. This
|
9
|
+
# includes the option to remove the original *.rb files leaving
|
10
|
+
# only the compiled *.rbo files.
|
11
|
+
|
12
|
+
class Gem::Commands::CompileCommand < Gem::Commands::InstallCommand
|
13
|
+
include Gem::Compile::Methods
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
super # so that InstallCommand options are registered
|
17
|
+
@command = 'compile' # now we override certain attributes
|
18
|
+
@summary = 'Install and compile gems using the MacRuby compiler'
|
19
|
+
@program_name = 'gem compile'
|
20
|
+
|
21
|
+
defaults[:'remove-original-files'] = false
|
22
|
+
add_option( '-r', '--[no-]remove-original-files',
|
23
|
+
'Delete the original *.rb source files after compiling',
|
24
|
+
) do |value, options|
|
25
|
+
options[:'remove-original-files'] = value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def defaults_str # :nodoc:
|
30
|
+
super + "\n--no-remove-original-files"
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Lookup the gems and their listed files. It will only compile files
|
35
|
+
# that are located in the `require_path` for a gem.
|
36
|
+
|
37
|
+
def execute
|
38
|
+
|
39
|
+
verbose = Gem.configuration.verbose
|
40
|
+
slash = verbose.is_a?(Fixnum) ? '/' : ''
|
41
|
+
post_compile = Proc.new do |_,_| end
|
42
|
+
|
43
|
+
if options[:'remove-original-files']
|
44
|
+
post_compile = Proc.new do |file, full_path|
|
45
|
+
say "\tRemoving #{file}" if verbose.is_a? Fixnum
|
46
|
+
FileUtils.rm full_path
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
Gem.post_install do |gem|
|
51
|
+
spec = gem.spec
|
52
|
+
say "Compiling #{spec.name}-#{spec.version}#{slash}" if verbose
|
53
|
+
|
54
|
+
path = spec.full_gem_path
|
55
|
+
files = find_files_to_compile spec
|
56
|
+
|
57
|
+
files.each { |file|
|
58
|
+
say "\t#{file} => #{file}o" if verbose.is_a? Fixnum
|
59
|
+
full_path = path + '/' + file
|
60
|
+
`#{MACRUBYC} -C '#{full_path}' -o '#{full_path}o'`
|
61
|
+
post_compile.call file, full_path
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
super
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
Gem::CommandManager.instance.register_command :compile
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rubygems/command'
|
3
|
+
require 'rubygems/commands/install_command'
|
4
|
+
require 'rubygems-compile/common_methods'
|
5
|
+
|
6
|
+
##
|
7
|
+
# @todo need to look at dependencies too? use --include-dependencies option?
|
8
|
+
#
|
9
|
+
# Remove the compiled files for a gem. This is sometimes necessary for
|
10
|
+
# gems that do not work after being compiled.
|
11
|
+
|
12
|
+
class Gem::Commands::DecompileCommand < Gem::Commands::InstallCommand
|
13
|
+
include Gem::Compile::Methods
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
super
|
17
|
+
@command = 'decompile'
|
18
|
+
@summary = 'Remove compiled *.rbo files for gems, possibily reinstalling'
|
19
|
+
@program_name = 'gem decompilecompile'
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Try to only remove *.rbo files, but in the case that the original *.rb files
|
24
|
+
# are gone, we will also have to reinstall the gem.
|
25
|
+
|
26
|
+
def execute
|
27
|
+
|
28
|
+
verbose = Gem.configuration.verbose
|
29
|
+
slash = verbose.is_a?(Fixnum) ? '/' : ''
|
30
|
+
|
31
|
+
get_specs_for_gems(get_all_gem_names).each { |gem|
|
32
|
+
say "Decompiling #{gem.name}-#{gem.version}#{slash}" if verbose
|
33
|
+
|
34
|
+
path = gem.full_gem_path
|
35
|
+
files = find_files_to_compile gem
|
36
|
+
reinstall = false
|
37
|
+
|
38
|
+
files.each { |file|
|
39
|
+
say "\tRemoving #{file}o" if verbose.is_a? Fixnum
|
40
|
+
full_path = "#{path}/#{file}"
|
41
|
+
FileUtils.rm( full_path + 'o' )
|
42
|
+
reinstall = true unless File.exists? full_path
|
43
|
+
}
|
44
|
+
|
45
|
+
super if reinstall
|
46
|
+
}
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
Gem::CommandManager.instance.register_command :decompile
|
data/lib/rubygems_plugin.rb
CHANGED
@@ -1,16 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
dir = gem.gem_home + '/gems/' + spec.name + '-' + spec.version.version
|
5
|
-
|
6
|
-
files = spec.files - spec.test_files - spec.extra_rdoc_files
|
7
|
-
files = files.reject { |file| file.match /^(?:test|spec)/ }
|
8
|
-
|
9
|
-
files.each do |file|
|
10
|
-
next unless file.match /\.rb$/
|
11
|
-
puts "Compiling #{file} to #{file}o"
|
12
|
-
file = "#{dir}/#{file}"
|
13
|
-
`macrubyc -C '#{file}' -o '#{file}o'`
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
1
|
+
require 'rubygems-compile/monkey_patches'
|
2
|
+
require 'rubygems-compile/compile'
|
3
|
+
require 'rubygems-compile/decompile'
|
data/test/helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'rubygems/command_manager'
|
6
|
+
require 'rubygems_plugin'
|
7
|
+
|
8
|
+
gem 'minitest', '>= 2.0.2'
|
9
|
+
require 'minitest/pride'
|
10
|
+
require 'minitest/autorun'
|
11
|
+
|
12
|
+
class MiniTest::Unit::TestCase
|
13
|
+
def setup
|
14
|
+
@command = Gem::Commands::CompileCommand.new
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestFindFilesToCompile < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
super
|
7
|
+
@test_gem = MiniTest::Mock.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_strips_test_files
|
11
|
+
@test_gem.expect :files, [
|
12
|
+
'test/file1', 'test/file2', 'spec/file1', 'spec/file2', 'setup.rb'
|
13
|
+
]
|
14
|
+
@test_gem.expect :test_files, [ 'test/file1', 'spec/file1' ]
|
15
|
+
@test_gem.expect :extra_rdoc_files, []
|
16
|
+
|
17
|
+
assert_equal [ 'setup.rb' ], @command.find_files_to_compile(@test_gem)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_strips_non_ruby_source_files
|
21
|
+
@test_gem.expect :files, [
|
22
|
+
'README.rdoc', 'LICENSE.txt', 'Gemfile', 'setup.rb'
|
23
|
+
]
|
24
|
+
@test_gem.expect :test_files, []
|
25
|
+
@test_gem.expect :extra_rdoc_files, [
|
26
|
+
'README.rdoc', 'LICENSE.txt', 'Gemfile'
|
27
|
+
]
|
28
|
+
assert_equal [ 'setup.rb' ], @command.find_files_to_compile(@test_gem)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_returns_array_of_files
|
32
|
+
source_files = [
|
33
|
+
'lib/gem.rb', 'lib/gem/helper.rb', 'ext/help/extconf.rb', 'setup.rb'
|
34
|
+
]
|
35
|
+
@test_gem.expect :files, source_files
|
36
|
+
@test_gem.expect :test_files, []
|
37
|
+
@test_gem.expect :extra_rdoc_files, []
|
38
|
+
|
39
|
+
ret = @command.find_files_to_compile @test_gem
|
40
|
+
assert_instance_of Array, ret
|
41
|
+
assert_equal source_files, ret
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestGetSpecsForGems < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def test_doesnt_explode_with_bad_gem_names
|
6
|
+
assert_empty @command.get_specs_for_gems ['not_a_real_gem']
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_takes_an_array
|
10
|
+
assert @command.get_specs_for_gems ['minitest', 'not_a_real_gem']
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_returns_gemspecs
|
14
|
+
ret = @command.get_specs_for_gems ['minitest']
|
15
|
+
assert_instance_of Array, ret
|
16
|
+
assert_instance_of Gem::Specification, ret.first
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
metadata
CHANGED
@@ -2,32 +2,32 @@
|
|
2
2
|
name: rubygems-compile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0
|
5
|
+
version: 0.2.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Mark Rada
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-03-06 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: minitest
|
17
17
|
prerelease: false
|
18
18
|
requirement: !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - '>='
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.
|
23
|
+
version: 2.0.2
|
24
24
|
type: :development
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
none: false
|
27
27
|
requirements:
|
28
28
|
- - '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version: 0.
|
30
|
+
version: 2.0.2
|
31
31
|
description: 'A rubygems post-install hook to compile gems using the MacRuby compiler.
|
32
32
|
|
33
33
|
'
|
@@ -35,12 +35,21 @@ email: mrada@marketcircle.com
|
|
35
35
|
executables: []
|
36
36
|
extensions: []
|
37
37
|
extra_rdoc_files:
|
38
|
+
- Rakefile
|
38
39
|
- LICENSE.txt
|
39
40
|
- README.rdoc
|
40
41
|
files:
|
42
|
+
- lib/rubygems-compile/common_methods.rb
|
43
|
+
- lib/rubygems-compile/compile.rb
|
44
|
+
- lib/rubygems-compile/decompile.rb
|
45
|
+
- lib/rubygems-compile/monkey_patches.rb
|
41
46
|
- lib/rubygems_plugin.rb
|
47
|
+
- Rakefile
|
42
48
|
- LICENSE.txt
|
43
49
|
- README.rdoc
|
50
|
+
- test/test_find_files_to_compile.rb
|
51
|
+
- test/test_get_specs_for_gems.rb
|
52
|
+
- test/helper.rb
|
44
53
|
has_rdoc: true
|
45
54
|
homepage: http://github.com/ferrous26/rubygems-compile
|
46
55
|
licenses:
|
@@ -49,9 +58,19 @@ post_install_message: '
|
|
49
58
|
|
50
59
|
***********************************************************
|
51
60
|
|
52
|
-
Make sure to uninstall earlier versions of rubygems-compile
|
53
61
|
|
54
|
-
|
62
|
+
Please uninstall previous versions of this gem, or else
|
63
|
+
|
64
|
+
rubygems will try to load each version of the gem.
|
65
|
+
|
66
|
+
|
67
|
+
The functionality of this gem has changed since the 0.0.x
|
68
|
+
|
69
|
+
series. It now operates as its own command, see the README.
|
70
|
+
|
71
|
+
|
72
|
+
https://github.com/ferrous26/rubygems-compile
|
73
|
+
|
55
74
|
|
56
75
|
***********************************************************
|
57
76
|
|
@@ -78,4 +97,7 @@ rubygems_version: 1.4.2
|
|
78
97
|
signing_key:
|
79
98
|
specification_version: 3
|
80
99
|
summary: A rubygems post-install hook using the MacRuby compiler to compile gems
|
81
|
-
test_files:
|
100
|
+
test_files:
|
101
|
+
- test/test_find_files_to_compile.rb
|
102
|
+
- test/test_get_specs_for_gems.rb
|
103
|
+
- test/helper.rb
|