Class: MonkeyLens::Provenance

Inherits:
Object
  • Object
show all
Defined in:
lib/monkey_lens/provenance.rb

Constant Summary collapse

KINDS =
%w[gem app stdlib eval unknown].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(kind:, gem: nil, path: nil, line: nil) ⇒ Provenance

Returns a new instance of Provenance.



9
10
11
12
13
14
# File 'lib/monkey_lens/provenance.rb', line 9

def initialize(kind:, gem: nil, path: nil, line: nil)
  @kind = kind.to_s
  @gem = gem
  @path = path
  @line = line
end

Instance Attribute Details

#gemObject (readonly)

Returns the value of attribute gem.



7
8
9
# File 'lib/monkey_lens/provenance.rb', line 7

def gem
  @gem
end

#kindObject (readonly)

Returns the value of attribute kind.



7
8
9
# File 'lib/monkey_lens/provenance.rb', line 7

def kind
  @kind
end

#lineObject (readonly)

Returns the value of attribute line.



7
8
9
# File 'lib/monkey_lens/provenance.rb', line 7

def line
  @line
end

#pathObject (readonly)

Returns the value of attribute path.



7
8
9
# File 'lib/monkey_lens/provenance.rb', line 7

def path
  @path
end

Class Method Details

.app_path?(path) ⇒ Boolean

Returns:

  • (Boolean)


65
66
67
68
# File 'lib/monkey_lens/provenance.rb', line 65

def self.app_path?(path)
  cwd = File.expand_path(Dir.pwd)
  path.start_with?("#{cwd}/") || path == cwd
end

.classify(path) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/monkey_lens/provenance.rb', line 26

def self.classify(path)
  return ["eval", nil] if eval_path?(path)

  expanded = File.expand_path(path)
  gem_info = gem_for_path(expanded)
  return ["gem", gem_info] if gem_info

  if stdlib_path?(expanded)
    ["stdlib", nil]
  elsif app_path?(expanded)
    ["app", nil]
  else
    ["unknown", nil]
  end
end

.eval_path?(path) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
# File 'lib/monkey_lens/provenance.rb', line 42

def self.eval_path?(path)
  path.start_with?("(eval") || path == "eval"
end

.for_source_location(location) ⇒ Object



16
17
18
19
20
21
22
23
24
# File 'lib/monkey_lens/provenance.rb', line 16

def self.for_source_location(location)
  return nil unless location

  path, line = location
  path = path.to_s
  line = Integer(line)
  kind, gem_name = classify(path)
  new(kind:, gem: gem_name, path: normalize_path(path), line:)
end

.gem_for_path(path) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/monkey_lens/provenance.rb', line 46

def self.gem_for_path(path)
  Gem.loaded_specs.each_value do |spec|
    spec.full_require_paths.each do |require_path|
      expanded = File.expand_path(require_path)
      next unless path.start_with?("#{expanded}/") || path == expanded

      return spec.name
    end
  end
  nil
end

.normalize_path(path) ⇒ Object



70
71
72
73
74
# File 'lib/monkey_lens/provenance.rb', line 70

def self.normalize_path(path)
  absolute = File.expand_path(path)
  cwd = File.expand_path(Dir.pwd)
  absolute.start_with?("#{cwd}/") ? absolute.delete_prefix("#{cwd}/") : absolute
end

.stdlib_path?(path) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
61
62
63
# File 'lib/monkey_lens/provenance.rb', line 58

def self.stdlib_path?(path)
  ruby_root = RbConfig::CONFIG["rubylibdir"]
  return path.start_with?(ruby_root) if ruby_root

  path.include?("/ruby/") && path.include?("/lib/")
end

Instance Method Details

#to_hObject



76
77
78
79
80
81
82
83
# File 'lib/monkey_lens/provenance.rb', line 76

def to_h
  {
    "kind" => kind,
    "gem" => gem,
    "path" => path,
    "line" => line
  }.compact
end