Configuring Rubocop with Packwerk to apply cops to files in packs folders

This message was imported from the Ruby/Rails Modularity Slack server. Find more info in the import thread.

Message originally sent by slack user U72GGKIGPTW

Is anyone using rubocop-rails with Packwerk? And if so, how are you configuring Rubocop to work with your packs folders? Details in thread :arrow_down:

Message originally sent by slack user U72GGKIGPTW

I am implementing Packwerk for the first time, and am running into an issue where rubocop is no longer applying certain cops to files in my packs. rubocop-rails has a bunch of cops with specific includes, e.g. “Rails/FindBy” by default only applies to “app/models//*.rb”. I’d like to keep the default configuration for these cops, and have them check the same path but inside the packs, e.g. “packs//app/models/**/*.rb”. But this isn’t happening when I run rubocop from the root dir, and I’m not sure how to set up my .rubocop.yml(s) to make this happen. I don’t want to override every single opinionated cop in rubocop-rails with custom includes. I do have a root .rubocop.yml that I would like to apply to every pack; the only solution I’ve found so far is to copy the root .rubocop.yml into each pack, which isn’t very maintainable or DRY.

Anyone have any pointers on this? It seems like Rails Engines would have the same problem; I found some open rubocop-rails issues here and here, but no solution yet. Thanks in advance!

Yeah, at Gusto, we just override the rubocop-rails cops so they look at pack directories as well.

For example, here’s a default for one cop, and here’s our override:

Rails/Exit:
  Exclude: []
  Include:
    - app/**/*.rb
    - config/**/*.rb
    - lib/**/*.{rb,rake}
    - packs/**/{app,lib}/**/*.{rb,rake}

Message originally sent by slack user U72GGKIGPTW

Thanks for sharing, @AlexEvanczuk! Aw snap, that’s the pattern I was hoping to avoid :upside_down_face: it makes sense that you’d have to do that, though, if there’s no other way. I’m guessing you’ve got a ton of overrides, then, and would need to update that list whenever you update rubocop-rails?

Basically yeah. We don’t update it that often, but generally speaking with that pattern if there are new cops/new patterns in rubocop-rails then yeah it’d need manual maintenance to add the override.

I agree it’s not ideal.

At some point it would be great to have better support for packs in rubocop, where basically we can have pack-level rubocops say extends: '../../.rubocop.yml, which would then place all rubocop (including rubocop-rails) cops to be relative to the pack. The hard part I think is reaching an agreement with rubocop maintainers so modular monoliths are better supported with rubocop, but it’d make patterns like this a lot simpler to implement.

Message originally sent by slack user U72GGKIGPTW

That makes sense - thank you so much!

Message originally sent by slack user U712YWCKK8T

We’ve been adding a .rubocop.yml file at the root of each pack with the following content:

inherit_from: ../../.rubocop.yml

This inherits the root config but the checks are all done from the pack’s folder, so no need to override the default config most of the time

Message originally sent by slack user U712YWCKK8T

I’m not sure if there’s an advantage to inherits_from vs extends, but I know it works

Message originally sent by slack user U712YWCKK8T

(I had actually started a thread about this before, but it seems it’s been lost due to the free plan)

Message originally sent by slack user U72GGKIGPTW

Tried this and it works beautifully - thank you <@U712YWCKK8T>!