Packwerk check warning for dependencies between /services and /packages

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

Message originally sent by slack user U70DMI6W1TM

OK, having a weird issue: we have packs defined in two places – within /app (covering code we haven’t yet moved into our domain-specific packs) and in /services (the domain-specific packs; these are Rails engines). We’re trying to add a third location to differentiate packs with HTTP APIs (which will stay in services) and those that are purely internal, which will live in /packages and which won’t be engines.

My problem is that packwerk check is warning when code in one of the new /packages violates a /services dependency, but it isn’t warning in the other direction, when code in a /services pack violates a /packages dependency. Pack config is the same between the two (enforce_privacy and enforce_dependencies both set to true in all relevant packs)

Does anyone have any ideas?

:thinking_face: Can you provide a minimal repro case? If not we can dig in more!

Message originally sent by slack user U70DMI6W1TM

Yeah, that’s the problem – I can repro it in our system (where the /packages pack is super barebones), but the system as a whole is … very far from minimal. I haven’t had time to stand up a fresh Rails 6 app, add an engine to it, and try there yet :disappointed:

Message originally sent by slack user U70TIGAX94P

Are dependency violations between packages in /packages correctly reported?

Message originally sent by slack user U70TIGAX94P

(Trying to find out whether constants defined in there are even correctly resolved)

Message originally sent by slack user U70DMI6W1TM

we’ve only got one package in /packages at present, but that’s a good idea – I’ll test it out first thing in the morning

Message originally sent by slack user U70DMI6W1TM

OK, checked, and I’m not getting violations from one /package pack to another

Message originally sent by slack user U70DMI6W1TM

And I just set up a minimal repro, which makes me think I’m missing something blatantly obvious. Here it is:

https://github.com/bscofield/packwerk-debug

(details are in the README)

Can you try removing package_paths from packwerk.yml and see if it fixes anything for ya?

Message originally sent by slack user U70DMI6W1TM

Nope, doesn’t fix it

Interesting… where do you set your load paths for /packages?

So I pulled your repo and noticed a couple of things. The path to EaterData::Eater is packages/eater_data/models/eater.rb. By default, zeitwerk won’t know how to find this. You need to configure your autoload paths so that zeitwerk would know how to find these constants, as packwerk relies on the conventions of zeitwerk to work.

We published a gem that makes this easy: https://github.com/rubyatscale/stimpack

With this, you can divide up your app like: packs/*/app/services/* and it will set up the autoload paths for you.

Message originally sent by slack user U70DMI6W1TM

ya, I’ve played with load_paths and collapse_paths (not in the repro); I’ll pull in what we’ve tried there

Message originally sent by slack user U70DMI6W1TM

I also looked at stimpack, but my intuition was that its opinions wouldn’t match our existing app

Message originally sent by slack user U70DMI6W1TM

updated the repo with the autoload, eager_load, and collapse changes

Interesting, would love to hear more about which opinions didn’t match your existing app!

I know some folks were working on making collapse work with packwerk, but not sure if that ended up going through.

https://github.com/Shopify/packwerk/blob/18a42c952164dfe40d1bd88d7c8a3268f9bf7108/README.md#limitations