diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..9fe964ad --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,2 @@ +**WARNING:** Please do not report issues about missing Django, see +[README](https://github.com/PyCQA/pylint-django#installation)! diff --git a/.travis.yml b/.travis.yml index 6258fd4c..a8fd73ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,16 +5,26 @@ python: - 3.5 - 3.6 env: - - DJANGO=1.11 + # note: latest versions first b/c the top-most is included in new + # build stages if not specified - DJANGO=2.0 + - DJANGO=1.11 +stages: + - django_not_installed + - django_is_installed + - test + - build_and_package_sanity matrix: exclude: # Python/Django combinations that aren't officially supported - { python: 2.7, env: DJANGO=2.0 } include: - - { python: 3.6, env: TOXENV=flake8 } - - { python: 3.6, env: TOXENV=pylint } - - { python: 3.6, env: TOXENV=readme } + - { stage: django_not_installed, python: 3.6, env: TOXENV=django_not_installed } + - { stage: django_is_installed, python: 3.6, env: TOXENV=django_is_installed } + - { stage: test, python: 3.6, env: TOXENV=flake8 } + - { stage: test, python: 3.6, env: TOXENV=pylint } + - { stage: test, python: 3.6, env: TOXENV=readme } + - { stage: build_and_package_sanity, python: 3.6, env: SANITY_CHECK=1 } allow_failures: - env: TOXENV=flake8 - env: TOXENV=pylint @@ -23,11 +33,21 @@ matrix: install: - pip install tox-travis script: - - tox + - | + + if [ -z "$SANITY_CHECK" ]; then + tox + else + ./scripts/build.sh + fi after_success: - - pip install coveralls - - coveralls + - | + if [ -z "$SANITY_CHECK" ]; then + pip install coveralls + coveralls + fi + notifications: email: on_failure: change diff --git a/README.md b/README.md index af8029b6..eaa3e3e3 100644 --- a/README.md +++ b/README.md @@ -16,21 +16,24 @@ pylint-django pip install pylint-django ``` -**WARNING:** `pylint-django` requires `Django` to be installed. Our `setup.py` file doesn't -specify which particular version of Django is going to be installed because we have no idea -what version is used inside your project. The latest version of Django will be installed if -it has not been installed beforehand! DO NOT report issues about mismatching Django versions -if that happens. Instead get your testing environment sorted out and make sure that you have -the appropriate version of Django installed! +**WARNING:** `pylint-django` will not install `Django` by default because this +causes more trouble than good, +[see discussion](https://github.com/PyCQA/pylint-django/pull/132). If you wish +to automatically install the latest version of `Django` then -# Usage +``` +pip install pylint-django[with_django] +``` -## Pylint +otherwise sort out your testing environment and please **DO NOT** report issues +about missing Django! + +# Usage Ensure `pylint-django` is installed and on your path and then execute: ``` -pylint --load-plugins pylint_django [..other options..] +pylint --load-plugins pylint_django [..other options..] ``` ## Prospector diff --git a/pylint_django/plugin.py b/pylint_django/plugin.py index 06fb6f4d..9420e351 100644 --- a/pylint_django/plugin.py +++ b/pylint_django/plugin.py @@ -2,7 +2,6 @@ from pylint.checkers.base import NameChecker from pylint_plugin_utils import get_checker -from pylint_django.augmentations import apply_augmentations from pylint_django.checkers import register_checkers # we want to import the transforms to make sure they get added to the astroid manager, @@ -26,4 +25,10 @@ def register(linter): register_checkers(linter) # register any checking fiddlers - apply_augmentations(linter) + try: + from pylint_django.augmentations import apply_augmentations + apply_augmentations(linter) + except ModuleNotFoundError: + # probably trying to execute pylint_django when Django isn't installed + # in this case the django-not-installed checker will kick-in + pass diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 00000000..350ec40c --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +# Build packages for distribution on PyPI +# and execute some sanity scripts on them +# +# note: must be executed from the root directory of the project + +# first clean up the local environment +echo "..... Clean up first" +find . -type f -name '*.pyc' -delete +find . -type d -name __pycache__ -delete +find . -type d -name '*.egg-info' | xargs rm -rf +rm -rf build/ .cache/ dist/ .eggs/ .tox/ + +# then build the packages +echo "..... Building PyPI packages" +set -e +python setup.py sdist >/dev/null +python setup.py bdist_wheel >/dev/null +set +e + +# then run some sanity tests +echo "..... Searching for .pyc files inside the built packages" +matched_files=`tar -tvf dist/*.tar.gz | grep -c "\.pyc"` +if [ "$matched_files" -gt "0" ]; then + echo "ERROR: .pyc files found in .tar.gz package" + exit 1 +fi +matched_files=`unzip -t dist/*.whl | grep -c "\.pyc"` +if [ "$matched_files" -gt "0" ]; then + echo "ERROR: .pyc files found in wheel package" + exit 1 +fi + +echo "..... Trying to verify that all source files are present" +# remove pylint_django/*.egg-info/ generated during build +find . -type d -name '*.egg-info' | xargs rm -rf + +source_files=`find ./pylint_django/ -type f | sed 's|./||'` + +# verify for .tar.gz package +package_files=`tar -tvf dist/*.tar.gz` +for src_file in $source_files; do + echo "$package_files" | grep $src_file >/dev/null + if [ "$?" -ne 0 ]; then + echo "ERROR: $src_file not found inside tar.gz package" + exit 1 + fi +done + +# verify for wheel package +package_files=`unzip -t dist/*.whl` +for src_file in $source_files; do + echo "$package_files" | grep $src_file >/dev/null + if [ "$?" -ne 0 ]; then + echo "ERROR: $src_file not found inside wheel package" + exit 1 + fi +done + +# exit on error from now on +set -e + +echo "..... Trying to install the new tarball inside a virtualenv" +# note: installs with the optional dependency to verify this is still working +virtualenv .venv/test-tarball +source .venv/test-tarball/bin/activate +pip install --no-binary :all: -f dist/ pylint_django[with_django] +pip freeze | grep Django +deactivate +rm -rf .venv/ + +echo "..... Trying to install the new wheel inside a virtualenv" +virtualenv .venv/test-wheel +source .venv/test-wheel/bin/activate +pip install pylint-plugin-utils # because it does not provide a wheel package +pip install --only-binary :all: -f dist/ pylint_django +deactivate +rm -rf .venv/ + +echo "..... PASS" diff --git a/setup.py b/setup.py index b6f77185..309cc849 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,6 @@ """ Setup module for Pylint plugin for Django. """ -import os from setuptools import setup, find_packages @@ -18,8 +17,10 @@ install_requires=[ 'pylint-plugin-utils>=0.2.1', 'pylint>=1.8.2', - 'Django', ], + extras_require={ + 'with_django': ['Django'], + }, license='GPLv2', classifiers=[ 'Development Status :: 4 - Beta', diff --git a/tox.ini b/tox.ini index 3f374773..ca4f63da 100644 --- a/tox.ini +++ b/tox.ini @@ -3,6 +3,8 @@ [tox] envlist = + django_not_installed + django_is_installed flake8 pylint readme @@ -11,6 +13,8 @@ envlist = [testenv] commands = + django_not_installed: bash -c \'pylint --load-plugins=pylint_django setup.py | grep django-not-available\' + django_is_installed: pylint --load-plugins=pylint_django setup.py flake8: flake8 pylint: pylint --rcfile=tox.ini pylint_django setup readme: python setup.py check --restructuredtext --strict @@ -19,6 +23,7 @@ commands = clean: find . -type d -name __pycache__ -delete clean: rm -rf build/ .cache/ dist/ .eggs/ pylint_django.egg-info/ .tox/ deps = + django_is_installed: Django flake8: flake8 pylint: pylint pylint: Django>=2.0,<2.1 @@ -35,6 +40,7 @@ setenv = PIP_DISABLE_PIP_VERSION_CHECK = 1 PYTHONPATH = . whitelist_externals = + django_not_installed: bash clean: find clean: rm