diff --git a/src/poetry/console/commands/check.py b/src/poetry/console/commands/check.py
index ae90004d318..86a7f5a02c2 100644
--- a/src/poetry/console/commands/check.py
+++ b/src/poetry/console/commands/check.py
@@ -7,6 +7,7 @@
from cleo.helpers import option
from poetry.console.commands.command import Command
+from poetry.utils.helpers import lock_command_hint_for
if TYPE_CHECKING:
@@ -161,9 +162,10 @@ def handle(self) -> int:
if self.option("lock") and not self.poetry.locker.is_locked():
check_result["errors"] += ["poetry.lock was not found."]
if self.poetry.locker.is_locked() and not self.poetry.locker.is_fresh():
+ hint = lock_command_hint_for(self.poetry.locker.lock)
check_result["errors"] += [
"pyproject.toml changed significantly since poetry.lock was last generated. "
- "Run `poetry lock` to fix the lock file."
+ f"Run {hint} to fix the lock file."
]
return_code = 0
diff --git a/src/poetry/console/commands/show.py b/src/poetry/console/commands/show.py
index 779f423bf49..66df0ad65d7 100644
--- a/src/poetry/console/commands/show.py
+++ b/src/poetry/console/commands/show.py
@@ -13,6 +13,7 @@
from poetry.console.commands.env_command import EnvCommand
from poetry.console.commands.group_command import GroupCommand
+from poetry.utils.helpers import lock_command_hint_for
if TYPE_CHECKING:
@@ -146,9 +147,9 @@ def handle(self) -> int:
self.io.input.set_option("latest", True)
if not self.poetry.locker.is_locked():
+ hint = lock_command_hint_for(self.poetry.locker.lock)
self.line_error(
- "Error: poetry.lock not found. Run `poetry lock` to create"
- " it."
+ f"Error: poetry.lock not found. Run {hint} to create it."
)
return 1
diff --git a/src/poetry/installation/installer.py b/src/poetry/installation/installer.py
index b4e9eaaaafd..ec4b9b498d2 100644
--- a/src/poetry/installation/installer.py
+++ b/src/poetry/installation/installer.py
@@ -12,6 +12,7 @@
from poetry.repositories import RepositoryPool
from poetry.repositories.installed_repository import InstalledRepository
from poetry.repositories.lockfile_repository import LockfileRepository
+from poetry.utils.helpers import lock_command_hint_for
if TYPE_CHECKING:
@@ -255,9 +256,10 @@ def _do_install(self) -> int:
self._io.write_line("Installing dependencies from lock file>")
if not self._locker.is_fresh():
+ hint = lock_command_hint_for(self._locker.lock)
raise ValueError(
"pyproject.toml changed significantly since poetry.lock was last"
- " generated. Run `poetry lock` to fix the lock file."
+ f" generated. Run {hint} to fix the lock file."
)
if not (reresolve or self._locker.is_locked_groups_and_markers()):
if self._io.is_verbose():
diff --git a/src/poetry/utils/helpers.py b/src/poetry/utils/helpers.py
index c5facf140f6..1d84bb3ef09 100644
--- a/src/poetry/utils/helpers.py
+++ b/src/poetry/utils/helpers.py
@@ -64,6 +64,25 @@
)
+def lock_command_hint_for(lock_path: Path) -> str:
+ """Return the appropriate lock command hint for a given lock file path.
+
+ If the lock file resides in Poetry's configuration directory, this suggests
+ using the self-locking command. Otherwise, it suggests the regular project
+ lock command.
+ """
+ try:
+ from poetry.locations import CONFIG_DIR
+ except Exception:
+ return "`poetry lock`"
+
+ return (
+ "`poetry self lock`"
+ if lock_path.parent == Path(CONFIG_DIR)
+ else "`poetry lock`"
+ )
+
+
@contextmanager
def directory(path: Path) -> Iterator[Path]:
cwd = Path.cwd()
diff --git a/tests/console/commands/self/test_show.py b/tests/console/commands/self/test_show.py
index d1b553a2af0..d924eecf8de 100644
--- a/tests/console/commands/self/test_show.py
+++ b/tests/console/commands/self/test_show.py
@@ -70,3 +70,30 @@ def test_show_format(tester: CommandTester, options: str) -> None:
)
assert tester.execute(options) == 0
assert tester.io.fetch_output().strip() == expected
+
+
+def test_self_show_errors_without_lock_file(tester: CommandTester) -> None:
+ from poetry.console.commands.self.self_command import SelfCommand
+
+ pyproject_content = {
+ "tool": {
+ "poetry": {
+ "name": "poetry-instance",
+ "version": __version__,
+ "dependencies": {"python": "^3.9", "poetry": __version__},
+ }
+ }
+ }
+
+ system_pyproject_file = SelfCommand.get_default_system_pyproject_file()
+ system_pyproject_file.write_text(tomlkit.dumps(pyproject_content), encoding="utf-8")
+
+ lock_path = system_pyproject_file.parent.joinpath("poetry.lock")
+ if lock_path.exists():
+ lock_path.unlink()
+
+ tester.execute("")
+
+ expected = "Error: poetry.lock not found. Run `poetry self lock` to create it.\n"
+ assert tester.io.fetch_error() == expected
+ assert tester.status_code == 1
diff --git a/tests/installation/test_installer.py b/tests/installation/test_installer.py
index 851c9594b80..ef39a2adae9 100644
--- a/tests/installation/test_installer.py
+++ b/tests/installation/test_installer.py
@@ -228,6 +228,25 @@ def test_not_fresh_lock(installer: Installer, locker: Locker) -> None:
installer.run()
+def test_not_fresh_lock_in_self_context_suggests_self_lock(
+ installer: Installer, locker: Locker
+) -> None:
+ from pathlib import Path
+
+ from poetry.locations import CONFIG_DIR
+
+ locker.locked().fresh(False).set_lock_path(Path(CONFIG_DIR))
+
+ with pytest.raises(
+ ValueError,
+ match=re.escape(
+ "pyproject.toml changed significantly since poetry.lock was last generated. "
+ "Run `poetry self lock` to fix the lock file."
+ ),
+ ):
+ installer.run()
+
+
def test_run_with_dependencies(
installer: Installer, locker: Locker, repo: Repository, package: ProjectPackage
) -> None: