import-linter icon indicating copy to clipboard operation
import-linter copied to clipboard

Support wildcard references to modules in contracts

Open sobolevn opened this issue 5 years ago • 12 comments

I have this directory structure: https://github.com/wemake-services/wemake-python-styleguide/tree/ae821ddb0b9c234870953ed5a17cd3858a52ee3c/wemake_python_styleguide/visitors

Every module in any module should be respect type = independent contract. But, I have like dozens of modules, and new ones are created like once a week.

What do I want? I want to enforce independent contract on all modules in a package and sub-packages. And mark several exceptions: base and decorators in my case. Something like this:

[importlinter:contract:independence]
name = Independence contract (all shall be free!)
type = independence

modules =
  wemake_python_styleguide.visitors.**.*
  # Or at least something like this will do:
  wemake_python_styleguide.visitors.ast.*
  wemake_python_styleguide.visitors.tokenize.*
  wemake_python_styleguide.visitors.filenames.*
ignore_imports =
  # It is ok to be related on these modules:
  wemake_python_styleguide.visitors.base
  wemake_python_styleguide.visitors.decorators

Is it possible? Original issue: https://github.com/wemake-services/wemake-python-styleguide/issues/720

sobolevn avatar Jul 28 '19 11:07 sobolevn

Thanks for the feature request. I think this is a good idea. I've renamed the issue accordingly.

If you're eager to see a feature like this soon, you could implement it yourself by creating a custom contract and field type: https://import-linter.readthedocs.io/en/latest/custom_contract_types.html

seddonym avatar Jul 29 '19 14:07 seddonym

@seddonym this is an awesome project to contribute to, but sadly I dont' have enough time to work on it right now. I have a big release of wemake-python-styleguide in a month. 😞

sobolevn avatar Jul 29 '19 14:07 sobolevn

hi :wave:

@seddonym thanks for great tool!

Possibility to define modules with wildcards is the feature I really need to start truly using import-linterin my projects. This feature opens a lot of new possibilities like using import-linter within django's projects (where your can have many apps with the same structures and rules) without remembering to update .importlinter config whenever some new app will be added. Iit will make maintainability much easier.

I think fnmatch and some custom functions will be good for first iteration and after getting some feedback we can consider cleaner solution.

I will try to prepare initial implementation in following weeks

skarzi avatar May 17 '20 11:05 skarzi

+100500

I use manual addition of rules to each contract, this is so annoying.

sobolevn avatar May 17 '20 11:05 sobolevn

I will try to prepare initial implementation in following weeks

Thanks @skarzi. You should be able to do this without any changes to core import-linter by implementing a custom contract and field type: https://import-linter.readthedocs.io/en/latest/custom_contract_types.html

Of course I'd be happy to consider a PR to core import-linter, but it's worth knowing that you hopefully don't need anything from me in order to make this possible.

Let me know how you get on!

seddonym avatar May 21 '20 06:05 seddonym

anyone above got this to work with a custom contract types? I can probably figure it out, but a code snippet would save some time if you fancy sharing :)

arski avatar Mar 29 '21 21:03 arski

This issue still open more than for 3 years. Is there any progress? How i can help you?

Niccolum avatar Jan 31 '23 20:01 Niccolum

Thanks for the nudge @Niccolum .

Reading back this issue, I'm not sure exactly what the deliverable is. I'm going to try to define it more precisely...

Perhaps what is required is for it to be possible to lint for independence between all child modules of a package, without specifying the modules directly.

For example, I'd like to prevent imports between anything in mypackage.blue, mypackage.green and mypackage.yellow. And if I added a mypackage.orange then I'd want the contract to check that too, without needing to change the contract. (To be clear, I'm just talking about independence contracts here.)

In terms of excluding some of the child modules from that list, I'm not sure that would make much sense in an independence contract. If, for example, the contract excluded mypackage.special from independence, that wouldn't say much about the relationship between, say, mypackage.blue and mypackage.special and so imports could go in either direction. To me that suggests we're looking more at a layers contract. I have long thought that layers contracts could support some form of independence in them, so depending on how important that requirement is, it might need to come after that ticket is addressed.

Another alternative would be for the more general purpose graph contract types proposed here.

Interested to hear anyone's thoughts.

To manage expectations, I'm not sure how likely it is that I'd work on any of these as a priority (I'm more focused on speeding up the linter at the moment) but might be able to support work on others' pull requests. It's important we define what we're trying to achieve first though.

seddonym avatar Feb 03 '23 14:02 seddonym

This linter is great, thanks for creating it as an open-source project!

This would be a great feature to have. I'd like to apply import-linter to a monorepo and we can't expect all contributors to add an entry when a new module is added (or at least its error-prone).

I understand the maintainer has little time. What about tagging this feature as "help wanted"?

sbrugman avatar Feb 23 '24 14:02 sbrugman

Thank you! I haven't had any reply about the potential ways we could do this, so perhaps I could propose a more concrete option. The API could be as follows:

[importlinter:contract:independence]
name = Independence contract (all shall be free!)
type = independence
modules =
  mypackage.*
exclude_modules
  mypackage.yellow

This would be the equivalent of listing all children of mypackage in the modules section except mypackage.yellow.

If anyone would like to work on this, let me know and I'd be happy to support it.

seddonym avatar Feb 23 '24 14:02 seddonym

For independence the wildcard format that is already used for ignore_imports could be supported:

https://import-linter.readthedocs.io/en/stable/contract_types.html#options-used-by-multiple-contracts

(That would be sufficient for my use case)

sbrugman avatar Feb 23 '24 15:02 sbrugman