rubygems-compile 0.0.3 → 0.2.0
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.
- 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
|