Commit 921ce26f by Mathieu Kniewallner Committed by GitHub

Some improvements over `init` command (#5838)

* test(init): add tests for all options

* feat(init): only ask description when necessary

* refactor(init): remove useless license validator

* feat(init): only ask license when necessary

* feat(init): validate package definition

* feat(init): reword package add prompt
parent a273a28a
......@@ -118,12 +118,9 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the
)
version = self.ask(question)
description = self.option("description") or ""
question = self.create_question(
f"Description [<comment>{description}</comment>]: ",
default=description,
)
description = self.ask(question)
description = self.option("description")
if not description:
description = self.ask(self.create_question("Description []: ", default=""))
author = self.option("author")
if not author and vcs_config.get("user.name"):
......@@ -143,13 +140,9 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the
else:
authors = [author]
license = self.option("license") or ""
question = self.create_question(
f"License [<comment>{license}</comment>]: ", default=license
)
question.set_validator(self._validate_license)
license = self.ask(question)
license = self.option("license")
if not license:
license = self.ask(self.create_question("License []: ", default=""))
python = self.option("python")
if not python:
......@@ -175,7 +168,7 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the
question = "Would you like to define your main dependencies interactively?"
help_message = """\
You can specify a package in the following forms:
- A single name (<b>requests</b>)
- A single name (<b>requests</b>): this will search for matches on PyPI
- A name and a constraint (<b>requests@^2.23.0</b>)
- A git url (<b>git+https://github.com/python-poetry/poetry.git</b>)
- A git url with a revision\
......@@ -272,9 +265,12 @@ You can specify a package in the following forms:
if not requires:
result = []
package = self.ask(
"Search for package to add (or leave blank to continue):"
question = self.create_question(
"Package to add or search for (leave blank to skip):"
)
question.set_validator(self._validate_package)
package = self.ask(question)
while package:
constraint = self._parse_requirements([package])[0]
if (
......@@ -457,13 +453,12 @@ You can specify a package in the following forms:
return author
def _validate_license(self, license: str) -> str:
from poetry.core.spdx.helpers import license_by_id
if license:
license_by_id(license)
@staticmethod
def _validate_package(package: str | None) -> str | None:
if package and len(package.split()) > 2:
raise ValueError("Invalid package definition.")
return license
return package
def _get_pool(self) -> Pool:
from poetry.repositories import Pool
......
......@@ -11,6 +11,7 @@ import pytest
from cleo.testers.command_tester import CommandTester
from poetry.console.commands.init import InitCommand
from poetry.repositories import Pool
from poetry.utils._compat import decode
from poetry.utils.helpers import canonicalize_name
......@@ -587,6 +588,56 @@ pytest = "^3.6.0"
assert expected in tester.io.fetch_output()
def test_interactive_with_wrong_dependency_inputs(
tester: CommandTester, repo: TestRepository
):
repo.add_package(get_package("pendulum", "2.0.0"))
repo.add_package(get_package("pytest", "3.6.0"))
inputs = [
"my-package", # Package name
"1.2.3", # Version
"This is a description", # Description
"n", # Author
"MIT", # License
"^3.8", # Python
"", # Interactive packages
"pendulum 2.0.0 foo", # Package name and constraint (invalid)
"pendulum 2.0.0", # Package name and constraint (invalid)
"pendulum 2.0.0", # Package name and constraint (invalid)
"pendulum 2.0.0", # Package name and constraint (invalid)
"pendulum@^2.0.0", # Package name and constraint (valid)
"", # End package selection
"", # Interactive dev packages
"pytest 3.6.0 foo", # Dev package name and constraint (invalid)
"pytest 3.6.0", # Dev package name and constraint (invalid)
"pytest@3.6.0", # Dev package name and constraint (valid)
"", # End package selection
"\n", # Generate
]
tester.execute(inputs="\n".join(inputs))
expected = """\
[tool.poetry]
name = "my-package"
version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
readme = "README.md"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "^3.8"
pendulum = "^2.0.0"
[tool.poetry.group.dev.dependencies]
pytest = "3.6.0"
"""
assert expected in tester.io.fetch_output()
def test_python_option(tester: CommandTester):
inputs = [
"my-package", # Package name
......@@ -779,6 +830,51 @@ pytest-requests = "^0.2.0"
assert 'pytest = "^3.6.0"' in output
def test_predefined_all_options(tester: CommandTester, repo: TestRepository):
repo.add_package(get_package("pendulum", "2.0.0"))
repo.add_package(get_package("pytest", "3.6.0"))
inputs = [
"1.2.3", # Version
"", # Author
"n", # Interactive packages
"n", # Interactive dev packages
"\n", # Generate
]
tester.execute(
"--name my-package "
"--description 'This is a description' "
"--author 'Foo Bar <foo@example.com>' "
"--python '^3.8' "
"--license MIT "
"--dependency pendulum "
"--dev-dependency pytest",
inputs="\n".join(inputs),
)
expected = """\
[tool.poetry]
name = "my-package"
version = "1.2.3"
description = "This is a description"
authors = ["Foo Bar <foo@example.com>"]
license = "MIT"
readme = "README.md"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "^3.8"
pendulum = "^2.0.0"
[tool.poetry.group.dev.dependencies]
pytest = "^3.6.0"
"""
output = tester.io.fetch_output()
assert expected in output
def test_add_package_with_extras_and_whitespace(tester: CommandTester):
result = tester.command._parse_requirements(["databases[postgresql, sqlite]"])
......@@ -861,3 +957,29 @@ build-backend = "setuptools.build_meta"
== "A pyproject.toml file with a defined build-system already exists."
)
assert existing_section in pyproject_file.read_text()
@pytest.mark.parametrize(
"name",
[
None,
"",
"foo",
" foo ",
"foo==2.0",
"foo@2.0",
" foo@2.0 ",
"foo 2.0",
" foo 2.0 ",
],
)
def test__validate_package_valid(name: str | None):
assert InitCommand._validate_package(name) == name
@pytest.mark.parametrize(
"name", ["foo bar 2.0", " foo bar 2.0 ", "foo bar foobar 2.0"]
)
def test__validate_package_invalid(name: str):
with pytest.raises(ValueError):
assert InitCommand._validate_package(name)
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