realm / SwiftLint

A tool to enforce Swift style and conventions.
https://realm.github.io/SwiftLint
MIT License
18.58k stars 2.22k forks source link

Allow nested configs to specify parent/child configs. #3540

Open CaioSym opened 3 years ago

CaioSym commented 3 years ago

New Issue Checklist

Request

I'd like to propose allowing nested configs to specify a child_config. The current documentation states that:

Also, parent_config / child_config specifications of nested configurations are getting ignored because there's no sense to that.

However, lets take the following project structure:

ProjectRoot
       | - .swiftlint.yml // the main config with project wide rules
       | - DirA
       |      |- Sources
       |               |- //...
       |
       |      |- Tests
       |               |- .swiftlint.yml // nested config with specific rules for this folder
       |
       | - DirB
       |      |- Sources
       |               |- //...
       |
       |      |- Tests
       |               |- .swiftlint.yml // nested config with specific rules for this folder
       |
       | - DirC
       |      |- Sources
       |               |- //...
       |
       |      |- Tests
       |               |- .swiftlint.yml // nested config with specific rules for this folder
       |  
       | // Rest of the dir structure where I want just the base rules

This works great and allows me to refine the rules for the Tests Dirs A, B and C. However, let us say that I wanted to apply the exact same refinements to the Test folders on each of the 3 dirs. Right now I would be forced to copy_paste and maintain 3 different refinement files, which is quite unwieldy and bound to run out of sync.

However, if I could simply define the nested files as having a child_config pointing to a .swiftlint_test_refinements.yml then I could use that file as the single source of truth to maintain these refinements.

Another option would be to allow the nested configs to have a parent_config. swiftlint would generate the final rules for the Dir structure by using the project's config as the base, followed by any refinements from the nested config's parent_config, followed by the nested config's own refinements. I believe this would be more robust but probably harder to implement....

I believe this use case to be fairly common for mono-repo projects that have various libraries in the same project. Does the functionality seem sensible to the maintainers? If not, could you provide some guidance as to how I could achieve this with the existing rules?

Thank you for all the awesome work you folks have been doing so far!

jpsim commented 3 years ago

@fredpi is SwiftLint's resident configuration expert, maybe he can comment on this?

fredpi commented 3 years ago

@CaioSym You're totally right, this is a valid use case.

At some point during the big refactoring of the whole configuration system (when I didn't yet think about the possibility of including files from a higher level like parent_config: ../../nested_config_parent.yml) I simply decided that there's no sense to parent_config / child_config in nested configs and didn't spend any more thought on this since...

But now that you've raised this issue, I will try to implement it. Considering all possible (mis)use cases & adding tests for them may be a bit tricky and take some time (which I don't have currently), so don't expect a PR this month, but rather in April.

CaioSym commented 3 years ago

@fredpi Thanks for getting back to me. I look forward to seeing what you come up with. Please let me know if there is anything I could help out with to give back a bit!

teameh commented 3 years ago

@fredpi any luck with this? Anything we can do to help?

fredpi commented 2 years ago

@teameh Sorry for my inactivity and lack of progress on this issue – the last months have been much more busy than expected and, unfortunately, I couldn't find any time to address this and other open issues. I will have to look whether I find some time for it in the coming months.

That being said, if someone else wants to take on this issue prior to me taking action, feel free to do it!

adya commented 1 year ago

This is a really useful feature! I was looking for the same thing.

Looks like it can be implemented quite easily by changing this line: https://github.com/realm/SwiftLint/blob/6b094dd71172af748b60b6a1eac041bcd4966294/Source/SwiftLintCore/Extensions/Configuration%2BMerging.swift#L117 to pass false

I'll try to come around with a PR 🙂

teameh commented 1 year ago

Haha that sounds too good to be true. Good luck!

Skoti commented 10 months ago

It would be great if nested configs could work recursively, each being a refinement to the closest parent up the path, unless a different parent is specified via parent_config. Currently, the nested configs are very limited when you want to have a more granular configuration. Exmaple:

root
| - .swiftlint.yml
| - Tests
    | - .swiftlint.yml
    | - OtherFolder
        | - .swiftlint.yml
    | - YetAnother
        | - .swiftlint.yml

Expected behavior:

  1. Tests/.swiftlint.yml is merged to the root/.swiftlint.yml and then executed for files in Tests dir and lower unless there is a another .swiftlint.yml somewhere
  2. Tests/OtherFolder is currently merged to the root/.swiftlint.yml but the expected behavior is to be merged to the result of merging Tests/.swiftlint.yml to root/.swiftlint.yml
  3. Tests/YetAnother with a parent_config set to root/.swiftlint.yml would on-demand omit the merging with Tests/.swiftlint.yml as in the case above