diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000..fe57e65 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +environment: + matrix: + - PYTHON: "C:\\Python35-x64" + - PYTHON: "C:\\Python36-x64" + - PYTHON: "C:\\Python37-x64" + +skip_commits: + files: + - "*.rst" + - "LICENSE" + +install: + - "%PYTHON%\\python.exe -m pip install -U . -r requirements.txt" + +build: off + +test_script: + - "%PYTHON%\\python.exe -m pytest" diff --git a/.travis.yml b/.travis.yml index 2e64dbf..538c7c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,23 +5,24 @@ language: python cache: pip python: - - "2.7" - "3.4" - "3.5" - "3.6" + - "3.7" install: - - pip install . -r requirements.txt - pip install codecov + - pip install -U -r requirements.txt script: + - pip install . - pytest after_success: - codecov before_deploy: - - python setup.py sdist bdist_egg bdist_wheel + - python setup.py bdist_wheel deploy: - provider: releases @@ -34,10 +35,8 @@ deploy: repo: yanqd0/csft branch: master tags: true - python: "3.6" - provider: pypi distributions: "sdist bdist_wheel" - skip_cleanup: true user: yanqd0 password: secure: Mh1+Tx0WmzKXxzTqXWAsmNEDO/loJlR/Xt+rPljQ43lBiIJrEOs3xYe4S7+FHoVsuHGlmu3IronIsrdNCYzY5myOgqae8kBcDqmxw/R7k7eeBYno2c+IgCEh50A0iAO+FXzKjZKTB+TQciQAdpwxdDoxsoH86YLxQxhUReIDQdttVkaq3abU0RS4D7jKUSS+F7ImaMvdJwux4V6ffNONU26M7U9UG8U3sYeI0ggHYCCI5hh1LoMImADkuA8UlIZmC+jfhCMhPpFKdikDRBFS2CTTXH1EE0onka4ihJwPMGRvbu92424NaQBtl8dWXdSuUJs3gjJsPzMoSw0svD+S67VISgDpThyexQHf3jBrXLpXUBkK23sWpIeBa29W+xRfYfBaBiBHIYARWk3Ss6zSq7Nm0gOVHr8vh6YcKF5e9m9daIcMJjAtOpz+hh7IOZbF+GfI6O8OPaYymsvxcbmuCASZMMHQDgrKEI8dr7IbZrFKLJdTPlr7XYbbfsmp3EQm06BGz/4gdZizjEI3A7ewC9y7pJxxNCAncASo9xNKxyVWFYp5UnUCywevLXwOdps21xK1KvmuJvMZCt9HW4iPjYwBgQuz+flW5lktjixe9uJCASlknPKZcx+XMhe3ek5SIbY9Edv6aGDqu8qBV9ySmFHxD6Ap+yCEUaENVQO3M7E= diff --git a/LICENSE b/LICENSE index 074e881..5fb7e62 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Yan QiDong +Copyright (c) 2017~2019 Yan QiDong Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.rst b/README.rst index b1d23c5..0e41484 100644 --- a/README.rst +++ b/README.rst @@ -16,6 +16,12 @@ csft - Count Sizes of File Types .. image:: https://img.shields.io/github/license/yanqd0/csft.svg :target: https://github.com/yanqd0/csft/blob/master/LICENSE :alt: License +.. image:: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fyanqd0%2Fcsft.svg?type=shield + :target: https://app.fossa.io/projects/git%2Bgithub.com%2Fyanqd0%2Fcsft?ref=badge_shield + :alt: FOSSA +.. image:: https://img.shields.io/badge/code%20style-yapf-blue + :target: https://github.com/google/yapf + :alt: Code style: yapf A CLI to count sizes of file types in a directory, implemented by Python. diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index afa2815..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,26 +0,0 @@ -environment: - matrix: - - PYTHON: "C:\\Python27" - - PYTHON: "C:\\Python27-x64" - - PYTHON: "C:\\Python35-x64" - - PYTHON: "C:\\Python36-x64" - -skip_commits: - files: - - "*.yml" - - "*.rst" - - "LICENSE" - -install: - - "%PYTHON%\\python.exe -m pip install . -r requirements.txt" - -build: off - -test_script: - - "%PYTHON%\\python.exe -m pytest" - -notifications: - - provider: Email - to: - - yanqd0@outlook.com - on_build_status_changed: true diff --git a/requirements.txt b/requirements.txt index bbc8903..8107318 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,5 +8,7 @@ pytest-pep8 pytest-flakes pytest-runner pytest-mock +pytest-isort +pytest-yapf3 mock -setuptools_scm \ No newline at end of file +setuptools_scm diff --git a/setup.cfg b/setup.cfg index b5c915e..2692eec 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,7 +9,20 @@ addopts = --verbose --cov csft --pep8 --flakes + --isort + --yapf python_files = tests/* mock_use_standalone_module = true flakes-ignore = tests/* ALL **/__init__.py UnusedImport + +[isort] +line_length = 79 +multi_line_output = 3 +include_trailing_comma = true +known_first_party = csft + +[yapf] +based_on_style = facebook +coalesce_brackets = true +dedent_closing_brackets = true diff --git a/setup.py b/setup.py index 2b9ab4e..299add9 100755 --- a/setup.py +++ b/setup.py @@ -1,8 +1,8 @@ #!/usr/bin/env python # -*- coding:utf-8 -*- - """ Setup script for csft """ -import runpy +from distutils.version import LooseVersion +from runpy import run_path from sys import version from setuptools import find_packages, setup @@ -11,34 +11,33 @@ 'pandas >= 0.20.3', 'humanfriendly >= 4.6', ] - -if version < '3.4': +SYS_VERSION = LooseVersion(version) +if SYS_VERSION < LooseVersion('3.4'): REQUIRES.append('pathlib >= 1.0.1') - -if version < '3.5': +if SYS_VERSION < LooseVersion('3.5'): REQUIRES[0] = 'pandas >= 0.20.3, < 0.22' REQUIRES.append('scandir >= 1.5') -INFO = runpy.run_path('csft/_meta.py') +INFO = run_path('src/csft/_meta.py') setup( + # metadata name='csft', description='Count Sizes of File Types', - use_scm_version=True, - url=INFO['__url__'], author=INFO['__author__'], author_email=INFO['__email__'], license=INFO['__license__'], - - packages=find_packages(), + use_scm_version=True, + # package + zip_safe=False, + packages=find_packages('src'), + package_dir={'': 'src'}, entry_points={ - 'console_scripts': ( - 'csft = csft.__main__:main', - ), + 'console_scripts': ('csft = csft.__main__:main', ), }, - - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', + # requires + python_requires='>=3.4', install_requires=REQUIRES, setup_requires=[ 'pytest-runner', @@ -50,10 +49,11 @@ 'pytest-pep8', 'pytest-flakes', 'pytest-mock', + 'pytest-isort', + 'pytest-yapf3', 'mock', ], - - zip_safe=False, + # PyPI keywords=['CLI'], platforms=['any'], classifiers=[ @@ -64,10 +64,8 @@ 'Operating System :: MacOS :: MacOS X', 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', - ] + ], ) diff --git a/csft/__init__.py b/src/csft/__init__.py similarity index 53% rename from csft/__init__.py rename to src/csft/__init__.py index b38eef6..947727a 100644 --- a/csft/__init__.py +++ b/src/csft/__init__.py @@ -1,10 +1,14 @@ # -*- coding:utf-8 -*- - """ Count Sizes of File Types """ from ._csft import csft2data from ._meta import ( - __author__, __copyright__, __email__, __license__, __url__, __version__, + __author__, + __copyright__, + __email__, + __license__, + __url__, + __version__, ) diff --git a/csft/__main__.py b/src/csft/__main__.py similarity index 79% rename from csft/__main__.py rename to src/csft/__main__.py index 281ac05..e0b9f95 100644 --- a/csft/__main__.py +++ b/src/csft/__main__.py @@ -1,6 +1,5 @@ #!/usr/bin/env python # -*- coding:utf-8 -*- - """ The entry point of csft. """ @@ -14,7 +13,8 @@ from humanfriendly import format_size -from . import __name__ as _name, __version__ as _version +from . import __name__ as _name +from . import __version__ as _version from ._csft import column, csft2data @@ -37,10 +37,17 @@ def _parse_args(argv): parser = ArgumentParser(prog=_name) parser.add_argument('-V', '--version', action='version', version=_version) parser.add_argument('path', type=_dir, help='the directory to be analyzed') - parser.add_argument('--top', type=_positive_int, metavar='N', - help='only display top N results') - parser.add_argument('--with-raw', action='store_true', - help='print raw size without units') + parser.add_argument( + '--top', + type=_positive_int, + metavar='N', + help='only display top N results', + ) + parser.add_argument( + '--with-raw', + action='store_true', + help='print raw size without units', + ) return parser.parse_args(args=argv) diff --git a/csft/_csft.py b/src/csft/_csft.py similarity index 95% rename from csft/_csft.py rename to src/csft/_csft.py index aff4a7c..c8a6369 100644 --- a/csft/_csft.py +++ b/src/csft/_csft.py @@ -1,17 +1,17 @@ # -*- coding:utf-8 -*- - """ The implementations of csft. """ import sys from collections import OrderedDict, namedtuple +from distutils.version import LooseVersion from os.path import getsize, islink, join, split, splitext from pathlib import Path from pandas import DataFrame, Series -if sys.version < '3.5': +if LooseVersion(sys.version) < LooseVersion('3.5'): from scandir import walk else: from os import walk diff --git a/csft/_meta.py b/src/csft/_meta.py similarity index 100% rename from csft/_meta.py rename to src/csft/_meta.py diff --git a/tests/test_csft.py b/tests/test_csft.py index fcf0488..cd87e74 100644 --- a/tests/test_csft.py +++ b/tests/test_csft.py @@ -1,4 +1,3 @@ -# -*- coding:utf-8 -*- from collections import Iterable, OrderedDict from os.path import dirname, isfile, join @@ -19,7 +18,7 @@ def tempdir(tmpdir): from shutil import copy, copytree tmpdir = str(tmpdir) - copytree('csft', join(tmpdir, 'csft')) + copytree('src', join(tmpdir, 'src')) copy('LICENSE', tmpdir) copy('requirements.txt', tmpdir) return tmpdir @@ -70,10 +69,14 @@ def test_sum_data_by_type(): assert len(result[column.TYPE]) == len(expect[column.TYPE]) assert len(result[column.SIZE]) == len(expect[column.SIZE]) assert all(result[column.TYPE].isin(expect[column.TYPE])) - type2size = {t: result[column.SIZE][index] - for index, t in enumerate(result[column.TYPE])} - assert all(type2size[t] == expect[column.SIZE][index] - for index, t in enumerate(expect[column.TYPE])) + type2size = { + t: result[column.SIZE][index] + for index, t in enumerate(result[column.TYPE]) + } + assert all( + type2size[t] == expect[column.SIZE][index] + for index, t in enumerate(expect[column.TYPE]) + ) assert all(test == backup) diff --git a/tests/test_main.py b/tests/test_main.py index 7ab9504..68a8c79 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,6 +1,7 @@ # -*- coding:utf-8 -*- import sys +from distutils.version import LooseVersion from os.path import curdir, devnull from subprocess import check_call @@ -26,12 +27,17 @@ def data(): def test_call(null): - check_call(['python', '-m', 'csft', 'csft'], stdout=null, stderr=null) + check_call(['python', '-m', 'csft', 'src'], stdout=null, stderr=null) -@mark.parametrize('argv', [None, [], [''], ['csft'], ]) +@mark.parametrize('argv', [ + None, + [], + [''], + ['src'], +]) def test_main(argv, data, mocker, capsys): - mocker.patch('sys.argv', ['csft']) + mocker.patch('sys.argv', ['src']) csft2data = mocker.patch('csft.__main__.csft2data', return_value=data) assert 0 == main.main(argv=argv) @@ -62,11 +68,12 @@ def test_show_version(capsys): assert 0 == err.code from csft import __version__ - if sys.version < '3.0': + if LooseVersion(sys.version) < LooseVersion('3.0'): _, out = capsys.readouterr() else: out, _ = capsys.readouterr() assert __version__ == out.strip() + assert LooseVersion(__version__) == LooseVersion(out.strip()) def test_arg_top(data, mocker, capsys):