Class: Sorbet::Private::RequireEverything
- Inherits:
-
Object
- Object
- Sorbet::Private::RequireEverything
- Defined in:
- lib/require_everything.rb
Class Method Summary collapse
- .excluded_rails_files ⇒ Object
- .load_bundler ⇒ Object
- .load_rails ⇒ Object
- .my_require(abs_path, numerator, denominator) ⇒ Object
- .patch_kernel ⇒ Object
- .rails? ⇒ Boolean
- .rails_load_paths ⇒ Object
- .rb_file_paths ⇒ Object
- .require_all_files ⇒ Object
-
.require_everything ⇒ Object
Goes through the most common ways to require all your userland code.
Class Method Details
.excluded_rails_files ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/require_everything.rb', line 144 def self.excluded_rails_files excluded_paths = Set.new # Exclude files that have already been loaded by rails self.rails_load_paths.each do |path| excluded_paths += Dir.glob("#{path}/**/*.rb") end # Exclude initializers, as they have already been run by rails and # can contain side-effects like monkey-patching that should # only be run once. excluded_paths += Dir.glob("#{Dir.pwd}/config/initializers/**/*.rb") end |
.load_bundler ⇒ Object
32 33 34 35 36 37 38 39 40 |
# File 'lib/require_everything.rb', line 32 def self.load_bundler return unless File.exist?('Gemfile') begin require 'bundler' rescue LoadError return end Sorbet::Private::GemLoader.require_all_gems end |
.load_rails ⇒ Object
23 24 25 26 27 28 29 30 |
# File 'lib/require_everything.rb', line 23 def self.load_rails return unless rails? require './config/application' rails = Object.const_get(:Rails) rails.application.require_environment! rails.application.eager_load! true end |
.my_require(abs_path, numerator, denominator) ⇒ Object
85 86 87 88 89 |
# File 'lib/require_everything.rb', line 85 def self.my_require(abs_path, numerator, denominator) rel_path = Pathname.new(abs_path).relative_path_from(Pathname.new(Dir.pwd)).to_s Sorbet::Private::Status.say("[#{numerator}/#{denominator}] require_relative './#{rel_path}'") require_relative abs_path end |
.patch_kernel ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/require_everything.rb', line 91 def self.patch_kernel Kernel.send(:define_method, :exit) do |*| puts 'Kernel#exit was called while requiring ruby source files' raise ExitCalledError.new end Kernel.send(:define_method, :at_exit) do |&block| if File.split($0).last == 'rake' # Let `rake test` work super return proc {} end # puts "Ignoring at_exit: #{block}" proc {} end end |
.rails? ⇒ Boolean
172 173 174 175 176 177 178 179 180 |
# File 'lib/require_everything.rb', line 172 def self.rails? return false unless File.exist?('config/application.rb') begin require 'rails' rescue LoadError return false end true end |
.rails_load_paths ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/require_everything.rb', line 158 def self.rails_load_paths rails = Object.const_get(:Rails) # As per changes made to change the arity of this method: # https://github.com/rails/rails/commit/b6e17b6a4b67ccc9fac5fe16741c3db720f00959 # This sets the `add_autoload_paths_to_load_path` parameter to `true` which will # provide parity with older versions of Rails prior to the mentioned commit. if Gem::Version.new(rails.version) >= Gem::Version.new('6.0.0.rc2') rails.application.send(:_all_load_paths, true) else rails.application.send(:_all_load_paths) end end |
.rb_file_paths ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/require_everything.rb', line 110 def self.rb_file_paths srb = File.realpath("#{__dir__}/../bin/srb") output = IO.popen([ srb, "tc", "-p", "file-table-json", "--stop-after=parser", "--silence-dev-message", "--no-error-count", "-e", "''", ]) {|io| io.read} # This returns a hash with structure: # { files: # [ # { # "strict": ["Ignore"|"False"|"True"|"Strict"|"Strong"|"Stdlib"], # "path": "./path/to/file", # ... # } # ... # ] # } parsed = JSON.parse(output) parsed .fetch('files', []) .reject{|file| ["Ignore", "Stdlib"].include?(file["strict"])} .map{|file| file["path"]} .select{|path| File.file?(path)} # Some files have https:// paths. We ignore those here. .select{|path| /.rb$/.match(path)} .map{|path| File.(path)} # Requires absolute path end |
.require_all_files ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/require_everything.rb', line 42 def self.require_all_files excluded_paths = Set.new excluded_paths += excluded_rails_files if rails? abs_paths = rb_file_paths errors = [] abs_paths.each_with_index do |abs_path, i| # Executable files are likely not meant to be required. # Some things we're trying to prevent against: # - misbehaving require-time side effects (removing files, reading from stdin, etc.) # - extra long runtime (making network requests, running a benchmark) # While this isn't a perfect heuristic for these things, it's pretty good. next if File.executable?(abs_path) next if excluded_paths.include?(abs_path) # Skip db/schema.rb, as requiring it can wipe the database. This is left # out of exclude_rails_files, as it is possible to use the packages that # generate it without using the whole rails ecosystem. next if /db\/schema.rb$/.match(abs_path) # Skip **/extconf.rb, as running it will emit build configuration artifacts next if /\/extconf.rb$/.match(abs_path) begin my_require(abs_path, i+1, abs_paths.size) rescue LoadError, NoMethodError, SyntaxError next rescue errors << abs_path next end end # one more chance for order dependent things errors.each_with_index do |abs_path, i| begin my_require(abs_path, i+1, errors.size) rescue end end Sorbet::Private::Status.done end |
.require_everything ⇒ Object
Goes through the most common ways to require all your userland code
14 15 16 17 18 19 20 21 |
# File 'lib/require_everything.rb', line 14 def self.require_everything return if @already_ran @already_ran = true patch_kernel load_rails load_bundler # this comes second since some rails projects fail `Bundler.require' before rails is loaded require_all_files end |