Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Port #3046 #3047 #3051 #3076 to master #3080

Merged
merged 5 commits into from
Oct 5, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion poetry/console/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from cleo import option
from tomlkit import inline_table

from poetry.core.pyproject import PyProjectException
from poetry.core.pyproject.toml import PyProjectTOML
from poetry.utils._compat import OrderedDict
from poetry.utils._compat import Path
Expand Down Expand Up @@ -378,7 +379,7 @@ def _parse_requirements(

try:
cwd = self.poetry.file.parent
except RuntimeError:
except (PyProjectException, RuntimeError):
cwd = Path.cwd()

for requirement in requirements:
Expand Down
4 changes: 3 additions & 1 deletion poetry/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,13 @@ def create_poetry(

# Load local sources
repositories = {}
existing_repositories = config.get("repositories", {})
for source in base_poetry.pyproject.poetry_config.get("source", []):
name = source.get("name")
url = source.get("url")
if name and url:
repositories[name] = {"url": url}
if name not in existing_repositories:
repositories[name] = {"url": url}

config.merge({"repositories": repositories})

Expand Down
14 changes: 13 additions & 1 deletion poetry/installation/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,24 @@ def use_executor(self, use_executor=True): # type: (bool) -> Installer
return self

def _do_refresh(self):
from poetry.puzzle import Solver

# Checking extras
for extra in self._extras:
if extra not in self._package.extras:
raise ValueError("Extra [{}] is not specified.".format(extra))

ops = self._get_operations_from_lock(self._locker.locked_repository(True))
locked_repository = self._locker.locked_repository(True)
solver = Solver(
self._package,
self._pool,
locked_repository,
locked_repository,
self._io, # noqa
)

ops = solver.solve(use_latest=[])

local_repo = Repository()
self._populate_local_repo(local_repo, ops)

Expand Down
14 changes: 7 additions & 7 deletions poetry/puzzle/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ def complete_package(
self._pool.package(
package.name,
package.version.text,
extras=package.dependency.extras,
extras=list(package.dependency.extras),
repository=package.dependency.source_name,
),
)
Expand Down Expand Up @@ -478,12 +478,12 @@ def complete_package(
if self._env and not dep.marker.validate(self._env.marker_env):
continue

if (
dep.is_optional()
and dep.name not in optional_dependencies
and not package.is_root()
):
continue
if not package.is_root():
if (dep.is_optional() and dep.name not in optional_dependencies) or (
dep.in_extras
and not set(dep.in_extras).intersection(package.dependency.extras)
):
continue

_dependencies.append(dep)

Expand Down
98 changes: 80 additions & 18 deletions tests/console/commands/test_init.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
import os
import shutil
import sys

import pytest

from cleo import CommandTester

from poetry.repositories import Pool
from poetry.utils._compat import Path
from poetry.utils._compat import decode
from tests.helpers import TestApplication
from tests.helpers import get_package


@pytest.fixture
def source_dir(tmp_path): # type: (Path) -> Path
yield Path(tmp_path.as_posix())
def source_dir(tmp_path): # type: (...) -> Path
cwd = os.getcwd()

try:
os.chdir(str(tmp_path))
yield Path(tmp_path.as_posix())
finally:
os.chdir(cwd)


@pytest.fixture(autouse=True)
def patches(mocker, source_dir):
patch = mocker.patch("poetry.utils._compat.Path.cwd")
patch.return_value = source_dir
@pytest.fixture
def patches(mocker, source_dir, repo):
mocker.patch("poetry.utils._compat.Path.cwd", return_value=source_dir)
mocker.patch(
"poetry.console.commands.init.InitCommand._get_pool", return_value=Pool([repo])
)


@pytest.fixture
def tester(command_tester_factory):
return command_tester_factory("init")
def tester(patches):
# we need a test application without poetry here.
app = TestApplication(None)
return CommandTester(app.find("init"))


@pytest.fixture
Expand Down Expand Up @@ -265,10 +281,13 @@ def test_interactive_with_git_dependencies_and_other_name(tester, repo):
assert expected in tester.io.fetch_output()


def test_interactive_with_directory_dependency(tester, repo):
def test_interactive_with_directory_dependency(tester, repo, source_dir, fixture_dir):
repo.add_package(get_package("pendulum", "2.0.0"))
repo.add_package(get_package("pytest", "3.6.0"))

demo = fixture_dir("git") / "github.com" / "demo" / "demo"
shutil.copytree(str(demo), str(source_dir / "demo"))

inputs = [
"my-package", # Package name
"1.2.3", # Version
Expand All @@ -277,7 +296,7 @@ def test_interactive_with_directory_dependency(tester, repo):
"MIT", # License
"~2.7 || ^3.6", # Python
"", # Interactive packages
"../../fixtures/git/github.com/demo/demo", # Search for package
"./demo", # Search for package
"", # Stop searching for packages
"", # Interactive dev packages
"pytest", # Search for package
Expand All @@ -298,19 +317,23 @@ def test_interactive_with_directory_dependency(tester, repo):

[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
demo = {path = "../../fixtures/git/github.com/demo/demo"}
demo = {path = "demo"}

[tool.poetry.dev-dependencies]
pytest = "^3.6.0"
"""

assert expected in tester.io.fetch_output()


def test_interactive_with_directory_dependency_and_other_name(tester, repo):
def test_interactive_with_directory_dependency_and_other_name(
tester, repo, source_dir, fixture_dir
):
repo.add_package(get_package("pendulum", "2.0.0"))
repo.add_package(get_package("pytest", "3.6.0"))

demo = fixture_dir("git") / "github.com" / "demo" / "pyproject-demo"
shutil.copytree(str(demo), str(source_dir / "pyproject-demo"))

inputs = [
"my-package", # Package name
"1.2.3", # Version
Expand All @@ -319,7 +342,7 @@ def test_interactive_with_directory_dependency_and_other_name(tester, repo):
"MIT", # License
"~2.7 || ^3.6", # Python
"", # Interactive packages
"../../fixtures/git/github.com/demo/pyproject-demo", # Search for package
"./pyproject-demo", # Search for package
"", # Stop searching for packages
"", # Interactive dev packages
"pytest", # Search for package
Expand All @@ -340,7 +363,7 @@ def test_interactive_with_directory_dependency_and_other_name(tester, repo):

[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
demo = {path = "../../fixtures/git/github.com/demo/pyproject-demo"}
demo = {path = "pyproject-demo"}

[tool.poetry.dev-dependencies]
pytest = "^3.6.0"
Expand All @@ -349,10 +372,13 @@ def test_interactive_with_directory_dependency_and_other_name(tester, repo):
assert expected in tester.io.fetch_output()


def test_interactive_with_file_dependency(tester, repo):
def test_interactive_with_file_dependency(tester, repo, source_dir, fixture_dir):
repo.add_package(get_package("pendulum", "2.0.0"))
repo.add_package(get_package("pytest", "3.6.0"))

demo = fixture_dir("distributions") / "demo-0.1.0-py2.py3-none-any.whl"
shutil.copyfile(str(demo), str(source_dir / demo.name))

inputs = [
"my-package", # Package name
"1.2.3", # Version
Expand All @@ -361,7 +387,7 @@ def test_interactive_with_file_dependency(tester, repo):
"MIT", # License
"~2.7 || ^3.6", # Python
"", # Interactive packages
"../../fixtures/distributions/demo-0.1.0-py2.py3-none-any.whl", # Search for package
"./demo-0.1.0-py2.py3-none-any.whl", # Search for package
"", # Stop searching for packages
"", # Interactive dev packages
"pytest", # Search for package
Expand All @@ -382,7 +408,7 @@ def test_interactive_with_file_dependency(tester, repo):

[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
demo = {path = "../../fixtures/distributions/demo-0.1.0-py2.py3-none-any.whl"}
demo = {path = "demo-0.1.0-py2.py3-none-any.whl"}

[tool.poetry.dev-dependencies]
pytest = "^3.6.0"
Expand Down Expand Up @@ -595,6 +621,42 @@ def test_init_existing_pyproject_simple(
)


def test_init_non_interactive_existing_pyproject_add_dependency(
tester, source_dir, init_basic_inputs, repo
):
pyproject_file = source_dir / "pyproject.toml"
existing_section = """
[tool.black]
line-length = 88
"""
pyproject_file.write_text(decode(existing_section))

repo.add_package(get_package("foo", "1.19.2"))

tester.execute(
"--author 'Your Name <[email protected]>' "
"--name 'my-package' "
"--python '^3.6' "
"--dependency foo",
interactive=False,
)

expected = """\
[tool.poetry]
name = "my-package"
version = "0.1.0"
description = ""
authors = ["Your Name <[email protected]>"]

[tool.poetry.dependencies]
python = "^3.6"
foo = "^1.19.2"

[tool.poetry.dev-dependencies]
"""
assert "{}\n{}".format(existing_section, expected) in pyproject_file.read_text()


def test_init_existing_pyproject_with_build_system_fails(
tester, source_dir, init_basic_inputs
):
Expand Down
57 changes: 57 additions & 0 deletions tests/console/commands/test_lock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import shutil
import sys

import pytest

from poetry.factory import Factory
from poetry.packages import Locker
from poetry.utils._compat import Path


@pytest.fixture
def source_dir(tmp_path): # type: (Path) -> Path
yield Path(tmp_path.as_posix())


@pytest.fixture
def tester(command_tester_factory):
return command_tester_factory("lock")


@pytest.fixture
def poetry_with_old_lockfile(fixture_dir, source_dir):
project_dir = source_dir / "project"
shutil.copytree(str(fixture_dir("old_lock")), str(project_dir))
poetry = Factory().create_poetry(cwd=project_dir)
return poetry


@pytest.mark.skipif(
sys.platform == "win32", reason="does not work on windows under ci environments"
)
def test_lock_no_update(command_tester_factory, poetry_with_old_lockfile, http):
http.disable()

locked_repository = poetry_with_old_lockfile.locker.locked_repository(
with_dev_reqs=True
)
assert (
poetry_with_old_lockfile.locker.lock_data["metadata"].get("lock-version")
== "1.0"
)

tester = command_tester_factory("lock", poetry=poetry_with_old_lockfile)
tester.execute("--no-update")

locker = Locker(
lock=poetry_with_old_lockfile.pyproject.file.path.parent / "poetry.lock",
local_config={},
)
packages = locker.locked_repository(True).packages

assert len(packages) == len(locked_repository.packages)

assert locker.lock_data["metadata"].get("lock-version") == "1.1"

for package in packages:
assert locked_repository.find_packages(package.to_dependency())
Loading