iseq_rails_tools 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +0 -2
- data/lib/iseq_rails_tools/railtie.rb +0 -27
- data/lib/iseq_rails_tools/source_file.rb +51 -0
- data/lib/iseq_rails_tools/version.rb +1 -1
- data/lib/iseq_rails_tools.rb +25 -33
- data/lib/tasks/iseq_rails_tools_tasks.rake +2 -2
- metadata +3 -3
- data/lib/iseq_rails_tools/compiler.rb +0 -87
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a802839bd0e4261a2dd82d40a707494ba223eef
|
4
|
+
data.tar.gz: 923dc5b3171c51ed69f92585fe532649c0bbd4df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50a3674a4d4fde446ff856eba2a06326c380718194946a6a38c22d3ba7ea55ae7054d878a78b29b2ad75b74fca47a85d1458c51dc128fabe3aa18cecabb3d696
|
7
|
+
data.tar.gz: abe87ccfbfd509e806b90b33ead97e5e002ced034633631a693dd47d0be6334f711ab61c089ea613794a68300831107d7099cc97746492f92c3bf96f7b5c5807
|
data/README.md
CHANGED
@@ -5,8 +5,6 @@
|
|
5
5
|
|
6
6
|
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.
|
7
7
|
|
8
|
-
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.
|
9
|
-
|
10
8
|
When deploying to production, you can take advantage of the quicker boot times by adding the `iseq:all` rake task to your deploy script. A simple way to do this is to make `iseq:all` a prerequisite of `assets:precompile`, like so: `Rake::Task['assets:precompile'].enhance(['iseq:all'])`.
|
11
9
|
|
12
10
|
## Usage
|
@@ -1,32 +1,5 @@
|
|
1
1
|
module IseqRailsTools
|
2
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
3
|
rake_tasks do
|
31
4
|
rake_paths = File.expand_path(File.join('..', 'tasks', '*.rake'), __dir__)
|
32
5
|
Dir[rake_paths].each { |filepath| load filepath }
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module IseqRailsTools
|
4
|
+
class SourceFile
|
5
|
+
attr_reader :source_path, :iseq_path
|
6
|
+
|
7
|
+
def initialize(source_path, iseq_path)
|
8
|
+
@source_path = source_path
|
9
|
+
@iseq_path = iseq_path
|
10
|
+
end
|
11
|
+
|
12
|
+
def dump
|
13
|
+
# Lonely operator necessary here because Rails.logger might not be
|
14
|
+
# initialized yet
|
15
|
+
Rails.logger&.debug("[IseqRailsTools] Compiling #{source_path}")
|
16
|
+
|
17
|
+
iseq = RubyVM::InstructionSequence.compile_file(source_path)
|
18
|
+
digest = ::Digest::SHA1.file(source_path).digest
|
19
|
+
File.binwrite(iseq_path, iseq.to_binary("SHA-1:#{digest}"))
|
20
|
+
iseq
|
21
|
+
rescue SyntaxError, RuntimeError
|
22
|
+
Rails.logger.debug("[IseqRailsTools] Failed to compile #{source_path}")
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def load
|
27
|
+
if compiled? && !needs_recompile?
|
28
|
+
binary = File.binread(iseq_path)
|
29
|
+
RubyVM::InstructionSequence.load_from_binary(binary)
|
30
|
+
else
|
31
|
+
dump
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.load(source_path)
|
36
|
+
iseq_path = source_path.gsub(/[^A-Za-z0-9\._-]/) { |c| '%02x' % c.ord }
|
37
|
+
iseq_path = File.join(IseqRailsTools.iseq_dir, "#{iseq_path}.yarb")
|
38
|
+
new(source_path, iseq_path).load
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def compiled?
|
44
|
+
File.exist?(iseq_path)
|
45
|
+
end
|
46
|
+
|
47
|
+
def needs_recompile?
|
48
|
+
File.mtime(source_path) > File.mtime(iseq_path)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/iseq_rails_tools.rb
CHANGED
@@ -1,45 +1,37 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def clear_compiled_iseq_files
|
8
|
-
end
|
9
|
-
|
10
|
-
def watching?(filepath)
|
11
|
-
false
|
12
|
-
end
|
13
|
-
end
|
1
|
+
# Only actually hook into Rails when the environment isn't test so that tools
|
2
|
+
# like simplecov will continue to function as expected. Also people do weird
|
3
|
+
# stuff in test mode, so who knows.
|
4
|
+
if !Rails.env.test? || IseqRailsTools.respond_to?(:internal?)
|
5
|
+
require 'iseq_rails_tools/railtie'
|
6
|
+
require 'iseq_rails_tools/source_file'
|
14
7
|
|
15
|
-
|
16
|
-
|
8
|
+
module IseqRailsTools
|
9
|
+
DIRECTORY_NAME = '.iseq'
|
17
10
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
11
|
+
class << self
|
12
|
+
attr_accessor :iseq_dir
|
21
13
|
|
22
|
-
|
23
|
-
|
14
|
+
def clear
|
15
|
+
Dir.glob(File.join(iseq_dir, '**/*.yarb')) { |path| File.delete(path) }
|
16
|
+
end
|
24
17
|
end
|
25
|
-
end
|
26
18
|
|
27
|
-
|
28
|
-
|
19
|
+
root =
|
20
|
+
caller_locations.detect do |location|
|
21
|
+
path = location.absolute_path || location.path
|
22
|
+
if path != __FILE__ && path !~ %r{bundler[\w.-]*/lib/bundler}
|
23
|
+
break File.dirname(path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
root = File.dirname(root) until File.exist?("#{root}/config.ru")
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
unless Rails.env.test?
|
34
|
-
require 'iseq_rails_tools/railtie'
|
28
|
+
self.iseq_dir = File.join(root, DIRECTORY_NAME)
|
29
|
+
FileUtils.mkdir_p(iseq_dir) unless File.directory?(iseq_dir)
|
30
|
+
end
|
35
31
|
|
36
32
|
RubyVM::InstructionSequence.singleton_class.prepend(Module.new do
|
37
33
|
def load_iseq(filepath)
|
38
|
-
|
39
|
-
::IseqRailsTools.compiler.load_iseq(filepath)
|
40
|
-
elsif method(:load_iseq).super_method
|
41
|
-
super
|
42
|
-
end
|
34
|
+
::IseqRailsTools::SourceFile.load(filepath)
|
43
35
|
end
|
44
36
|
end)
|
45
37
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
namespace :iseq do
|
2
2
|
desc 'Compile iseq files for all files under autoloaded paths'
|
3
3
|
task all: :environment do
|
4
|
-
|
4
|
+
Rails.application.eager_load!
|
5
5
|
end
|
6
6
|
|
7
7
|
desc 'Clear out all compiled iseq files'
|
8
8
|
task clear: :environment do
|
9
|
-
IseqRailsTools.
|
9
|
+
IseqRailsTools.watcher.clear
|
10
10
|
end
|
11
11
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iseq_rails_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Deisz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -37,8 +37,8 @@ files:
|
|
37
37
|
- README.md
|
38
38
|
- Rakefile
|
39
39
|
- lib/iseq_rails_tools.rb
|
40
|
-
- lib/iseq_rails_tools/compiler.rb
|
41
40
|
- lib/iseq_rails_tools/railtie.rb
|
41
|
+
- lib/iseq_rails_tools/source_file.rb
|
42
42
|
- lib/iseq_rails_tools/version.rb
|
43
43
|
- lib/tasks/iseq_rails_tools_tasks.rake
|
44
44
|
homepage: https://github.com/kddeisz/iseq-rails-tools
|
@@ -1,87 +0,0 @@
|
|
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
|