-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Process path/result so it's paths have same case as excludedPaths #4444
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
base: main
Are you sure you want to change the base?
Conversation
… so that it correctly resolves path case consistent with the exclude and include values.
Here's an example of your CHANGELOG entry: * Recompute the absolute path supplied on the command line as relative,….
[alexbbrown](https://github.com/alexbbrown)
[#issue_number](https://github.com/realm/SwiftLint/issues/issue_number)note: There are two invisible spaces after the entry's text. Generated by 🚫 Danger |
|
Closing while I fix a couple issues |
|
It's hard to write a test for this without actually creating files on the fileSystem, because the behaviour that changes the case of the paths actually comes from NSURL (not fileManager) reading the disk |
|
I have re-opened this pull request. If anyone reviews this, I would appreciate suggestions on how to write a test that constructs a sample set of folders and swift files in a temporary directory (see the issue for a simple example) so I can write a test. I can see only one example - in sandbox test code - where this is done so far in the SwiftLint tests. |
TL;DR;
When swiftLint is invoked like this:
on a folder
where config includes an exclusion
excludePaths can fail to actually exclude if
<path>contains path elements whose case does not exactly match the filesystem.This is because path and excludePaths are processed slightly differently, so that excludePaths gets case-corrected to the filesystem version but
<path>does not.This can occur in real situations because when checking out a git repo, the client can write the name of the git repo in ANY case. Scripts written in sibling repos may refer to it using their preferred case.
This patch fixes the case processing and makes them consistent.
Summary
Recompute the absolute path supplied on the command line as relative, so that it correctly resolves path case consistent with the exclude and include values.
To address this issue: #4415 - where a trivial use of excludes can fail if the (root) path supplied to lint is not case-identical to the path on the filesystem.
Detailed Issue
In detail: currently the included and excluded paths are always computed as relative paths, like so:
while the rootPath is just taken verbatim, and is an absolute path.
The includedPaths, excludedPaths and the rootPath (aka
path) are searched to find all lintable filesIn filterExcludedPathsByPrefix the set of lintable files reachable from the excludedPaths is subtracted from the set reachable from includedPaths plus rootPath.
This subtraction can fail if rootPath case does not exactly match the actual case of files on disk, leading to excluded paths being unexpectedly linted.
This is because rootPath is the only absolute path, and case errors in its path are not corrected.
However, the Include and Exclude paths are computed as paths relative to the CWD, and when they are converted back to absolute paths, any case errors are corrected.
Resolution
Compute the path as a path relative to CWD, and then turn it back to absolute.
Now the exact same processing that happens to the include/exclude paths is also applied to the rootPath, which means it has the same case.
Alternatives considered:
Alternative: change SourceKitten
This change could also be applied to sourceKitten's
absolutePathRepresentation(rootDirectory: String = FileManager.default.currentDirectoryPath)to make its response to the different values more consistent. However that might affect other clients of that Package in unexpected ways, so instead I think it makes sense for SwiftLint to just use that API in a more consistent way.Alternative: Case Insensitive Compare when excluding files
Instead of making the case consistent for the path/result and excludePaths path sets, we could just change it so it does a case insensitive match - of the whole URL or just the relative portion. However, it's possible some clients of swiftLint are using truly case insensitive file systems or rely on that for other reasons. Since I can't know that, I'm skipping that option.
Alternative: fix excludePaths so it doesn't adjust its case
Change excludePaths and includePaths so they don't rewrite the case of the base portions of their URLs.
That would make them consistent with the path/result URL compute. However, I don't know why that design decision was originally made: it might have an unexpected impact, so I don't want to change that. Someone with more insight may understand if that's appropriate.