Resolv::Hosts
is a hostname resolver that uses the system hosts file.
Gem::DependencyList
is used for installing and uninstalling gems in the correct order to avoid conflicts.
Raised when attempting to uninstall a gem that isn’t in GEM_HOME.
Potentially raised when a specification is validated.
Raised by Gem::Validator
when something is not right in a gem.
Raised by Gem::WebauthnListener when an error occurs during security device verification.
Raised to indicate that a system exit should occur with the specified exit_code
A RequestSet
groups a request to activate a set of dependencies.
nokogiri = Gem::Dependency.new 'nokogiri', '~> 1.6' pg = Gem::Dependency.new 'pg', '~> 0.14' set = Gem::RequestSet.new nokogiri, pg requests = set.resolve p requests.map { |r| r.full_name } #=> ["nokogiri-1.6.0", "mini_portile-0.5.1", "pg-0.17.0"]
S3URISigner
implements AWS SigV4 for S3 Source to avoid a dependency on the aws-sdk-* gems More on AWS SigV4: docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html
The SourceList
represents the sources rubygems has been configured to use. A source may be created from an array of sources:
Gem::SourceList.from %w[https://rubygems.example https://internal.example]
Or by adding them:
sources = Gem::SourceList.new sources << 'https://rubygems.example'
The most common way to get a SourceList
is Gem.sources
.
Gem::StubSpecification
reads the stub: line from the gemspec. This prevents us having to eval the entire gemspec in order to find out certain information.
A TargetConfig is a wrapper around an RbConfig
object that provides a consistent interface for querying configuration for *deployment target platform*, where the gem being installed is intended to run on.
The TargetConfig is typically created from the RbConfig
of the running Ruby process, but can also be created from an RbConfig
file on disk for cross- compiling gems.
The UriFormatter
handles URIs from user-input and escaping.
uf = Gem::UriFormatter.new 'example.com' p uf.normalize #=> 'http://example.com'
Represents a single line of code of a given source file
This object contains metadata about the line such as amount of indentation, if it is empty or not, and lexical data, such as if it has an ‘end` or a keyword in it.
Visibility of lines can be toggled off. Marking a line as invisible indicates that it should not be used for syntax checks. It’s functionally the same as commenting it out.
Example:
line = CodeLine.from_source("def foo\n").first line.number => 1 line.empty? # => false line.visible? # => true line.mark_invisible line.visible? # => false
Outputs code with highlighted lines
Whatever is passed to this class will be rendered even if it is “marked invisible” any filtering of output should be done before calling this class.
DisplayCodeWithLineNumbers.new( lines: lines, highlight_lines: [lines[2], lines[3]] ).call # => 1 2 def cat > 3 Dir.chdir > 4 end 5 end 6
Used for formatting invalid blocks
Explains syntax errors based on their source
example:
source = "def foo; puts 'lol'" # Note missing end explain ExplainSyntax.new( code_lines: CodeLine.from_source(source) ).call explain.errors.first # => "Unmatched keyword, missing `end' ?"
When the error cannot be determined by lexical counting then the parser is run against the input and the raw errors are returned.
Example:
source = "1 * " # Note missing a second number explain ExplainSyntax.new( code_lines: CodeLine.from_source(source) ).call explain.errors.first # => "syntax error, unexpected end-of-input"
Capture
parse errors from Ripper
Prism
returns the errors with their messages, but Ripper
does not. To get them we must make a custom subclass.
Example:
puts RipperErrors.new(" def foo").call.errors # => ["syntax error, unexpected end-of-input, expecting ';' or '\\n'"]
Scans up/down from the given block
You can try out a change, stash it, or commit it to save for later
Example:
scanner = ScanHistory.new(code_lines: code_lines, block: block) scanner.scan( up: ->(_, _, _) { true }, down: ->(_, _, _) { true } ) scanner.changed? # => true expect(scanner.lines).to eq(code_lines) scanner.stash_changes expect(scanner.lines).to_not eq(code_lines)