iseq_rails_tools 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +36 -0
- data/Rakefile +34 -0
- data/lib/iseq_rails_tools.rb +40 -0
- data/lib/iseq_rails_tools/compiler.rb +87 -0
- data/lib/iseq_rails_tools/railtie.rb +35 -0
- data/lib/iseq_rails_tools/version.rb +3 -0
- data/lib/tasks/iseq_rails_tools_tasks.rake +11 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0b5e048c97ff3fdbd635135e589ac488d70bc0c4
|
4
|
+
data.tar.gz: 2a614cd2aa085f5a9638f2157b683dcf522a2c21
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6cdf29659c15bdde45f5ccb455cf15fedfa17440929a6befc68d16849a3c89e43a1ec70849b0d150aaa1c000b8ab3ae251ce98d8ac17fcdadb4b42930f6e4509
|
7
|
+
data.tar.gz: 3707519c3391f1553d918295451ce636dcaa2a43be8c9305fb9eefcea211a0cff9ce964841f91c63bd1c1d47d6b5c818090afbdf964f171568aefbd7293dfd1c
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 Kevin Deisz
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# IseqRailsTools
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/kddeisz/iseq-rails-tools.svg?branch=master)](https://travis-ci.org/kddeisz/iseq-rails-tools)
|
4
|
+
|
5
|
+
Since Ruby 2.3, we've had the ability to dump out compiled Ruby bytecode to files to alleviate that process when ruby files are required. This can significantly boost boot times, especially when running with larger Ruby projects.
|
6
|
+
|
7
|
+
This gem hooks into ActiveSupport's autoloading in development mode to bring AOT compiling to Rails. This can improve both the console and server boot times.
|
8
|
+
|
9
|
+
When deploying to production, you can take advantage of the quicker boot times by adding the `iseq:all` rake task to your deploy script.
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
1. Add `iseq_rails_tools` to your `Gemfile`.
|
14
|
+
2. Run `bundle install` to download the gem.
|
15
|
+
3. Add `.iseq/` to your `.gitignore`.
|
16
|
+
|
17
|
+
Then when running the console or the server, the compiled files will start to be generated in a new `.iseq` directory in the root of the repository.
|
18
|
+
|
19
|
+
## Tasks
|
20
|
+
|
21
|
+
`IseqRailsTools` adds a couple `Rake` tasks to your Rails project:
|
22
|
+
|
23
|
+
1. `iseq:all` - Compile iseq files for all files under autoloaded paths
|
24
|
+
2. `iseq:clear` - Clear out all compiled iseq files
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/kddeisz/iseq-rails-tools.
|
29
|
+
|
30
|
+
## License
|
31
|
+
|
32
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
33
|
+
|
34
|
+
## Credit
|
35
|
+
|
36
|
+
A lot of the inspiration (as well as some of the code) for this gem came from Koichi Sasada's great work on the [yomikomu](https://github.com/ko1/yomikomu) gem.
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'IseqRailsTools'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'lib'
|
28
|
+
t.libs << 'test'
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
task default: :test
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
require 'iseq_rails_tools/compiler'
|
5
|
+
require 'iseq_rails_tools/railtie'
|
6
|
+
|
7
|
+
module IseqRailsTools
|
8
|
+
class NullCompiler
|
9
|
+
def clear_compiled_iseq_files
|
10
|
+
end
|
11
|
+
|
12
|
+
def watching?(filepath)
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
attr_accessor :compiler
|
19
|
+
|
20
|
+
def clear_compiled_iseq_files
|
21
|
+
compiler.clear_compiled_iseq_files
|
22
|
+
end
|
23
|
+
|
24
|
+
def compile_all
|
25
|
+
compiler.compile_all
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
self.compiler = NullCompiler.new
|
30
|
+
end
|
31
|
+
|
32
|
+
RubyVM::InstructionSequence.singleton_class.prepend(Module.new do
|
33
|
+
def load_iseq(filepath)
|
34
|
+
if ::IseqRailsTools.compiler.watching?(filepath)
|
35
|
+
::IseqRailsTools.compiler.load_iseq(filepath)
|
36
|
+
elsif method(:load_iseq).super_method
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end)
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module IseqRailsTools
|
2
|
+
class Compiler
|
3
|
+
DIRECTORY_NAME = '.iseq'
|
4
|
+
|
5
|
+
attr_reader :application, :directory
|
6
|
+
|
7
|
+
def initialize(application)
|
8
|
+
@application = application
|
9
|
+
@directory = application.root.join(DIRECTORY_NAME).to_s
|
10
|
+
FileUtils.mkdir_p(directory) unless File.directory?(directory)
|
11
|
+
end
|
12
|
+
|
13
|
+
def clear_compiled_iseq_files
|
14
|
+
Dir.glob(File.join(directory, '**/*.yarb')) { |path| FileUtils.rm(path) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def compile_all
|
18
|
+
globs.each do |glob|
|
19
|
+
Dir.glob(glob).each do |filepath|
|
20
|
+
iseq_key = iseq_key_name(filepath)
|
21
|
+
compile_and_store_iseq(filepath, iseq_key)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def iseq_key_name(filepath)
|
27
|
+
path = filepath.gsub("#{application.root.to_s}/", '')
|
28
|
+
.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }
|
29
|
+
File.join(directory, "#{path}.yarb")
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_iseq(filepath)
|
33
|
+
iseq_key = iseq_key_name(filepath)
|
34
|
+
|
35
|
+
if compiled_iseq_exist?(iseq_key) && compiled_iseq_is_younger?(filepath, iseq_key)
|
36
|
+
binary = File.binread(iseq_key)
|
37
|
+
RubyVM::InstructionSequence.load_from_binary(binary)
|
38
|
+
else
|
39
|
+
compile_and_store_iseq(filepath, iseq_key)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def recompile_modified
|
44
|
+
globs.each do |glob|
|
45
|
+
Dir.glob(glob).each do |filepath|
|
46
|
+
iseq_key = iseq_key_name(filepath)
|
47
|
+
|
48
|
+
if !compiled_iseq_exist?(iseq_key) || !compiled_iseq_is_younger?(filepath, iseq_key)
|
49
|
+
compile_and_store_iseq(filepath, iseq_key)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def watching?(filepath)
|
56
|
+
globs.any? { |glob| Dir.glob(glob).include?(filepath) }
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def compile_and_store_iseq(filepath, iseq_key)
|
62
|
+
Rails.logger.debug("[IseqRailsTools] Compiling #{filepath}")
|
63
|
+
iseq = RubyVM::InstructionSequence.compile_file(filepath)
|
64
|
+
binary = iseq.to_binary("SHA-1:#{::Digest::SHA1.file(filepath).digest}")
|
65
|
+
File.binwrite(iseq_key, binary)
|
66
|
+
iseq
|
67
|
+
rescue SyntaxError, RuntimeError => e
|
68
|
+
puts "#{e}: #{filepath}"
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
def compiled_iseq_exist?(iseq_key)
|
73
|
+
File.exist?(iseq_key)
|
74
|
+
end
|
75
|
+
|
76
|
+
def compiled_iseq_is_younger?(filepath, iseq_key)
|
77
|
+
File.mtime(iseq_key) >= File.mtime(filepath)
|
78
|
+
end
|
79
|
+
|
80
|
+
def globs
|
81
|
+
@globs ||=
|
82
|
+
application.config.iseq_compile_paths.map do |directory|
|
83
|
+
File.join(directory, '**/*.rb')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module IseqRailsTools
|
2
|
+
class Railtie < ::Rails::Railtie
|
3
|
+
config.iseq_compile_paths = []
|
4
|
+
|
5
|
+
initializer 'iseq_rails_tools.initialize' do |app|
|
6
|
+
IseqRailsTools.compiler = Compiler.new(app)
|
7
|
+
|
8
|
+
# Yeah, sorry about this. This was the easiest way to get all access to
|
9
|
+
# all of the reloadable paths.
|
10
|
+
app.config.iseq_compile_paths = app.send(:_all_autoload_paths)
|
11
|
+
|
12
|
+
files =
|
13
|
+
app.config.iseq_compile_paths.flat_map do |path|
|
14
|
+
Dir.glob(File.join(path, '**/*.rb'))
|
15
|
+
end
|
16
|
+
|
17
|
+
directories =
|
18
|
+
app.config.iseq_compile_paths.map { |path| [path, 'rb'] }.to_h
|
19
|
+
|
20
|
+
reloader =
|
21
|
+
app.config.file_watcher.new(files, directories) do
|
22
|
+
Rails.logger.debug('[IseqRailsTools] Compiling files')
|
23
|
+
IseqRailsTools.compiler.recompile_modified
|
24
|
+
end
|
25
|
+
|
26
|
+
app.reloaders.unshift(reloader)
|
27
|
+
reloader.execute
|
28
|
+
end
|
29
|
+
|
30
|
+
rake_tasks do
|
31
|
+
rake_paths = File.expand_path(File.join('..', 'tasks', '*.rake'), __dir__)
|
32
|
+
Dir[rake_paths].each { |filepath| load filepath }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
namespace :iseq do
|
2
|
+
desc 'Compile iseq files for all files under autoloaded paths'
|
3
|
+
task all: :environment do
|
4
|
+
IseqRailsTools.compile_all
|
5
|
+
end
|
6
|
+
|
7
|
+
desc 'Clear out all compiled iseq files'
|
8
|
+
task clear: :environment do
|
9
|
+
IseqRailsTools.clear_compiled_iseq_files
|
10
|
+
end
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: iseq_rails_tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin Deisz
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.0.0
|
27
|
+
description: |2
|
28
|
+
Allows you to take advantage of ruby's AOT bytecode generation
|
29
|
+
within a Rails project.
|
30
|
+
email:
|
31
|
+
- kevin.deisz@gmail.com
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- MIT-LICENSE
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- lib/iseq_rails_tools.rb
|
40
|
+
- lib/iseq_rails_tools/compiler.rb
|
41
|
+
- lib/iseq_rails_tools/railtie.rb
|
42
|
+
- lib/iseq_rails_tools/version.rb
|
43
|
+
- lib/tasks/iseq_rails_tools_tasks.rake
|
44
|
+
homepage: https://github.com/kddeisz/iseq-rails-tools
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 2.3.0
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 2.6.11
|
65
|
+
signing_key:
|
66
|
+
specification_version: 4
|
67
|
+
summary: Use AOT compilation within Rails
|
68
|
+
test_files: []
|