Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In strict mode, check only for violations unlisted in package_todo.yml #368

Merged
merged 3 commits into from
Jan 4, 2024
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
2 changes: 1 addition & 1 deletion USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ It will be a dependency violation when `components/shop_identity` tries to refer

#### Using strict mode

Once there are no more violations in a package, you can turn on `strict` mode, which will prevent new violations from being added to the package's `package_todo.yml`. To use this, simply change `enforce_dependencies: true` to `enforce_dependencies: strict` in your `package.yml`.
You can turn on `strict` mode to prevent new violations from being added to the package's `package_todo.yml`. To use this, simply change `enforce_dependencies: true` to `enforce_dependencies: strict` in your `package.yml`.

Then, when you run `bin/packwerk check`, new violations will cause the following error to be displayed:
```
Expand Down
4 changes: 2 additions & 2 deletions lib/packwerk/checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ def checker_by_violation_type(name)
sig { abstract.returns(String) }
def violation_type; end

sig { abstract.params(listed_offense: ReferenceOffense).returns(T::Boolean) }
def strict_mode_violation?(listed_offense); end
sig { abstract.params(offense: ReferenceOffense).returns(T::Boolean) }
def strict_mode_violation?(offense); end

sig { abstract.params(reference: Reference).returns(T::Boolean) }
def invalid_reference?(reference); end
Expand Down
6 changes: 4 additions & 2 deletions lib/packwerk/commands/check_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@ def run
end
offense_collection.add_offenses(all_offenses)

unlisted_strict_mode_violations = offense_collection.unlisted_strict_mode_violations

messages = [
offenses_formatter.show_offenses(offense_collection.outstanding_offenses),
offenses_formatter.show_stale_violations(offense_collection, @files_for_processing.files),
offenses_formatter.show_strict_mode_violations(offense_collection.strict_mode_violations),
offenses_formatter.show_strict_mode_violations(unlisted_strict_mode_violations),
]

out.puts(messages.select(&:present?).join("\n") + "\n")

offense_collection.outstanding_offenses.empty? &&
!offense_collection.stale_violations?(@files_for_processing.files) &&
offense_collection.strict_mode_violations.empty?
unlisted_strict_mode_violations.empty?
end

private
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def message(reference)
EOS
end

sig { override.params(listed_offense: ReferenceOffense).returns(T::Boolean) }
def strict_mode_violation?(listed_offense)
referencing_package = listed_offense.reference.package
sig { override.params(offense: ReferenceOffense).returns(T::Boolean) }
def strict_mode_violation?(offense)
referencing_package = offense.reference.package
referencing_package.config["enforce_dependencies"] == "strict"
end

Expand Down
71 changes: 70 additions & 1 deletion test/unit/packwerk/commands/check_command_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ class CheckCommandTest < Minitest::Test
refute result
end

test "#run lists out violations of strict mode" do
test "#run does not list out violations of strict mode for listed offenses" do
use_template(:minimal)

source_package = Packwerk::Package.new(
Expand Down Expand Up @@ -291,8 +291,77 @@ class CheckCommandTest < Minitest::Test

No offenses detected
No stale violations detected
EOS
assert_match(/#{expected_output}/, out.string)

assert result
end

test "#run lists out violations of strict mode" do
use_template(:minimal)

source_package = Packwerk::Package.new(
name: "components/source",
config: { "enforce_dependencies" => "strict" },
)
write_app_file("#{source_package.name}/package_todo.yml", <<~YML.strip)
---
"components/destination":
"::SomeName":
violations:
- dependency
files:
- components/source/some/path.rb
YML

listed_offense = ReferenceOffense.new(
reference: build_reference(path: "components/source/some/path.rb", source_package: source_package),
message: "some message",
violation_type: ReferenceChecking::Checkers::DependencyChecker::VIOLATION_TYPE
)
unlisted_offense = ReferenceOffense.new(
reference: build_reference(path: "components/source/other/path.rb", source_package: source_package),
message: "some message",
violation_type: ReferenceChecking::Checkers::DependencyChecker::VIOLATION_TYPE
)

RunContext.any_instance.stubs(:process_file)
.with(relative_file: "components/source/some/path.rb")
.returns([listed_offense])
RunContext.any_instance.stubs(:process_file)
.with(relative_file: "components/source/other/path.rb")
.returns([unlisted_offense])
FilesForProcessing.any_instance.stubs(:files).returns(
Set.new(["components/source/some/path.rb", "components/source/other/path.rb"])
)

out = StringIO.new
configuration = Configuration.new({ "parallel" => false })
check_command = CheckCommand.new(
[],
configuration: configuration,
out: out,
err_out: StringIO.new,
progress_formatter: Formatters::ProgressFormatter.new(out),
offenses_formatter: configuration.offenses_formatter
)

result = check_command.run

expected_output = <<~EOS
📦 Packwerk is inspecting 2 files
\\.E
📦 Finished in \\d+\\.\\d+ seconds

\\e\\[36mcomponents/source/other/path.rb\\e\\[m
some message

1 offense detected

No stale violations detected
components/source cannot have dependency violations on components/destination because strict mode is enabled for dependency violations in the enforcing package's package.yml
EOS

assert_match(/#{expected_output}/, out.string)

refute result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def message(_reference)
@message
end

def strict_mode_violation?(_listed_offense)
def strict_mode_violation?(_offense)
false
end
end
Expand Down