Class: RSpec::Signal::Project
- Inherits:
-
Object
- Object
- RSpec::Signal::Project
- Defined in:
- lib/rspec/signal/project.rb
Overview
Knows which paths belong to the project under test ("first party") and how to render any path compactly.
First-party means: the host application's own code, plus code from gems
that are developed alongside it (Bundler path: sources, local Rails
engines). Those are things the agent can actually open and edit.
Constant Summary collapse
- VENDORED =
Directories that live inside the project root but are not project code.
%w[ vendor/bundle vendor/cache vendor/ruby .bundle node_modules tmp/ .git/ coverage/ ].freeze
- GEM_PATH =
Matches ".../gems/capybara-3.40.0/lib/capybara/node/finders.rb".
The leading
.*/is greedy on purpose: a RubyGems install path contains "/gems/" twice ("/lib/ruby/gems/3.3.0/gems/capybara-3.40.0/..."), and it is the last one that introduces the gem. %r{ \A.*/(?:gems|bundler/gems)/ (?<name>[A-Za-z0-9_.-]+?) # A release version, or the short SHA Bundler uses for git sources. (?:-(?<version>\d[\w.]*(?:-[a-z0-9]+)?|[0-9a-f]{12,40}))? /(?<rest>.*)\z }x.freeze
- STDLIB_PATH =
Matches ".../lib/ruby/3.3.0/json/common.rb" and ".../ruby/3.3.0/x86_64-linux/..."
%r{ /lib/ruby/(?:\d+\.\d+\.\d+|site_ruby|vendor_ruby)/ (?:[a-z0-9_]+-[a-z0-9_-]+/)?(?<rest>.*)\z }x.freeze
Instance Attribute Summary collapse
-
#root ⇒ Object
readonly
Returns the value of attribute root.
Instance Method Summary collapse
- #absolutize(path) ⇒ Object
-
#display_path(path) ⇒ Object
A short, stable, human/agent readable rendering of a path.
- #first_party?(path) ⇒ Boolean
-
#gem_name(path) ⇒ Object
The gem a path belongs to, or nil.
-
#initialize(root: Dir.pwd, extra_first_party: []) ⇒ Project
constructor
A new instance of Project.
-
#local_gem_prefixes ⇒ Object
Absolute path prefixes of Bundler
path:gems (local gems and engines). - #relative_to_root(absolute) ⇒ Object
Constructor Details
#initialize(root: Dir.pwd, extra_first_party: []) ⇒ Project
Returns a new instance of Project.
42 43 44 45 46 47 |
# File 'lib/rspec/signal/project.rb', line 42 def initialize(root: Dir.pwd, extra_first_party: []) @root = File.(root) @root_prefix = "#{@root}/" @extra = extra_first_party.map { |p| "#{File.(p)}/" } @cache = {} end |
Instance Attribute Details
#root ⇒ Object (readonly)
Returns the value of attribute root.
37 38 39 |
# File 'lib/rspec/signal/project.rb', line 37 def root @root end |
Instance Method Details
#absolutize(path) ⇒ Object
90 91 92 93 94 95 96 97 98 |
# File 'lib/rspec/signal/project.rb', line 90 def absolutize(path) stripped = path.to_s.sub(%r{\A\./}, "") # Ruby emits pseudo-frames that are not file paths at all: "<internal:...>", # "-e", "(eval)", "(irb)". Joining those to the project root would wrongly # make them look first party. return stripped if stripped.start_with?("/", "<", "-", "(") File.join(@root, stripped) end |
#display_path(path) ⇒ Object
A short, stable, human/agent readable rendering of a path.
/app/spec/models/user_spec.rb -> spec/models/user_spec.rb
.../gems/capybara-3.40.0/lib/capybara/node/finders.rb -> capybara/node/finders.rb
.../lib/ruby/3.3.0/json/common.rb -> ruby/json/common.rb
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/rspec/signal/project.rb', line 67 def display_path(path) return path if path.nil? || path.empty? absolute = absolutize(path) return relative_to_root(absolute) if under?(absolute, @root_prefix) || first_party?(path) if (m = GEM_PATH.match(absolute)) return "#{m[:name]}/#{strip_redundant_prefix(m[:name], m[:rest].sub(%r{\Alib/}, ""))}" end if (stdlib = STDLIB_PATH.match(absolute)) return "ruby/#{stdlib[:rest]}" end relative_to_root(absolute) end |
#first_party?(path) ⇒ Boolean
56 57 58 59 60 |
# File 'lib/rspec/signal/project.rb', line 56 def first_party?(path) return false if path.nil? || path.empty? @cache[path] ||= compute_first_party(path) end |
#gem_name(path) ⇒ Object
The gem a path belongs to, or nil.
85 86 87 88 |
# File 'lib/rspec/signal/project.rb', line 85 def gem_name(path) m = GEM_PATH.match(absolutize(path)) m && m[:name] end |
#local_gem_prefixes ⇒ Object
Absolute path prefixes of Bundler path: gems (local gems and engines).
Discovered lazily and defensively: any Bundler problem simply means we
fall back to plain root-relative detection.
52 53 54 |
# File 'lib/rspec/signal/project.rb', line 52 def local_gem_prefixes @local_gem_prefixes ||= discover_local_gem_prefixes end |
#relative_to_root(absolute) ⇒ Object
100 101 102 103 104 |
# File 'lib/rspec/signal/project.rb', line 100 def relative_to_root(absolute) return absolute[@root_prefix.length..] if under?(absolute, @root_prefix) absolute end |