What should the RootNamespace be for a pack located in a subfolder? (Packs/RootNamespaceIsPackName cop)

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

Message originally sent by slack user U72QH3HFB69

Hello :wave: - We have a question around pack naming and what the RootNamespace should be.

In the packwerk documentation the name of the pack is defined as the path from the project root to the folder with the package.yml. For example, if the package.yml is in ‘packs/legacy’, then the packname is ‘packs/legacy’.

We have the Packs/RootNamespaceIsPackName cop enabled, and in this case the cop verifies that the RootNamespace is ‘Legacy::’.

If we add another level to the file structure, e.g. packs/legacy/foo, should the RootNamespace in this case be Legacy::Foo, or just ‘Foo’ since that is the folder where the package.yml is located at?

Message originally sent by slack user U72QH3HFB69

We noticed that the Packs/RootNamesapcePackName cop only verifies that the folder name is in the RootNamespace and not the entire pack name. Is there a specific reason that the cop only checks for the folder name and not the entire packname (including the full path)?

Message originally sent by slack user U70VMMV37TJ

When we wrote the rubocop, all the packs lived under one folder, /packs — we’ve since explored nested packs, and I suspect that you have found a bug.

You can learn more about the cop at this repo: https://github.com/rubyatscale/rubocop-packs/blob/main/lib/rubocop/cop/packs/root_namespace_is_pack_name.rb

Message originally sent by slack user U70VMMV37TJ

When all our packs are in one directory, we expect the ruby namespace to match the path, so packs/companies/app/public/companies/identity.rb would be…

module Companies
   class Identity
   end
end

Message originally sent by slack user U70VMMV37TJ

Because we moved files around quite a bit, a pack might have several namespaces in it (for legacy reasons), but ideally all ruby code in that pack would belong to the same top level module.

Message originally sent by slack user U70VMMV37TJ

e.g. packs/companies/app/public/ would only have one folder in it, companies

Message originally sent by slack user U72V5TEEY5V

Hey Todd, could you elaborate on how your exploration with nested packs went? We currently have a folder structure that’s like packs/legacy/serializer_shims/app/… , would you expect the the folder structure under app to be packs/legacy/serializer_shims/app/legacy/serializer_shims or packs/legacy/serializer_shims/app/serializer_shims ?

<@U72QH3HFB69> the cop was intended to ensure that the top-level namespace would match the pack’s name (just the last part of the package path … as you observed). It makes no statements about nested namespaces within that.

Your question regarding packs/legacy/foo is actually handled by zeitwerk. It will expect that folder to define Legacy::Foo. It is important to note that my answer assumes that you’re using packs-rails or a compatible autoloading setup.

<@U72V5TEEY5V> are you using packs-rails and zeitwerk? Also, where in your example are the package.yml files?

Message originally sent by slack user U72QH3HFB69

@stephan Our monolith that we are currently packing up is not a true “rails” app. It’s a mixture of grape/sinatra/activerecord/activesupport that is structured very much like a traditional Rails app. We are using the packwerk rust implementation and everything is loaded with Zeitwerk.

Our question is more around what the recommendation is when dealing with sub-packs. Should we make the RootNamespace the entire path? Or just the last part of the package path? Is there a best practice?

Message originally sent by slack user U72QH3HFB69

To answer for <@U72V5TEEY5V>, the package.yml file, in his example, is in the packs/legacy/serializer_shims folder.

Should we make the RootNamespace the entire path? Or just the last part of the package path? Is there a best practice?

We’ve been going back and forth on this and there is no perfect answer. I understand why you want it to be the first (entire path)… but then moving packs becomes a total hassle. Last part is weird, because now you can have namespace collisions unless you also enforce that every pack has a unique name.