danger-packwerk 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ad3f46c259911564eb4b955fb62e8152962db5c5682a6ba6000054dde9d8128
4
- data.tar.gz: ef61b403058b20869cda462629724943317e55f5f4b1bfe125f9be7323a634c4
3
+ metadata.gz: cf8895f7ae2e94e0b1d09e146176b6777ba8f952fe03381380071114fcec2bd4
4
+ data.tar.gz: 2e68e2096375433cfad68d85ca8d5eac7855dcb542b34f79417a53b1e4c9eb1b
5
5
  SHA512:
6
- metadata.gz: cfc452185f83aef5f9ff5e53c475ac7472d7cfcda477a0a1f1fcc863704df6e93358a6e6096f5d4f1afb68176c687c8748a8c2c2562458c03bac47d120de91b4
7
- data.tar.gz: '08df3f5e1d6e6d7367c3dc85f464346cf479dd13b5d831b26847b194f90190cb33e429c92095517124ae78eb0d23479c2a3b1146ab5a1ef529bfe967b9cf9192'
6
+ metadata.gz: bfbe7e86650ac170c89c014f7519d0d40abdb3d864b995d8cdb5ef2478ec3e4fe6f2e3afc4854dbc216e622a8adc99761bd7d9a420167553db6b70084446740f
7
+ data.tar.gz: b6729e1b52a5f25ae5da573d706bb1f3fc4217c750976dcd51aafd7611a5c7f53b4851727e3fd20cb66065570d2a99b0c4a4c367572c84fc08fb6918dfdfeb6b
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  `danger-packwerk` integrates [`packwerk`](https://github.com/Shopify/packwerk) with [`danger`](https://github.com/danger/danger) to provide inline comments in PRs related to boundaries in a Rails application.
4
4
 
5
- ## Installation
5
+ ## Installation and Basic Usage
6
6
  Step 1: Add this line to your `Gemfile` (to whatever group your CI uses, as it is not needed in production) and `bundle install`:
7
7
 
8
8
  ```ruby
@@ -13,41 +13,50 @@ Step 2: Add these to your `Dangerfile`:
13
13
 
14
14
  ```ruby
15
15
  packwerk.check
16
- deprecated_references_yml_changes.check
16
+ package_todo_yml_changes.check
17
17
  ```
18
18
 
19
19
  That's it for basic usage!
20
20
 
21
- ## Usage
21
+ ## Advanced Usage
22
22
 
23
23
  There are currently two danger checks that ship with `danger-packwerk`:
24
24
  1) One that runs `bin/packwerk check` and leaves inline comments in source code on new violations
25
- 2) One that looks at changes to `deprecated_references.yml` files and leaves inline comments on added violations.
25
+ 2) One that looks at changes to `package_todo.yml` files and leaves inline comments on added violations.
26
26
 
27
27
  In upcoming iterations, we will include other danger checks, including:
28
28
  1) A danger check that detects changes to `package.yml` files and posts user-configurable messages on the `package.yml` files that are modified.
29
29
  2) A danger check that detects changes to `packwerk.yml` files and allows you to specify the action taken when that happens.
30
30
 
31
31
  ## packwerk.check
32
- ![This is an image displaying a comment from the Danger github bot. The comment is inline with the PR in Github and displays the following text. Dependency violation: ::FeatureFlag belongs to 'packs/feature_flags', but 'packs/gusto_slack' does not specify a dependency on 'packs/feature_flags'. Are we missing an abstraction? Is the code making the reference, and the referenced constant, in the right packages? Inference details: this is a reference to ::FeatureFlag which seems to be defined in packs/feature_flags/app/models/feature_flag.rb. To receive help interpreting or resolving this error message, see: https://github.com/Shopify/packwerk/blob/main/TROUBLESHOOT.md#Troubleshooting-violations Privacy violation: '::FeatureFlag' is private to 'packs/feature_flags' but referenced from 'packs/gusto_slack'. Is there a public entrypoint in 'packs/feature_flags/app/public/' that you can use instead? Inference details: this is a reference to ::FeatureFlag which seems to be defined in packs/feature_flags/app/models/feature_flag.rb. To receive help interpreting or resolving this error message, see: https://github.com/Shopify/packwerk/blob/main/TROUBLESHOOT.md#Troubleshooting-violations](docs/basic_usage.png)
32
+ ![This is an image displaying a comment from the Danger github bot after running bin/packwerk check.](docs/check_1.png)
33
+ ![This is an image displaying a comment from the Danger github bot after running bin/packwerk check with the "quick suggestions" accordian open](docs/check_2.png)
33
34
 
34
- Without any configuration, `packwerk.check` should just work. By default, it will post a maximum of 15 messages in a PR, using the default messaging from packwerk, and it will not fail the build.
35
+ Without any configuration, `packwerk.check` should just work. By default, it will post a maximum of 15 messages in a PR and it will not fail the build.
35
36
 
36
37
  `packwerk.check` can be configured to in the following ways:
37
38
 
38
39
  ### Change the message that displays in the markdown
39
- The default message displayed is from `bin/packwerk check`. To customize this this, pass in `offenses_formatter` to `packwerk.check` in your `Dangerfile`. Here's a simple example:
40
+ To customize the message in the GitHub comment, pass in `offenses_formatter` to `packwerk.check` in your `Dangerfile`. Here's a simple example:
40
41
  ```ruby
41
- packwerk.check(
42
- # Offenses are a T::Array[Packwerk::ReferenceOffense] => https://github.com/Shopify/packwerk/blob/main/lib/packwerk/reference_offense.rb
43
- offenses_formatter: -> (offenses) do
44
- "There are #{offenses.count} packwerk offenses on this line!"
42
+ class MyFormatter
43
+ extend T::Sig
44
+ include DangerPackwerk::Check::OffensesFormatter
45
+ # Packwerk::ReferenceOffense: https://github.com/Shopify/packwerk/blob/main/lib/packwerk/reference_offense.rb
46
+ sig { override.params(offenses: T::Array[Packwerk::ReferenceOffense], repo_link: String, org_name: String).returns(String) }
47
+ def format_offenses(offenses, repo_link, org_name)
48
+ # your logic here
45
49
  end
46
- )
50
+ end
51
+
52
+ packwerk.check(offenses_formatter: MyFormatter.new)
47
53
  ```
48
54
 
49
- A more advanced example could give more specific information about the violation and information specific to your organization or project about how to resolve. Here is a screenshot of what our message looks like at Gusto:
50
- ![This is an image displaying a comment from the Danger github bot. The comment is inline with the PR in Github and displays the following text: Hi there! It looks like FeatureFlag is private API of packs/feature_flags, which is also not in packs/gusto_slack's list of dependencies. Before you run bin/packwerk update-deprecations, read through How to Handle Dependency and Privacy Violations (with Flow Chart!). Here are some quick suggestions to resolve: Does the code you are writing live in the right pack? If not, try bin/move_to_pack -n packs/destination_pack -f packs/gusto_slack/app/services/slack/client.rb. Does FeatureFlag live in the right pack? If not, try bin/move_to_pack -n packs/destination_pack -f packs/feature_flags/app/models/feature_flag.rb. Do we actually want to depend on packs/feature_flags. If so, try adding packs/feature_flags to packs/gusto_slack/package.yml dependencies. If not, what can we change about the design so we do not have to depend on packs/feature_flags? Does API in packs/feature_flags/public support this use case? If not, can we work with @Gusto/product-infrastructure to create and use a public API? If FeatureFlag should already be public, try bin/make_public -f packs/feature_flags/app/models/feature_flag.rb. Need help? Join us in #ruby-modularity or provide feedback.](docs/advanced_usage.png)
55
+ If you'd like to keep the default messaging but add some context customized to your organization, you can pass that in as follows:
56
+ ```ruby
57
+ custom_help_message = "Need help? Check out our internal docs [here](www.example.com)"
58
+ packwerk.check(offenses_formatter: DangerPackwerk::Check::DefaultFormatter.new(custom_help_message: custom_help_message))
59
+ ```
51
60
 
52
61
  ### Fail the build on new violations
53
62
  Simply pass in `fail_build: true` into `check`, as such:
@@ -75,42 +84,48 @@ packwerk.check(
75
84
  )
76
85
  ```
77
86
 
78
- ## deprecated_references_yml_changes.check
79
- ![This is an image displaying a comment from the Danger github bot. The comment is inline with the PR in Github and displays the following text. We noticed you ran `bin/packwerk update-deprecations`. Make sure to read through the docs for other ways to resolve.](docs/basic_usage_2.png)
87
+ ## package_todo_yml_changes.check
88
+ ![This is an image displaying an inline comment from the Danger github bot.](docs/update.png)
80
89
 
81
- Without any configuration, `deprecated_references_yml_changes.check` should just work. By default, it will post a maximum of 15 messages in a PR, using default messaging defined within this gem.
90
+ Without any configuration, `package_todo_yml_changes.check` should just work. By default, it will post a maximum of 15 messages in a PR, using default messaging defined within this gem.
82
91
 
83
- `deprecated_references_yml_changes.check` can be configured to in the following ways:
92
+ `package_todo_yml_changes.check` can be configured to in the following ways:
84
93
 
85
94
  ### Change the message that displays in the markdown
86
- The default message displayed is from `lib/danger-packwerk/private/default_offenses_formatter.rb`. To customize this this, pass in `offenses_formatter` to `deprecated_references_yml_changes.check` in your `Dangerfile`. Here's a simple example:
95
+ To customize the message in the GitHub comment, pass in `offenses_formatter` to `package_todo_yml_changes.check` in your `Dangerfile`. Here's a simple example:
87
96
  ```ruby
88
- deprecated_references_yml_changes.check(
89
- # Offenses are a T::Array[DangerPackwerk::BasicReferenceOffense]
90
- offenses_formatter: -> (added_offenses) do
91
- "There are #{added_offenses.count} new violations this line!"
97
+ class MyFormatter
98
+ extend T::Sig
99
+ include DangerPackwerk::Update::OffensesFormatter
100
+ # DangerPackwerk::BasicReferenceOffense
101
+ sig { override.params(offenses: T::Array[DangerPackwerk::BasicReferenceOffense], repo_link: String, org_name: String).returns(String) }
102
+ def format_offenses(offenses, repo_link, org_name)
103
+ # your logic here
92
104
  end
93
- )
105
+ end
106
+
107
+ package_todo_yml_changes.check(offenses_formatter: MyFormatter.new)
94
108
  ```
95
109
 
96
- A more advanced example could give more specific information about the violation and information specific to your organization or project about how to resolve. Here is a screenshot of what our message looks like at Gusto:
97
- ![This is an image displaying a comment from the Danger github bot. The comment is inline with the PR in Github and displays the following text. Hi again! It looks like FeatureFlag is private API of packs/feature_flags, which is also not in packs/gusto_slack's list of dependencies.. We noticed you ran bin/packwerk update-deprecations. Make sure to read through How to Handle Dependency and Privacy Violations (with Flow Chart!). Could you add some context as a reply here about why we needed to add these violations packs/gusto_slack/package.yml is configured with notify_on_new_violations to notify @Gusto/product-infrastructure (#product-infrastructure) on new dependency violations. packs/feature_flags/package.yml is configured with notify_on_new_violations to notify @Gusto/product-infrastructure (#product-infrastructure) on new privacy violations
98
- Need help? Join us in #ruby-modularity or provide feedback.
99
- ](docs/advanced_usage_2.png)
110
+ If you'd like to keep the default messaging but add some context customized to your organization, you can pass that in as follows:
111
+ ```ruby
112
+ custom_help_message = "Need help? Check out our internal docs [here](www.example.com)"
113
+ package_todo_yml_changes.check(offenses_formatter: DangerPackwerk::Update::DefaultFormatter.new(custom_help_message: custom_help_message))
114
+ ```
100
115
 
101
116
  ### Change the max number of comments that will display
102
117
  If you do not change this, the default max is 15. More information about why we chose this number in the source code.
103
118
  ```ruby
104
- deprecated_references_yml_changes.check(max_comments: 3)
119
+ package_todo_yml_changes.check(max_comments: 3)
105
120
  ```
106
121
 
107
122
  ### Do something extra before we leave comments
108
123
  Maybe you want to notify slack or do something else before we leave comments.
109
124
 
110
125
  ```ruby
111
- deprecated_references_yml_changes.check(
112
- # violation_diff is a DangerPackwerk::ViolationDiff and changed_deprecated_references_ymls is a T::Array[String]
113
- before_comment: -> (violation_diff, changed_deprecated_references_ymls) do
126
+ package_todo_yml_changes.check(
127
+ # violation_diff is a DangerPackwerk::ViolationDiff and changed_package_todo_ymls is a T::Array[String]
128
+ before_comment: -> (violation_diff, changed_package_todo_ymls) do
114
129
  # Notify slack or otherwise do something extra!
115
130
  end
116
131
  )
@@ -4,8 +4,8 @@ module DangerPackwerk
4
4
  #
5
5
  # We call this BasicReferenceOffense as it is intended to have a subset of the interface of Packwerk::ReferenceOffense, located here:
6
6
  # https://github.com/Shopify/packwerk/blob/a22862b59f7760abf22bda6804d41a52d05301d8/lib/packwerk/reference_offense.rb#L1
7
- # However, we cannot actually construct a Packwerk::ReferenceOffense from `deprecated_referencs.yml` alone, since they are normally
8
- # constructed in packwerk when packwerk parses the AST and actually outputs `deprecated_references.yml`, a process in which some information,
7
+ # However, we cannot actually construct a Packwerk::ReferenceOffense from `package_todo.yml` alone, since they are normally
8
+ # constructed in packwerk when packwerk parses the AST and actually outputs `package_todo.yml`, a process in which some information,
9
9
  # such as the location where the constant is defined, is lost.
10
10
  #
11
11
  class BasicReferenceOffense < T::Struct
@@ -41,21 +41,21 @@ module DangerPackwerk
41
41
  const :type, String
42
42
  const :file_location, Location
43
43
 
44
- sig { params(deprecated_references_yml: String).returns(T::Array[BasicReferenceOffense]) }
45
- def self.from(deprecated_references_yml)
46
- deprecated_references_yml_pathname = Pathname.new(deprecated_references_yml)
44
+ sig { params(package_todo_yml: String).returns(T::Array[BasicReferenceOffense]) }
45
+ def self.from(package_todo_yml)
46
+ package_todo_yml_pathname = Pathname.new(package_todo_yml)
47
47
 
48
- from_package = ParsePackwerk.package_from_path(deprecated_references_yml_pathname)
48
+ from_package = ParsePackwerk.package_from_path(package_todo_yml_pathname)
49
49
  from_package_name = from_package.name
50
- violations = Private::DeprecatedReferences.from(deprecated_references_yml_pathname).violations
50
+ violations = Private::PackageTodo.from(package_todo_yml_pathname).violations
51
51
 
52
52
  # See the larger comment below for more information on why we need this information.
53
53
  # This is a small optimization that lets us find the location of referenced files within
54
- # a `deprecated_references.yml` file. Getting this now allows us to avoid reading through the file
54
+ # a `package_todo.yml` file. Getting this now allows us to avoid reading through the file
55
55
  # once for every referenced file in the inner loop below.
56
56
  file_reference_to_line_number_index = T.let({}, T::Hash[String, T::Array[Integer]])
57
57
  all_referenced_files = violations.flat_map(&:files).uniq
58
- deprecated_references_yml_pathname.readlines.each_with_index do |line, index|
58
+ package_todo_yml_pathname.readlines.each_with_index do |line, index|
59
59
  # We can use `find` here to exit early since each line will include one path that is unique to that file.
60
60
  # Paths should not be substrings of each other, since they are all paths relative to the root.
61
61
  file_on_line = all_referenced_files.find { |file| line.include?(file) }
@@ -69,24 +69,24 @@ module DangerPackwerk
69
69
  violations.flat_map do |violation|
70
70
  #
71
71
  # We identify two locations associated with this violation.
72
- # First, we find the reference to the constant within the `deprecated_references.yml` file.
73
- # We know that each constant reference can occur only once per `deprecated_references.yml` file
72
+ # First, we find the reference to the constant within the `package_todo.yml` file.
73
+ # We know that each constant reference can occur only once per `package_todo.yml` file
74
74
  # 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
75
75
  # raise if this assumption is not true: https://github.com/Shopify/constant_resolver/blob/e78af0c8d5782b06292c068cfe4176e016c51b34/lib/constant_resolver.rb#L74
76
76
  #
77
- # Second, we find the reference to the specific file that references the constant within the `deprecated_references.yml` file.
78
- # 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
77
+ # Second, we find the reference to the specific file that references the constant within the `package_todo.yml` file.
78
+ # This can occur multiple times per `package_todo.yml` file, but we know that the very first reference to the file after the class name key will be the one we care
79
79
  # about, so we take the first instance that occurs after the class is listed.
80
80
  #
81
- # 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,
81
+ # Note though that since one constant reference in a `package_todo.yml` can be both a privacy and a dependency violation AND it can occur in many files,
82
82
  # 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.
83
83
  # Therefore we will group all of those 20 into one message to the user rather than providing 20 messages.
84
84
  #
85
- _line, class_name_line_number = deprecated_references_yml_pathname.readlines.each_with_index.find do |line, _index|
85
+ _line, class_name_line_number = package_todo_yml_pathname.readlines.each_with_index.find do |line, _index|
86
86
  # If you have a class `::MyClass`, then you can get a false match if another constant in the file
87
87
  # is named `MyOtherClass::MyClassThing`. Therefore we include quotes in our match to ensure that we match
88
88
  # the constant and only the constant.
89
- # Right now `packwerk` `deprecated_references.yml` files typically use double quotes, but sometimes folks linters change this to single quotes.
89
+ # Right now `packwerk` `package_todo.yml` files typically use double quotes, but sometimes folks linters change this to single quotes.
90
90
  # To be defensive, we match against either.
91
91
  class_name_with_quote_boundaries = /["|']#{violation.class_name}["|']:/
92
92
  line.match?(class_name_with_quote_boundaries)
@@ -94,16 +94,16 @@ module DangerPackwerk
94
94
 
95
95
  if class_name_line_number.nil?
96
96
  debug_info = { class_name: violation.class_name, to_package_name: violation.to_package_name, type: violation.type }
97
- raise "Unable to find reference to violation #{debug_info} in #{deprecated_references_yml}"
97
+ raise "Unable to find reference to violation #{debug_info} in #{package_todo_yml}"
98
98
  end
99
99
 
100
100
  violation.files.map do |file|
101
101
  file_line_numbers = file_reference_to_line_number_index.fetch(file, [])
102
102
  file_line_number = file_line_numbers.select { |index| index > class_name_line_number }.min
103
- 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?
103
+ raise "Unable to find reference to violation #{{ file: file, to_package_name: violation.to_package_name, type: violation.type }} in #{package_todo_yml}" if file_line_number.nil?
104
104
 
105
105
  # We add one to the line number since `each_with_index` is zero-based indexed but Github line numbers are one-based indexed
106
- file_location = Location.new(file: deprecated_references_yml, line_number: file_line_number + 1)
106
+ file_location = Location.new(file: package_todo_yml, line_number: file_line_number + 1)
107
107
 
108
108
  BasicReferenceOffense.new(
109
109
  class_name: violation.class_name,
@@ -45,7 +45,7 @@ module DangerPackwerk
45
45
  team_to_work_with = constant_source_package_ownership_info.owning_team ? constant_source_package_ownership_info.markdown_link_to_github_members_no_tag : 'the pack owner'
46
46
  privacy_violation_message = "- Does API in #{constant_source_package.name}/public support this use case?\n - If not, can we work with #{team_to_work_with} to create and use a public API?\n - If `#{constant_name}` should already be public, try `bin/packs make_public #{constant_location}`."
47
47
 
48
- if violation_types.include?(Packwerk::ViolationType::Dependency) && violation_types.include?(Packwerk::ViolationType::Privacy)
48
+ if violation_types.include?(::DangerPackwerk::DEPENDENCY_VIOLATION_TYPE) && violation_types.include?(::DangerPackwerk::PRIVACY_VIOLATION_TYPE)
49
49
  <<~MESSAGE
50
50
  **Packwerk Violation**
51
51
  - Type: Privacy :lock: + Dependency :knot:
@@ -65,7 +65,7 @@ module DangerPackwerk
65
65
 
66
66
  _#{@custom_help_message}_
67
67
  MESSAGE
68
- elsif violation_types.include?(Packwerk::ViolationType::Dependency)
68
+ elsif violation_types.include?(::DangerPackwerk::DEPENDENCY_VIOLATION_TYPE)
69
69
  <<~MESSAGE
70
70
  **Packwerk Violation**
71
71
  - Type: Dependency :knot:
@@ -84,7 +84,7 @@ module DangerPackwerk
84
84
 
85
85
  _#{@custom_help_message}_
86
86
  MESSAGE
87
- else # violation_types.include?(Packwerk::ViolationType::Privacy)
87
+ else # violation_types.include?(::DangerPackwerk::PRIVACY_VIOLATION_TYPE)
88
88
  <<~MESSAGE
89
89
  **Packwerk Violation**
90
90
  - Type: Privacy :lock:
@@ -9,7 +9,7 @@ require 'danger-packwerk/violation_diff'
9
9
  require 'open3'
10
10
 
11
11
  module DangerPackwerk
12
- class DangerDeprecatedReferencesYmlChanges < Danger::Plugin
12
+ class DangerPackageTodoYmlChanges < Danger::Plugin
13
13
  extend T::Sig
14
14
 
15
15
  # We choose 5 here because violation additions tend to fall into a bimodal distribution, where most PRs only add a handful (<10) of new violations,
@@ -17,8 +17,8 @@ module DangerPackwerk
17
17
  # Therefore we hope to capture the majority case of people making changes to code while not spamming PRs that do a big rename.
18
18
  # We set a max (rather than unlimited) to avoid GitHub rate limiting and general spam if a PR does some sort of mass rename.
19
19
  DEFAULT_MAX_COMMENTS = 5
20
- BeforeComment = T.type_alias { T.proc.params(violation_diff: ViolationDiff, changed_deprecated_references_ymls: T::Array[String]).void }
21
- DEFAULT_BEFORE_COMMENT = T.let(->(violation_diff, changed_deprecated_references_ymls) {}, BeforeComment)
20
+ BeforeComment = T.type_alias { T.proc.params(violation_diff: ViolationDiff, changed_package_todo_ymls: T::Array[String]).void }
21
+ DEFAULT_BEFORE_COMMENT = T.let(->(violation_diff, changed_package_todo_ymls) {}, BeforeComment)
22
22
 
23
23
  sig do
24
24
  params(
@@ -36,13 +36,13 @@ module DangerPackwerk
36
36
  repo_link = github.pr_json[:base][:repo][:html_url]
37
37
  org_name = github.pr_json[:base][:repo][:owner][:login]
38
38
 
39
- changed_deprecated_references_ymls = (git.modified_files + git.added_files + git.deleted_files).grep(DEPRECATED_REFERENCES_PATTERN)
39
+ changed_package_todo_ymls = (git.modified_files + git.added_files + git.deleted_files).grep(PACKAGE_TODO_PATTERN)
40
40
 
41
41
  violation_diff = get_violation_diff
42
42
 
43
43
  before_comment.call(
44
44
  violation_diff,
45
- changed_deprecated_references_ymls.to_a
45
+ changed_package_todo_ymls.to_a
46
46
  )
47
47
 
48
48
  current_comment_count = 0
@@ -67,16 +67,16 @@ module DangerPackwerk
67
67
  added_violations = T.let([], T::Array[BasicReferenceOffense])
68
68
  removed_violations = T.let([], T::Array[BasicReferenceOffense])
69
69
 
70
- git.added_files.grep(DEPRECATED_REFERENCES_PATTERN).each do |added_deprecated_references_yml_file|
70
+ git.added_files.grep(PACKAGE_TODO_PATTERN).each do |added_package_todo_yml_file|
71
71
  # Since the file is added, we know on the base commit there are no violations related to this pack,
72
72
  # and that all violations from this file are new
73
- added_violations += BasicReferenceOffense.from(added_deprecated_references_yml_file)
73
+ added_violations += BasicReferenceOffense.from(added_package_todo_yml_file)
74
74
  end
75
75
 
76
- git.deleted_files.grep(DEPRECATED_REFERENCES_PATTERN).each do |deleted_deprecated_references_yml_file|
76
+ git.deleted_files.grep(PACKAGE_TODO_PATTERN).each do |deleted_package_todo_yml_file|
77
77
  # Since the file is deleted, we know on the HEAD commit there are no violations related to this pack,
78
78
  # and that all violations from this file are deleted
79
- deleted_violations = get_violations_before_patch_for(deleted_deprecated_references_yml_file)
79
+ deleted_violations = get_violations_before_patch_for(deleted_package_todo_yml_file)
80
80
  removed_violations += deleted_violations
81
81
  end
82
82
 
@@ -84,13 +84,13 @@ module DangerPackwerk
84
84
  renamed_files_before = git.renamed_files.map { |before_after_file| before_after_file[:before] }
85
85
  renamed_files_after = git.renamed_files.map { |before_after_file| before_after_file[:after] }
86
86
 
87
- git.modified_files.grep(DEPRECATED_REFERENCES_PATTERN).each do |modified_deprecated_references_yml_file|
88
- # We skip over modified files if one of the modified files is a renamed `deprecated_references.yml` file.
87
+ git.modified_files.grep(PACKAGE_TODO_PATTERN).each do |modified_package_todo_yml_file|
88
+ # We skip over modified files if one of the modified files is a renamed `package_todo.yml` file.
89
89
  # This allows us to rename packs while ignoring "new violations" in those renamed packs.
90
- next if renamed_files_before.include?(modified_deprecated_references_yml_file)
90
+ next if renamed_files_before.include?(modified_package_todo_yml_file)
91
91
 
92
- head_commit_violations = BasicReferenceOffense.from(modified_deprecated_references_yml_file)
93
- base_commit_violations = get_violations_before_patch_for(modified_deprecated_references_yml_file)
92
+ head_commit_violations = BasicReferenceOffense.from(modified_package_todo_yml_file)
93
+ base_commit_violations = get_violations_before_patch_for(modified_package_todo_yml_file)
94
94
  added_violations += head_commit_violations - base_commit_violations
95
95
  removed_violations += base_commit_violations - head_commit_violations
96
96
  end
@@ -128,9 +128,9 @@ module DangerPackwerk
128
128
 
129
129
  private
130
130
 
131
- sig { params(deprecated_references_yml_file: String).returns(T::Array[BasicReferenceOffense]) }
132
- def get_violations_before_patch_for(deprecated_references_yml_file)
133
- # The strategy to get the violations before this PR is to reverse the patch on each `deprecated_references.yml`.
131
+ sig { params(package_todo_yml_file: String).returns(T::Array[BasicReferenceOffense]) }
132
+ def get_violations_before_patch_for(package_todo_yml_file)
133
+ # The strategy to get the violations before this PR is to reverse the patch on each `package_todo.yml`.
134
134
  # A previous strategy attempted to use `git merge-base --fork-point`, but there are many situations where it returns
135
135
  # empty values. That strategy is fickle because it depends on the state of the `reflog` within the CI suite, which appears
136
136
  # to not be reliable to depend on.
@@ -139,24 +139,24 @@ module DangerPackwerk
139
139
  # the PR without needing to use git commands that interpret the branch history based on local git history.
140
140
  #
141
141
  # We apply the patch to the original file so that we can seamlessly reverse the patch applied to that file (since patches are coupled to
142
- # the files they modify). After parsing the violations from that `deprecated_references.yml` file with the patch reversed,
142
+ # the files they modify). After parsing the violations from that `package_todo.yml` file with the patch reversed,
143
143
  # we use a temporary copy of the original file to rewrite to it with the original contents.
144
144
  # Note that practically speaking, we don't need to rewrite the original contents (since we already fetched the
145
145
  # original contents above and the CI file system should be ephemeral). However, we do this anyways in case we later change these
146
146
  # assumptions, or another client's environment is different and expects these files not to be mutated.
147
147
 
148
148
  # Keep track of the original file contents. If the original file has been deleted, then we delete the file after inverting the patch at the end, rather than rewriting it.
149
- deprecated_references_yml_file_copy = (File.read(deprecated_references_yml_file) if File.exist?(deprecated_references_yml_file))
149
+ package_todo_yml_file_copy = (File.read(package_todo_yml_file) if File.exist?(package_todo_yml_file))
150
150
 
151
151
  Tempfile.create do |patch_file|
152
- # Normally we'd use `git.diff_for_file(deprecated_references_yml_file).patch` here, but there is a bug where it does not work for deleted files yet.
152
+ # Normally we'd use `git.diff_for_file(package_todo_yml_file).patch` here, but there is a bug where it does not work for deleted files yet.
153
153
  # I have a fix for that here: https://github.com/danger/danger/pull/1357
154
154
  # Until that lands, I'm just using the underlying implementation of that method to get the diff for a file.
155
155
  # Note that I might want to use a safe escape operator, `&.patch` and return gracefully if the patch cannot be found.
156
156
  # However I'd be interested in why that ever happens, so for now going to proceed as is.
157
157
  # (Note that better yet we'd have observability into these so I can just log under those circumstances rather than surfacing an error to the user,
158
158
  # but we don't have that quite yet.)
159
- patch_for_file = git.diff[deprecated_references_yml_file].patch
159
+ patch_for_file = git.diff[package_todo_yml_file].patch
160
160
  # This appears to be a known issue that patches require new lines at the end. It seems like this is an issue with Danger that
161
161
  # it gives us a patch without a newline.
162
162
  # https://stackoverflow.com/questions/18142870/git-error-fatal-corrupt-patch-at-line-36
@@ -165,13 +165,13 @@ module DangerPackwerk
165
165
  # https://git-scm.com/docs/git-apply
166
166
  _stdout, _stderr, _status = Open3.capture3("git apply --reverse #{patch_file.path}")
167
167
  # https://www.rubyguides.com/2019/05/ruby-tempfile/
168
- BasicReferenceOffense.from(deprecated_references_yml_file)
168
+ BasicReferenceOffense.from(package_todo_yml_file)
169
169
  end
170
170
  ensure
171
- if deprecated_references_yml_file_copy
172
- File.write(deprecated_references_yml_file, deprecated_references_yml_file_copy)
171
+ if package_todo_yml_file_copy
172
+ File.write(package_todo_yml_file, package_todo_yml_file_copy)
173
173
  else
174
- File.delete(deprecated_references_yml_file)
174
+ File.delete(package_todo_yml_file)
175
175
  end
176
176
  end
177
177
  end
@@ -60,6 +60,16 @@ module DangerPackwerk
60
60
  def show_stale_violations(offense_collection, for_files)
61
61
  ''
62
62
  end
63
+
64
+ sig { override.params(strict_mode_violations: T::Array[::Packwerk::ReferenceOffense]).returns(::String) }
65
+ def show_strict_mode_violations(strict_mode_violations)
66
+ ''
67
+ end
68
+
69
+ sig { override.returns(::String) }
70
+ def identifier
71
+ 'offenses_aggregator'
72
+ end
63
73
  end
64
74
  end
65
75
  end
@@ -3,7 +3,7 @@
3
3
  module DangerPackwerk
4
4
  module Private
5
5
  #
6
- # The `Violation` and `DeprecatedReferences` classes come from Gusto's private `ParsePackwerk` gem.
6
+ # The `Violation` and `PackageTodo` classes come from Gusto's private `ParsePackwerk` gem.
7
7
  # Until we decide to open source that gem, we inline these as a private implementation detail of `DangerPackwerk` for now.
8
8
  #
9
9
  class Violation < T::Struct
@@ -25,22 +25,22 @@ module DangerPackwerk
25
25
  end
26
26
  end
27
27
 
28
- class DeprecatedReferences < T::Struct
28
+ class PackageTodo < T::Struct
29
29
  extend T::Sig
30
30
 
31
31
  const :pathname, Pathname
32
32
  const :violations, T::Array[Violation]
33
33
 
34
- sig { params(pathname: Pathname).returns(DeprecatedReferences) }
34
+ sig { params(pathname: Pathname).returns(PackageTodo) }
35
35
  def self.from(pathname)
36
36
  if pathname.exist?
37
- deprecated_references_loaded_yml = YAML.load_file(pathname)
37
+ package_todo_loaded_yml = YAML.load_file(pathname)
38
38
 
39
39
  all_violations = []
40
- deprecated_references_loaded_yml&.each_key do |to_package_name|
41
- deprecated_references_per_package = deprecated_references_loaded_yml[to_package_name]
42
- deprecated_references_per_package.each_key do |class_name|
43
- symbol_usage = deprecated_references_per_package[class_name]
40
+ package_todo_loaded_yml&.each_key do |to_package_name|
41
+ package_todo_per_package = package_todo_loaded_yml[to_package_name]
42
+ package_todo_per_package.each_key do |class_name|
43
+ symbol_usage = package_todo_per_package[class_name]
44
44
  files = symbol_usage['files']
45
45
  violations = symbol_usage['violations']
46
46
  all_violations << Violation.new(type: 'dependency', to_package_name: to_package_name, class_name: class_name, files: files) if violations.include? 'dependency'
@@ -1,6 +1,6 @@
1
1
  # typed: strict
2
2
 
3
- require 'danger-packwerk/private/deprecated_references'
3
+ require 'danger-packwerk/private/package_todo'
4
4
  require 'danger-packwerk/private/ownership_information'
5
5
  require 'constant_resolver'
6
6
 
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module DangerPackwerk
5
- VERSION = '0.8.0'
5
+ VERSION = '0.9.0'
6
6
  end
@@ -5,10 +5,12 @@
5
5
  require 'sorbet-runtime'
6
6
 
7
7
  module DangerPackwerk
8
- DEPRECATED_REFERENCES_PATTERN = T.let(/.*?deprecated_references\.yml\z/.freeze, Regexp)
8
+ PACKAGE_TODO_PATTERN = T.let(/.*?package_todo\.yml\z/.freeze, Regexp)
9
+ DEPENDENCY_VIOLATION_TYPE = 'dependency'
10
+ PRIVACY_VIOLATION_TYPE = 'privacy'
9
11
 
10
12
  require 'danger-packwerk/danger_packwerk'
11
- require 'danger-packwerk/danger_deprecated_references_yml_changes'
13
+ require 'danger-packwerk/danger_package_todo_yml_changes'
12
14
  require 'danger-packwerk/check/offenses_formatter'
13
15
  require 'danger-packwerk/check/default_formatter'
14
16
  require 'danger-packwerk/update/offenses_formatter'