bootsnap 1.10.3 → 1.18.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/bootsnap.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative("bootsnap/version")
4
- require_relative("bootsnap/bundler")
5
- require_relative("bootsnap/load_path_cache")
6
- require_relative("bootsnap/compile_cache")
3
+ require_relative "bootsnap/version"
4
+ require_relative "bootsnap/bundler"
5
+ require_relative "bootsnap/load_path_cache"
6
+ require_relative "bootsnap/compile_cache"
7
7
 
8
8
  module Bootsnap
9
9
  InvalidConfiguration = Class.new(StandardError)
@@ -11,6 +11,16 @@ module Bootsnap
11
11
  class << self
12
12
  attr_reader :logger
13
13
 
14
+ def log_stats!
15
+ stats = {hit: 0, revalidated: 0, miss: 0, stale: 0}
16
+ self.instrumentation = ->(event, _path) { stats[event] += 1 }
17
+ Kernel.at_exit do
18
+ stats.each do |event, count|
19
+ $stderr.puts "bootsnap #{event}: #{count}"
20
+ end
21
+ end
22
+ end
23
+
14
24
  def log!
15
25
  self.logger = $stderr.method(:puts)
16
26
  end
@@ -18,9 +28,9 @@ module Bootsnap
18
28
  def logger=(logger)
19
29
  @logger = logger
20
30
  self.instrumentation = if logger.respond_to?(:debug)
21
- ->(event, path) { @logger.debug("[Bootsnap] #{event} #{path}") }
31
+ ->(event, path) { @logger.debug("[Bootsnap] #{event} #{path}") unless event == :hit }
22
32
  else
23
- ->(event, path) { @logger.call("[Bootsnap] #{event} #{path}") }
33
+ ->(event, path) { @logger.call("[Bootsnap] #{event} #{path}") unless event == :hit }
24
34
  end
25
35
  end
26
36
 
@@ -39,55 +49,41 @@ module Bootsnap
39
49
  cache_dir:,
40
50
  development_mode: true,
41
51
  load_path_cache: true,
42
- autoload_paths_cache: nil,
43
- disable_trace: nil,
52
+ ignore_directories: nil,
53
+ readonly: false,
54
+ revalidation: false,
44
55
  compile_cache_iseq: true,
45
56
  compile_cache_yaml: true,
46
57
  compile_cache_json: true
47
58
  )
48
- unless autoload_paths_cache.nil?
49
- warn "[DEPRECATED] Bootsnap's `autoload_paths_cache:` option is deprecated and will be removed. " \
50
- "If you use Zeitwerk this option is useless, and if you are still using the classic autoloader " \
51
- "upgrading is recommended."
52
- end
53
-
54
- unless disable_trace.nil?
55
- warn "[DEPRECATED] Bootsnap's `disable_trace:` option is deprecated and will be removed. " \
56
- "If you use Ruby 2.5 or newer this option is useless, if not upgrading is recommended."
57
- end
58
-
59
- if compile_cache_iseq && !iseq_cache_supported?
60
- warn "Ruby 2.5 has a bug that break code tracing when code is loaded from cache. It is recommened " \
61
- "to turn `compile_cache_iseq` off on Ruby 2.5"
62
- end
63
-
64
59
  if load_path_cache
65
60
  Bootsnap::LoadPathCache.setup(
66
- cache_path: cache_dir + "/bootsnap/load-path-cache",
61
+ cache_path: "#{cache_dir}/bootsnap/load-path-cache",
67
62
  development_mode: development_mode,
63
+ ignore_directories: ignore_directories,
64
+ readonly: readonly,
68
65
  )
69
66
  end
70
67
 
71
68
  Bootsnap::CompileCache.setup(
72
- cache_dir: cache_dir + "/bootsnap/compile-cache",
69
+ cache_dir: "#{cache_dir}/bootsnap/compile-cache",
73
70
  iseq: compile_cache_iseq,
74
71
  yaml: compile_cache_yaml,
75
72
  json: compile_cache_json,
73
+ readonly: readonly,
74
+ revalidation: revalidation,
76
75
  )
77
76
  end
78
77
 
79
- def iseq_cache_supported?
80
- return @iseq_cache_supported if defined? @iseq_cache_supported
81
-
82
- ruby_version = Gem::Version.new(RUBY_VERSION)
83
- @iseq_cache_supported = ruby_version < Gem::Version.new("2.5.0") || ruby_version >= Gem::Version.new("2.6.0")
78
+ def unload_cache!
79
+ LoadPathCache.unload!
84
80
  end
85
81
 
86
82
  def default_setup
87
83
  env = ENV["RAILS_ENV"] || ENV["RACK_ENV"] || ENV["ENV"]
88
84
  development_mode = ["", nil, "development"].include?(env)
89
85
 
90
- unless ENV["DISABLE_BOOTSNAP"]
86
+ if enabled?("BOOTSNAP")
91
87
  cache_dir = ENV["BOOTSNAP_CACHE_DIR"]
92
88
  unless cache_dir
93
89
  config_dir_frame = caller.detect do |line|
@@ -109,17 +105,26 @@ module Bootsnap
109
105
  cache_dir = File.join(app_root, "tmp", "cache")
110
106
  end
111
107
 
108
+ ignore_directories = if ENV.key?("BOOTSNAP_IGNORE_DIRECTORIES")
109
+ ENV["BOOTSNAP_IGNORE_DIRECTORIES"].split(",")
110
+ end
111
+
112
112
  setup(
113
113
  cache_dir: cache_dir,
114
114
  development_mode: development_mode,
115
- load_path_cache: !ENV["DISABLE_BOOTSNAP_LOAD_PATH_CACHE"],
116
- compile_cache_iseq: !ENV["DISABLE_BOOTSNAP_COMPILE_CACHE"] && iseq_cache_supported?,
117
- compile_cache_yaml: !ENV["DISABLE_BOOTSNAP_COMPILE_CACHE"],
118
- compile_cache_json: !ENV["DISABLE_BOOTSNAP_COMPILE_CACHE"],
115
+ load_path_cache: enabled?("BOOTSNAP_LOAD_PATH_CACHE"),
116
+ compile_cache_iseq: enabled?("BOOTSNAP_COMPILE_CACHE"),
117
+ compile_cache_yaml: enabled?("BOOTSNAP_COMPILE_CACHE"),
118
+ compile_cache_json: enabled?("BOOTSNAP_COMPILE_CACHE"),
119
+ readonly: bool_env("BOOTSNAP_READONLY"),
120
+ revalidation: bool_env("BOOTSNAP_REVALIDATE"),
121
+ ignore_directories: ignore_directories,
119
122
  )
120
123
 
121
124
  if ENV["BOOTSNAP_LOG"]
122
125
  log!
126
+ elsif ENV["BOOTSNAP_STATS"]
127
+ log_stats!
123
128
  end
124
129
  end
125
130
  end
@@ -133,5 +138,27 @@ module Bootsnap
133
138
  path.start_with?("/")
134
139
  end
135
140
  end
141
+
142
+ # This is a semi-accurate ruby implementation of the native `rb_get_path(VALUE)` function.
143
+ # The native version is very intricate and may behave differently on windows etc.
144
+ # But we only use it for non-MRI platform.
145
+ def rb_get_path(fname)
146
+ path_path = fname.respond_to?(:to_path) ? fname.to_path : fname
147
+ String.try_convert(path_path) || raise(TypeError, "no implicit conversion of #{path_path.class} into String")
148
+ end
149
+
150
+ # Allow the C extension to redefine `rb_get_path` without warning.
151
+ alias_method :rb_get_path, :rb_get_path # rubocop:disable Lint/DuplicateMethods
152
+
153
+ private
154
+
155
+ def enabled?(key)
156
+ !ENV["DISABLE_#{key}"]
157
+ end
158
+
159
+ def bool_env(key, default: false)
160
+ value = ENV.fetch(key) { default }
161
+ !["0", "false", false].include?(value)
162
+ end
136
163
  end
137
164
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootsnap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.3
4
+ version: 1.18.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2022-02-02 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: msgpack
@@ -57,7 +56,6 @@ files:
57
56
  - lib/bootsnap/load_path_cache/loaded_features_index.rb
58
57
  - lib/bootsnap/load_path_cache/path.rb
59
58
  - lib/bootsnap/load_path_cache/path_scanner.rb
60
- - lib/bootsnap/load_path_cache/realpath_cache.rb
61
59
  - lib/bootsnap/load_path_cache/store.rb
62
60
  - lib/bootsnap/setup.rb
63
61
  - lib/bootsnap/version.rb
@@ -69,7 +67,6 @@ metadata:
69
67
  changelog_uri: https://github.com/Shopify/bootsnap/blob/main/CHANGELOG.md
70
68
  source_code_uri: https://github.com/Shopify/bootsnap
71
69
  allowed_push_host: https://rubygems.org
72
- post_install_message:
73
70
  rdoc_options: []
74
71
  require_paths:
75
72
  - lib
@@ -77,15 +74,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
74
  requirements:
78
75
  - - ">="
79
76
  - !ruby/object:Gem::Version
80
- version: 2.3.0
77
+ version: 2.6.0
81
78
  required_rubygems_version: !ruby/object:Gem::Requirement
82
79
  requirements:
83
80
  - - ">="
84
81
  - !ruby/object:Gem::Version
85
82
  version: '0'
86
83
  requirements: []
87
- rubygems_version: 3.2.20
88
- signing_key:
84
+ rubygems_version: 3.6.8
89
85
  specification_version: 4
90
86
  summary: Boot large ruby/rails apps faster
91
87
  test_files: []
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bootsnap
4
- module LoadPathCache
5
- class RealpathCache
6
- def initialize
7
- @cache = Hash.new { |h, k| h[k] = realpath(*k) }
8
- end
9
-
10
- def call(*key)
11
- @cache[key]
12
- end
13
-
14
- private
15
-
16
- def realpath(caller_location, path)
17
- base = File.dirname(caller_location)
18
- abspath = File.expand_path(path, base).freeze
19
- find_file(abspath)
20
- end
21
-
22
- def find_file(name)
23
- return File.realpath(name).freeze if File.exist?(name)
24
-
25
- CACHED_EXTENSIONS.each do |ext|
26
- filename = "#{name}#{ext}"
27
- return File.realpath(filename).freeze if File.exist?(filename)
28
- end
29
- name
30
- end
31
- end
32
- end
33
- end