abstract class
Analyzer::Ruby::RubyEngine
- Analyzer::Ruby::RubyEngine
- Analyzer
- Reference
- Object
Direct Known Subclasses
- Analyzer::Ruby::ActionCable
- Analyzer::Ruby::Cli
- Analyzer::Ruby::Grape
- Analyzer::Ruby::Hanami
- Analyzer::Ruby::Rails
- Analyzer::Ruby::Roda
- Analyzer::Ruby::Sinatra
- Analyzer::Ruby::Webrick
Defined in:
analyzer/engines/ruby_engine.crConstant Summary
-
HANAMI_ROUTER_RE =
/Hanami::Rout|Hanami\.app\b|Hanami\.routes\b/ -
HTTP_VERBS =
["get", "post", "put", "delete", "patch", "head", "options"] -
RAILS_ROUTER_RE =
/\.routes\.draw\b|ActionDispatch::Routing/ -
Rails, Hanami and Sinatra all spell a route
get "/books" …, and every Ruby analyzer is handed every.rbfile in the scan, so each one could parse the others' route table with its own DSL. These two predicates identify a file as unmistakably belonging to Rails or to Hanami; an analyzer that is neither uses them to step aside.Rails.application.routes.drawandHanami::Routesare positive markers — a router that carries one is that framework's and nobody else's. There is deliberately no Sinatra equivalent: a Sinatra route file can be a bareget "/x" do … endwith no framework reference at all, which is why the checks run in this direction only. -
RUBY_NON_PRODUCTION_DIRS =
Set {"spec", "test", "tests", "features", "benchmark", "benchmarks", "examples", "coverage", "tmp"} -
RUBY_NON_PRODUCTION_PATH_RE =
begin alternation = RUBY_NON_PRODUCTION_DIRS.join("|") do |dir| Regex.escape(dir) end Regex.new("\\A(?:#{alternation})(?:/|\\z)|/(?:#{alternation})/") end -
Whole-tree Ruby analyzers (Sinatra/Grape/Roda/WEBrick) otherwise see Rack test helpers, benchmark apps, and framework examples as live services. Match these directories only relative to the configured scan root so noir's own fixture tree under
spec/functional_test/fixturesis not accidentally skipped when the fixture directory itself is the base path. Exact translation of the three-way check this replaces:relative == dirandrelative.starts_with?("#{dir}/")collapse to the leading branch,relative.includes?("/#{dir}/")to the second. Deliberately NOT(?:\A|\/)dir(?:\/|\z), which would also match a trailing segment (app/spec) the old chain rejected.The chain built two interpolated Strings per directory per call — 18 allocations on every Ruby file, for every whole-tree Ruby analyzer — before scanning for each of them separately.
-
RUBY_SOURCE_EXTENSIONS =
[".rb", ".ru"] -
Walk Ruby sources (
.rb/.ru) in parallel. Used by analyzers that scan the whole tree (Sinatra, Grape, Roda, WEBrick); Rails/Hanami target specific config files directly. Candidates come from the extension index so monorepofile_mapentries in other languages never enter the channel. Paths are detector- registered regular files — no per-pathFile.exists?/File.directory?.Name-consistent with the other engines'
parallel_file_scanhelpers. -
VERB_ROUTE_PATTERNS =
HTTP_VERBS.map do |verb| {verb, /^#{verb}\s*\(?\s*['"](.+?)['"]/} end -
Crystal recompiles an interpolated regex literal on every evaluation (a full PCRE2 JIT compile). The verb set is fixed, so precompile the
<verb> "<path>"matchers once at load time.
Class Method Summary
-
.ruby_test_path?(path : String) : Bool
Minitest's
*_test.rband RSpec's*_spec.rbconventions are rigid in Ruby —rake test/mri testonly run files matching the first, andrspecdiscovers the second.
Instance Method Summary
-
#line_to_endpoint(content : String, details : Details | Nil = nil) : Endpoint
Match the
<verb> "<path>"idiom on a single line and return the first endpoint found, or an empty endpoint if none match.
Instance methods inherited from class Analyzer
analyze
analyze,
base_path : String
base_path,
base_paths : Array(String)
base_paths,
base_relative_path(path : String) : String
base_relative_path,
callees_needed? : Bool
callees_needed?,
content_matches?(content : String, markers : Regex) : Bool
content_matches?,
http_header_name(name : String) : String | Nil
http_header_name,
line_number_for_index(content : String, char_index : Int32) : Int32
line_number_for_index,
logger : NoirLogger
logger,
parallel_analyze(files : Array(String), &block : String -> Nil)
parallel_analyze,
read_file_content(path : String) : String
read_file_content,
result : Array(Endpoint)
result,
unique_params(params : Array(Param)) : Array(Param)
unique_params,
url : String
url,
web_root_path(path : String, markers : Array(String)) : String
web_root_path
Constructor methods inherited from class Analyzer
new(options : Hash(String, YAML::Any))
new
Macros inherited from class Analyzer
analyzer_for(tech)
analyzer_for
Instance methods inherited from module FileHelper
all_files : Array(String)
all_files,
get_files_by_basename(basename : String) : Array(String)
get_files_by_basename,
get_files_by_extension(extension : String) : Array(String)
get_files_by_extension,
get_files_by_extensions(extensions : Array(String)) : Array(String)
get_files_by_extensions,
get_files_by_prefix(prefix : String) : Array(String)
get_files_by_prefix,
get_files_by_prefix_and_extension(prefix : String, extension : String) : Array(String)
get_files_by_prefix_and_extension,
get_files_by_relative_path(relative_path : String, root : String = "") : Array(String)
get_files_by_relative_path,
get_public_dir_files(base_path : String, folder : String) : Array(String)
get_public_dir_files,
get_public_files(base_path : String, anchors : Array(String) = ["shard.yml", "Gemfile"]) : Array(String)
get_public_files,
walked_path(expanded : String) : String
walked_path
Class Method Detail
Minitest's *_test.rb and RSpec's *_spec.rb conventions are
rigid in Ruby — rake test / mri test only run files matching
the first, and rspec discovers the second. Production Ruby
never adopts either filename, so the suffix check is safe for
every Ruby analyzer (sinatra, grape, roda, hanami). Promoted
from Analyzer::Ruby::Sinatra (#1571) so the rest of the
family stays in sync.
Test::Unit / Minitest equally support the inverse test_*.rb
prefix (rake test globs test/test_*.rb). gollum, for
instance, exercises its modular Sinatra app exclusively through
test/test_app.rb-style files whose inline Rack::Test requests
(get "/wiki/Home", post "/gollum/upload_file") are
indistinguishable from real route registrations to a line-based
matcher — ~70 phantom endpoints per scan. Production route files
never carry the test_ prefix, so it is as safe as the suffix
forms. We match on the basename only (never the full path) so a
legitimate app that merely lives under a spec/-suffixed
absolute path — e.g. noir's own fixtures — is untouched.
Instance Method Detail
Match the <verb> "<path>" idiom on a single line and return the first
endpoint found, or an empty endpoint if none match. Shared by Hanami
and Sinatra (Rails uses a different per-line-multi-match shape).