Skip to content
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

Add missing .realpath checks that was causing validation error #65

Merged
merged 3 commits into from
Nov 16, 2020

Conversation

wildmaples
Copy link
Contributor

@wildmaples wildmaples commented Nov 10, 2020

What are you trying to accomplish?

There are two bugs in v1.0.1 that results in packwerk validate failure because the paths were not real paths as it was recently removed. Because there was no test to catch it, this ended up in a release.

What approach did you choose and why?

There are two fixes in this PR. I have linked the appropriate PRs / line change that caused the bug.

What should reviewers focus on?

We should get this change out ASAP.

You can help by confirming this change with the steps below:

  1. checkout a master branch of Core with a local version of Packwerk v1.0.1 linked
  2. run bin/spring packwerk validate - this will fail
  3. checkout this branch and run validate again - this should pass

Type of Change

  • Bugfix
  • New feature
  • Non-breaking change (a change that doesn't alter functionality - i.e., code refactor, configs, etc.)

Additional Release Notes

  • Breaking change (fix or feature that would cause existing functionality to change)

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

  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • It is safe to rollback this change.

@wildmaples wildmaples changed the title Add .realpath back to #package_manifests Add missing .realpath checks that was causing validation error Nov 11, 2020
path = Pathname.new(path_string)

next unless path.exist?
# ignore paths outside of the Rails root
next unless path.exist? && path.realpath.fnmatch(Rails.root.join("**").to_s)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously we did the check to see if the path exist and if the realpath version matches a path inside the rails root. The latter part of the check was removed in this PR: https://github.com/Shopify/packwerk/pull/21/files#diff-e43184d1a960a3c3821da21b3eb72c83379c2dcc996f6bcfac9aadd6898cd374L64

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: it feels a bit clearer to me if these two conditionals exist on their own lines:

next unless path.exist?
next unless path.realpath.fnmatch(Rails.root.join("**").to_s)

path.exist? is a precondition for the rest of the loop, not just for your new Rails path condition.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we test this new condition in configuration_test? Maybe by appending an external path to Rails.application.config.autoload_paths beforehand? Don't forget to restore the paths to their old value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we test this new condition in configuration_test? Maybe by appending an external path to Rails.application.config.autoload_paths beforehand? Don't forget to restore the paths to their old value.

Tested in #68 where this logic was moved into its own class.

@@ -329,7 +329,8 @@ def package_glob
end

def package_manifests(glob_pattern)
PackageSet.package_paths(@configuration.root_path, glob_pattern).map(&:to_s)
PackageSet.package_paths(@configuration.root_path, glob_pattern)
.map { |f| File.realpath(f) }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified that File.realpath(Pathname) returns a string, so there's no need to add to_s like in the old code.

[9] pry(main)> File.realpath(Pathname.new("."))
=> "/Users/rochlefebvre/src/github.com/Shopify/parsnip"

👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\nit I'm thinking out loud here, but could it make sense to add a method to the PackageSet that returns all the realpaths for the given packages instead of ApplicationValidator being aware of retrieving that information? 🤔

@wildmaples wildmaples marked this pull request as ready for review November 11, 2020 14:51
@wildmaples wildmaples requested a review from a team as a code owner November 11, 2020 14:51
Copy link
Contributor

@exterm exterm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can add a test, we can merge this. Thank you, Maple!

@wildmaples
Copy link
Contributor Author

If we can add a test, we can merge this. Thank you, Maple!

I know this is not optimal, but I tried testing and it is hard. Two changes in this PR:

  • For the validator: we have an existing issue for ApplicationValidator unit tests and I believe @rochlefebvre is working on it.
  • The change within Configuration#all_application_autoload_paths is also quite hard to test without a huge refactor. We could move the Rails logic out of the method/class so we can make it easier to test but unfortunately that is without a larger refactor right now.

I don't want to avoid testing. Can you see any easy test suite I can add to account for either these two cases? Otherwise I vote to ship this change/release and work on the test in another PR.

@exterm
Copy link
Contributor

exterm commented Nov 11, 2020

The way I see it, all_application_autoload_paths does three things:

  1. get all autoload paths out of rails
  2. filter the paths to just the ones that are interesting to us
  3. warn if no paths remain

The part that broke was 2.. If you can extract these three steps into separate methods, you should be able to easily test just step 2. It would just be a method that takes a list of paths as well as an application root path and a bundle path, and returns a list of paths.

paths.map { |path| path.relative_path_from(rails_root).to_s }
paths
.map { |path| path.relative_path_from(rails_root).to_s }
.uniq
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this .uniq because #filter_relevant_paths may result in some added load paths. This was causing a failure when I tophatted on Core.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .uniq was removed from ApplicationValidator here, but I figure it is best to add it in this class so we can also test for it.

Copy link
Contributor

@tomstuart tomstuart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code change looks correct to me. I tophatted it on core and it works. Thank you!

@wildmaples wildmaples merged commit 549ee51 into main Nov 16, 2020
@wildmaples wildmaples deleted the fix-realpath branch November 16, 2020 18:24
@tonymarklove-babylon
Copy link

Apologies for the breakage, everyone! I was just looking at the latest version and spotted that I managed to break an entire release. 🤦 It worked on our codebase!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants