Support nested packs with UsePackwerk - #6
Conversation
|
|
||
| package = ParsePackwerk::Package.from(package_location.join(ParsePackwerk::PACKAGE_YML_NAME)) | ||
|
|
||
| package = T.must(ParsePackwerk.package_from_path(path)) |
There was a problem hiding this comment.
The above was just a way of finding what package the file belonged to. Now that ParsePackwerk implements this, this could all be removed.
|
|
||
| sig { params(original_package: ParsePackwerk::Package).returns(ParsePackwerk::Package) } | ||
| def self.rewrite_package_with_original_packwerk_values(original_package) | ||
| ParsePackwerk.bust_cache! |
There was a problem hiding this comment.
This is because I added a cache to ParsePackwerk.all.
I slightly regret doing that, since it ended up being a bit confusing, and I think I want to change to something closer to what packwerk does later:
rubyatscale/parse_packwerk#9
| new_package_root.join(T.must(parts[2..]).join('/')).cleanpath | ||
| else | ||
| raise StandardError.new("Don't know how to find destination path for #{origin_pathname.inspect}") | ||
| Pathname.new(origin_pathname.to_s.gsub(origin_pack.name, new_package_root.to_s)).cleanpath |
There was a problem hiding this comment.
The old implementation was a bit convoluted because I was basically inferring whether it was the root pack or a parent pack based on the first parts of the directory. It's much more explicit to just swap out the old pack name with the new one! This actually resulted in even less code for the child pack case.
| filepath_without_pack_name = origin_pathname.to_s.gsub("#{origin_pack.name}/", '') | ||
| end | ||
|
|
||
| # We join the pack name with the rest of the path... |
There was a problem hiding this comment.
Similar to above -- I was casing based on whether it was a root or parent pack. This implementation just looks at the path following the pack name, which I think is a lot simpler to understand.
| - packs/organisms/app/services/bug_like/fly.rb | ||
| CONTENTS | ||
|
|
||
| write_file('packs/organisms/package.yml', <<~CONTENTS) |
There was a problem hiding this comment.
The new implementation requires that packs exist for us to be able to find what pack a file belongs to, so the tests need to be changed accordingly.
I found the tests a bit convoluted coming back to them, so I want to do some work at some point to clean up UsePackwerk tests (making each test have a smaller, inline setup).
| @@ -1,6 +1,10 @@ | |||
| # typed: false | |||
| RSpec.describe UsePackwerk do | |||
|
|
|||
There was a problem hiding this comment.
Lots of new tests for the new behavior. Definitely view with "hide whitespace change" set to true since I did a lot of context nesting of the old tests.
Adds explicit least-privilege GITHUB_TOKEN permissions to the three reusable-workflow callers that had none (alerts #4, #2, #1), matching the job-level style already used in ci.yml and codeql.yml: - cd.yml -> contents: write. shared-config's cd.yml checks out with persisted credentials and runs discourse/publish-rubygems-action (rake release does a raw git push of the version tag) followed by gh release create, both of which need write access to contents. - stale.yml -> issues: write + pull-requests: write. shared-config's stale.yml runs actions/stale, which comments on and closes both stale issues and stale pull requests. - triage.yml -> issues: write. shared-config's triage.yml runs gh issue edit --add-label triage. Fixes the two rb/shell-command-constructed-from-input alerts (#5, #6) in Packs.check, where the caller-supplied file list was interpolated into a single string handed to Kernel#system and therefore to /bin/sh. A path containing a space, quote, semicolon or backtick would have been re-interpreted by the shell. Private.system_with now takes the argv array and splats it into system, so the command is exec'd directly and never goes through a shell. All six callers in lib/packs.rb and the two specs that stub the seam are updated. The sig is params(argv: T::Array[String]); T.unsafe is needed only because Sorbet cannot type-check a splat of statically unknown size. srb tc, rspec (119 examples) and rubocop all pass; actionlint is clean on the workflow files.
Overall, this turned out to be easier than I thought, since I realized for a lot of the logic to determine new paths I just needed to swap the old path name in the path for the new path name -- nothing too fancy needed.
I did have a hard time with the tests, most of all, because they are a bit convoluted and I'd like to clean them up.