diff options
author | Benjamin ABEL <bbig26@gmail.com> | 2015-03-02 19:15:29 +0100 |
---|---|---|
committer | Benjamin ABEL <bbig26@gmail.com> | 2015-03-02 19:26:47 +0100 |
commit | ea10824e12e7d9409e7a8918094c1dbfa2d66f05 (patch) | |
tree | f028c5fe9f86109f90793270426ab296a76d8a3b | |
parent | 74ddc39485c18cb78972fc0088f82b8af7b24c53 (diff) | |
download | isort-ea10824e12e7d9409e7a8918094c1dbfa2d66f05.tar.gz |
Add Setuptools integration issue #261
These changes enable any user that installs `isort` to check his source
code from setup.py with the command `python setup.py isort`
I also checked isort package code with his command in tox and travis.
Acknowledgements: this is mostly inspired by flake8 setuptools integration,
see [flake8 doc](http://flake8.readthedocs.org/en/2.2.3/setuptools.html)
-rw-r--r-- | .editorconfig | 10 | ||||
-rw-r--r-- | .travis.yml | 20 | ||||
-rw-r--r-- | README.md | 32 | ||||
-rwxr-xr-x | isort/main.py | 66 | ||||
-rwxr-xr-x | setup.py | 3 | ||||
-rw-r--r-- | tox.ini | 12 |
6 files changed, 127 insertions, 16 deletions
diff --git a/.editorconfig b/.editorconfig index e2da10c7..5e1a36e2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,4 +9,12 @@ known_third_party = kate ignore_frosted_errors = E103 skip = runtests.py,build balanced_wrapping = true -not_skip = __init__.py
\ No newline at end of file +not_skip = __init__.py + +[*.{rst,ini}] +indent_style = space +indent_size = 4 + +[*.yml] +indent_style = space +indent_size = 2 diff --git a/.travis.yml b/.travis.yml index 02bae897..5ed06553 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,13 @@ language: python -python: - - "pypy" - - "2.6" - - "2.7" - - "3.2" - - "3.3" - - "3.4" -script: python setup.py test +env: + - TOXENV=isort-check + - TOXENV=py26 + - TOXENV=py27 + - TOXENV=py32 + - TOXENV=py33 + - TOXENV=py34 + - TOXENV=pypy +install: + - pip install tox +script: + - tox -e $TOXENV @@ -385,7 +385,10 @@ or: menu > Python > Remove Import Using isort to verify code -====================== +========================== + +The ```--check-only``` option +----------------------------- isort can also be used to used to verify that code is correctly formatted by running it with -c. Any files that contain incorrectly sorted imports will be outputted to stderr. @@ -403,7 +406,7 @@ Which can help to ensure a certain level of code quality throughout a project. Git hook -======== +-------- isort provides a hook function that can be integrated into your Git pre-commit script to check Python code before committing. @@ -419,6 +422,31 @@ To cause the commit to fail if there are isort errors (strict mode), include the If you just want to display warnings, but allow the commit to happen anyway, call git_hook without the `strict` parameter. +Setuptools integration +---------------------- + +Upon installation, isort enables a setuptools command that checks Python files +declared by your project. + +Running ``python setup.py isort`` on the command line will check the files +listed in your ``py_modules`` and ``packages``. If any warning is found, +the command will exit with an error code:: + + $ python setup.py isort + +Also, to allow users to be able to use the command without having to install +isort themselves, add isort to the setup_requires of your setup() like so:: + + setup( + name="project", + packages=["project"], + + setup_requires=[ + "isort" + ] + ) + + Why isort? ====================== diff --git a/isort/main.py b/isort/main.py index c10405c1..a51bc5cf 100755 --- a/isort/main.py +++ b/isort/main.py @@ -21,12 +21,15 @@ OTHER DEALINGS IN THE SOFTWARE. from __future__ import absolute_import, division, print_function, unicode_literals import argparse +import glob import os import sys +import setuptools from pies.overrides import * from isort import SECTION_NAMES, SortImports, __version__ +from isort.settings import default, from_path def iter_source_code(paths): @@ -41,7 +44,62 @@ def iter_source_code(paths): yield path -def main(): +class ISortCommand(setuptools.Command): + """The :class:`ISortCommand` class is used by setuptools to perform + imports checks on registered modules. + """ + + description = "Run isort on modules registered in setuptools" + user_options = [] + + def initialize_options(self): + default_settings = default.copy() + for (key, value) in itemsview(default_settings): + setattr(self, key, value) + + def finalize_options(self): + "Get options from config files." + self.arguments = {} + computed_settings = from_path(os.getcwd()) + for (key, value) in itemsview(computed_settings): + self.arguments[key] = value + + def distribution_files(self): + """Find distribution packages.""" + # This is verbatim from flake8 + if self.distribution.packages: + package_dirs = self.distribution.package_dir or {} + for package in self.distribution.packages: + pkg_dir = package + if package in package_dirs: + pkg_dir = package_dirs[package] + elif '' in package_dirs: + pkg_dir = package_dirs[''] + os.path.sep + pkg_dir + yield pkg_dir.replace('.', os.path.sep) + + if self.distribution.py_modules: + for filename in self.distribution.py_modules: + yield "%s.py" % filename + # Don't miss the setup.py file itself + yield "setup.py" + + def run(self): + arguments = self.arguments + wrong_sorted_files = False + arguments['check'] = True + for path in self.distribution_files(): + for python_file in glob.iglob(os.path.join(path, '*.py')): + try: + incorrectly_sorted = SortImports(python_file, **arguments).incorrectly_sorted + if incorrectly_sorted: + wrong_sorted_files = True + except IOError as e: + print("WARNING: Unable to parse file {0} due to {1}".format(file_name, e)) + if wrong_sorted_files: + exit(1) + + +def create_parser(): parser = argparse.ArgumentParser(description='Sort Python import definitions alphabetically ' 'within logical sections.') parser.add_argument('files', nargs='+', help='One or more Python source files that need their imports sorted.') @@ -64,7 +122,7 @@ def main(): help='Force sortImports to recognize a module as being part of the current python project.') parser.add_argument('-m', '--multi_line', dest='multi_line_output', type=int, choices=[0, 1, 2, 3, 4, 5], help='Multi line output (0-grid, 1-vertical, 2-hanging, 3-vert-hanging, 4-vert-grid, ' - '5-vert-grid-grouped).') + '5-vert-grid-grouped).') parser.add_argument('-i', '--indent', help='String to place for indents defaults to " " (4 spaces).', dest='indent', type=str) parser.add_argument('-a', '--add_import', dest='add_imports', action='append', @@ -116,6 +174,10 @@ def main(): help='Force from imports to be grid wrapped regardless of line length') arguments = dict((key, value) for (key, value) in itemsview(vars(parser.parse_args())) if value) + return arguments + +def main(): + arguments = create_parser() file_names = arguments.pop('files', []) if file_names == ['-']: @@ -53,7 +53,8 @@ setup(name='isort', entry_points={ 'console_scripts': [ 'isort = isort.main:main', - ] + ], + 'distutils.commands': ['isort = isort.main:ISortCommand'], }, packages=['isort'], requires=['pies', 'natsort'], @@ -4,9 +4,17 @@ # and then run "tox" from this directory. [tox] -envlist = py26, py27, py32, py33, py34, pypy +envlist = + isort-check, + py26, py27, py32, py33, py34, pypy [testenv] -commands = py.test {posargs} +commands = + py.test {posargs} deps = pytest + +[testenv:isort-check] +commands = + python setup.py isort +deps = |