Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions lib/packwerk/application_load_paths.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module ApplicationLoadPaths
class << self
extend T::Sig

sig { params(root: String, environment: String).returns(T::Hash[String, Module]) }
sig { params(root: String, environment: String).returns(T::Array[String]) }
def extract_relevant_paths(root, environment)
require_application(root, environment)
all_paths = extract_application_autoload_paths
Expand All @@ -18,30 +18,30 @@ def extract_relevant_paths(root, environment)
relative_path_strings(relevant_paths)
end

sig { returns(T::Hash[String, Module]) }
sig { returns(T::Array[String]) }
def extract_application_autoload_paths
Rails.autoloaders.inject({}) do |h, loader|
h.merge(loader.root_dirs)
end
end.keys
end

sig do
params(all_paths: T::Hash[String, Module], bundle_path: Pathname, rails_root: Pathname)
.returns(T::Hash[Pathname, Module])
params(all_paths: T::Array[String], bundle_path: Pathname, rails_root: Pathname)
.returns(T::Array[Pathname])
end
def filter_relevant_paths(all_paths, bundle_path: Bundler.bundle_path, rails_root: Rails.root)
bundle_path_match = bundle_path.join("**")
rails_root_match = rails_root.join("**")

all_paths
.transform_keys { |path| Pathname.new(path).expand_path }
.map { |path| Pathname.new(path).expand_path }
.select { |path| path.fnmatch(rails_root_match.to_s) } # path needs to be in application directory
.reject { |path| path.fnmatch(bundle_path_match.to_s) } # reject paths from vendored gems
end

sig { params(load_paths: T::Hash[Pathname, Module], rails_root: Pathname).returns(T::Hash[String, Module]) }
sig { params(load_paths: T::Array[Pathname], rails_root: Pathname).returns(T::Array[String]) }
def relative_path_strings(load_paths, rails_root: Rails.root)
load_paths.transform_keys { |path| Pathname.new(path).relative_path_from(rails_root).to_s }
load_paths.map { |path| Pathname.new(path).relative_path_from(rails_root).to_s }
end

private
Expand All @@ -59,7 +59,7 @@ def require_application(root, environment)
end
end

sig { params(paths: T::Hash[T.untyped, Module]).void }
sig { params(paths: T::Array[Pathname]).void }
def assert_load_paths_present(paths)
if paths.empty?
raise <<~EOS
Expand Down
2 changes: 1 addition & 1 deletion lib/packwerk/run_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def from_configuration(configuration)
sig do
params(
root_path: String,
load_paths: T::Hash[String, Module],
load_paths: T::Array[String],
inflector: T.class_of(ActiveSupport::Inflector),
cache_directory: Pathname,
config_path: T.nilable(String),
Expand Down
12 changes: 5 additions & 7 deletions test/unit/application_load_paths_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,39 @@ class ApplicationLoadPathsTest < Minitest::Test
relative_path = "app/models"
absolute_path = rails_root.join(relative_path)
relative_path_strings = ApplicationLoadPaths.relative_path_strings(
{ absolute_path => Object },
[absolute_path],
rails_root: rails_root
)

assert_equal({ relative_path => Object }, relative_path_strings)
assert_equal([relative_path], relative_path_strings)
end

test ".filter_relevant_paths excludes paths outside of the application root" do
valid_paths = ["/application/app/models"]
paths = valid_paths + ["/users/tobi/.gems/something/app/models", "/application/../something/"]
paths = paths.each_with_object({}) { |p, h| h[p.to_s] = Object }
filtered_paths = ApplicationLoadPaths.filter_relevant_paths(
paths,
bundle_path: Pathname.new("/application/vendor/"),
rails_root: Pathname.new("/application/")
)

assert_equal({ "/application/app/models" => Object }, filtered_paths.transform_keys(&:to_s))
assert_equal(["/application/app/models"], filtered_paths.map(&:to_s))
end

test ".filter_relevant_paths excludes paths from vendored gems" do
valid_paths = ["/application/app/models"]
paths = valid_paths + ["/application/vendor/something/app/models"]
paths = paths.each_with_object({}) { |p, h| h[p.to_s] = Object }
filtered_paths = ApplicationLoadPaths.filter_relevant_paths(
paths,
bundle_path: Pathname.new("/application/vendor/"),
rails_root: Pathname.new("/application/")
)

assert_equal({ "/application/app/models" => Object }, filtered_paths.transform_keys(&:to_s))
assert_equal(["/application/app/models"], filtered_paths.map(&:to_s))
end

test ".extract_relevant_paths calls out to filter the paths" do
ApplicationLoadPaths.expects(:filter_relevant_paths).once.returns(Pathname.new("/fake_path").to_s => Object)
ApplicationLoadPaths.expects(:filter_relevant_paths).once.returns([Pathname.new("/fake_path").to_s])
ApplicationLoadPaths.expects(:require_application).with("/application", "test").once.returns(true)

ApplicationLoadPaths.extract_relevant_paths("/application", "test")
Expand Down
6 changes: 3 additions & 3 deletions test/unit/cli_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class CliTest < Minitest::Test
offense = Offense.new(file: file_path, message: violation_message)

configuration = Configuration.new({ "parallel" => false })
configuration.stubs(load_paths: {})
configuration.stubs(load_paths: [])
RunContext.any_instance.stubs(:process_file).at_least_once.returns([offense])

string_io = StringIO.new
Expand All @@ -49,7 +49,7 @@ class CliTest < Minitest::Test
offense = Offense.new(file: file_path, message: violation_message)

configuration = Configuration.new({ "parallel" => false })
configuration.stubs(load_paths: {})
configuration.stubs(load_paths: [])

RunContext.any_instance.stubs(:process_file)
.at_least(2)
Expand Down Expand Up @@ -137,7 +137,7 @@ def show_stale_violations(_offense_collection, _fileset)
offense = Offense.new(file: file_path, message: violation_message)

configuration = Configuration.new
configuration.stubs(load_paths: {})
configuration.stubs(load_paths: [])
RunContext.any_instance.stubs(:process_file)
.returns([offense])

Expand Down