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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41adbda1e1b89000183500297f553297069a38bf
4
- data.tar.gz: 2037d45bda86a9e59d2a01375342bd2f13c32643
3
+ metadata.gz: 4a802839bd0e4261a2dd82d40a707494ba223eef
4
+ data.tar.gz: 923dc5b3171c51ed69f92585fe532649c0bbd4df
5
5
  SHA512:
6
- metadata.gz: cecb536938e03c599314815ccce2a02237d2ee7c236ddd65eaea3be223a398e0f56378179664bdaea81c604c1c412b1c65d8c1933de8e781a7d413023926481d
7
- data.tar.gz: 4e89dc8c64eca43d8306d15b40b1acec176e7c132c726b925baa05fd9c1f183ebbac928af2f720a7dd43724003fddedd4cef20a629a40d451f75a7f97ccdb7f8
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
@@ -1,3 +1,3 @@
1
1
  module IseqRailsTools
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -1,45 +1,37 @@
1
- require 'digest/sha1'
2
- require 'fileutils'
3
- require 'iseq_rails_tools/compiler'
4
-
5
- module IseqRailsTools
6
- class NullCompiler
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
- class << self
16
- attr_accessor :compiler
8
+ module IseqRailsTools
9
+ DIRECTORY_NAME = '.iseq'
17
10
 
18
- def clear_compiled_iseq_files
19
- compiler.clear_compiled_iseq_files
20
- end
11
+ class << self
12
+ attr_accessor :iseq_dir
21
13
 
22
- def compile_all
23
- compiler.compile_all
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
- self.compiler = NullCompiler.new
28
- end
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
- # Only actually hook into Rails when the environment isn't test so that tools
31
- # like simplecov will continue to function as expected. Also people do weird
32
- # stuff in test mode, so who knows.
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
- if ::IseqRailsTools.compiler.watching?(filepath)
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
- IseqRailsTools.compile_all
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.clear_compiled_iseq_files
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.2
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-26 00:00:00.000000000 Z
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