1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00
pry--pry/lib/pry/code/code_file.rb
Kyrylo Silin edaa1383f2 Require files from pry.rb; deps from each file that uses them
This change brings some order to how we require files. Previously, we required
app files from everywhere, including pry.rb. Now we require app files only from
pry.rb.

External and stdlib dependencies are required at places where they're used, not
globally.
2019-03-10 13:20:03 +02:00

112 lines
3.3 KiB
Ruby

require 'method_source'
class Pry
class CodeFile
DEFAULT_EXT = '.rb'.freeze
# List of all supported languages.
# @return [Hash]
EXTENSIONS = {
%w[.py] => :python,
%w[.js] => :javascript,
%w[.css] => :css,
%w[.xml] => :xml,
%w[.php] => :php,
%w[.html] => :html,
%w[.diff] => :diff,
%w[.java] => :java,
%w[.json] => :json,
%w[.c .h] => :c,
%w[.rhtml] => :rhtml,
%w[.yaml .yml] => :yaml,
%w[.cpp .hpp .cc .h .cxx] => :cpp,
%w[.rb .ru .irbrc .gemspec .pryrc .rake] => :ruby
}.freeze
FILES = {
%w[Gemfile Rakefile Guardfile Capfile] => :ruby
}.freeze
# Store the current working directory. This allows show-source etc. to work if
# your process has changed directory since boot. [Issue #675]
INITIAL_PWD = Dir.pwd
# @return [Symbol] The type of code stored in this wrapper.
attr_reader :code_type
# @param [String] filename The name of a file with code to be detected
# @param [Symbol] code_type The type of code the `filename` contains
def initialize(filename, code_type = type_from_filename(filename))
@filename = filename
@code_type = code_type
end
# @return [String] The code contained in the current `@filename`.
def code
if @filename == Pry.eval_path
Pry.line_buffer.drop(1)
elsif Pry::Method::Patcher.code_for(@filename)
Pry::Method::Patcher.code_for(@filename)
else
path = abs_path
@code_type = type_from_filename(path)
File.read(path)
end
end
private
# @raise [MethodSource::SourceNotFoundError] if the `filename` is not
# readable for some reason.
# @return [String] absolute path for the given `filename`.
def abs_path
code_path.detect { |path| readable?(path) } ||
raise(MethodSource::SourceNotFoundError,
"Cannot open #{@filename.inspect} for reading.")
end
# @param [String] path
# @return [Boolean] if the path, with or without the default ext,
# is a readable file then `true`, otherwise `false`.
def readable?(path)
File.readable?(path) && !File.directory?(path) ||
File.readable?(path << DEFAULT_EXT)
end
# @return [Array] All the paths that contain code that Pry can use for its
# API's. Skips directories.
def code_path
[from_pwd, from_pry_init_pwd, *from_load_path]
end
# @param [String] filename
# @param [Symbol] default (:unknown) the file type to assume if none could be
# detected.
# @return [Symbol, nil] The CodeRay type of a file from its extension, or
# `nil` if `:unknown`.
def type_from_filename(filename, default = :unknown)
_, @code_type = EXTENSIONS.find do |k, _|
k.any? { |ext| ext == File.extname(filename) }
end || FILES.find do |k, _|
k.any? { |file_name| file_name == File.basename(filename) }
end
code_type || default
end
# @return [String]
def from_pwd
File.expand_path(@filename, Dir.pwd)
end
# @return [String]
def from_pry_init_pwd
File.expand_path(@filename, INITIAL_PWD)
end
# @return [String]
def from_load_path
$LOAD_PATH.map { |path| File.expand_path(@filename, path) }
end
end
end