Skip to content
New issue

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

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

Already on GitHub? # to your account

Moving "poetry lock --check" to "poetry check --lock" #8015

Merged
merged 17 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
8 changes: 6 additions & 2 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,10 @@ This command is also available as a pre-commit hook. See [pre-commit hooks]({{<
poetry check
```

### Options

* `--lock`: Verify that `poetry.lock` is consistent with `pyproject.toml`.

## search

This command searches for packages on a remote index.
Expand All @@ -659,7 +663,7 @@ poetry lock

### Options

* `--check`: Verify that `poetry.lock` is consistent with `pyproject.toml`
* `--check`: Verify that `poetry.lock` is consistent with `pyproject.toml`. (**Deprecated**) Use `poetry check --lock` instead.
* `--no-update`: Do not update locked versions, only refresh lock file.

## version
Expand Down Expand Up @@ -944,7 +948,7 @@ poetry self lock

#### Options

* `--check`: Verify that `poetry.lock` is consistent with `pyproject.toml`
* `--check`: Verify that `poetry.lock` is consistent with `pyproject.toml`. (**Deprecated**) Use `poetry check --lock` instead.
* `--no-update`: Do not update locked versions, only refresh lock file.

### self show
Expand Down
25 changes: 25 additions & 0 deletions src/poetry/console/commands/check.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
from __future__ import annotations

from cleo.helpers import option

from poetry.console.commands.command import Command


class CheckCommand(Command):
name = "check"
description = "Checks the validity of the <comment>pyproject.toml</comment> file."

options = [
option(
"lock",
None,
(
"Check that the <comment>poetry.lock</> file corresponds to the current"
" version of <comment>pyproject.toml</>."
),
),
]

def validate_classifiers(
self, project_classifiers: set[str]
) -> tuple[list[str], list[str]]:
Expand Down Expand Up @@ -58,6 +71,18 @@ def validate_classifiers(
return errors, warnings

def handle(self) -> int:
if self.option("lock"):
if self.poetry.locker.is_locked() and self.poetry.locker.is_fresh():
self.line("poetry.lock is consistent with pyproject.toml.")
return 0
self.line_error(
"<error>"
"Error: poetry.lock is not consistent with pyproject.toml. "
"Run `poetry lock [--no-update]` to fix it."
"</error>"
)
return 1

from poetry.factory import Factory
from poetry.pyproject.toml import PyProjectTOML

Expand Down
7 changes: 6 additions & 1 deletion src/poetry/console/commands/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class LockCommand(InstallerCommand):
None,
(
"Check that the <comment>poetry.lock</> file corresponds to the current"
" version of <comment>pyproject.toml</>."
" version of <comment>pyproject.toml</>. (<warning>Deprecated</>) Use"
" <comment>poetry check --lock</> instead."
),
),
]
Expand All @@ -36,6 +37,10 @@ class LockCommand(InstallerCommand):

def handle(self) -> int:
if self.option("check"):
self.line_error(
"<warning>poetry lock --check is deprecated, use `poetry"
" check --lock` instead.</warning>"
)
if self.poetry.locker.is_locked() and self.poetry.locker.is_fresh():
self.line("poetry.lock is consistent with pyproject.toml.")
return 0
Expand Down
84 changes: 84 additions & 0 deletions tests/console/commands/test_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,56 @@

import pytest

from poetry.packages import Locker


if TYPE_CHECKING:
import httpretty

from cleo.testers.command_tester import CommandTester
from pytest_mock import MockerFixture

from poetry.poetry import Poetry
from tests.types import CommandTesterFactory
from tests.types import FixtureDirGetter
from tests.types import ProjectFactory


@pytest.fixture()
def tester(command_tester_factory: CommandTesterFactory) -> CommandTester:
return command_tester_factory("check")


def _project_factory(
fixture_name: str,
project_factory: ProjectFactory,
fixture_dir: FixtureDirGetter,
) -> Poetry:
source = fixture_dir(fixture_name)
pyproject_content = (source / "pyproject.toml").read_text(encoding="utf-8")
poetry_lock_content = (source / "poetry.lock").read_text(encoding="utf-8")
return project_factory(
name="foobar",
pyproject_content=pyproject_content,
poetry_lock_content=poetry_lock_content,
source=source,
)


@pytest.fixture
def poetry_with_outdated_lockfile(
project_factory: ProjectFactory, fixture_dir: FixtureDirGetter
) -> Poetry:
return _project_factory("outdated_lock", project_factory, fixture_dir)


@pytest.fixture
def poetry_with_up_to_date_lockfile(
project_factory: ProjectFactory, fixture_dir: FixtureDirGetter
) -> Poetry:
return _project_factory("up_to_date_lock", project_factory, fixture_dir)


def test_check_valid(tester: CommandTester) -> None:
tester.execute()

Expand Down Expand Up @@ -74,3 +110,51 @@ def test_check_private(
"""

assert tester.io.fetch_output() == expected


def test_lock_check_outdated(
command_tester_factory: CommandTesterFactory,
poetry_with_outdated_lockfile: Poetry,
http: type[httpretty.httpretty],
) -> None:
http.disable()

locker = Locker(
lock=poetry_with_outdated_lockfile.pyproject.file.path.parent / "poetry.lock",
local_config=poetry_with_outdated_lockfile.locker._local_config,
)
poetry_with_outdated_lockfile.set_locker(locker)

tester = command_tester_factory("check", poetry=poetry_with_outdated_lockfile)
status_code = tester.execute("--lock")
expected = (
"Error: poetry.lock is not consistent with pyproject.toml. "
"Run `poetry lock [--no-update]` to fix it.\n"
)

assert tester.io.fetch_error() == expected

# exit with an error
assert status_code == 1


def test_lock_check_up_to_date(
command_tester_factory: CommandTesterFactory,
poetry_with_up_to_date_lockfile: Poetry,
http: type[httpretty.httpretty],
) -> None:
http.disable()

locker = Locker(
lock=poetry_with_up_to_date_lockfile.pyproject.file.path.parent / "poetry.lock",
local_config=poetry_with_up_to_date_lockfile.locker._local_config,
)
poetry_with_up_to_date_lockfile.set_locker(locker)

tester = command_tester_factory("check", poetry=poetry_with_up_to_date_lockfile)
status_code = tester.execute("--lock")
expected = "poetry.lock is consistent with pyproject.toml.\n"
assert tester.io.fetch_output() == expected

# exit with an error
assert status_code == 0
10 changes: 8 additions & 2 deletions tests/console/commands/test_lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def poetry_with_invalid_lockfile(
return _project_factory("invalid_lock", project_factory, fixture_dir)


def test_lock_check_outdated(
def test_lock_check_outdated_legacy(
command_tester_factory: CommandTesterFactory,
poetry_with_outdated_lockfile: Poetry,
http: type[httpretty.httpretty],
Expand All @@ -105,6 +105,7 @@ def test_lock_check_outdated(
tester = command_tester_factory("lock", poetry=poetry_with_outdated_lockfile)
status_code = tester.execute("--check")
expected = (
"poetry lock --check is deprecated, use `poetry check --lock` instead.\n"
"Error: poetry.lock is not consistent with pyproject.toml. "
"Run `poetry lock [--no-update]` to fix it.\n"
)
Expand All @@ -115,7 +116,7 @@ def test_lock_check_outdated(
assert status_code == 1


def test_lock_check_up_to_date(
def test_lock_check_up_to_date_legacy(
command_tester_factory: CommandTesterFactory,
poetry_with_up_to_date_lockfile: Poetry,
http: type[httpretty.httpretty],
Expand All @@ -133,6 +134,11 @@ def test_lock_check_up_to_date(
expected = "poetry.lock is consistent with pyproject.toml.\n"
assert tester.io.fetch_output() == expected

expected_error = (
"poetry lock --check is deprecated, use `poetry check --lock` instead.\n"
)
assert tester.io.fetch_error() == expected_error

# exit with an error
assert status_code == 0

Expand Down