Commit c01f15a6 by Sébastien Eustace

Fix validation of the Poetry configuration

parent 93b5128c
from poetry.poetry import Poetry
from poetry.utils._compat import Path
from poetry.utils.toml_file import TomlFile
from .command import Command
......@@ -7,8 +11,10 @@ class CheckCommand(Command):
description = "Checks the validity of the <comment>pyproject.toml</comment> file."
def handle(self):
# Load poetry and display errors, if any
check_result = self.poetry.check(self.poetry.local_config, strict=True)
# Load poetry config and display errors, if any
poetry_file = Poetry.locate(Path.cwd())
config = TomlFile(str(poetry_file)).read()["tool"]["poetry"]
check_result = Poetry.check(config, strict=True)
if not check_result["errors"] and not check_result["warnings"]:
self.info("All set!")
......
......@@ -404,6 +404,7 @@
"extra-script": {
"type": "object",
"description": "A script that should be installed only if extras are activated.",
"additionalProperties": false,
"properties": {
"callable": {
"$ref": "#/definitions/script"
......@@ -419,6 +420,7 @@
},
"repository": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
......
......@@ -86,21 +86,7 @@ class Poetry:
@classmethod
def create(cls, cwd): # type: (Path) -> Poetry
candidates = [Path(cwd)]
candidates.extend(Path(cwd).parents)
for path in candidates:
poetry_file = path / "pyproject.toml"
if poetry_file.exists():
break
else:
raise RuntimeError(
"Poetry could not find a pyproject.toml file in {} or its parents".format(
cwd
)
)
poetry_file = cls.locate(cwd)
local_config = TomlFile(poetry_file.as_posix()).read()
if "tool" not in local_config or "poetry" not in local_config["tool"]:
......@@ -110,7 +96,13 @@ class Poetry:
local_config = local_config["tool"]["poetry"]
# Checking validity
cls.check(local_config)
check_result = cls.check(local_config)
if check_result["errors"]:
message = ""
for error in check_result["errors"]:
message += " - {}\n".format(error)
raise RuntimeError("The Poetry configuration is invalid:\n" + message)
# Load package
name = local_config["name"]
......@@ -224,6 +216,24 @@ class Poetry:
return LegacyRepository(name, url, auth=auth)
@classmethod
def locate(cls, cwd): # type: (Path) -> Poetry
candidates = [Path(cwd)]
candidates.extend(Path(cwd).parents)
for path in candidates:
poetry_file = path / "pyproject.toml"
if poetry_file.exists():
return poetry_file
else:
raise RuntimeError(
"Poetry could not find a pyproject.toml file in {} or its parents".format(
cwd
)
)
@classmethod
def check(cls, config, strict=False): # type: (dict, bool) -> Dict[str, List[str]]
"""
Checks the validity of a configuration
......
......@@ -18,10 +18,15 @@ All set!
assert expected == tester.io.fetch_output()
def test_check_invalid(app):
app._poetry = Poetry.create(
Path(__file__).parent.parent.parent / "fixtures" / "invalid_pyproject"
def test_check_invalid(app, mocker):
mocker.patch(
"poetry.poetry.Poetry.locate",
return_value=Path(__file__).parent.parent.parent
/ "fixtures"
/ "invalid_pyproject"
/ "pyproject.toml",
)
command = app.find("check")
tester = CommandTester(command)
......
......@@ -169,3 +169,22 @@ def test_check_fails():
)
assert Poetry.check(content) == {"errors": [expected], "warnings": []}
def test_create_fails_on_invalid_configuration():
with pytest.raises(RuntimeError) as e:
Poetry.create(
Path(__file__).parent / "fixtures" / "invalid_pyproject" / "pyproject.toml"
)
if PY2:
expected = """\
The Poetry configuration is invalid:
- u'description' is a required property
"""
else:
expected = """\
The Poetry configuration is invalid:
- 'description' is a required property
"""
assert expected == str(e.value)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment