Skip to content

Commit

Permalink
feat(python-poetry#8083): Added support for poetry config being store…
Browse files Browse the repository at this point in the history
…d in a project .poetry directory and added the 'self init' command.
  • Loading branch information
BEllis committed Jun 9, 2023
1 parent a9ac06f commit b0ed97d
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 2 deletions.
5 changes: 5 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,11 @@ poetry self remove poetry-plugin-export

* `--dry-run`: Outputs the operations but will not execute anything (implicitly enables --verbose).

### self init

The `self init` command creates a local `.poetry` configuration directory for poetry. Poetry will
use configuration and it's dependencies from this directory instead of the system default.

### self install

The `self install` command ensures all additional packages specified are installed in the current
Expand Down
2 changes: 2 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ Poetry uses the following default directories:
- Windows: `%APPDATA%\pypoetry`
- MacOS: `~/Library/Application Support/pypoetry`

If there is a `.poetry` directory in the project directory, this will override the default configuration directory.

You can override the Config directory by setting the `POETRY_CONFIG_DIR` environment variable.

### Data Directory
Expand Down
1 change: 1 addition & 0 deletions src/poetry/console/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def _load() -> Command:
"env use",
# Self commands
"self add",
"self init",
"self install",
"self lock",
"self remove",
Expand Down
57 changes: 57 additions & 0 deletions src/poetry/console/commands/self/init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from __future__ import annotations

from pathlib import Path

from cleo.helpers import option

from poetry.console.commands.self.self_command import SelfCommand


class SelfInitCommand(SelfCommand):
name = "self init"
description = """\
Initializes a local .poetry directory to be used instead of the global poetry \
configuration.\
"""
options = [
option(
"project-dir",
None,
(
"The directory containing a pyproject.toml file to which the .poetry "
" directory will be added."
),
flag=False,
default=None,
),
]
help = """\
The <c1>self init</c1> command creates and initializes a .poetry directory that\
contains poetry configuration specific for the project directory instead of using the\
global poetry configuration.
"""

loggers = ["poetry.repositories.pypi_repository", "poetry.inspection.info"]

def __init__(self):
self._system_pyproject = super().system_pyproject
super().__init__()

def handle(self) -> int:
project_dir = self.option("project-dir")
if project_dir is None:
project_dir = Path.cwd()
self._system_pyproject = Path(project_dir) / ".poetry" / "pyproject.toml"
if self.system_pyproject.exists():
self.line(f"Poetry settings already exist for project {project_dir}")
self.line_error("\nNo changes were applied.")
return 1

self.line(f"Initialising poetry settings for project {project_dir}")
self.system_pyproject.parent.mkdir(parents=True, exist_ok=True)
self.generate_system_pyproject()
return 0

@property
def system_pyproject(self) -> Path:
return self._system_pyproject
5 changes: 3 additions & 2 deletions src/poetry/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@

DEFAULT_CACHE_DIR = user_cache_path(_APP_NAME, appauthor=False)
CONFIG_DIR = Path(
os.getenv("POETRY_CONFIG_DIR")
or user_config_path(_APP_NAME, appauthor=False, roaming=True)
os.getenv("POETRY_CONFIG_DIR") or Path.cwd() / ".poetry"
if (Path.cwd() / ".poetry").exists()
else None or user_config_path(_APP_NAME, appauthor=False, roaming=True)
)

# platformdirs 2.0.0 corrected the OSX/macOS config directory from
Expand Down
64 changes: 64 additions & 0 deletions tests/console/commands/self/test_init_plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from __future__ import annotations

import os

from pathlib import Path
from typing import TYPE_CHECKING

import pytest

from poetry.core.utils.helpers import temporary_directory


if TYPE_CHECKING:
from cleo.testers.command_tester import CommandTester

from tests.types import CommandTesterFactory


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


def test_init_no_args(
tester: CommandTester,
) -> None:
with temporary_directory() as tmp_dir:
current_dir = os.getcwd()
try:
os.chdir(tmp_dir)
tester.execute()
assert tester.io.fetch_output() == f"""\
Initialising poetry settings for project {tmp_dir}
"""
assert (Path(tmp_dir) / ".poetry" / "pyproject.toml").exists()
assert tester.status_code == 0
finally:
os.chdir(current_dir)


def test_init_project_dir(
tester: CommandTester,
) -> None:
with temporary_directory() as tmp_dir:
tester.execute(args=f"--project-dir {tmp_dir}")
assert tester.io.fetch_output() == f"""\
Initialising poetry settings for project {tmp_dir}
"""
assert (Path(tmp_dir) / ".poetry" / "pyproject.toml").exists()
assert tester.status_code == 0


def test_init_project_dir_already_exists(
tester: CommandTester,
) -> None:
with temporary_directory() as tmp_dir:
pyproject_file = Path(tmp_dir) / ".poetry" / "pyproject.toml"
pyproject_file.parent.mkdir()
pyproject_file.write_text("hello world")
tester.execute(args=f"--project-dir {tmp_dir}")
assert tester.io.fetch_output() == f"""\
Poetry settings already exist for project {tmp_dir}
"""
assert tester.status_code == 1

0 comments on commit b0ed97d

Please sign in to comment.