After updating to 0.41.0, I've noticed a change of behavior with nested configs and using --config
. We have a config file in the root of the project and nested configs in Test folders using disabled_rules
.
disabled_rules
from the nested config would be applied when calling swiftlint lint --config .swiftlint.yml
disabled_rules
from the nested config are NOT applied when calling swiftlint lint --config .swiftlint.yml
. They're applied if I don't pass --config
though.
This is especially a problem because we use danger-ruby-swiftlint, which always uses --config
swiftlint version
to be sure)? 0.41.0# insert yaml contents here
xcodebuild -version
)? 12.2.1echo "[string here]" | swiftlint lint --no-cache --use-stdin --enable-all-rules
swiftlint lint --path [file here] --no-cache --enable-all-rules
.// This triggers a violation:
let foo = try! bar()
Sorry for this pain @marcelofabri. This was an intentional change that @jpsim and I discussed in #3362, and it was implemented in #3379. The behavior you were relying on was indeed how SwiftLint was working, but was deemed unintentional behavior. If you're explicitly passing in a config, it doesn't really make sense to merge that config with any other configs. We now treat an explicitly passed-in config as an "override" instead.
This likely should have been noted as a breaking change in the release notes instead of a bug fix, but it _was_
released along with other breaking changes, so I think that's still ok in terms of versioning.
Thanks for the clarification, @sethfri - I'm glad this is intentional. Unfortunately (as you've probably realized now), handling nested configs is kind of a landmine π
I've submitted https://github.com/ashfurrow/danger-ruby-swiftlint/pull/154 to handle this on danger-ruby-swiftlint
Totally agree π
Hopefully the new behavior for --config
is a little clearer going forward. It will always be treated as an explicit override and never implicitly merged with other configs. I think it's the implicit nature of SwiftLint's config system that makes it especially tricky in general
Is there any way to disable rules in a specific directory when not using nested configs?
@cltnschlosser I don't believe so. I think that was the intended use case for nested configs. Is there a reason you can't use nested configs?
Well we have multiple projects using the same config via --config
. Previously nested configs was being used as well, but that _feature_ was removed. It would be nice to share the configs without needing to duplicate them.
Maybe simlinks will work, will have to test.
Can you not disable a rule in a nested config any more?
@jpsim You can. I believe @cltnschlosser is talking about how passing in a config vΓa --config
is treated as an override instead of being merged
Ah yes, thatβs totally what we discussed too when merging the PR.
Looks like we can simlink to the config and drop the --config
parameter in all the projects.
(root)
βββ .swiftlint.yml
βββ Dir (pwd)
βΒ Β βββ
Before 0.41.0, when swiftlint --path ../
was executed from pwd
in the graph above, it behaved the same as when executed swiftlint
from root.
That's not the case with 0.41.0.
Is this also the intended behavior change?
SwiftLint's configuration merging/nesting behavior has always been a bit of a landmine. It's not always clear how given a mix of various parameters the tool _should_ behave and when it's not clear, how we can reason about the observed behavior.
Before continuing much further, I'd really appreciate if someone (perhaps @sethfri or @fredpi since you both had to consider a lot scenarios when touching configuration resolution lately) could take a stab at _documenting_ the various scenarios and expected behaviors for configuration resolution (finding + merging) so that we can more formally discuss tradeoffs in strategies.
We've covered configuration merging through unit tests before, but that hasn't done much to avoid accidentally breaking the complex range of possible usage patterns that exist "in the wild".
@jpsim I guess it is best to document nested configs over at https://github.com/realm/SwiftLint/pull/3058. That PR already updates the documentation regarding nested configs and I will try to make it even more specific.
IMO what @soranoba described in https://github.com/realm/SwiftLint/issues/3417#issuecomment-724443010 is a legit bug:
(root) βββ .swiftlint.yml βββ Dir (pwd) β βββ
Before 0.41.0, when
swiftlint --path ../
was executed frompwd
in the graph above, it behaved the same as when executedswiftlint
from root.
We have some excluded
paths in our .swiftlint.yml
. If I run just swiftlint lint
from the (root)
, these paths are respected. However, if I run swiftlint lint
from Dir
with either of the following, the excluded
paths are not honored:
swiftlint lint --config ../.swiftlint.yml --path ../
swiftlint lint --config ../.swiftlint.yml
swiftlint lint --path ../
swiftlint lint
In the hopes of this getting fixed and not being intended behavior (I don't see how it would be), here's how you can downgrade back to 0.40.3
, in case you are using brew
:
# Download the formula right before it was upgraded to `0.41.0`
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/bb4c1a37e7f2e96da070ecc70a6d312d78bda672/Formula/swiftlint.rb
# Uninstall current version
brew uninstall swiftlint
# Install `0.40.3`
brew install ./swiftlint.rb
And now swiftlint lint --path ../
(as described in https://github.com/realm/SwiftLint/issues/3417#issuecomment-726218225) works as expected again.
Another option, if you don't want to downgrade, is to replace --path
with cd
, like so:
# broken
swiftlint lint --path ../
# works
(cd ../ && swiftlint lint)
By wrapping the commands in braces the CWD is only changed for swiftlint
.
This works with 0.40.3
_and_ 0.41.0
.
@buschtoens I encourage you to weigh in on the efforts to formalize the file path resolution & merging of configurations in https://github.com/realm/SwiftLint/pull/3058 to ensure that your use cases are carefully considered.
I have updated the documentation on multiple configurations via #3058 that is now merged into master
. I guess we can close this then, @jpsim?
Most helpful comment
Before 0.41.0, when
swiftlint --path ../
was executed frompwd
in the graph above, it behaved the same as when executedswiftlint
from root.That's not the case with 0.41.0.
Is this also the intended behavior change?