Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide hints when an invalid license id is input #1634

Merged
merged 1 commit into from
Jun 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion poetry/spdx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,36 @@ def license_by_id(identifier):
id = identifier.lower()

if id not in _licenses:
raise ValueError("Invalid license id: {}".format(identifier))
err = "Invalid license id: {}\nPoetry uses SPDX license identifiers: https://spdx.org/licenses/".format(
identifier
)

# Covers the licenses listed as common for python packages in https://snyk.io/blog/over-10-of-python-packages-on-pypi-are-distributed-without-any-license/
# MIT/WTFPL/Unlicense are excluded as their ids are simply their name - if someone types "mit", they've already found the license they were looking for

common_strings = ["agpl", "lgpl", "gpl", "bsd", "apache", "mpl", "cc0"]
for string in common_strings:
if string in id:

err += "\n"
err += "Did you mean one of the following?"

matches = sorted(
{
license.id
for license in _licenses.values()
if license.id.lower().startswith(string)
and not license.is_deprecated
}
)

for license in matches:
err += "\n * {}".format(license)

# Don't match agpl for "gpl"
break

raise ValueError(err)

return _licenses[id]

Expand Down
35 changes: 35 additions & 0 deletions tests/spdx/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,38 @@ def test_license_by_id_with_full_name():
def test_license_by_id_invalid():
with pytest.raises(ValueError):
license_by_id("invalid")


def test_license_by_id_invalid_gpl():
with pytest.raises(ValueError) as exc_info:
license_by_id("gpl")

assert "Did you mean" in str(exc_info.value)
assert " GPL-3.0-only" in str(exc_info.value)
assert " AGPL-3.0-only" not in str(exc_info.value)


def test_license_by_id_invalid_agpl():
with pytest.raises(ValueError) as exc_info:
license_by_id("agpl")

assert "Did you mean" in str(exc_info.value)
assert " GPL-3.0-only" not in str(exc_info.value)
assert " AGPL-3.0-only" in str(exc_info.value)


def test_license_by_id_invalid_agpl_versioned():
with pytest.raises(ValueError) as exc_info:
license_by_id("gnu agpl v3+")

assert "Did you mean" in str(exc_info.value)
assert " GPL-3.0-only" not in str(exc_info.value)
assert " AGPL-3.0-only" in str(exc_info.value)


def test_license_by_id_invalid_unpopular():
with pytest.raises(ValueError) as exc_info:
license_by_id("not-a-well-known-license")

assert "spdx.org" in str(exc_info.value)
assert "Did you mean" not in str(exc_info.value)