소스 검색

udd scripts, fix/lint and pytest

Nikos Atlas 2 년 전
부모
커밋
b230b91023

+ 45 - 1
.gitignore

@@ -1 +1,45 @@
-virtualenv
+env/
+virtualenv/
+venv/
+node_modules/
+__pycache__
+**/__pycache__
+*.pyc
+.pipcache
+.benchmarks/
+.pytest_cache
+.mypy_cache
+.DS_Store
+.vscode/
+newrelic_agent.log
+/tags
+
+# PyCharm stuff we don't need to keep in our repo.
+.idea/codeStyles/
+.idea/codeStyleSettings.xml
+.idea/dataSources*
+.idea/dataSources/
+.idea/encodings.xml
+.idea/GitScope.xml
+.idea/inspectionProfiles/
+.idea/jsLibraryMappings.xml
+.idea/maple.iml
+.idea/markdown-navigator*
+.idea/misc.xml
+.idea/mypy.xml
+.idea/remote-mappings.xml
+.idea/shelf/
+.idea/tasks.xml
+.idea/workspace.xml
+
+.tags
+.tags1
+stellar.yaml
+
+# Special place for the home directory in the docker containers (see docker-compose.dev.yml).
+*.local*
+# Shell history and other local configuration can be kept here.
+.home
+
+# Configuration file for docker-compose
+.env

+ 26 - 0
pyproject.toml

@@ -0,0 +1,26 @@
+[tool.black]
+line-length = 110
+target-version = ['py37']
+include = '\.pyi?$'
+exclude = '''
+
+/( # Default config
+    \.git
+  | \.hg
+  | \.mypy_cache
+  | \.tox
+  | \.venv
+  | build
+  | dist
+
+  # Our config
+  | node_modules
+  | migrations
+  | env
+  | .env
+  | venv
+  | .venv
+  | .pytest_cache
+  | .pipcache
+)/
+'''

+ 2 - 0
pytest.ini

@@ -0,0 +1,2 @@
+[pytest]
+DJANGO_SETTINGS_MODULE = telecaster.settings

+ 36 - 0
requirements-dev.txt

@@ -0,0 +1,36 @@
+asgiref==3.5.0
+attrs==21.4.0
+backports.zoneinfo==0.2.1
+black==22.1.0
+click==8.0.4
+coverage==6.3.1
+Django==4.0.2
+django-stubs==1.9.0
+django-stubs-ext==0.3.1
+djangorestframework==3.13.1
+docformatter==1.4
+environ==1.0
+flake8==4.0.1
+iniconfig==1.1.1
+mccabe==0.6.1
+mypy==0.931
+mypy-extensions==0.4.3
+packaging==21.3
+pathspec==0.9.0
+platformdirs==2.5.0
+pluggy==1.0.0
+py==1.11.0
+pycodestyle==2.8.0
+pyflakes==2.4.0
+pyparsing==3.0.7
+pytest==7.0.1
+pytest-cov==3.0.0
+pytest-django==4.5.2
+pytz==2021.3
+sqlparse==0.4.2
+toml==0.10.2
+tomli==2.0.1
+types-pytz==2021.3.5
+types-PyYAML==6.0.4
+typing_extensions==4.1.1
+untokenize==0.1.1

+ 32 - 0
requirements.txt

@@ -1,4 +1,36 @@
 asgiref==3.5.0
+attrs==21.4.0
 backports.zoneinfo==0.2.1
+black==22.1.0
+click==8.0.4
+coverage==6.3.1
 Django==4.0.2
+django-stubs==1.9.0
+django-stubs-ext==0.3.1
+djangorestframework==3.13.1
+docformatter==1.4
+environ==1.0
+flake8==4.0.1
+iniconfig==1.1.1
+mccabe==0.6.1
+mypy==0.931
+mypy-extensions==0.4.3
+packaging==21.3
+pathspec==0.9.0
+platformdirs==2.5.0
+pluggy==1.0.0
+py==1.11.0
+pycodestyle==2.8.0
+pyflakes==2.4.0
+pyparsing==3.0.7
+pytest==7.0.1
+pytest-cov==3.0.0
+pytest-django==4.5.2
+pytz==2021.3
 sqlparse==0.4.2
+toml==0.10.2
+tomli==2.0.1
+types-pytz==2021.3.5
+types-PyYAML==6.0.4
+typing_extensions==4.1.1
+untokenize==0.1.1

+ 19 - 0
setup.cfg

@@ -0,0 +1,19 @@
+[mypy]
+python_version = 3.8
+ignore_missing_imports = true
+mypy_path = ./stubs
+junit_xml = lint_types/report.xml
+plugins =
+    mypy_django_plugin.main
+
+[mypy-telecaster]
+ignore_errors = True
+
+[mypy.plugins.django-stubs]
+django_settings_module = telecaster.settings.test
+
+[flake8]
+ignore = E501,W503,E203,W605,E722,N813
+max_line_length = 120
+exclude = **migrations/*, **node_modules/*, **settings/*, **env/*, **.env/ **.pytest_cache/*, **static/*
+

+ 89 - 0
setup.py

@@ -0,0 +1,89 @@
+import sys
+from distutils.cmd import Command
+from subprocess import check_call
+from typing import List
+
+from setuptools import setup, find_packages
+
+
+class CustomCommand(Command):
+    user_options: List[str] = []
+    description = 'Custom command'
+
+    def initialize_options(self):
+        pass
+
+    def finalize_options(self):
+        pass
+
+
+class DevelopCommand(CustomCommand):
+    def run(self):
+        print('Do not try to install telecaster. Run `pip install -r requirements.txt` instead.')  # noqa
+        sys.exit(1)
+
+
+class LocalCommand(CustomCommand):
+    def run(self):
+        print('Do not try to install telecaster. Run `pip install -r requirements-dev.txt` instead.')  # noqa
+        sys.exit(1)
+
+
+def create_command(text: str, commands: List[List[str]]):
+    class GeneratedCommand(CustomCommand):
+        description = text
+
+        def run(self):
+            for cmd in commands:
+                check_call(cmd)
+
+    return GeneratedCommand
+
+
+setup(
+    name='telecaster',
+    version='1.0',
+    packages=find_packages(),
+    scripts=['manage.py'],
+    cmdclass=dict(
+        develop=DevelopCommand,
+        local=LocalCommand,
+        fix=create_command(
+            'Auto-fixes and lints code',
+            [
+                ['python', 'setup.py', 'format'],
+                ['python', 'setup.py', 'lint'],
+                ['python', 'setup.py', 'lint_types'],
+                ['python', 'setup.py', 'format_docstrings'],
+            ],
+        ),
+        verify=create_command(
+            'Verifies that code is valid',
+            [
+                ['python', 'setup.py', 'verify_format'],
+                ['python', 'setup.py', 'lint'],
+                ['python', 'setup.py', 'lint_types'],
+                ['python', 'setup.py', 'verify_format_docstrings'],
+            ],
+        ),
+        format=create_command('Auto-formats code', [['black', '-S', '--config', './pyproject.toml', '.']]),
+        verify_format=create_command(
+            'Verifies that code is properly formatted',
+            [['black', '-S', '--check', '--config', './pyproject.toml', '.']],
+        ),
+        format_docstrings=create_command(
+            'Auto-formats doc strings', [['docformatter', '-r', '-e', 'env', 'venv', '-i', '.']]
+        ),
+        verify_format_docstrings=create_command(
+            'Verifies that doc strings are properly formatted',
+            [['docformatter', '-r', '-e', 'env', 'venv', 'node_modules', '-c', '.']],
+        ),
+        lint=create_command('Lints the code', [['flake8', '.']]),
+        lint_types=create_command(
+            'Type checks the code',
+            [
+                ['mypy', 'telecaster', '--strict', '--config-file', './setup.cfg'],
+            ],
+        ),
+    ),
+)

BIN
telecaster/.coverage


+ 1 - 1
telecaster/manage.py

@@ -4,7 +4,7 @@ import os
 import sys
 
 
-def main():
+def main() -> None:
     """Run administrative tasks."""
     os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'telecaster.settings')
     try:

+ 0 - 0
telecaster/settings/__init__.py


+ 0 - 0
telecaster/settings/development.py


+ 5 - 0
telecaster/settings/production.py

@@ -0,0 +1,5 @@
+import environ
+
+env = environ.Env(PUBLIC_FACING=bool)
+
+SET_A_ENV_VARIABLE = env.bool("WHATEVER")

+ 0 - 0
telecaster/settings/test.py


+ 1 - 2
telecaster/telecaster/asgi.py

@@ -1,5 +1,4 @@
-"""
-ASGI config for telecaster project.
+"""ASGI config for telecaster project.
 
 It exposes the ASGI callable as a module-level variable named ``application``.
 

+ 0 - 0
telecaster/telecaster/models/__init__.py


+ 2 - 2
telecaster/telecaster/settings.py

@@ -1,5 +1,4 @@
-"""
-Django settings for telecaster project.
+"""Django settings for telecaster project.
 
 Generated by 'django-admin startproject' using Django 4.0.2.
 
@@ -13,6 +12,7 @@ https://docs.djangoproject.com/en/4.0/ref/settings/
 from pathlib import Path
 
 # Build paths inside the project like this: BASE_DIR / 'subdir'.
+
 BASE_DIR = Path(__file__).resolve().parent.parent
 
 

+ 53 - 0
telecaster/telecaster/tests/conftest.py

@@ -0,0 +1,53 @@
+import uuid
+
+import pytest
+from rest_framework.authtoken.models import Token
+
+
[email protected]
+def test_password():
+    return 'strong-test-pass'
+
+
[email protected]
+def create_user(db, django_user_model, test_password):
+    def make_user(**kwargs):
+        kwargs['password'] = test_password
+        if 'username' not in kwargs:
+            kwargs['username'] = str(uuid.uuid4())
+        return django_user_model.objects.create_user(**kwargs)
+
+    return make_user
+
+
[email protected]
+def auto_login_user(db, client, create_user, test_password):
+    def make_auto_login(user=None):
+        if user is None:
+            user = create_user()
+        client.login(username=user.username, password=test_password)
+        return client, user
+
+    return make_auto_login
+
+
[email protected]
+def api_client():
+    from rest_framework.test import APIClient
+
+    return APIClient()
+
+
[email protected]
+def get_or_create_token(db, create_user):
+    user = create_user()
+    token, _ = Token.objects.get_or_create(user=user)
+    return token
+
+
[email protected]
+def api_client_with_credentials(db, create_user, api_client):
+    user = create_user()
+    api_client.force_authenticate(user=user)
+    yield api_client
+    api_client.force_authenticate(user=None)

+ 1 - 1
telecaster/telecaster/urls.py

@@ -1,4 +1,4 @@
-"""telecaster URL Configuration
+"""telecaster URL Configuration.
 
 The `urlpatterns` list routes URLs to views. For more information please see:
     https://docs.djangoproject.com/en/4.0/topics/http/urls/

+ 1 - 2
telecaster/telecaster/wsgi.py → telecaster/wsgi.py

@@ -1,5 +1,4 @@
-"""
-WSGI config for telecaster project.
+"""WSGI config for telecaster project.
 
 It exposes the WSGI callable as a module-level variable named ``application``.