diff --git a/.travis.yml b/.travis.yml index a9b6193..bd6d5c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,10 @@ dist: xenial language: python python: - - "3.5" - "3.6" - "3.7" - "3.8" + - "3.9-dev" install: - pip install -r dev-requirements.txt script: diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b88337..a693942 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ ## CHANGELOG +### 3.0.0 + +* Dropped support Python 3.5 +* Clarified support for Python 3.9 +* Migrate package metadata to `setup.cfg` +* Breaking changes + * Change default behavior to `--from=mixed` + ### 2.3.0 * Implement new option for manage unicode characters diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 08a8526..30228dc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ The design policy of `pip-licenses` is as follows. * Focus only on outputting license information of Python packages installed in user's environment. -* Support Python 3.5 or later. +* Support Python 3.6 or later. * External packages that depend on runtime are [PTable](https://pypi.org/project/PTable/) only. * Expect that pip and setuptools are implicitly installed. diff --git a/README.md b/README.md index 8bf489d..f5de133 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Execute the command with your venv (or virtualenv) environment. ### Option: from -By default, this tool finds the license from package Metadata (`--from=meta`). However, depending on the type of package, it does not declare a license only in the Classifiers. +By default, this tool finds the license from [Trove Classifiers](https://pypi.org/classifiers/) or package Metadata. Some Python packages declare their license only in Trove Classifiers. (See also): [Set license to MIT in setup.py by alisianoi ・ Pull Request #1058 ・ pypa/setuptools](https://github.com/pypa/setuptools/pull/1058), [PEP 314\#License](https://www.python.org/dev/peps/pep-0314/#license) @@ -98,22 +98,23 @@ Author-email: distutils-sig@python.org License: UNKNOWN ``` -If you want to refer to the license declared in [the Classifiers](https://pypi.python.org/pypi?%3Aaction=list_classifiers), use the `--from=classifier` option. +The mixed mode (`--from=mixed`) of this tool works well and looks for licenses. ```bash -(venv) $ pip-licenses --from=classifier --with-system | grep setuptools +(venv) $ pip-licenses --from=mixed --with-system | grep setuptools setuptools 38.5.0 MIT License ``` -If you want to find a license from whichever, mixed mode (`--from=mixed`) is available in `pip-licenses` version 1.14.0 or later. +In mixed mode, it first tries to look for licenses in the Trove Classifiers. When not found in the Trove Classifiers, the license declared in Metadata is displayed. -In mixed mode, it first tries to look for licenses in the Classifiers. When not found in the Classifiers, the license declared in Metadata is displayed. +If you want to looks only in metadata, use `--from=meta`. If you want to looks only in Trove Classifiers, use `--from=classifier`. **Note:** If neither can find license information, please check with the `with-authors` and `with-urls` options and contact the software author. * The `m` keyword is prepared as alias of `meta`. * The `c` keyword is prepared as alias of `classifier`. * The `mix` keyword is prepared as alias of `mixed`. + * Default behavior in this tool ### Option: with-system diff --git a/dev-requirements.in b/dev-requirements.in index 567d717..85dc2ea 100644 --- a/dev-requirements.in +++ b/dev-requirements.in @@ -7,6 +7,6 @@ wheel pip-tools pypandoc pytest-cov -pytest-pycodestyle<2.1 # Pinned for Python 3.5 +pytest-pycodestyle pytest-runner -twine<2 # Pinned for Python 3.5 +twine diff --git a/dev-requirements.txt b/dev-requirements.txt index 4b66017..08c4a6e 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -4,42 +4,49 @@ # # pip-compile dev-requirements.in # -attrs==19.3.0 # via pytest -autopep8==1.5.3 # via -r dev-requirements.in -bleach==3.1.5 # via readme-renderer +attrs==20.2.0 # via pytest +autopep8==1.5.4 # via -r dev-requirements.in +bleach==3.2.1 # via readme-renderer certifi==2020.6.20 # via requests +cffi==1.14.3 # via cryptography chardet==3.0.4 # via requests click==7.1.2 # via pip-tools -codecov==2.1.7 # via -r dev-requirements.in -coverage==5.1 # via codecov, pytest-cov +codecov==2.1.10 # via -r dev-requirements.in +colorama==0.4.4 # via twine +coverage==5.3 # via codecov, pytest-cov +cryptography==3.1.1 # via secretstorage docutils==0.16 # via -r dev-requirements.in, readme-renderer -idna==2.9 # via requests -more-itertools==8.4.0 # via pytest +idna==2.10 # via requests +iniconfig==1.1.1 # via pytest +jeepney==0.4.3 # via keyring, secretstorage +keyring==21.4.0 # via twine packaging==20.4 # via bleach, pytest -pip-tools==5.2.1 # via -r dev-requirements.in -pkginfo==1.5.0.1 # via twine +pip-tools==5.3.1 # via -r dev-requirements.in +pkginfo==1.6.0 # via twine pluggy==0.13.1 # via pytest ptable==0.9.2 # via -r requirements.in -py==1.8.2 # via pytest +py==1.9.0 # via pytest pycodestyle==2.6.0 # via autopep8, pytest-pycodestyle -pygments==2.6.1 # via readme-renderer +pycparser==2.20 # via cffi +pygments==2.7.2 # via readme-renderer pypandoc==1.5 # via -r dev-requirements.in pyparsing==2.4.7 # via packaging -pytest-cov==2.10.0 # via -r dev-requirements.in -pytest-pycodestyle==2.0.0 # via -r dev-requirements.in +pytest-cov==2.10.1 # via -r dev-requirements.in +pytest-pycodestyle==2.2.0 # via -r dev-requirements.in pytest-runner==5.2 # via -r dev-requirements.in -pytest==5.4.3 # via pytest-cov, pytest-pycodestyle -readme-renderer==26.0 # via twine +pytest==6.1.1 # via pytest-cov, pytest-pycodestyle +readme-renderer==28.0 # via twine requests-toolbelt==0.9.1 # via twine requests==2.24.0 # via codecov, requests-toolbelt, twine -six==1.15.0 # via bleach, packaging, pip-tools, readme-renderer -toml==0.10.1 # via autopep8 -tqdm==4.46.1 # via twine -twine==1.15.0 # via -r dev-requirements.in -urllib3==1.25.9 # via requests -wcwidth==0.2.5 # via pytest +rfc3986==1.4.0 # via twine +secretstorage==3.1.2 # via keyring +six==1.15.0 # via bleach, cryptography, packaging, pip-tools, readme-renderer +toml==0.10.1 # via autopep8, pytest +tqdm==4.50.2 # via twine +twine==3.2.0 # via -r dev-requirements.in +urllib3==1.25.11 # via requests webencodings==0.5.1 # via bleach -wheel==0.34.2 # via -r dev-requirements.in, pypandoc +wheel==0.35.1 # via -r dev-requirements.in, pypandoc # The following packages are considered to be unsafe in a requirements file: # pip diff --git a/piplicenses.py b/piplicenses.py index 29ab8f6..ea6bd2d 100644 --- a/piplicenses.py +++ b/piplicenses.py @@ -61,7 +61,7 @@ open = open # allow monkey patching __pkgname__ = 'pip-licenses' -__version__ = '2.3.0' +__version__ = '3.0.0' __author__ = 'raimon' __license__ = 'MIT License' __summary__ = ('Dump the software license list of ' @@ -583,10 +583,10 @@ def create_parser(): version='%(prog)s ' + __version__) parser.add_argument('--from', action='store', type=str, - default='meta', metavar='SOURCE', + default='mixed', metavar='SOURCE', help=('where to find license information\n' '"meta", "classifier, "mixed"\n' - 'default: --from=meta')) + 'default: --from=mixed')) parser.add_argument('-s', '--with-system', action='store_true', default=False, diff --git a/setup.cfg b/setup.cfg index 5526edb..88eca94 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,51 @@ +[metadata] +author_email = raimon49@hotmail.com +project_urls = + Releases = https://github.com/raimon49/pip-licenses/releases + Issues = https://github.com/raimon49/pip-licenses/issues +keywords = pip pypi package license check +classifiers = + Development Status :: 5 - Production/Stable + Intended Audience :: Developers + License :: OSI Approved :: MIT License + Programming Language :: Python :: 3 + Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Topic :: System :: Systems Administration + Topic :: System :: System Shells + +[options] +packages = find: +include_package_data = True +python_requires = ~=3.6 +py_modules = + piplicenses +setup_requires = + setuptools >= 40.9.0 + pytest-runner +install_requires = + PTable +tests_require = + docutils + pytest-cov + pytest-pycodestyle + pytest-runner + +[options.extras_require] +test = + docutils + pytest-cov + pytest-pycodestyle + pytest-runner + [bdist_wheel] -universal=0 +universal = 0 + [aliases] -test=pytest +test = pytest + [tool:pytest] -addopts=--pycodestyle -v --cov --cov-report term-missing +addopts = --pycodestyle -v --cov --cov-report term-missing diff --git a/setup.py b/setup.py index 957c4f7..30f5371 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ """ import os -from setuptools import setup, find_packages +from setuptools import setup from codecs import open from os import path @@ -60,14 +60,6 @@ def read_file(filename): LONG_DESC = read_file('README.md') -TEST_DEPENDS = [ - 'docutils', - 'pytest-cov', - 'pytest-pycodestyle', - 'pytest-runner', -] - - setup( name=PKG_NAME, version=VERSION, @@ -75,30 +67,7 @@ def read_file(filename): long_description=LONG_DESC, url=URL, author=AUTHOR, - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Topic :: System :: Systems Administration', - 'Topic :: System :: System Shells', - ], - keywords='pip pypi package license check', - py_modules=['piplicenses'], license=LICENSE, - python_requires='~=3.5', - install_requires=['PTable'], - setup_requires=[ - 'pytest-runner', - ], - tests_require=TEST_DEPENDS, - extras_require={ - 'test': TEST_DEPENDS, - }, entry_points={ 'console_scripts': [ PKG_NAME + '=piplicenses:main', diff --git a/test_piplicenses.py b/test_piplicenses.py index 6fc0031..6fa40b6 100644 --- a/test_piplicenses.py +++ b/test_piplicenses.py @@ -106,9 +106,21 @@ def test_with_empty_args(self): output_string = create_output_string(args) self.assertNotIn('', output_string) + def test_from_meta(self): + from_args = ['--from=meta'] + args = self.parser.parse_args(from_args) + table = create_licenses_table(args) + + output_fields = get_output_fields(args) + self.assertIn('License', output_fields) + + license_columns = self._create_license_columns(table) + license_notation_as_meta = 'BSD-3-Clause' + self.assertIn(license_notation_as_meta, license_columns) + def test_from_classifier(self): - from_classifier_args = ['--from=classifier'] - args = self.parser.parse_args(from_classifier_args) + from_args = ['--from=classifier'] + args = self.parser.parse_args(from_args) table = create_licenses_table(args) output_fields = get_output_fields(args) @@ -119,8 +131,8 @@ def test_from_classifier(self): self.assertIn(license_notation_as_classifier, license_columns) def test_from_mixed(self): - from_classifier_args = ['--from=mixed'] - args = self.parser.parse_args(from_classifier_args) + from_args = ['--from=mixed'] + args = self.parser.parse_args(from_args) table = create_licenses_table(args) output_fields = get_output_fields(args) @@ -346,11 +358,11 @@ def test_format_plain(self): self.assertEqual(RULE_FRAME, table.hrules) def test_format_plain_vertical(self): - format_plain_args = ['--format=plain-vertical'] + format_plain_args = ['--format=plain-vertical', '--from=classifier'] args = self.parser.parse_args(format_plain_args) output_string = create_output_string(args) self.assertIsNotNone( - re.search(r'pytest\n\d\.\d\.\d\nMIT license\n', output_string)) + re.search(r'pytest\n\d\.\d\.\d\nMIT License\n', output_string)) def test_format_markdown(self): format_markdown_args = ['--format=markdown']