Skip to content
Closed
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
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ Metrics/CyclomaticComplexity:
Metrics/ModuleLength:
Enabled: false

Metrics/ClassLength:
Enabled: false

Sorbet/FalseSigil:
Enabled: false

Expand Down
35 changes: 34 additions & 1 deletion lib/danger-packwerk/danger_packwerk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,14 @@ def check(
packwerk_reference_offenses_to_care_about = packwerk_reference_offenses.reject do |packwerk_reference_offense|
constant_name = packwerk_reference_offense.reference.constant.name
filepath_that_defines_this_constant = Private.constant_resolver.resolve(constant_name)&.location
reference_path = packwerk_reference_offense.reference.relative_path

# Ignore references that have been renamed
renamed_files.include?(filepath_that_defines_this_constant) ||
# Ignore violations that are not in the allow-list of violation types to leave comments for
!violation_types.include?(packwerk_reference_offense.violation_type)
!violation_types.include?(packwerk_reference_offense.violation_type) ||
# Ignore violations that match enforcement_globs_ignore
ignored_by_enforcement_globs(packwerk_reference_offense, reference_path)
end

# We group by the constant name, line number, and reference path. Any offenses with these same values should only differ on what type of violation
Expand Down Expand Up @@ -151,5 +155,34 @@ def check(
on_failure.call(packwerk_reference_offenses)
end
end

sig do
params(
packwerk_reference_offense: Packwerk::ReferenceOffense,
reference_path: String
).returns(T::Boolean)
end
def ignored_by_enforcement_globs(packwerk_reference_offense, reference_path)
# Get the package for this reference to check for enforcement_globs_ignore
package = ParsePackwerk.package_from_path(reference_path)
enforcement_globs_ignore = package.config['enforcement_globs_ignore']

# Check if this offense should be ignored based on enforcement_globs_ignore
if enforcement_globs_ignore.is_a?(Array)
enforcement_globs_ignore.any? do |glob_config|
next false unless glob_config.is_a?(Hash)

enforcements = glob_config['enforcements']
ignores = glob_config['ignores']

# Check if this violation type is in the enforcements list
# and if the file path matches any of the ignores glob patterns
enforcements&.include?(packwerk_reference_offense.violation_type) &&
ignores&.any? { |ignore_pattern| File.fnmatch(ignore_pattern, reference_path) }
end
else
false
end
end
end
end
45 changes: 44 additions & 1 deletion spec/danger_packwerk/danger_packwerk_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def format_offenses(offenses, repo_link, org_name, repo_url_builder:)
let(:modified_files) { [write_file('packs/referencing_pack/some_file.rb').to_s] }

before do
# This is the root package.yml file
write_file('package.yml', <<~YML)
enforce_dependencies: true
enforce_privacy: true
Expand All @@ -112,7 +113,7 @@ def format_offenses(offenses, repo_link, org_name, repo_url_builder:)
context 'when the only files modified are ones that packwerk ignores' do
let(:modified_files) { [write_file('frontend/javascript/some_file.js').to_s] }

it 'leaves an inline comment helping the user figure out what to do next' do
it 'leaves no comments' do
expect_any_instance_of(Packwerk::Cli).not_to receive(:execute_command)
packwerk_check
expect(dangerfile.status_report[:warnings]).to be_empty
Expand All @@ -122,6 +123,48 @@ def format_offenses(offenses, repo_link, org_name, repo_url_builder:)
end
end

context 'when the privacy violation matches enforcement_globs_ignore' do
let(:offenses) { [generic_privacy_violation] }

it 'does not report when ignoring privacy violations with a path' do
write_file('packs/some_pack/package.yml', <<~YML)
enforce_dependencies: true
enforce_privacy: true
enforcement_globs_ignore:
- enforcements:
- privacy
ignores:
- packs/referencing_pack/some_file.rb
reason: man this one is just too difficult to fix
YML

packwerk_check
expect(dangerfile.status_report[:warnings]).to be_empty
expect(dangerfile.status_report[:errors]).to be_empty
actual_markdowns = dangerfile.status_report[:markdowns]
expect(actual_markdowns.first&.message).to be_nil
end

it 'does not report when ignoring privacy violations with a glob' do
write_file('packs/some_pack/package.yml', <<~YML)
enforce_dependencies: true
enforce_privacy: true
enforcement_globs_ignore:
- enforcements:
- privacy
ignores:
- packs/referencing_pack/*.rb
reason: All of these are impossible
YML

packwerk_check
expect(dangerfile.status_report[:warnings]).to be_empty
expect(dangerfile.status_report[:errors]).to be_empty
actual_markdowns = dangerfile.status_report[:markdowns]
expect(actual_markdowns.first&.message).to be_nil
end
end

context 'when there is a new privacy violation when running packwerk check' do
let(:offenses) { [generic_privacy_violation] }

Expand Down
4 changes: 1 addition & 3 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ def sorbet_double(stubbed_class, attr_map = {})
end
end

def write_package_yml(
pack_name
)
def write_package_yml(pack_name)
write_pack(pack_name, { 'enforce_dependencies' => true, 'enforce_privacy' => true })
end
Loading