danger-packwerk 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/danger-packwerk/basic_reference_offense.rb +37 -9
- data/lib/danger-packwerk/danger_deprecated_references_yml_changes.rb +6 -3
- data/lib/danger-packwerk/private/default_offenses_formatter.rb +1 -2
- data/lib/danger-packwerk/version.rb +1 -1
- data/sorbet/rbi/todo.rbi +3 -1
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8789235e049c26367bdf6a909d22646d76b44adb350fb35e777d2be40ec0e14a
|
4
|
+
data.tar.gz: 1bd02af0c72f377ad0a7982681fe9bfdb8bc6e4550fdb6b756ee8e9840cba27b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3839e46d7a89a4dbb7dcee0957be8d891a9e151d29485f06e8a53ab21a92af7a7a1a2d4c09da48030e6c95040956c6e4f92d380a663a57c02b48085fa189ff62
|
7
|
+
data.tar.gz: ddcb0fec757eafe11d18b5c0146202fb3ea6a655087bf3c11534a3f556f85ccf76a945eca3a86683ba37197f9ca22a8fc1ad92049bdd0b7cfd4a80ff73125bdb
|
@@ -38,38 +38,66 @@ module DangerPackwerk
|
|
38
38
|
const :file, String
|
39
39
|
const :to_package_name, String
|
40
40
|
const :type, String
|
41
|
-
const :
|
41
|
+
const :file_location, Location
|
42
42
|
|
43
43
|
sig { params(deprecated_references_yml: String).returns(T::Array[BasicReferenceOffense]) }
|
44
44
|
def self.from(deprecated_references_yml)
|
45
45
|
deprecated_references_yml_pathname = Pathname.new(deprecated_references_yml)
|
46
46
|
violations = Private::DeprecatedReferences.from(deprecated_references_yml_pathname).violations
|
47
47
|
|
48
|
+
# See the larger comment below for more information on why we need this information.
|
49
|
+
# This is a small optimization that lets us find the location of referenced files within
|
50
|
+
# a `deprecated_references.yml` file. Getting this now allows us to avoid reading through the file
|
51
|
+
# once for every referenced file in the inner loop below.
|
52
|
+
file_reference_to_line_number_index = T.let({}, T::Hash[String, T::Array[Integer]])
|
53
|
+
all_referenced_files = violations.flat_map(&:files).uniq
|
54
|
+
deprecated_references_yml_pathname.readlines.each_with_index do |line, index|
|
55
|
+
# We can use `find` here to exit early since each line will include one path that is unique to that file.
|
56
|
+
# Paths should not be substrings of each other, since they are all paths relative to the root.
|
57
|
+
file_on_line = all_referenced_files.find { |file| line.include?(file) }
|
58
|
+
# Not all lines contain a reference to a file
|
59
|
+
if file_on_line
|
60
|
+
file_reference_to_line_number_index[file_on_line] ||= []
|
61
|
+
file_reference_to_line_number_index.fetch(file_on_line) << index
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
48
65
|
violations.flat_map do |violation|
|
49
|
-
#
|
50
|
-
# We
|
66
|
+
#
|
67
|
+
# We identify two locations associated with this violation.
|
68
|
+
# First, we find the reference to the constant within the `deprecated_references.yml` file.
|
69
|
+
# We know that each constant reference can occur only once per `deprecated_references.yml` file
|
51
70
|
# The reason for this is that we know that only one file in the codebase can define a constant, and packwerk's constant_resolver will actually
|
52
71
|
# raise if this assumption is not true: https://github.com/Shopify/constant_resolver/blob/e78af0c8d5782b06292c068cfe4176e016c51b34/lib/constant_resolver.rb#L74
|
53
72
|
#
|
73
|
+
# Second, we find the reference to the specific file that references the constant within the `deprecated_references.yml` file.
|
74
|
+
# This can occur multiple times per `deprecated_references.yml` file, but we know that the very first reference to the file after the class name key will be the one we care
|
75
|
+
# about, so we take the first instance that occurs after the class is listed.
|
76
|
+
#
|
54
77
|
# Note though that since one constant reference in a `deprecated_referencs.yml` can be both a privacy and a dependency violation AND it can occur in many files,
|
55
78
|
# we need to group them. That is -- if `MyPrivateConstant` is both a dependency and a privacy violation AND it occurs in 10 files, that would represent 20 violations.
|
56
79
|
# Therefore we will group all of those 20 into one message to the user rather than providing 20 messages.
|
57
|
-
|
58
|
-
|
80
|
+
#
|
81
|
+
_line, class_name_line_number = deprecated_references_yml_pathname.readlines.each_with_index.find { |line, _index| line.include?(violation.class_name) }
|
82
|
+
if class_name_line_number.nil?
|
59
83
|
debug_info = { class_name: violation.class_name, to_package_name: violation.to_package_name, type: violation.type }
|
60
84
|
raise "Unable to find reference to violation #{debug_info} in #{deprecated_references_yml}"
|
61
85
|
end
|
62
86
|
|
63
|
-
# We add one to the line number since `each_with_index` is zero-based indexed but Github line numbers are one-based indexed
|
64
|
-
location = Location.new(file: deprecated_references_yml, line_number: line_number + 1)
|
65
|
-
|
66
87
|
violation.files.map do |file|
|
88
|
+
file_line_numbers = file_reference_to_line_number_index.fetch(file, [])
|
89
|
+
file_line_number = file_line_numbers.select { |index| index > class_name_line_number }.min
|
90
|
+
raise "Unable to find reference to violation #{{ file: file, to_package_name: violation.to_package_name, type: violation.type }} in #{deprecated_references_yml}" if file_line_number.nil?
|
91
|
+
|
92
|
+
# We add one to the line number since `each_with_index` is zero-based indexed but Github line numbers are one-based indexed
|
93
|
+
file_location = Location.new(file: deprecated_references_yml, line_number: file_line_number + 1)
|
94
|
+
|
67
95
|
BasicReferenceOffense.new(
|
68
96
|
class_name: violation.class_name,
|
69
97
|
file: file,
|
70
98
|
to_package_name: violation.to_package_name,
|
71
99
|
type: violation.type,
|
72
|
-
|
100
|
+
file_location: file_location
|
73
101
|
)
|
74
102
|
end
|
75
103
|
end
|
@@ -44,9 +44,12 @@ module DangerPackwerk
|
|
44
44
|
)
|
45
45
|
|
46
46
|
current_comment_count = 0
|
47
|
-
|
47
|
+
|
48
|
+
violation_diff.added_violations.group_by(&:class_name).each do |_class_name, violations|
|
48
49
|
break if current_comment_count >= max_comments
|
49
50
|
|
51
|
+
location = T.must(violations.first).file_location
|
52
|
+
|
50
53
|
markdown(
|
51
54
|
added_offenses_formatter.call(violations),
|
52
55
|
line: location.line_number,
|
@@ -71,13 +74,13 @@ module DangerPackwerk
|
|
71
74
|
git.deleted_files.grep(DEPRECATED_REFERENCES_PATTERN).each do |deleted_deprecated_references_yml_file|
|
72
75
|
# Since the file is deleted, we know on the HEAD commit there are no violations related to this pack,
|
73
76
|
# and that all violations from this file are deleted
|
74
|
-
|
77
|
+
deleted_violations = get_violations_before_patch_for(deleted_deprecated_references_yml_file)
|
78
|
+
removed_violations += deleted_violations
|
75
79
|
end
|
76
80
|
|
77
81
|
git.modified_files.grep(DEPRECATED_REFERENCES_PATTERN).each do |modified_deprecated_references_yml_file|
|
78
82
|
head_commit_violations = BasicReferenceOffense.from(modified_deprecated_references_yml_file)
|
79
83
|
base_commit_violations = get_violations_before_patch_for(modified_deprecated_references_yml_file)
|
80
|
-
|
81
84
|
added_violations += head_commit_violations - base_commit_violations
|
82
85
|
removed_violations += base_commit_violations - head_commit_violations
|
83
86
|
end
|
@@ -28,8 +28,7 @@ module DangerPackwerk
|
|
28
28
|
else # violations.any?(&:privacy?)
|
29
29
|
<<~MESSAGE
|
30
30
|
Hi! It looks like the pack defining `#{constant_name}` considers this private API.
|
31
|
-
#{disclaimer}
|
32
|
-
#{request_to_add_context}
|
31
|
+
#{disclaimer}#{request_to_add_context}
|
33
32
|
MESSAGE
|
34
33
|
end
|
35
34
|
end
|
data/sorbet/rbi/todo.rbi
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: danger-packwerk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gusto Engineers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04-
|
11
|
+
date: 2022-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: danger-plugin-api
|
@@ -81,35 +81,35 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: rspec
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
103
|
+
version: '3.0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
110
|
+
version: '3.0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop
|
112
|
+
name: rubocop
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
@@ -123,7 +123,7 @@ dependencies:
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name: sorbet
|
126
|
+
name: rubocop-sorbet
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - ">="
|
@@ -137,7 +137,7 @@ dependencies:
|
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
140
|
+
name: sorbet
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - ">="
|
@@ -151,7 +151,7 @@ dependencies:
|
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: tapioca
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
157
|
- - ">="
|