Skip to content

Commit 88b8cd4

Browse files
committed
Drop Ruby 2.3 support.
Ref: #402 Ref: https://bugs.ruby-lang.org/issues/10222 Ref: ruby/ruby@5754f15 Ref: ruby/ruby@b6d3927 Up to Ruby 2.3, `require` would resolve symlinks, but `require_relative` wouldn't: ```ruby require 'fileutils' FileUtils.mkdir_p("realpath") File.write("realpath/a.rb", "p :a_loaded") File.symlink("realpath", "symlink") rescue nil $LOAD_PATH.unshift(File.realpath(__dir__) + "/symlink") require "a.rb" # load symlink/a.rb in 2.3 and older, load realpath/a.rb on 2.4 and newer require_relative "realpath/a.rb" # noop on 2.4+ ``` This would easily cause double loading issue when `require` and `require_relative` were mixed, but was fixed in 2.4 (https://bugs.ruby-lang.org/issues/10222). The problem is that `Bootsnap` kinda negated this fix, because `realpath()` wouldn't be applied to absolute paths: ```ruby require 'fileutils' FileUtils.mkdir_p("realpath") File.write("realpath/a.rb", "p :a_loaded") File.symlink("realpath", "symlink") rescue nil $LOAD_PATH.unshift(File.realpath(__dir__) + "/symlink") require File.expand_path("symlink/a.rb") # load symlink/a.rb in 3.0 and older, load realpath/a.rb on 3.1 and newer require_relative "realpath/a.rb" # noop on 3.1+ ``` And for performance reasons, Bootsnap tried really hard not to call `realpath`, as it's a syscall, instead it used `expand_path`, which is entirely in use space and doesn't reach to the file system. So if you had a `symlink` in `$LOAD_PATH`, `bootcsnap` would perpetuate this bug, which led to the addition of #136. This was ultimately fixed in Ruby 3.1 (https://bugs.ruby-lang.org/issues/17885), now `realpath` is applied even on absolute paths. While `realpath` is indeed expensive, I think the performance impact is ok if we only call it for `$LOAD_PATH` members, rather than for all requirable files. So if you have X gems, it's going to be more or less X `realpath` calls. It would stay a problem if a gem actually contained symlinks and used `require_relative`, but it's quite the stretch, and with 3.1 now handling it, it's not worth keeping such workaround. See: #402
1 parent 4d78e68 commit 88b8cd4

7 files changed

Lines changed: 74 additions & 69 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ jobs:
3232
- uses: actions/checkout@v2
3333
- uses: ruby/setup-ruby@v1
3434
with:
35-
ruby-version: '2.3'
35+
ruby-version: '2.4'
3636
bundler-cache: true
3737
- run: bundle exec rubocop
3838

3939
rubies:
4040
strategy:
4141
matrix:
4242
os: [ubuntu]
43-
ruby: ['2.3', '2.4', '2.5', '2.6', '2.7', '3.0', '3.1', 'ruby-head', 'debug']
43+
ruby: ['2.4', '2.5', '2.6', '2.7', '3.0', '3.1', 'ruby-head', 'debug']
4444
runs-on: ${{ matrix.os }}-latest
4545
steps:
4646
- uses: actions/checkout@v2

.rubocop.yml

Lines changed: 65 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,17 @@ AllCops:
22
Exclude:
33
- 'vendor/**/*'
44
- 'tmp/**/*'
5-
TargetRubyVersion: 2.3
5+
TargetRubyVersion: 2.4
66

7-
# This doesn't take into account retrying from an exception
8-
Lint/SuppressedException:
9-
Enabled: false
10-
11-
# allow String.new to create mutable strings
12-
Style/EmptyLiteral:
13-
Enabled: false
14-
15-
Style/EmptyMethod:
7+
Bundler/OrderedGems:
168
Enabled: false
179

18-
# allow the use of globals which makes sense in a CLI app like this
19-
Style/GlobalVars:
10+
Gemspec/OrderedDependencies:
2011
Enabled: false
2112

22-
Style/PercentLiteralDelimiters:
13+
Gemspec/DuplicatedAssignment:
2314
Enabled: false
2415

25-
Style/TrailingCommaInHashLiteral:
26-
EnforcedStyleForMultiline: comma
27-
28-
Style/TrailingCommaInArrayLiteral:
29-
EnforcedStyleForMultiline: comma
30-
31-
Style/TrailingCommaInArguments:
32-
EnforcedStyleForMultiline: comma
33-
34-
Layout/LineLength:
35-
Max: 120
36-
3716
Metrics/AbcSize:
3817
Enabled: false
3918

@@ -65,33 +44,12 @@ Naming/MethodName:
6544
Naming/RescuedExceptionsVariableName:
6645
PreferredName: error
6746

68-
Bundler/OrderedGems:
69-
Enabled: false
70-
71-
Gemspec/OrderedDependencies:
72-
Enabled: false
73-
74-
Gemspec/DuplicatedAssignment:
47+
Naming/VariableNumber:
7548
Enabled: false
7649

7750
Layout/MultilineMethodCallIndentation:
7851
EnforcedStyle: indented
7952

80-
Style/SymbolArray:
81-
Enabled: false
82-
83-
Style/StderrPuts:
84-
Enabled: false
85-
86-
Style/ModuleFunction:
87-
Enabled: false
88-
89-
Style/IfUnlessModifier:
90-
Enabled: false
91-
92-
Style/GuardClause:
93-
Enabled: false
94-
9553
Layout/EndAlignment:
9654
EnforcedStyleAlignWith: start_of_line
9755

@@ -101,24 +59,78 @@ Layout/RescueEnsureAlignment:
10159
Layout/FirstHashElementIndentation:
10260
EnforcedStyle: consistent
10361

104-
Style/NumericPredicate:
105-
Enabled: false
106-
10762
Layout/SpaceInsideHashLiteralBraces:
10863
EnforcedStyle: no_space
10964

65+
Layout/SpaceAroundMethodCallOperator:
66+
Enabled: true
67+
68+
Layout/LineLength:
69+
Max: 120
70+
71+
# This doesn't take into account retrying from an exception
72+
Lint/SuppressedException:
73+
Enabled: false
74+
11075
Lint/AssignmentInCondition:
11176
AllowSafeAssignment: true
11277

11378
Lint/UnusedMethodArgument:
11479
AllowUnusedKeywordArguments: true
11580

81+
Lint/RaiseException:
82+
Enabled: true
83+
84+
Lint/StructNewOverride:
85+
Enabled: true
86+
11687
Security/MarshalLoad:
11788
Enabled: false
11889

11990
Security/YAMLLoad:
12091
Enabled: false
12192

93+
# allow String.new to create mutable strings
94+
Style/EmptyLiteral:
95+
Enabled: false
96+
97+
Style/EmptyMethod:
98+
Enabled: false
99+
100+
# allow the use of globals which makes sense in a CLI app like this
101+
Style/GlobalVars:
102+
Enabled: false
103+
104+
Style/PercentLiteralDelimiters:
105+
Enabled: false
106+
107+
Style/TrailingCommaInHashLiteral:
108+
EnforcedStyleForMultiline: comma
109+
110+
Style/TrailingCommaInArrayLiteral:
111+
EnforcedStyleForMultiline: comma
112+
113+
Style/TrailingCommaInArguments:
114+
EnforcedStyleForMultiline: comma
115+
116+
Style/SymbolArray:
117+
Enabled: false
118+
119+
Style/StderrPuts:
120+
Enabled: false
121+
122+
Style/ModuleFunction:
123+
Enabled: false
124+
125+
Style/IfUnlessModifier:
126+
Enabled: false
127+
128+
Style/GuardClause:
129+
Enabled: false
130+
131+
Style/NumericPredicate:
132+
Enabled: false
133+
122134
Style/Alias:
123135
EnforcedStyle: prefer_alias_method
124136

@@ -131,22 +143,12 @@ Style/DoubleNegation:
131143
Style/CommentedKeyword:
132144
Enabled: false
133145

134-
Naming/VariableNumber:
135-
Enabled: false
136-
137146
Style/Next:
138147
Enabled: false
139148

140149
Style/StringLiterals:
141150
EnforcedStyle: double_quotes
142151

143-
144-
Lint/RaiseException:
145-
Enabled: true
146-
147-
Lint/StructNewOverride:
148-
Enabled: true
149-
150152
Style/HashEachMethods:
151153
Enabled: true
152154

@@ -161,3 +163,6 @@ Style/RedundantReturn:
161163

162164
Style/YodaCondition:
163165
Enabled: false
166+
167+
Style/ExponentialNotation:
168+
Enabled: true

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Unreleased
22

3+
* Drop support for Ruby 2.3.
4+
35
# 1.10.3
46

57
* Fix Regexp and Date type support in YAML compile cache. (#400)

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ gem "minitest", "~> 5.0"
1616
gem "mocha", "~> 1.2"
1717

1818
group :development do
19-
gem "rubocop", "0.81.0" # Ruby 2.3 support
19+
gem "rubocop", "0.82.0" # Ruby 2.4 support
2020
gem "byebug", platform: :ruby
2121
end

bootsnap.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
2929
spec.bindir = "exe"
3030
spec.executables = %w(bootsnap)
3131

32-
spec.required_ruby_version = ">= 2.3.0"
32+
spec.required_ruby_version = ">= 2.4.0"
3333

3434
if RUBY_PLATFORM =~ /java/
3535
spec.platform = "java"

lib/bootsnap/compile_cache.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ def self.permission_error(path)
5050

5151
def self.supported?
5252
# only enable on 'ruby' (MRI), POSIX (darwin, linux, *bsd), Windows (RubyInstaller2) and >= 2.3.0
53-
RUBY_ENGINE == "ruby" &&
54-
RUBY_PLATFORM =~ /darwin|linux|bsd|mswin|mingw|cygwin/ &&
55-
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.3.0")
53+
RUBY_ENGINE == "ruby" && RUBY_PLATFORM.match?(/darwin|linux|bsd|mswin|mingw|cygwin/)
5654
end
5755
end
5856
end

test/compile_cache_key_format_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ def test_key_ruby_revision
4949
def test_key_size
5050
key = cache_key_for_file(FILE)
5151
exp = File.size(FILE)
52-
act = key[R[:size]].unpack("Q")[0]
52+
act = key[R[:size]].unpack1("Q")
5353
assert_equal(exp, act)
5454
end
5555

5656
def test_key_mtime
5757
key = cache_key_for_file(FILE)
5858
exp = File.mtime(FILE).to_i
59-
act = key[R[:mtime]].unpack("Q")[0]
59+
act = key[R[:mtime]].unpack1("Q")
6060
assert_equal(exp, act)
6161
end
6262

0 commit comments

Comments
 (0)