diff --git a/COOKBOOK.md b/COOKBOOK.md new file mode 100644 index 0000000..c1a6a36 --- /dev/null +++ b/COOKBOOK.md @@ -0,0 +1,106 @@ +# reLint Cookbook + +A collection of recipes for reLint. Please feel free to contribute! + +# Table of Contents + +- [Python](#python) + - [Django](#django) +- [HTML](#html) + +# Python + +## Django + +### Databases + +```yaml +- name: potential database connection limit with use of threading # by @syphar + pattern: "(threading|ThreadPoolExecutor)[^#]*(?!\\s+# noqa)$" + hint: | + When using threads, keep in mind that they might use additional database + connections. This can lead to a connection limit being reached. You may + also need to manually close the database connection in the thread. + filePattern: .*\.py +``` + +### Utils + +```yaml +- name: Do not import datetime or date directly # by @codingjoe + pattern: '(from datetime import|from django.utils.timezone import)' + filePattern: .*\.py + hint: | + To differentiate between naive and timezone-aware dates, + please use the following imports: + * 'from django.utils import timezone' + * 'import datetime' +``` + +### Management Commands + +```yaml +- name: No logger in management commands # by @codingjoe + pattern: (logger|import logging) + hint: Please write to self.stdout or self.stderr in favor of using a logger. + filePattern: \/management\/commands\/.*\.py +``` + +### Testing + +#### PyTest-Django + +```yaml +- name: Code and tests seem too complex # by @codingjoe + pattern: '(pytest\.fixture|def (?!test_)).*(?!\\s+# noqa)$' + hint: | + Large test setups hint towards complex or convoluted production code. + Consider breaking down your code into smaller individually testable chunks. + You may also use pytest fixtures inside a conftest.py file. Their usage should + be limited to technical setups, like stubs or IO mocks. Data fixtures should + be implemented via baker recipes only. + filePattern: '.*\/test_.*\.py' +``` + +```yaml +- name: IO is lava – Avoid using database fixtures # by @codingjoe + pattern: '@pytest.fixture.*\n[ ]*def [^(]+\([^)]*(db|transactional_db)(, |\))' + hint: Please use the "django_db" marker on individual tests only. + filePattern: .*\.py +``` + +```yaml +- name: IO is lava – Avoid the 'db' fixture # by @codingjoe + pattern: "def test_[^(]+\\([^)]*db[^)]*\\):" + hint: Please use the "django_db" marker instead. + filePattern: .*\.py +``` + +```yaml +- name: IO is lava – Do not mark a whole test class for database usage # by @codingjoe + pattern: \@pytest\.mark\.django_db[^\n]*\n\w*class + hint: Please use the "django_db" marker on individual tests only. + filePattern: .*\.py +``` + +#### Model Bakery + +```yaml +- name: Follow the recipe # by @codingjoe + pattern: 'baker\.(make|prepare)\(' + filePattern: '.*\/test_.*\.py' + hint: | + Please use baker recipes instead of `baker.make` or `baker.prepare`. + This allows us to easily create complex objects with a single line of code. +``` + +# HTML + +```yaml +- name: no inline CSS # by @codingjoe + pattern: 'style=\"[^\"]*;[^\"]+\"' + hint: | + Please do not use more than one inline style attribute. + You may use a CSS class instead. + filePattern: .*\.(html|vue|jsx|tsx) +``` diff --git a/README.md b/README.md index aeb96a3..b5d55ee 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ python3 -m pip install relint ``` +## [Examples & Recipes – The reLint Cookbook](COOKBOOK.md) + ## Usage You can write your own regular rules in a YAML file, like so: @@ -90,27 +92,3 @@ following entry to your `.pre-commit-config.yaml`: - id: relint args: [-W] # optional, if you want to fail on warnings during commit ``` - -## Samples - -```yaml -- name: db fixtures - pattern: 'def test_[^(]+\([^)]*(customer|product)(, |\))' - hint: Use model_bakery recipes instead of db fixtures. - filePattern: test_.*\.py - -- name: model_bakery recipes - pattern: baker\.make\( - hint: Please use baker.make_recipe instead of baker.make. - filePattern: (test_.*|conftest)\.py - -- name: the database is lava - pattern: '@pytest.fixture.*\n[ ]*def [^(]+\([^)]*(db|transactional_db)(, |\))' - hint: Please do not create db fixtures but model_bakery recipes instead. - filePattern: .*\.py - -- name: No logger in management commands - pattern: (logger|import logging) - hint: Please write to self.stdout or self.stderr in favor of using a logger. - filePattern: \/management\/commands\/.*\.py -```