-
Notifications
You must be signed in to change notification settings - Fork 113
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
Packwerk checks for stale violations #61
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for doing this, Cindy!
No showstoppers here but I had a few ideas while reading through your code so I’ve added some comments for now in case you’d like to discuss them. Let me know what you think.
@@ -0,0 +1,45 @@ | |||
# typed: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good that new files to this codebase are in strict
mode. A lot of the benefits from sorbet only arise if we have enough type information available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While that would be nice, these methods are extracted from what used to be UpdatingDeprecatedReferences class and unfortunately I don't have enough context to know what the signatures for these classes would be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is important that we continue adopting sorbet in this codebase because it will improve the code's maintainability over time. It is inconvenient to look up the signatures, but it is beneficial in the long term.
Some classes in this codebase are hard to add typing, but in this case, the type signatures are pretty straightforward. I've added the signatures to the missing methods below, so once adopted, you should be able to change the class to strict:
sig { params(root_path: String, deprecated_references: T::Hash[String, Packwerk::DeprecatedReferences]) }
def initialize(root_path, deprecated_references = {})
@root_path = root_path
@deprecated_references = T.let(deprecated_references, T::Hash[String, Packwerk::DeprecatedReferences])
end
sig { params(package: Package).returns(Packwerk::DeprecatedReferences) }
def deprecated_references_for(package)
@deprecated_references[package] ||= Packwerk::DeprecatedReferences.new(
package,
deprecated_references_file_for(package),
)
end
sig { params(package: Package).returns(String) }
def deprecated_references_file_for(package)
File.join(@root_path, package.name, "deprecated_references.yml")
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I attempted to do this as it seemed like it would be low hanging fruit we could ship with this PR, but these signatures generated some really weird typecheck errors that should be further investigated in another PR. For instance, in deprecated_references_for
package param seems to be both a String and Package. It's a little weird and I really think necessitates further investigation.
5634f4f
to
0083aa2
Compare
…eferences class to support other functionality such as detecting stale deprecations
0083aa2
to
7d110ef
Compare
7d110ef
to
fe49aee
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay this is great work!
@@ -7,7 +7,6 @@ | |||
require "packwerk/reference" | |||
require "packwerk/reference_lister" | |||
require "packwerk/violation_type" | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👁️
5653fc5
to
32db927
Compare
I've pushed one more commit that moves the detect_stale_violations function that was in cli.rb into it's own class so we can get some separation of concerns in the Packwerk codebase. This required some refactoring of cli.rb as well by putting some common functions into a module. I've also updated the code to reflect some of the above mentioned comments, so please take a look. There are some sorbet signatures I have not added as it negatively affects the tests that I've written. The solution to that requires even more refactoring in my opinion. In the interest of time, I'd prefer not to drag out this PR more if it is related to further refactoring. I think this is better served by creating new GitHub issues around that so we can avoid scope creep. I'll also go ahead and rewrite some of the history so that the commits make a little more sense but after this PR is in a good enough state to ship. |
Thank you Cindy, the code looks good to me. My laptop is (very slowly) tophatting it now, then I’ll approve 👍 |
I’m sorry but I couldn’t successfully tophat
I can fix that by putting
I could fix that by making |
It was. I tested before all the refactoring shenanigans so that might've broken something. I figured it would have been covered by the test cases I wrote, but it seems like it wasn't. I'll take another look |
32db927
to
6a95712
Compare
There was a minor change in another file that broke the functionality of detect-stale-violations, I just pushed with an amended change. Tophatting should work now. |
What was the issue and how did you solve it? Edit: Asking because if you thought the test should have caught it, perhaps we are missing a test? |
RunContext#file_processor was a public function that was being used in DetectStaleViolationsCommand. However due to a refactor outside of this PR, it got changed to be a private function. However since this function was previously being used outside of it's own class, another function was written to replace the functionality of the function calls outside its' class. Thus I replaced RunContext#file_processor with RunContext#process_file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎩 Tophatted on Core and it works!!! 🎉
This is a huge (and much needed) change, but I would prefer to include it in release v1.0.3
instead of v1.0.2
.
Reason is because we are currently fixing a change for v1.0.2
and if this change is merged and for some unexpected reason breaks, we'd have two back-to-back broken versions.
Okay. Will we need to hold off merging this for a while then or would that not matter and just be something to do noted by the release manager when doing the releases? |
@progress_formatter.mark_as_failed | ||
end | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job on the feature and the cleanup 🙌
I think this PR is a good example of leaving the codebase in a better state than before 🎉
This is a huge (and much needed) change, but I would prefer to include it in release v1.0.3 instead of v1.0.2.
@wildmaples shouldn't this be a minor rather than patch version change? (v1.0.1 -> v1.1.0), because we are adding new non-breaking functionality?
MINOR version when you add functionality in a backward-compatible manner, and
https://semver.org/
…class as well as associated unit tests
…eck for stale violations as a reference lister. In addition wrote unit tests for this class
…y the functionality of dectect-stale-violations function in cli.rb
6a95712
to
e6ee950
Compare
Is anyone following up by using this to fix the stale violations check that is already in core CI? |
@exterm I'm doing that |
Have privacy checker check for shitlisted references
What are you trying to accomplish?
Adding feature for Packwerk checking stale violations. This should be incorporated into CI in the future to make sure that PRs don't pass CI if there are stale violations. Linked issue here: #12
What approach did you choose and why?
We had to refactor the code a bit to create this feature. We needed a lot of functionality in the UpdatingDeprecatedReferences.rb class but putting the change in that class didn't seem right. So CacheDeprecatingReferences.rb was created as a parent class that both UpdatingDeprecatedReferences.rb and DetectStaleDeprecatedReferences.rb now inherit from. Functionality common to both now belongs in CacheDeprecatingReferences.rb and functionality specific to updating vs detecting stale violations are now in their respective classes.
When executing the command, Packwerk will go through all the loaded files and check for violations in the files which it then stores in DetectStaleDeprecatedReferences.rb. At the end when all files were processed, we compare the deprecated_references.yml file of each component loaded to the actual violations generated. If there are references in deprecated_references.yml that aren't in the generated violations, then there are stale violations. The program will exits with status code 1. If there are no stale violations, program exits with status code 0.
What should reviewers focus on?
Any issues with the code refactor? Are there stale violation cases we may have missed with this code change?
Tophatting
My tophatting instructions use Packwerk in the shopify/shopify repo, but you can use another repo if you prefer
4) Generate a stale violation in shopify/shopify.
You can do this by changing package.yml of a component, enforcing dependencies on it and run Packwerk update to generate a deprecated_references.yml for that component which has boundary violations.
After you have a list of dependency violations for that component, you can add the component which the violation is coming from as a dependency in the package.yml of your component
dev packages detect-stale-violations path\to\your\component
$?
to check status of last command (0 if no stale violations, 1 if there were stale violations)Type of Change
Additional Release Notes
Include any notes here to include in the release description. For example, if you selected "breaking change" above, leave notes on how users can transition to this version.
If no additional notes are necessary, delete this section or leave it unchanged.
Checklist