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 CHANGED
@@ -1,39 +1,45 @@
1
1
  = rubygems-compile
2
2
 
3
- A post-install hook for `macgem` to automatically compile rubygems
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 you should get a bunch of output about files being compiled.
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
- == TODO
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
- In the future, there are a few different ways this plugin operate:
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
- * A gemspec property
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
- I'm not sure which is best, and maybe all of them will get implemented.
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
- * Some gems specifically require a file with the .rb extension, defeating the purpose of having a compiled version of the gem
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
- == Copyright
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
- Copyright (c) 2011 Mark Rada. See LICENSE.txt for
38
- further details.
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
@@ -0,0 +1,11 @@
1
+ unless Gem.suffixes.include? '.rbo'
2
+ module Gem
3
+ class << self
4
+ # To get around how rubygems-1.4.2 set's suffixes
5
+ alias_method :rubygems_compile_suffixes, :suffixes
6
+ def suffixes
7
+ ['.rbo'] + rubygems_compile_suffixes
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,16 +1,3 @@
1
- Gem.post_install do |gem|
2
-
3
- spec = gem.spec
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.3
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-02-19 00:00:00 -05:00
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: rake
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.8.7
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.8.7
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
- or you will end up compiling your gems multiple times.
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