Skip to content

Commit

Permalink
Avoid a deprecation warning on Ruby 3.4 with the uri gem
Browse files Browse the repository at this point in the history
I openend a PR to tapioca, which needs the same change: Shopify/tapioca#2026
  • Loading branch information
Earlopain committed Oct 1, 2024
1 parent 8501f5e commit b6d38cc
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
13 changes: 9 additions & 4 deletions lib/core_ext/uri.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@

module URI
class Generic
# Avoid a deprecation warning with Ruby 3.4 where the default parser was changed to RFC3986.
# This condition must remain even after support for 3.4 has been dropped for users that have
# `uri` in their lockfile, decoupling it from the ruby version.
PARSER = T.let(const_defined?(:RFC2396_PARSER) ? RFC2396_PARSER : DEFAULT_PARSER, RFC2396_Parser)

class << self
extend T::Sig

sig { params(path: String, fragment: T.nilable(String), scheme: String).returns(URI::Generic) }
def from_path(path:, fragment: nil, scheme: "file")
# On Windows, if the path begins with the disk name, we need to add a leading slash to make it a valid URI
escaped_path = if /^[A-Z]:/i.match?(path)
DEFAULT_PARSER.escape("/#{path}")
PARSER.escape("/#{path}")
elsif path.start_with?("//?/")
# Some paths on Windows start with "//?/". This is a special prefix that allows for long file paths
DEFAULT_PARSER.escape(path.delete_prefix("//?"))
PARSER.escape(path.delete_prefix("//?"))
else
DEFAULT_PARSER.escape(path)
PARSER.escape(path)
end

build(scheme: scheme, path: escaped_path, fragment: fragment)
Expand All @@ -29,7 +34,7 @@ def to_standardized_path
parsed_path = path
return unless parsed_path

unescaped_path = DEFAULT_PARSER.unescape(parsed_path)
unescaped_path = PARSER.unescape(parsed_path)

# On Windows, when we're getting the file system path back from the URI, we need to remove the leading forward
# slash
Expand Down
9 changes: 8 additions & 1 deletion lib/ruby_lsp/requests/support/source_uri.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ class Source < URI::File
T::Array[Symbol],
)

# `uri` for Ruby 3.4 switched the default parser from RFC2396 to RFC3986. The new parser emits a deprecation
# warning on a few methods and delegates them to RFC2396, namely `extract`/`make_regexp`/`escape`/`unescape`.
# On earlier versions of the uri gem, the RFC2396_PARSER constant doesn't exist, so it needs some special
# handling to select a parser that doesn't emit deprecations. While it was backported to Ruby 3.1, users may
# have the uri gem in their own bundle and thus not use a compatible version.
PARSER = T.let(const_defined?(:RFC2396_PARSER) ? RFC2396_PARSER : DEFAULT_PARSER, RFC2396_Parser)

T.unsafe(self).alias_method(:gem_name, :host)
T.unsafe(self).alias_method(:line_number, :fragment)

Expand All @@ -41,7 +48,7 @@ def build(gem_name:, gem_version:, path:, line_number:)
{
scheme: "source",
host: gem_name,
path: DEFAULT_PARSER.escape("/#{gem_version}/#{path}"),
path: PARSER.escape("/#{gem_version}/#{path}"),
fragment: line_number,
}
)
Expand Down

0 comments on commit b6d38cc

Please sign in to comment.