Commit 9b286303 by Sébastien Eustace Committed by GitHub

Add a Factory class to help create objects needed by Poetry (#1349)

parent 2e579c74
...@@ -11,13 +11,16 @@ from poetry.locations import CACHE_DIR ...@@ -11,13 +11,16 @@ from poetry.locations import CACHE_DIR
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils._compat import basestring from poetry.utils._compat import basestring
from .config_source import ConfigSource
from .dict_config_source import DictConfigSource
_NOT_SET = object() _NOT_SET = object()
boolean_validator = lambda val: val in {"true", "false", "1", "0"} boolean_validator = lambda val: val in {"true", "false", "1", "0"}
boolean_normalizer = lambda val: val in ["true", "1"] boolean_normalizer = lambda val: val in ["true", "1"]
class Config: class Config(object):
default_config = { default_config = {
"cache-dir": str(CACHE_DIR), "cache-dir": str(CACHE_DIR),
...@@ -34,6 +37,8 @@ class Config: ...@@ -34,6 +37,8 @@ class Config:
self._config = deepcopy(self.default_config) self._config = deepcopy(self.default_config)
self._use_environment = use_environment self._use_environment = use_environment
self._base_dir = base_dir self._base_dir = base_dir
self._config_source = DictConfigSource()
self._auth_config_source = DictConfigSource()
@property @property
def name(self): def name(self):
...@@ -43,6 +48,24 @@ class Config: ...@@ -43,6 +48,24 @@ class Config:
def config(self): def config(self):
return self._config return self._config
@property
def config_source(self): # type: () -> ConfigSource
return self._config_source
@property
def auth_config_source(self): # type: () -> ConfigSource
return self._auth_config_source
def set_config_source(self, config_source): # type: (ConfigSource) -> Config
self._config_source = config_source
return self
def set_auth_config_source(self, config_source): # type: (ConfigSource) -> Config
self._auth_config_source = config_source
return self
def merge(self, config): # type: (Dict[str, Any]) -> None def merge(self, config): # type: (Dict[str, Any]) -> None
from poetry.utils.helpers import merge_dicts from poetry.utils.helpers import merge_dicts
......
import io
import os
from contextlib import contextmanager
from typing import Any from typing import Any
from tomlkit import document
from tomlkit import table
from poetry.utils.toml_file import TomlFile
class ConfigSource:
def __init__(self, file, auth_config=False): # type: (TomlFile, bool) -> None
self._file = file
self._auth_config = auth_config
@property
def name(self): # type: () -> str
return str(self._file.path)
@property
def file(self): # type: () -> TomlFile
return self._file
class ConfigSource(object):
def add_property(self, key, value): # type: (str, Any) -> None def add_property(self, key, value): # type: (str, Any) -> None
with self.secure() as config: raise NotImplementedError()
keys = key.split(".")
for i, key in enumerate(keys):
if key not in config and i < len(keys) - 1:
config[key] = table()
if i == len(keys) - 1:
config[key] = value
break
config = config[key]
def remove_property(self, key): # type: (str) -> None def remove_property(self, key): # type: (str) -> None
with self.secure() as config: raise NotImplementedError()
keys = key.split(".")
current_config = config
for i, key in enumerate(keys):
if key not in current_config:
return
if i == len(keys) - 1:
del current_config[key]
break
current_config = current_config[key]
@contextmanager
def secure(self):
if self.file.exists():
initial_config = self.file.read()
config = self.file.read()
else:
initial_config = document()
config = document()
new_file = not self.file.exists()
yield config
try:
# Ensuring the file is only readable and writable
# by the current user
mode = 0o600
if new_file:
self.file.touch(mode=mode)
self.file.write(config)
except Exception:
self.file.write(initial_config)
raise
from typing import Any
from typing import Dict
from .config_source import ConfigSource
class DictConfigSource(ConfigSource):
def __init__(self): # type: () -> None
self._config = {}
@property
def config(self): # type: () -> Dict[str, Any]
return self._config
def add_property(self, key, value): # type: (str, Any) -> None
keys = key.split(".")
config = self._config
for i, key in enumerate(keys):
if key not in config and i < len(keys) - 1:
config[key] = {}
if i == len(keys) - 1:
config[key] = value
break
config = config[key]
def remove_property(self, key): # type: (str) -> None
keys = key.split(".")
config = self._config
for i, key in enumerate(keys):
if key not in config:
return
if i == len(keys) - 1:
del config[key]
break
config = config[key]
from contextlib import contextmanager
from typing import Any
from tomlkit import document
from tomlkit import table
from poetry.utils.toml_file import TomlFile
from .config_source import ConfigSource
class FileConfigSource(ConfigSource):
def __init__(self, file, auth_config=False): # type: (TomlFile, bool) -> None
self._file = file
self._auth_config = auth_config
@property
def name(self): # type: () -> str
return str(self._file.path)
@property
def file(self): # type: () -> TomlFile
return self._file
def add_property(self, key, value): # type: (str, Any) -> None
with self.secure() as config:
keys = key.split(".")
for i, key in enumerate(keys):
if key not in config and i < len(keys) - 1:
config[key] = table()
if i == len(keys) - 1:
config[key] = value
break
config = config[key]
def remove_property(self, key): # type: (str) -> None
with self.secure() as config:
keys = key.split(".")
current_config = config
for i, key in enumerate(keys):
if key not in current_config:
return
if i == len(keys) - 1:
del current_config[key]
break
current_config = current_config[key]
@contextmanager
def secure(self):
if self.file.exists():
initial_config = self.file.read()
config = self.file.read()
else:
initial_config = document()
config = document()
new_file = not self.file.exists()
yield config
try:
# Ensuring the file is only readable and writable
# by the current user
mode = 0o600
if new_file:
self.file.touch(mode=mode)
self.file.write(config)
except Exception:
self.file.write(initial_config)
raise
...@@ -47,12 +47,13 @@ class Application(BaseApplication): ...@@ -47,12 +47,13 @@ class Application(BaseApplication):
@property @property
def poetry(self): def poetry(self):
from poetry.poetry import Poetry from poetry.factory import Factory
from poetry.utils._compat import Path
if self._poetry is not None: if self._poetry is not None:
return self._poetry return self._poetry
self._poetry = Poetry.create(os.getcwd()) self._poetry = Factory().create_poetry(Path.cwd())
return self._poetry return self._poetry
......
from poetry.poetry import Poetry from poetry.factory import Factory
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils.toml_file import TomlFile from poetry.utils.toml_file import TomlFile
...@@ -12,9 +12,9 @@ class CheckCommand(Command): ...@@ -12,9 +12,9 @@ class CheckCommand(Command):
def handle(self): def handle(self):
# Load poetry config and display errors, if any # Load poetry config and display errors, if any
poetry_file = Poetry.locate(Path.cwd()) poetry_file = Factory.locate(Path.cwd())
config = TomlFile(str(poetry_file)).read()["tool"]["poetry"] config = TomlFile(str(poetry_file)).read()["tool"]["poetry"]
check_result = Poetry.check(config, strict=True) check_result = Factory.validate(config, strict=True)
if not check_result["errors"] and not check_result["warnings"]: if not check_result["errors"] and not check_result["warnings"]:
self.info("All set!") self.info("All set!")
......
...@@ -4,6 +4,7 @@ import re ...@@ -4,6 +4,7 @@ import re
from cleo import argument from cleo import argument
from cleo import option from cleo import option
from poetry.factory import Factory
from poetry.utils.helpers import ( from poetry.utils.helpers import (
keyring_repository_password_del, keyring_repository_password_del,
keyring_repository_password_set, keyring_repository_password_set,
...@@ -37,6 +38,8 @@ To remove a repository (repo is a short alias for repositories): ...@@ -37,6 +38,8 @@ To remove a repository (repo is a short alias for repositories):
<comment>poetry config --unset repo.foo</comment>""" <comment>poetry config --unset repo.foo</comment>"""
LIST_PROHIBITED_SETTINGS = {"http-basic", "pypi-token"}
@property @property
def unique_config_values(self): def unique_config_values(self):
from poetry.locations import CACHE_DIR from poetry.locations import CACHE_DIR
...@@ -63,28 +66,24 @@ To remove a repository (repo is a short alias for repositories): ...@@ -63,28 +66,24 @@ To remove a repository (repo is a short alias for repositories):
return unique_config_values return unique_config_values
def handle(self): def handle(self):
from poetry.config.config import Config from poetry.config.file_config_source import FileConfigSource
from poetry.config.config_source import ConfigSource
from poetry.locations import CONFIG_DIR from poetry.locations import CONFIG_DIR
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils._compat import basestring from poetry.utils._compat import basestring
from poetry.utils.toml_file import TomlFile from poetry.utils.toml_file import TomlFile
config = Config() config = Factory.create_config(self.io)
config_file = TomlFile(Path(CONFIG_DIR) / "config.toml") config_file = TomlFile(Path(CONFIG_DIR) / "config.toml")
config_source = ConfigSource(config_file)
if config_source.file.exists():
config.merge(config_source.file.read())
auth_config_file = TomlFile(Path(CONFIG_DIR) / "auth.toml")
auth_config_source = ConfigSource(auth_config_file, auth_config=True)
local_config_file = TomlFile(self.poetry.file.parent / "poetry.toml") try:
if local_config_file.exists(): local_config_file = TomlFile(self.poetry.file.parent / "poetry.toml")
config.merge(local_config_file.read()) if local_config_file.exists():
config.merge(local_config_file.read())
except RuntimeError:
local_config_file = TomlFile(Path.cwd() / "poetry.toml")
if self.option("local"): if self.option("local"):
config_source = ConfigSource(local_config_file) config.set_config_source(FileConfigSource(local_config_file))
if not config_file.exists(): if not config_file.exists():
config_file.path.parent.mkdir(parents=True, exist_ok=True) config_file.path.parent.mkdir(parents=True, exist_ok=True)
...@@ -139,10 +138,13 @@ To remove a repository (repo is a short alias for repositories): ...@@ -139,10 +138,13 @@ To remove a repository (repo is a short alias for repositories):
unique_config_values = self.unique_config_values unique_config_values = self.unique_config_values
if setting_key in unique_config_values: if setting_key in unique_config_values:
if self.option("unset"): if self.option("unset"):
return config_source.remove_property(setting_key) return config.config_source.remove_property(setting_key)
return self._handle_single_value( return self._handle_single_value(
config_source, setting_key, unique_config_values[setting_key], values config.config_source,
setting_key,
unique_config_values[setting_key],
values,
) )
# handle repositories # handle repositories
...@@ -158,14 +160,16 @@ To remove a repository (repo is a short alias for repositories): ...@@ -158,14 +160,16 @@ To remove a repository (repo is a short alias for repositories):
"There is no {} repository defined".format(m.group(1)) "There is no {} repository defined".format(m.group(1))
) )
config_source.remove_property("repositories.{}".format(m.group(1))) config.config_source.remove_property(
"repositories.{}".format(m.group(1))
)
return 0 return 0
if len(values) == 1: if len(values) == 1:
url = values[0] url = values[0]
config_source.add_property( config.config_source.add_property(
"repositories.{}.url".format(m.group(1)), url "repositories.{}.url".format(m.group(1)), url
) )
...@@ -181,7 +185,7 @@ To remove a repository (repo is a short alias for repositories): ...@@ -181,7 +185,7 @@ To remove a repository (repo is a short alias for repositories):
if m: if m:
if self.option("unset"): if self.option("unset"):
keyring_repository_password_del(config, m.group(2)) keyring_repository_password_del(config, m.group(2))
auth_config_source.remove_property( config.auth_config_source.remove_property(
"{}.{}".format(m.group(1), m.group(2)) "{}.{}".format(m.group(1), m.group(2))
) )
...@@ -207,7 +211,7 @@ To remove a repository (repo is a short alias for repositories): ...@@ -207,7 +211,7 @@ To remove a repository (repo is a short alias for repositories):
except RuntimeError: except RuntimeError:
property_value.update(password=password) property_value.update(password=password)
auth_config_source.add_property( config.auth_config_source.add_property(
"{}.{}".format(m.group(1), m.group(2)), property_value "{}.{}".format(m.group(1), m.group(2)), property_value
) )
elif m.group(1) == "pypi-token": elif m.group(1) == "pypi-token":
...@@ -218,7 +222,7 @@ To remove a repository (repo is a short alias for repositories): ...@@ -218,7 +222,7 @@ To remove a repository (repo is a short alias for repositories):
token = values[0] token = values[0]
auth_config_source.add_property( config.auth_config_source.add_property(
"{}.{}".format(m.group(1), m.group(2)), token "{}.{}".format(m.group(1), m.group(2)), token
) )
...@@ -245,6 +249,9 @@ To remove a repository (repo is a short alias for repositories): ...@@ -245,6 +249,9 @@ To remove a repository (repo is a short alias for repositories):
orig_k = k orig_k = k
for key, value in sorted(config.items()): for key, value in sorted(config.items()):
if k + key in self.LIST_PROHIBITED_SETTINGS:
continue
raw_val = raw.get(key) raw_val = raw.get(key)
if isinstance(value, dict): if isinstance(value, dict):
......
from __future__ import absolute_import
from __future__ import unicode_literals
import shutil
from typing import Dict
from typing import List
from typing import Optional
from clikit.api.io.io import IO
from .config.config import Config
from .config.file_config_source import FileConfigSource
from .io.null_io import NullIO
from .json import validate_object
from .locations import CONFIG_DIR
from .packages.dependency import Dependency
from .packages.locker import Locker
from .packages.project_package import ProjectPackage
from .poetry import Poetry
from .repositories.pypi_repository import PyPiRepository
from .spdx import license_by_id
from .utils._compat import Path
from .utils.toml_file import TomlFile
class Factory:
"""
Factory class to create various elements needed by Poetry.
"""
def create_poetry(
self, cwd=None, io=None
): # type: (Optional[Path], Optional[IO]) -> Poetry
if io is None:
io = NullIO()
poetry_file = self.locate(cwd)
local_config = TomlFile(poetry_file.as_posix()).read()
if "tool" not in local_config or "poetry" not in local_config["tool"]:
raise RuntimeError(
"[tool.poetry] section not found in {}".format(poetry_file.name)
)
local_config = local_config["tool"]["poetry"]
# Checking validity
check_result = self.validate(local_config)
if check_result["errors"]:
message = ""
for error in check_result["errors"]:
message += " - {}\n".format(error)
raise RuntimeError("The Poetry configuration is invalid:\n" + message)
# Load package
name = local_config["name"]
version = local_config["version"]
package = ProjectPackage(name, version, version)
package.root_dir = poetry_file.parent
for author in local_config["authors"]:
package.authors.append(author)
for maintainer in local_config.get("maintainers", []):
package.maintainers.append(maintainer)
package.description = local_config.get("description", "")
package.homepage = local_config.get("homepage")
package.repository_url = local_config.get("repository")
package.documentation_url = local_config.get("documentation")
try:
license_ = license_by_id(local_config.get("license", ""))
except ValueError:
license_ = None
package.license = license_
package.keywords = local_config.get("keywords", [])
package.classifiers = local_config.get("classifiers", [])
if "readme" in local_config:
package.readme = Path(poetry_file.parent) / local_config["readme"]
if "platform" in local_config:
package.platform = local_config["platform"]
if "dependencies" in local_config:
for name, constraint in local_config["dependencies"].items():
if name.lower() == "python":
package.python_versions = constraint
continue
if isinstance(constraint, list):
for _constraint in constraint:
package.add_dependency(name, _constraint)
continue
package.add_dependency(name, constraint)
if "dev-dependencies" in local_config:
for name, constraint in local_config["dev-dependencies"].items():
if isinstance(constraint, list):
for _constraint in constraint:
package.add_dependency(name, _constraint, category="dev")
continue
package.add_dependency(name, constraint, category="dev")
extras = local_config.get("extras", {})
for extra_name, requirements in extras.items():
package.extras[extra_name] = []
# Checking for dependency
for req in requirements:
req = Dependency(req, "*")
for dep in package.requires:
if dep.name == req.name:
dep.in_extras.append(extra_name)
package.extras[extra_name].append(dep)
break
if "build" in local_config:
package.build = local_config["build"]
if "include" in local_config:
package.include = local_config["include"]
if "exclude" in local_config:
package.exclude = local_config["exclude"]
if "packages" in local_config:
package.packages = local_config["packages"]
# Custom urls
if "urls" in local_config:
package.custom_urls = local_config["urls"]
# Moving lock if necessary (pyproject.lock -> poetry.lock)
lock = poetry_file.parent / "poetry.lock"
if not lock.exists():
# Checking for pyproject.lock
old_lock = poetry_file.with_suffix(".lock")
if old_lock.exists():
shutil.move(str(old_lock), str(lock))
locker = Locker(poetry_file.parent / "poetry.lock", local_config)
# Loading global configuration
config = self.create_config(io)
# Loading local configuration
local_config_file = TomlFile(poetry_file.parent / "poetry.toml")
if local_config_file.exists():
if io.is_debug():
io.write_line(
"Loading configuration file {}".format(local_config_file.path)
)
config.merge(local_config_file.read())
poetry = Poetry(poetry_file, local_config, package, locker, config)
# Configuring sources
for source in local_config.get("source", []):
repository = self.create_legacy_repository(source, config)
is_default = source.get("default", False)
is_secondary = source.get("secondary", False)
if io.is_debug():
message = "Adding repository {} ({})".format(
repository.name, repository.url
)
if is_default:
message += " and setting it as the default one"
elif is_secondary:
message += " and setting it as secondary"
io.write_line(message)
poetry.pool.add_repository(repository, is_default, secondary=is_secondary)
# Always put PyPI last to prefer private repositories
# but only if we have no other default source
if not poetry.pool.has_default():
poetry.pool.add_repository(PyPiRepository(), True)
else:
if io.is_debug():
io.write_line("Deactivating the PyPI repository")
return poetry
@classmethod
def create_config(cls, io=None): # type: (Optional[IO]) -> Config
if io is None:
io = NullIO()
config = Config()
# Load global config
config_file = TomlFile(Path(CONFIG_DIR) / "config.toml")
if config_file.exists():
if io.is_debug():
io.write_line(
"<debug>Loading configuration file {}</debug>".format(
config_file.path
)
)
config.merge(config_file.read())
config.set_config_source(FileConfigSource(config_file))
# Load global auth config
auth_config_file = TomlFile(Path(CONFIG_DIR) / "auth.toml")
if auth_config_file.exists():
if io.is_debug():
io.write_line(
"<debug>Loading configuration file {}</debug>".format(
auth_config_file.path
)
)
config.merge(auth_config_file.read())
config.set_auth_config_source(FileConfigSource(auth_config_file))
return config
def create_legacy_repository(
self, source, auth_config
): # type: (Dict[str, str], Config) -> LegacyRepository
from .repositories.auth import Auth
from .repositories.legacy_repository import LegacyRepository
from .utils.helpers import get_http_basic_auth
if "url" in source:
# PyPI-like repository
if "name" not in source:
raise RuntimeError("Missing [name] in source.")
else:
raise RuntimeError("Unsupported source specified")
name = source["name"]
url = source["url"]
credentials = get_http_basic_auth(auth_config, name)
if not credentials:
return LegacyRepository(name, url)
auth = Auth(url, credentials[0], credentials[1])
return LegacyRepository(name, url, auth=auth)
@classmethod
def validate(
cls, config, strict=False
): # type: (dict, bool) -> Dict[str, List[str]]
"""
Checks the validity of a configuration
"""
result = {"errors": [], "warnings": []}
# Schema validation errors
validation_errors = validate_object(config, "poetry-schema")
result["errors"] += validation_errors
if strict:
# If strict, check the file more thoroughly
# Checking license
license = config.get("license")
if license:
try:
license_by_id(license)
except ValueError:
result["errors"].append("{} is not a valid license".format(license))
if "dependencies" in config:
python_versions = config["dependencies"]["python"]
if python_versions == "*":
result["warnings"].append(
"A wildcard Python dependency is ambiguous. "
"Consider specifying a more explicit one."
)
# Checking for scripts with extras
if "scripts" in config:
scripts = config["scripts"]
for name, script in scripts.items():
if not isinstance(script, dict):
continue
extras = script["extras"]
for extra in extras:
if extra not in config["extras"]:
result["errors"].append(
'Script "{}" requires extra "{}" which is not defined.'.format(
name, extra
)
)
return result
@classmethod
def locate(cls, cwd): # type: (Path) -> Path
candidates = [Path(cwd)]
candidates.extend(Path(cwd).parents)
for path in candidates:
poetry_file = path / "pyproject.toml"
if poetry_file.exists():
return poetry_file
else:
raise RuntimeError(
"Poetry could not find a pyproject.toml file in {} or its parents".format(
cwd
)
)
...@@ -6,7 +6,7 @@ import sys ...@@ -6,7 +6,7 @@ import sys
from clikit.io import NullIO from clikit.io import NullIO
from poetry.poetry import Poetry from poetry.factory import Factory
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils._compat import unicode from poetry.utils._compat import unicode
from poetry.utils.env import SystemEnv from poetry.utils.env import SystemEnv
...@@ -21,7 +21,7 @@ def get_requires_for_build_wheel(config_settings=None): ...@@ -21,7 +21,7 @@ def get_requires_for_build_wheel(config_settings=None):
""" """
Returns a list of requirements for building, as strings Returns a list of requirements for building, as strings
""" """
poetry = Poetry.create(".") poetry = Factory().create_poetry(Path("."))
main, _ = SdistBuilder.convert_dependencies(poetry.package, poetry.package.requires) main, _ = SdistBuilder.convert_dependencies(poetry.package, poetry.package.requires)
...@@ -33,7 +33,7 @@ get_requires_for_build_sdist = get_requires_for_build_wheel ...@@ -33,7 +33,7 @@ get_requires_for_build_sdist = get_requires_for_build_wheel
def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None): def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
poetry = Poetry.create(".") poetry = Factory().create_poetry(Path("."))
builder = WheelBuilder(poetry, SystemEnv(Path(sys.prefix)), NullIO()) builder = WheelBuilder(poetry, SystemEnv(Path(sys.prefix)), NullIO())
dist_info = Path(metadata_directory, builder.dist_info) dist_info = Path(metadata_directory, builder.dist_info)
...@@ -54,7 +54,7 @@ def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None): ...@@ -54,7 +54,7 @@ def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
"""Builds a wheel, places it in wheel_directory""" """Builds a wheel, places it in wheel_directory"""
poetry = Poetry.create(".") poetry = Factory().create_poetry(Path("."))
return unicode( return unicode(
WheelBuilder.make_in( WheelBuilder.make_in(
...@@ -65,7 +65,7 @@ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): ...@@ -65,7 +65,7 @@ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
def build_sdist(sdist_directory, config_settings=None): def build_sdist(sdist_directory, config_settings=None):
"""Builds an sdist, places it in sdist_directory""" """Builds an sdist, places it in sdist_directory"""
poetry = Poetry.create(".") poetry = Factory().create_poetry(Path("."))
path = SdistBuilder(poetry, SystemEnv(Path(sys.prefix)), NullIO()).build( path = SdistBuilder(poetry, SystemEnv(Path(sys.prefix)), NullIO()).build(
Path(sdist_directory) Path(sdist_directory)
......
import os import os
import tarfile import tarfile
import poetry.poetry from poetry.factory import Factory
from poetry.io.null_io import NullIO from poetry.io.null_io import NullIO
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils.helpers import temporary_directory from poetry.utils.helpers import temporary_directory
...@@ -43,7 +43,7 @@ class CompleteBuilder(Builder): ...@@ -43,7 +43,7 @@ class CompleteBuilder(Builder):
with self.unpacked_tarball(sdist_file) as tmpdir: with self.unpacked_tarball(sdist_file) as tmpdir:
WheelBuilder.make_in( WheelBuilder.make_in(
poetry.poetry.Poetry.create(tmpdir), Factory().create_poetry(tmpdir),
self._env, self._env,
self._io, self._io,
dist_dir, dist_dir,
...@@ -52,7 +52,7 @@ class CompleteBuilder(Builder): ...@@ -52,7 +52,7 @@ class CompleteBuilder(Builder):
else: else:
with self.unpacked_tarball(sdist_file) as tmpdir: with self.unpacked_tarball(sdist_file) as tmpdir:
WheelBuilder.make_in( WheelBuilder.make_in(
poetry.poetry.Poetry.create(tmpdir), Factory().create_poetry(tmpdir),
self._env, self._env,
self._io, self._io,
dist_dir, dist_dir,
...@@ -70,4 +70,4 @@ class CompleteBuilder(Builder): ...@@ -70,4 +70,4 @@ class CompleteBuilder(Builder):
assert len(files) == 1, files assert len(files) == 1, files
yield os.path.join(tmpdir, files[0]) yield Path(tmpdir) / files[0]
from __future__ import absolute_import from __future__ import absolute_import
from __future__ import unicode_literals from __future__ import unicode_literals
import shutil from typing import Optional
from typing import Dict
from typing import List
from .__version__ import __version__ from .__version__ import __version__
from .config.config import Config from .config.config import Config
from .json import validate_object
from .locations import CONFIG_DIR
from .packages import Dependency
from .packages import Locker from .packages import Locker
from .packages import Package
from .packages import ProjectPackage from .packages import ProjectPackage
from .repositories import Pool from .repositories.pool import Pool
from .repositories.auth import Auth
from .repositories.legacy_repository import LegacyRepository
from .repositories.pypi_repository import PyPiRepository
from .spdx import license_by_id
from .utils._compat import Path from .utils._compat import Path
from .utils.helpers import get_http_basic_auth
from .utils.toml_file import TomlFile from .utils.toml_file import TomlFile
...@@ -32,7 +20,7 @@ class Poetry: ...@@ -32,7 +20,7 @@ class Poetry:
self, self,
file, # type: Path file, # type: Path
local_config, # type: dict local_config, # type: dict
package, # type: Package package, # type: ProjectPackage
locker, # type: Locker locker, # type: Locker
config, # type: Config config, # type: Config
): ):
...@@ -41,28 +29,14 @@ class Poetry: ...@@ -41,28 +29,14 @@ class Poetry:
self._local_config = local_config self._local_config = local_config
self._locker = locker self._locker = locker
self._config = config self._config = config
# Configure sources
self._pool = Pool() self._pool = Pool()
for source in self._local_config.get("source", []):
repository = self.create_legacy_repository(source)
self._pool.add_repository(
repository,
source.get("default", False),
secondary=source.get("secondary", False),
)
# Always put PyPI last to prefer private repositories
# but only if we have no other default source
if not self._pool.has_default():
self._pool.add_repository(PyPiRepository(), True)
@property @property
def file(self): def file(self):
return self._file return self._file
@property @property
def package(self): # type: () -> Package def package(self): # type: () -> ProjectPackage
return self._package return self._package
@property @property
...@@ -81,221 +55,17 @@ class Poetry: ...@@ -81,221 +55,17 @@ class Poetry:
def config(self): # type: () -> Config def config(self): # type: () -> Config
return self._config return self._config
@classmethod def set_locker(self, locker): # type: (Locker) -> Poetry
def create(cls, cwd): # type: (Path) -> Poetry self._locker = locker
poetry_file = cls.locate(cwd)
local_config = TomlFile(poetry_file.as_posix()).read()
if "tool" not in local_config or "poetry" not in local_config["tool"]:
raise RuntimeError(
"[tool.poetry] section not found in {}".format(poetry_file.name)
)
local_config = local_config["tool"]["poetry"]
# Checking validity
check_result = cls.check(local_config)
if check_result["errors"]:
message = ""
for error in check_result["errors"]:
message += " - {}\n".format(error)
raise RuntimeError("The Poetry configuration is invalid:\n" + message)
# Load package
name = local_config["name"]
version = local_config["version"]
package = ProjectPackage(name, version, version)
package.root_dir = poetry_file.parent
for author in local_config["authors"]:
package.authors.append(author)
for maintainer in local_config.get("maintainers", []):
package.maintainers.append(maintainer)
package.description = local_config.get("description", "")
package.homepage = local_config.get("homepage")
package.repository_url = local_config.get("repository")
package.documentation_url = local_config.get("documentation")
try:
license_ = license_by_id(local_config.get("license", ""))
except ValueError:
license_ = None
package.license = license_
package.keywords = local_config.get("keywords", [])
package.classifiers = local_config.get("classifiers", [])
if "readme" in local_config:
package.readme = Path(poetry_file.parent) / local_config["readme"]
if "platform" in local_config:
package.platform = local_config["platform"]
if "dependencies" in local_config:
for name, constraint in local_config["dependencies"].items():
if name.lower() == "python":
package.python_versions = constraint
continue
if isinstance(constraint, list):
for _constraint in constraint:
package.add_dependency(name, _constraint)
continue
package.add_dependency(name, constraint)
if "dev-dependencies" in local_config:
for name, constraint in local_config["dev-dependencies"].items():
if isinstance(constraint, list):
for _constraint in constraint:
package.add_dependency(name, _constraint, category="dev")
continue
package.add_dependency(name, constraint, category="dev")
extras = local_config.get("extras", {})
for extra_name, requirements in extras.items():
package.extras[extra_name] = []
# Checking for dependency
for req in requirements:
req = Dependency(req, "*")
for dep in package.requires:
if dep.name == req.name:
dep.in_extras.append(extra_name)
package.extras[extra_name].append(dep)
break
if "build" in local_config:
package.build = local_config["build"]
if "include" in local_config:
package.include = local_config["include"]
if "exclude" in local_config:
package.exclude = local_config["exclude"]
if "packages" in local_config:
package.packages = local_config["packages"]
# Custom urls
if "urls" in local_config:
package.custom_urls = local_config["urls"]
# Moving lock if necessary (pyproject.lock -> poetry.lock)
lock = poetry_file.parent / "poetry.lock"
if not lock.exists():
# Checking for pyproject.lock
old_lock = poetry_file.with_suffix(".lock")
if old_lock.exists():
shutil.move(str(old_lock), str(lock))
locker = Locker(poetry_file.parent / "poetry.lock", local_config)
config = Config()
# Load global config
config_file = TomlFile(Path(CONFIG_DIR) / "config.toml")
if config_file.exists():
config.merge(config_file.read())
local_config_file = TomlFile(poetry_file.parent / "poetry.toml")
if local_config_file.exists():
config.merge(local_config_file.read())
# Load global auth config
auth_config_file = TomlFile(Path(CONFIG_DIR) / "auth.toml")
if auth_config_file.exists():
config.merge(auth_config_file.read())
return cls(poetry_file, local_config, package, locker, config)
def create_legacy_repository(
self, source
): # type: (Dict[str, str]) -> LegacyRepository
if "url" in source:
# PyPI-like repository
if "name" not in source:
raise RuntimeError("Missing [name] in source.")
else:
raise RuntimeError("Unsupported source specified")
name = source["name"]
url = source["url"]
credentials = get_http_basic_auth(self._config, name)
if not credentials:
return LegacyRepository(name, url)
auth = Auth(url, credentials[0], credentials[1])
return LegacyRepository(name, url, auth=auth)
@classmethod
def locate(cls, cwd): # type: (Path) -> Poetry
candidates = [Path(cwd)]
candidates.extend(Path(cwd).parents)
for path in candidates:
poetry_file = path / "pyproject.toml"
if poetry_file.exists():
return poetry_file
else:
raise RuntimeError(
"Poetry could not find a pyproject.toml file in {} or its parents".format(
cwd
)
)
@classmethod
def check(cls, config, strict=False): # type: (dict, bool) -> Dict[str, List[str]]
"""
Checks the validity of a configuration
"""
result = {"errors": [], "warnings": []}
# Schema validation errors
validation_errors = validate_object(config, "poetry-schema")
result["errors"] += validation_errors
if strict:
# If strict, check the file more thoroughly
# Checking license return self
license = config.get("license")
if license:
try:
license_by_id(license)
except ValueError:
result["errors"].append("{} is not a valid license".format(license))
if "dependencies" in config: def set_pool(self, pool): # type: (Pool) -> Poetry
python_versions = config["dependencies"]["python"] self._pool = pool
if python_versions == "*":
result["warnings"].append(
"A wildcard Python dependency is ambiguous. "
"Consider specifying a more explicit one."
)
# Checking for scripts with extras return self
if "scripts" in config:
scripts = config["scripts"]
for name, script in scripts.items():
if not isinstance(script, dict):
continue
extras = script["extras"] def set_config(self, config): # type: (Config) -> Poetry
for extra in extras: self._config = config
if extra not in config["extras"]:
result["errors"].append(
'Script "{}" requires extra "{}" which is not defined.'.format(
name, extra
)
)
return result return self
...@@ -11,6 +11,7 @@ from tempfile import mkdtemp ...@@ -11,6 +11,7 @@ from tempfile import mkdtemp
from typing import List from typing import List
from typing import Optional from typing import Optional
from poetry.factory import Factory
from poetry.packages import Dependency from poetry.packages import Dependency
from poetry.packages import DependencyPackage from poetry.packages import DependencyPackage
from poetry.packages import DirectoryDependency from poetry.packages import DirectoryDependency
...@@ -300,9 +301,7 @@ class Provider: ...@@ -300,9 +301,7 @@ class Provider:
) )
if supports_poetry: if supports_poetry:
from poetry.poetry import Poetry poetry = Factory().create_poetry(directory)
poetry = Poetry.create(directory)
pkg = poetry.package pkg = poetry.package
package = Package(pkg.name, pkg.version) package = Package(pkg.name, pkg.version)
......
...@@ -8,7 +8,7 @@ def test_config_get_default_value(config): ...@@ -8,7 +8,7 @@ def test_config_get_default_value(config):
def test_config_get_processes_depended_on_values(config): def test_config_get_processes_depended_on_values(config):
assert os.path.join(str(CACHE_DIR), "virtualenvs") == config.get("virtualenvs.path") assert os.path.join("/foo", "virtualenvs") == config.get("virtualenvs.path")
def test_config_get_from_environment_variable(config, environ): def test_config_get_from_environment_variable(config, environ):
......
...@@ -10,43 +10,68 @@ try: ...@@ -10,43 +10,68 @@ try:
except ImportError: except ImportError:
import urlparse import urlparse
from tomlkit import parse from typing import Any
from typing import Dict
from poetry.config.config import Config from poetry.config.config import Config as BaseConfig
from poetry.config.dict_config_source import DictConfigSource
from poetry.utils._compat import PY2 from poetry.utils._compat import PY2
from poetry.utils._compat import WINDOWS from poetry.utils._compat import WINDOWS
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils.helpers import merge_dicts
from poetry.utils.toml_file import TomlFile
class Config(BaseConfig):
def get(self, setting_name, default=None): # type: (str, Any) -> Any
self.merge(self._config_source.config)
self.merge(self._auth_config_source.config)
return super(Config, self).get(setting_name, default=default)
def raw(self): # type: () -> Dict[str, Any]
self.merge(self._config_source.config)
self.merge(self._auth_config_source.config)
return super(Config, self).raw()
def all(self): # type: () -> Dict[str, Any]
self.merge(self._config_source.config)
self.merge(self._auth_config_source.config)
return super(Config, self).all()
def tmp_dir():
dir_ = tempfile.mkdtemp(prefix="poetry_")
yield dir_
shutil.rmtree(dir_)
@pytest.fixture @pytest.fixture
def config_document(): def config_source():
content = """cache-dir = "/foo" source = DictConfigSource()
""" source.add_property("cache-dir", "/foo")
doc = parse(content)
return doc return source
@pytest.fixture @pytest.fixture
def config_source(config_document, mocker): def auth_config_source():
file = TomlFile(Path(tempfile.mktemp())) source = DictConfigSource()
mocker.patch.object(file, "exists", return_value=True)
mocker.patch.object(file, "read", return_value=config_document) return source
mocker.patch.object(
file, "write", return_value=lambda new: merge_dicts(config_document, new)
)
mocker.patch(
"poetry.config.config_source.ConfigSource.file",
new_callable=mocker.PropertyMock,
return_value=file,
)
@pytest.fixture @pytest.fixture
def config(config_source): def config(config_source, auth_config_source, mocker):
c = Config() c = Config()
c.merge(config_source.config)
c.set_config_source(config_source)
c.set_auth_config_source(auth_config_source)
mocker.patch("poetry.factory.Factory.create_config", return_value=c)
mocker.patch("poetry.config.config.Config.set_config_source")
return c return c
......
...@@ -2,7 +2,6 @@ from cleo.testers import CommandTester ...@@ -2,7 +2,6 @@ from cleo.testers import CommandTester
from poetry.utils._compat import PY2 from poetry.utils._compat import PY2
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.poetry import Poetry
def test_check_valid(app): def test_check_valid(app):
...@@ -20,7 +19,7 @@ All set! ...@@ -20,7 +19,7 @@ All set!
def test_check_invalid(app, mocker): def test_check_invalid(app, mocker):
mocker.patch( mocker.patch(
"poetry.poetry.Poetry.locate", "poetry.factory.Factory.locate",
return_value=Path(__file__).parent.parent.parent return_value=Path(__file__).parent.parent.parent
/ "fixtures" / "fixtures"
/ "invalid_pyproject" / "invalid_pyproject"
......
...@@ -4,13 +4,12 @@ import os ...@@ -4,13 +4,12 @@ import os
from cleo.testers import CommandTester from cleo.testers import CommandTester
from poetry.config.config_source import ConfigSource from poetry.config.config_source import ConfigSource
from poetry.poetry import Poetry from poetry.factory import Factory
def test_list_displays_default_value_if_not_set(app, config_source): def test_list_displays_default_value_if_not_set(app, config):
command = app.find("config") command = app.find("config")
tester = CommandTester(command) tester = CommandTester(command)
tester.execute("--list") tester.execute("--list")
expected = """cache-dir = "/foo" expected = """cache-dir = "/foo"
...@@ -24,7 +23,7 @@ virtualenvs.path = {path} # /foo{sep}virtualenvs ...@@ -24,7 +23,7 @@ virtualenvs.path = {path} # /foo{sep}virtualenvs
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
def test_list_displays_set_get_setting(app, config_source, config_document): def test_list_displays_set_get_setting(app, config):
command = app.find("config") command = app.find("config")
tester = CommandTester(command) tester = CommandTester(command)
...@@ -40,10 +39,11 @@ virtualenvs.path = {path} # /foo{sep}virtualenvs ...@@ -40,10 +39,11 @@ virtualenvs.path = {path} # /foo{sep}virtualenvs
path=json.dumps(os.path.join("{cache-dir}", "virtualenvs")), sep=os.path.sep path=json.dumps(os.path.join("{cache-dir}", "virtualenvs")), sep=os.path.sep
) )
assert 0 == config.set_config_source.call_count
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
def test_display_single_setting(app, config_source): def test_display_single_setting(app, config):
command = app.find("config") command = app.find("config")
tester = CommandTester(command) tester = CommandTester(command)
...@@ -55,8 +55,8 @@ def test_display_single_setting(app, config_source): ...@@ -55,8 +55,8 @@ def test_display_single_setting(app, config_source):
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
def test_display_single_local_setting(app, config_source, fixture_dir): def test_display_single_local_setting(app, config, fixture_dir):
poetry = Poetry.create(fixture_dir("with_local_config")) poetry = Factory().create_poetry(fixture_dir("with_local_config"))
app._poetry = poetry app._poetry = poetry
command = app.find("config") command = app.find("config")
...@@ -70,10 +70,7 @@ def test_display_single_local_setting(app, config_source, fixture_dir): ...@@ -70,10 +70,7 @@ def test_display_single_local_setting(app, config_source, fixture_dir):
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
def test_list_displays_set_get_local_setting( def test_list_displays_set_get_local_setting(app, config):
app, config_source, config_document, mocker
):
init = mocker.spy(ConfigSource, "__init__")
command = app.find("config") command = app.find("config")
tester = CommandTester(command) tester = CommandTester(command)
...@@ -89,14 +86,11 @@ virtualenvs.path = {path} # /foo{sep}virtualenvs ...@@ -89,14 +86,11 @@ virtualenvs.path = {path} # /foo{sep}virtualenvs
path=json.dumps(os.path.join("{cache-dir}", "virtualenvs")), sep=os.path.sep path=json.dumps(os.path.join("{cache-dir}", "virtualenvs")), sep=os.path.sep
) )
assert expected == tester.io.fetch_output() assert 1 == config.set_config_source.call_count
assert "poetry.toml" == init.call_args_list[2][0][1].path.name
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
def test_set_pypi_token(app, config_source, config_document, mocker): def test_set_pypi_token(app, config, config_source, auth_config_source):
init = mocker.spy(ConfigSource, "__init__")
command = app.find("config") command = app.find("config")
tester = CommandTester(command) tester = CommandTester(command)
...@@ -104,4 +98,4 @@ def test_set_pypi_token(app, config_source, config_document, mocker): ...@@ -104,4 +98,4 @@ def test_set_pypi_token(app, config_source, config_document, mocker):
tester.execute("--list") tester.execute("--list")
assert "mytoken" == config_document["pypi-token"]["pypi"] assert "mytoken" == auth_config_source.config["pypi-token"]["pypi"]
...@@ -5,11 +5,13 @@ import pytest ...@@ -5,11 +5,13 @@ import pytest
from cleo.testers import CommandTester from cleo.testers import CommandTester
from poetry.factory import Factory
from poetry.repositories.pool import Pool
from tests.helpers import get_package from tests.helpers import get_package
from ..conftest import Application from ..conftest import Application
from ..conftest import Locker
from ..conftest import Path from ..conftest import Path
from ..conftest import Poetry
PYPROJECT_CONTENT = """\ PYPROJECT_CONTENT = """\
...@@ -51,11 +53,15 @@ def poetry(repo, tmp_dir): ...@@ -51,11 +53,15 @@ def poetry(repo, tmp_dir):
with (Path(tmp_dir) / "pyproject.toml").open("w", encoding="utf-8") as f: with (Path(tmp_dir) / "pyproject.toml").open("w", encoding="utf-8") as f:
f.write(PYPROJECT_CONTENT) f.write(PYPROJECT_CONTENT)
p = Poetry.create(Path(tmp_dir)) p = Factory().create_poetry(Path(tmp_dir))
p.pool.remove_repository("pypi") locker = Locker(p.locker.lock.path, p.locker._local_config)
p.pool.add_repository(repo) locker.write()
p._locker.write() p.set_locker(locker)
pool = Pool()
pool.add_repository(repo)
p.set_pool(pool)
yield p yield p
......
...@@ -10,6 +10,7 @@ except ImportError: ...@@ -10,6 +10,7 @@ except ImportError:
from cleo import ApplicationTester from cleo import ApplicationTester
from poetry.console import Application as BaseApplication from poetry.console import Application as BaseApplication
from poetry.factory import Factory
from poetry.installation.noop_installer import NoopInstaller from poetry.installation.noop_installer import NoopInstaller
from poetry.poetry import Poetry as BasePoetry from poetry.poetry import Poetry as BasePoetry
from poetry.packages import Locker as BaseLocker from poetry.packages import Locker as BaseLocker
...@@ -112,8 +113,10 @@ class Application(BaseApplication): ...@@ -112,8 +113,10 @@ class Application(BaseApplication):
def reset_poetry(self): def reset_poetry(self):
poetry = self._poetry poetry = self._poetry
self._poetry = Poetry.create(self._poetry.file.path.parent) self._poetry = Factory().create_poetry(self._poetry.file.path.parent)
self._poetry._pool = poetry.pool self._poetry.set_pool(poetry.pool)
self._poetry.set_config(poetry.config)
self._poetry.set_locker(poetry.locker)
class Locker(BaseLocker): class Locker(BaseLocker):
...@@ -189,14 +192,20 @@ def project_directory(): ...@@ -189,14 +192,20 @@ def project_directory():
@pytest.fixture @pytest.fixture
def poetry(repo, project_directory, config_source): def poetry(repo, project_directory, config):
p = Poetry.create(Path(__file__).parent.parent / "fixtures" / project_directory) p = Factory().create_poetry(
Path(__file__).parent.parent / "fixtures" / project_directory
)
p.set_locker(Locker(p.locker.lock.path, p.locker._local_config))
with p.file.path.open(encoding="utf-8") as f: with p.file.path.open(encoding="utf-8") as f:
content = f.read() content = f.read()
p.pool.remove_repository("pypi") p.set_config(config)
p.pool.add_repository(repo)
pool = Pool()
pool.add_repository(repo)
p.set_pool(pool)
yield p yield p
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
from clikit.io import NullIO from clikit.io import NullIO
from email.parser import Parser from email.parser import Parser
from poetry.factory import Factory
from poetry.masonry.builders.builder import Builder from poetry.masonry.builders.builder import Builder
from poetry.poetry import Poetry
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils.env import NullEnv from poetry.utils.env import NullEnv
...@@ -13,7 +13,7 @@ def test_builder_find_excluded_files(mocker): ...@@ -13,7 +13,7 @@ def test_builder_find_excluded_files(mocker):
p.return_value = [] p.return_value = []
builder = Builder( builder = Builder(
Poetry.create(Path(__file__).parent / "fixtures" / "complete"), Factory().create_poetry(Path(__file__).parent / "fixtures" / "complete"),
NullEnv(), NullEnv(),
NullIO(), NullIO(),
) )
...@@ -26,7 +26,9 @@ def test_builder_find_case_sensitive_excluded_files(mocker): ...@@ -26,7 +26,9 @@ def test_builder_find_case_sensitive_excluded_files(mocker):
p.return_value = [] p.return_value = []
builder = Builder( builder = Builder(
Poetry.create(Path(__file__).parent / "fixtures" / "case_sensitive_exclusions"), Factory().create_poetry(
Path(__file__).parent / "fixtures" / "case_sensitive_exclusions"
),
NullEnv(), NullEnv(),
NullIO(), NullIO(),
) )
...@@ -47,7 +49,7 @@ def test_builder_find_invalid_case_sensitive_excluded_files(mocker): ...@@ -47,7 +49,7 @@ def test_builder_find_invalid_case_sensitive_excluded_files(mocker):
p.return_value = [] p.return_value = []
builder = Builder( builder = Builder(
Poetry.create( Factory().create_poetry(
Path(__file__).parent / "fixtures" / "invalid_case_sensitive_exclusions" Path(__file__).parent / "fixtures" / "invalid_case_sensitive_exclusions"
), ),
NullEnv(), NullEnv(),
...@@ -59,7 +61,7 @@ def test_builder_find_invalid_case_sensitive_excluded_files(mocker): ...@@ -59,7 +61,7 @@ def test_builder_find_invalid_case_sensitive_excluded_files(mocker):
def test_get_metadata_content(): def test_get_metadata_content():
builder = Builder( builder = Builder(
Poetry.create(Path(__file__).parent / "fixtures" / "complete"), Factory().create_poetry(Path(__file__).parent / "fixtures" / "complete"),
NullEnv(), NullEnv(),
NullIO(), NullIO(),
) )
...@@ -110,7 +112,7 @@ def test_get_metadata_content(): ...@@ -110,7 +112,7 @@ def test_get_metadata_content():
def test_metadata_homepage_default(): def test_metadata_homepage_default():
builder = Builder( builder = Builder(
Poetry.create(Path(__file__).parent / "fixtures" / "simple_version"), Factory().create_poetry(Path(__file__).parent / "fixtures" / "simple_version"),
NullEnv(), NullEnv(),
NullIO(), NullIO(),
) )
...@@ -122,7 +124,9 @@ def test_metadata_homepage_default(): ...@@ -122,7 +124,9 @@ def test_metadata_homepage_default():
def test_metadata_with_vcs_dependencies(): def test_metadata_with_vcs_dependencies():
builder = Builder( builder = Builder(
Poetry.create(Path(__file__).parent / "fixtures" / "with_vcs_dependency"), Factory().create_poetry(
Path(__file__).parent / "fixtures" / "with_vcs_dependency"
),
NullEnv(), NullEnv(),
NullIO(), NullIO(),
) )
...@@ -136,7 +140,9 @@ def test_metadata_with_vcs_dependencies(): ...@@ -136,7 +140,9 @@ def test_metadata_with_vcs_dependencies():
def test_metadata_with_url_dependencies(): def test_metadata_with_url_dependencies():
builder = Builder( builder = Builder(
Poetry.create(Path(__file__).parent / "fixtures" / "with_url_dependency"), Factory().create_poetry(
Path(__file__).parent / "fixtures" / "with_url_dependency"
),
NullEnv(), NullEnv(),
NullIO(), NullIO(),
) )
......
...@@ -14,8 +14,8 @@ import tempfile ...@@ -14,8 +14,8 @@ import tempfile
from clikit.io import NullIO from clikit.io import NullIO
from poetry import __version__ from poetry import __version__
from poetry.factory import Factory
from poetry.masonry.builders import CompleteBuilder from poetry.masonry.builders import CompleteBuilder
from poetry.poetry import Poetry
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils._compat import decode from poetry.utils._compat import decode
from poetry.utils.env import NullEnv from poetry.utils.env import NullEnv
...@@ -45,7 +45,7 @@ def clear_samples_dist(): ...@@ -45,7 +45,7 @@ def clear_samples_dist():
def test_wheel_c_extension(): def test_wheel_c_extension():
module_path = fixtures_dir / "extended" module_path = fixtures_dir / "extended"
builder = CompleteBuilder( builder = CompleteBuilder(
Poetry.create(module_path), NullEnv(execute=True), NullIO() Factory().create_poetry(module_path), NullEnv(execute=True), NullIO()
) )
builder.build() builder.build()
...@@ -102,7 +102,7 @@ $""".format( ...@@ -102,7 +102,7 @@ $""".format(
def test_wheel_c_extension_src_layout(): def test_wheel_c_extension_src_layout():
module_path = fixtures_dir / "src_extended" module_path = fixtures_dir / "src_extended"
builder = CompleteBuilder( builder = CompleteBuilder(
Poetry.create(module_path), NullEnv(execute=True), NullIO() Factory().create_poetry(module_path), NullEnv(execute=True), NullIO()
) )
builder.build() builder.build()
...@@ -155,7 +155,7 @@ $""".format( ...@@ -155,7 +155,7 @@ $""".format(
def test_complete(): def test_complete():
module_path = fixtures_dir / "complete" module_path = fixtures_dir / "complete"
builder = CompleteBuilder( builder = CompleteBuilder(
Poetry.create(module_path), NullEnv(execute=True), NullIO() Factory().create_poetry(module_path), NullEnv(execute=True), NullIO()
) )
builder.build() builder.build()
...@@ -244,7 +244,7 @@ def test_complete_no_vcs(): ...@@ -244,7 +244,7 @@ def test_complete_no_vcs():
shutil.copytree(module_path.as_posix(), temporary_dir.as_posix()) shutil.copytree(module_path.as_posix(), temporary_dir.as_posix())
builder = CompleteBuilder( builder = CompleteBuilder(
Poetry.create(temporary_dir), NullEnv(execute=True), NullIO() Factory().create_poetry(temporary_dir), NullEnv(execute=True), NullIO()
) )
builder.build() builder.build()
...@@ -341,7 +341,7 @@ My Package ...@@ -341,7 +341,7 @@ My Package
def test_module_src(): def test_module_src():
module_path = fixtures_dir / "source_file" module_path = fixtures_dir / "source_file"
builder = CompleteBuilder( builder = CompleteBuilder(
Poetry.create(module_path), NullEnv(execute=True), NullIO() Factory().create_poetry(module_path), NullEnv(execute=True), NullIO()
) )
builder.build() builder.build()
...@@ -367,7 +367,7 @@ def test_module_src(): ...@@ -367,7 +367,7 @@ def test_module_src():
def test_package_src(): def test_package_src():
module_path = fixtures_dir / "source_package" module_path = fixtures_dir / "source_package"
builder = CompleteBuilder( builder = CompleteBuilder(
Poetry.create(module_path), NullEnv(execute=True), NullIO() Factory().create_poetry(module_path), NullEnv(execute=True), NullIO()
) )
builder.build() builder.build()
...@@ -413,7 +413,7 @@ def test_package_with_include(mocker): ...@@ -413,7 +413,7 @@ def test_package_with_include(mocker):
/ "vcs_excluded.txt" / "vcs_excluded.txt"
), ),
] ]
builder = CompleteBuilder(Poetry.create(module_path), NullEnv(), NullIO()) builder = CompleteBuilder(Factory().create_poetry(module_path), NullEnv(), NullIO())
builder.build() builder.build()
sdist = fixtures_dir / "with-include" / "dist" / "with-include-1.2.3.tar.gz" sdist = fixtures_dir / "with-include" / "dist" / "with-include-1.2.3.tar.gz"
......
...@@ -3,8 +3,8 @@ from __future__ import unicode_literals ...@@ -3,8 +3,8 @@ from __future__ import unicode_literals
from clikit.io import NullIO from clikit.io import NullIO
from poetry.factory import Factory
from poetry.masonry.builders import EditableBuilder from poetry.masonry.builders import EditableBuilder
from poetry.poetry import Poetry
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils.env import MockEnv from poetry.utils.env import MockEnv
...@@ -18,7 +18,7 @@ def test_build_should_delegate_to_pip_for_non_pure_python_packages(tmp_dir, mock ...@@ -18,7 +18,7 @@ def test_build_should_delegate_to_pip_for_non_pure_python_packages(tmp_dir, mock
env.site_packages.mkdir(parents=True) env.site_packages.mkdir(parents=True)
module_path = fixtures_dir / "extended" module_path = fixtures_dir / "extended"
builder = EditableBuilder(Poetry.create(module_path), env, NullIO()) builder = EditableBuilder(Factory().create_poetry(module_path), env, NullIO())
builder.build() builder.build()
expected = [["python", "-m", "pip", "install", "-e", str(module_path)]] expected = [["python", "-m", "pip", "install", "-e", str(module_path)]]
...@@ -34,7 +34,7 @@ def test_build_should_temporarily_remove_the_pyproject_file(tmp_dir, mocker): ...@@ -34,7 +34,7 @@ def test_build_should_temporarily_remove_the_pyproject_file(tmp_dir, mocker):
env.site_packages.mkdir(parents=True) env.site_packages.mkdir(parents=True)
module_path = fixtures_dir / "extended" module_path = fixtures_dir / "extended"
builder = EditableBuilder(Poetry.create(module_path), env, NullIO()) builder = EditableBuilder(Factory().create_poetry(module_path), env, NullIO())
builder.build() builder.build()
expected = [["python", "-m", "pip", "install", "-e", str(module_path)]] expected = [["python", "-m", "pip", "install", "-e", str(module_path)]]
......
...@@ -8,11 +8,11 @@ from email.parser import Parser ...@@ -8,11 +8,11 @@ from email.parser import Parser
from clikit.io import NullIO from clikit.io import NullIO
from poetry.factory import Factory
from poetry.masonry.builders.sdist import SdistBuilder from poetry.masonry.builders.sdist import SdistBuilder
from poetry.masonry.utils.package_include import PackageInclude from poetry.masonry.utils.package_include import PackageInclude
from poetry.packages import Package from poetry.packages import Package
from poetry.packages.vcs_dependency import VCSDependency from poetry.packages.vcs_dependency import VCSDependency
from poetry.poetry import Poetry
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils._compat import to_str from poetry.utils._compat import to_str
from poetry.utils.env import NullEnv from poetry.utils.env import NullEnv
...@@ -111,7 +111,7 @@ def test_convert_dependencies(): ...@@ -111,7 +111,7 @@ def test_convert_dependencies():
def test_make_setup(): def test_make_setup():
poetry = Poetry.create(project("complete")) poetry = Factory().create_poetry(project("complete"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
setup = builder.build_setup() setup = builder.build_setup()
...@@ -144,7 +144,7 @@ def test_make_pkg_info(mocker): ...@@ -144,7 +144,7 @@ def test_make_pkg_info(mocker):
get_metadata_content = mocker.patch( get_metadata_content = mocker.patch(
"poetry.masonry.builders.builder.Builder.get_metadata_content" "poetry.masonry.builders.builder.Builder.get_metadata_content"
) )
poetry = Poetry.create(project("complete")) poetry = Factory().create_poetry(project("complete"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
builder.build_pkg_info() builder.build_pkg_info()
...@@ -153,7 +153,7 @@ def test_make_pkg_info(mocker): ...@@ -153,7 +153,7 @@ def test_make_pkg_info(mocker):
def test_make_pkg_info_any_python(): def test_make_pkg_info_any_python():
poetry = Poetry.create(project("module1")) poetry = Factory().create_poetry(project("module1"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
pkg_info = builder.build_pkg_info() pkg_info = builder.build_pkg_info()
...@@ -164,7 +164,7 @@ def test_make_pkg_info_any_python(): ...@@ -164,7 +164,7 @@ def test_make_pkg_info_any_python():
def test_find_files_to_add(): def test_find_files_to_add():
poetry = Poetry.create(project("complete")) poetry = Factory().create_poetry(project("complete"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
result = builder.find_files_to_add() result = builder.find_files_to_add()
...@@ -184,7 +184,7 @@ def test_find_files_to_add(): ...@@ -184,7 +184,7 @@ def test_find_files_to_add():
def test_make_pkg_info_multi_constraints_dependency(): def test_make_pkg_info_multi_constraints_dependency():
poetry = Poetry.create( poetry = Factory().create_poetry(
Path(__file__).parent.parent.parent Path(__file__).parent.parent.parent
/ "fixtures" / "fixtures"
/ "project_with_multi_constraints_dependency" / "project_with_multi_constraints_dependency"
...@@ -203,7 +203,7 @@ def test_make_pkg_info_multi_constraints_dependency(): ...@@ -203,7 +203,7 @@ def test_make_pkg_info_multi_constraints_dependency():
def test_find_packages(): def test_find_packages():
poetry = Poetry.create(project("complete")) poetry = Factory().create_poetry(project("complete"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
...@@ -220,7 +220,7 @@ def test_find_packages(): ...@@ -220,7 +220,7 @@ def test_find_packages():
"my_package.sub_pkg2": ["data2/*"], "my_package.sub_pkg2": ["data2/*"],
} }
poetry = Poetry.create(project("source_package")) poetry = Factory().create_poetry(project("source_package"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
...@@ -235,7 +235,7 @@ def test_find_packages(): ...@@ -235,7 +235,7 @@ def test_find_packages():
def test_package(): def test_package():
poetry = Poetry.create(project("complete")) poetry = Factory().create_poetry(project("complete"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
builder.build() builder.build()
...@@ -249,7 +249,7 @@ def test_package(): ...@@ -249,7 +249,7 @@ def test_package():
def test_module(): def test_module():
poetry = Poetry.create(project("module1")) poetry = Factory().create_poetry(project("module1"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
builder.build() builder.build()
...@@ -263,7 +263,7 @@ def test_module(): ...@@ -263,7 +263,7 @@ def test_module():
def test_prelease(): def test_prelease():
poetry = Poetry.create(project("prerelease")) poetry = Factory().create_poetry(project("prerelease"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
builder.build() builder.build()
...@@ -274,7 +274,7 @@ def test_prelease(): ...@@ -274,7 +274,7 @@ def test_prelease():
def test_with_c_extensions(): def test_with_c_extensions():
poetry = Poetry.create(project("extended")) poetry = Factory().create_poetry(project("extended"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
builder.build() builder.build()
...@@ -289,7 +289,7 @@ def test_with_c_extensions(): ...@@ -289,7 +289,7 @@ def test_with_c_extensions():
def test_with_c_extensions_src_layout(): def test_with_c_extensions_src_layout():
poetry = Poetry.create(project("src_extended")) poetry = Factory().create_poetry(project("src_extended"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
builder.build() builder.build()
...@@ -304,7 +304,7 @@ def test_with_c_extensions_src_layout(): ...@@ -304,7 +304,7 @@ def test_with_c_extensions_src_layout():
def test_with_src_module_file(): def test_with_src_module_file():
poetry = Poetry.create(project("source_file")) poetry = Factory().create_poetry(project("source_file"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
...@@ -329,7 +329,7 @@ def test_with_src_module_file(): ...@@ -329,7 +329,7 @@ def test_with_src_module_file():
def test_with_src_module_dir(): def test_with_src_module_dir():
poetry = Poetry.create(project("source_package")) poetry = Factory().create_poetry(project("source_package"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
...@@ -372,7 +372,7 @@ def test_default_with_excluded_data(mocker): ...@@ -372,7 +372,7 @@ def test_default_with_excluded_data(mocker):
.as_posix() .as_posix()
) )
] ]
poetry = Poetry.create(project("default_with_excluded_data")) poetry = Factory().create_poetry(project("default_with_excluded_data"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
...@@ -411,7 +411,7 @@ def test_default_with_excluded_data(mocker): ...@@ -411,7 +411,7 @@ def test_default_with_excluded_data(mocker):
def test_proper_python_requires_if_two_digits_precision_version_specified(): def test_proper_python_requires_if_two_digits_precision_version_specified():
poetry = Poetry.create(project("simple_version")) poetry = Factory().create_poetry(project("simple_version"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
pkg_info = builder.build_pkg_info() pkg_info = builder.build_pkg_info()
...@@ -422,7 +422,7 @@ def test_proper_python_requires_if_two_digits_precision_version_specified(): ...@@ -422,7 +422,7 @@ def test_proper_python_requires_if_two_digits_precision_version_specified():
def test_proper_python_requires_if_three_digits_precision_version_specified(): def test_proper_python_requires_if_three_digits_precision_version_specified():
poetry = Poetry.create(project("single_python")) poetry = Factory().create_poetry(project("single_python"))
builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder = SdistBuilder(poetry, NullEnv(), NullIO())
pkg_info = builder.build_pkg_info() pkg_info = builder.build_pkg_info()
......
...@@ -5,8 +5,8 @@ import zipfile ...@@ -5,8 +5,8 @@ import zipfile
from clikit.io import NullIO from clikit.io import NullIO
from poetry.factory import Factory
from poetry.masonry.builders import WheelBuilder from poetry.masonry.builders import WheelBuilder
from poetry.poetry import Poetry
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils.env import NullEnv from poetry.utils.env import NullEnv
...@@ -31,7 +31,7 @@ def clear_samples_dist(): ...@@ -31,7 +31,7 @@ def clear_samples_dist():
def test_wheel_module(): def test_wheel_module():
module_path = fixtures_dir / "module1" module_path = fixtures_dir / "module1"
WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) WheelBuilder.make(Factory().create_poetry(module_path), NullEnv(), NullIO())
whl = module_path / "dist" / "module1-0.1-py2.py3-none-any.whl" whl = module_path / "dist" / "module1-0.1-py2.py3-none-any.whl"
...@@ -43,7 +43,7 @@ def test_wheel_module(): ...@@ -43,7 +43,7 @@ def test_wheel_module():
def test_wheel_package(): def test_wheel_package():
module_path = fixtures_dir / "complete" module_path = fixtures_dir / "complete"
WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) WheelBuilder.make(Factory().create_poetry(module_path), NullEnv(), NullIO())
whl = module_path / "dist" / "my_package-1.2.3-py3-none-any.whl" whl = module_path / "dist" / "my_package-1.2.3-py3-none-any.whl"
...@@ -55,7 +55,7 @@ def test_wheel_package(): ...@@ -55,7 +55,7 @@ def test_wheel_package():
def test_wheel_prerelease(): def test_wheel_prerelease():
module_path = fixtures_dir / "prerelease" module_path = fixtures_dir / "prerelease"
WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) WheelBuilder.make(Factory().create_poetry(module_path), NullEnv(), NullIO())
whl = module_path / "dist" / "prerelease-0.1b1-py2.py3-none-any.whl" whl = module_path / "dist" / "prerelease-0.1b1-py2.py3-none-any.whl"
...@@ -64,7 +64,7 @@ def test_wheel_prerelease(): ...@@ -64,7 +64,7 @@ def test_wheel_prerelease():
def test_wheel_localversionlabel(): def test_wheel_localversionlabel():
module_path = fixtures_dir / "localversionlabel" module_path = fixtures_dir / "localversionlabel"
WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) WheelBuilder.make(Factory().create_poetry(module_path), NullEnv(), NullIO())
local_version_string = "localversionlabel-0.1b1+gitbranch.buildno.1" local_version_string = "localversionlabel-0.1b1+gitbranch.buildno.1"
whl = module_path / "dist" / (local_version_string + "-py2.py3-none-any.whl") whl = module_path / "dist" / (local_version_string + "-py2.py3-none-any.whl")
...@@ -76,7 +76,7 @@ def test_wheel_localversionlabel(): ...@@ -76,7 +76,7 @@ def test_wheel_localversionlabel():
def test_wheel_package_src(): def test_wheel_package_src():
module_path = fixtures_dir / "source_package" module_path = fixtures_dir / "source_package"
WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) WheelBuilder.make(Factory().create_poetry(module_path), NullEnv(), NullIO())
whl = module_path / "dist" / "package_src-0.1-py2.py3-none-any.whl" whl = module_path / "dist" / "package_src-0.1-py2.py3-none-any.whl"
...@@ -89,7 +89,7 @@ def test_wheel_package_src(): ...@@ -89,7 +89,7 @@ def test_wheel_package_src():
def test_wheel_module_src(): def test_wheel_module_src():
module_path = fixtures_dir / "source_file" module_path = fixtures_dir / "source_file"
WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) WheelBuilder.make(Factory().create_poetry(module_path), NullEnv(), NullIO())
whl = module_path / "dist" / "module_src-0.1-py2.py3-none-any.whl" whl = module_path / "dist" / "module_src-0.1-py2.py3-none-any.whl"
...@@ -101,7 +101,7 @@ def test_wheel_module_src(): ...@@ -101,7 +101,7 @@ def test_wheel_module_src():
def test_dist_info_file_permissions(): def test_dist_info_file_permissions():
module_path = fixtures_dir / "complete" module_path = fixtures_dir / "complete"
WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) WheelBuilder.make(Factory().create_poetry(module_path), NullEnv(), NullIO())
whl = module_path / "dist" / "my_package-1.2.3-py3-none-any.whl" whl = module_path / "dist" / "my_package-1.2.3-py3-none-any.whl"
......
import pytest import pytest
from poetry.factory import Factory
from poetry.io.null_io import NullIO from poetry.io.null_io import NullIO
from poetry.masonry.publishing.publisher import Publisher from poetry.masonry.publishing.publisher import Publisher
from poetry.poetry import Poetry
def test_publish_publishes_to_pypi_by_default(fixture_dir, mocker, config): def test_publish_publishes_to_pypi_by_default(fixture_dir, mocker, config):
uploader_auth = mocker.patch("poetry.masonry.publishing.uploader.Uploader.auth") uploader_auth = mocker.patch("poetry.masonry.publishing.uploader.Uploader.auth")
uploader_upload = mocker.patch("poetry.masonry.publishing.uploader.Uploader.upload") uploader_upload = mocker.patch("poetry.masonry.publishing.uploader.Uploader.upload")
poetry = Poetry.create(fixture_dir("sample_project")) poetry = Factory().create_poetry(fixture_dir("sample_project"))
poetry._config = config poetry._config = config
poetry.config.merge( poetry.config.merge(
{"http-basic": {"pypi": {"username": "foo", "password": "bar"}}} {"http-basic": {"pypi": {"username": "foo", "password": "bar"}}}
...@@ -24,7 +24,7 @@ def test_publish_publishes_to_pypi_by_default(fixture_dir, mocker, config): ...@@ -24,7 +24,7 @@ def test_publish_publishes_to_pypi_by_default(fixture_dir, mocker, config):
def test_publish_can_publish_to_given_repository(fixture_dir, mocker, config): def test_publish_can_publish_to_given_repository(fixture_dir, mocker, config):
uploader_auth = mocker.patch("poetry.masonry.publishing.uploader.Uploader.auth") uploader_auth = mocker.patch("poetry.masonry.publishing.uploader.Uploader.auth")
uploader_upload = mocker.patch("poetry.masonry.publishing.uploader.Uploader.upload") uploader_upload = mocker.patch("poetry.masonry.publishing.uploader.Uploader.upload")
poetry = Poetry.create(fixture_dir("sample_project")) poetry = Factory().create_poetry(fixture_dir("sample_project"))
poetry._config = config poetry._config = config
poetry.config.merge( poetry.config.merge(
{ {
...@@ -41,7 +41,7 @@ def test_publish_can_publish_to_given_repository(fixture_dir, mocker, config): ...@@ -41,7 +41,7 @@ def test_publish_can_publish_to_given_repository(fixture_dir, mocker, config):
def test_publish_raises_error_for_undefined_repository(fixture_dir, mocker, config): def test_publish_raises_error_for_undefined_repository(fixture_dir, mocker, config):
poetry = Poetry.create(fixture_dir("sample_project")) poetry = Factory().create_poetry(fixture_dir("sample_project"))
poetry._config = config poetry._config = config
poetry.config.merge( poetry.config.merge(
{"http-basic": {"my-repo": {"username": "foo", "password": "bar"}}} {"http-basic": {"my-repo": {"username": "foo", "password": "bar"}}}
...@@ -55,7 +55,7 @@ def test_publish_raises_error_for_undefined_repository(fixture_dir, mocker, conf ...@@ -55,7 +55,7 @@ def test_publish_raises_error_for_undefined_repository(fixture_dir, mocker, conf
def test_publish_uses_token_if_it_exists(fixture_dir, mocker, config): def test_publish_uses_token_if_it_exists(fixture_dir, mocker, config):
uploader_auth = mocker.patch("poetry.masonry.publishing.uploader.Uploader.auth") uploader_auth = mocker.patch("poetry.masonry.publishing.uploader.Uploader.auth")
uploader_upload = mocker.patch("poetry.masonry.publishing.uploader.Uploader.upload") uploader_upload = mocker.patch("poetry.masonry.publishing.uploader.Uploader.upload")
poetry = Poetry.create(fixture_dir("sample_project")) poetry = Factory().create_poetry(fixture_dir("sample_project"))
poetry._config = config poetry._config = config
poetry.config.merge({"pypi-token": {"pypi": "my-token"}}) poetry.config.merge({"pypi-token": {"pypi": "my-token"}})
publisher = Publisher(poetry, NullIO()) publisher = Publisher(poetry, NullIO())
......
import pytest import pytest
from poetry.factory import Factory
from poetry.io.null_io import NullIO from poetry.io.null_io import NullIO
from poetry.masonry.publishing.uploader import UploadError from poetry.masonry.publishing.uploader import UploadError
from poetry.masonry.publishing.uploader import Uploader from poetry.masonry.publishing.uploader import Uploader
from poetry.poetry import Poetry
from poetry.utils._compat import Path from poetry.utils._compat import Path
...@@ -16,7 +16,7 @@ def project(name): ...@@ -16,7 +16,7 @@ def project(name):
def test_uploader_properly_handles_400_errors(http): def test_uploader_properly_handles_400_errors(http):
http.register_uri(http.POST, "https://foo.com", status=400, body="Bad request") http.register_uri(http.POST, "https://foo.com", status=400, body="Bad request")
uploader = Uploader(Poetry.create(project("simple_project")), NullIO()) uploader = Uploader(Factory().create_poetry(project("simple_project")), NullIO())
with pytest.raises(UploadError) as e: with pytest.raises(UploadError) as e:
uploader.upload("https://foo.com") uploader.upload("https://foo.com")
...@@ -26,7 +26,7 @@ def test_uploader_properly_handles_400_errors(http): ...@@ -26,7 +26,7 @@ def test_uploader_properly_handles_400_errors(http):
def test_uploader_properly_handles_403_errors(http): def test_uploader_properly_handles_403_errors(http):
http.register_uri(http.POST, "https://foo.com", status=403, body="Unauthorized") http.register_uri(http.POST, "https://foo.com", status=403, body="Unauthorized")
uploader = Uploader(Poetry.create(project("simple_project")), NullIO()) uploader = Uploader(Factory().create_poetry(project("simple_project")), NullIO())
with pytest.raises(UploadError) as e: with pytest.raises(UploadError) as e:
uploader.upload("https://foo.com") uploader.upload("https://foo.com")
...@@ -39,7 +39,7 @@ def test_uploader_registers_for_appropriate_400_errors(mocker, http): ...@@ -39,7 +39,7 @@ def test_uploader_registers_for_appropriate_400_errors(mocker, http):
http.register_uri( http.register_uri(
http.POST, "https://foo.com", status=400, body="No package was ever registered" http.POST, "https://foo.com", status=400, body="No package was ever registered"
) )
uploader = Uploader(Poetry.create(project("simple_project")), NullIO()) uploader = Uploader(Factory().create_poetry(project("simple_project")), NullIO())
with pytest.raises(UploadError): with pytest.raises(UploadError):
uploader.upload("https://foo.com") uploader.upload("https://foo.com")
......
...@@ -4,7 +4,8 @@ from __future__ import unicode_literals ...@@ -4,7 +4,8 @@ from __future__ import unicode_literals
import pytest import pytest
from poetry.poetry import Poetry from poetry.io.null_io import NullIO
from poetry.factory import Factory
from poetry.utils._compat import PY2 from poetry.utils._compat import PY2
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils.toml_file import TomlFile from poetry.utils.toml_file import TomlFile
...@@ -13,8 +14,8 @@ from poetry.utils.toml_file import TomlFile ...@@ -13,8 +14,8 @@ from poetry.utils.toml_file import TomlFile
fixtures_dir = Path(__file__).parent / "fixtures" fixtures_dir = Path(__file__).parent / "fixtures"
def test_poetry(): def test_create_poetry():
poetry = Poetry.create(str(fixtures_dir / "sample_project")) poetry = Factory().create_poetry(fixtures_dir / "sample_project")
package = poetry.package package = poetry.package
...@@ -111,9 +112,9 @@ def test_poetry(): ...@@ -111,9 +112,9 @@ def test_poetry():
] ]
def test_poetry_with_packages_and_includes(): def test_create_poetry_with_packages_and_includes():
poetry = Poetry.create( poetry = Factory().create_poetry(
str(fixtures_dir.parent / "masonry" / "builders" / "fixtures" / "with-include") fixtures_dir.parent / "masonry" / "builders" / "fixtures" / "with-include"
) )
package = poetry.package package = poetry.package
...@@ -131,9 +132,9 @@ def test_poetry_with_packages_and_includes(): ...@@ -131,9 +132,9 @@ def test_poetry_with_packages_and_includes():
assert package.include == ["extra_dir/vcs_excluded.txt", "notes.txt"] assert package.include == ["extra_dir/vcs_excluded.txt", "notes.txt"]
def test_poetry_with_multi_constraints_dependency(): def test_create_poetry_with_multi_constraints_dependency():
poetry = Poetry.create( poetry = Factory().create_poetry(
str(fixtures_dir / "project_with_multi_constraints_dependency") fixtures_dir / "project_with_multi_constraints_dependency"
) )
package = poetry.package package = poetry.package
...@@ -142,26 +143,26 @@ def test_poetry_with_multi_constraints_dependency(): ...@@ -142,26 +143,26 @@ def test_poetry_with_multi_constraints_dependency():
def test_poetry_with_default_source(): def test_poetry_with_default_source():
poetry = Poetry.create(fixtures_dir / "with_default_source") poetry = Factory().create_poetry(fixtures_dir / "with_default_source")
assert 1 == len(poetry.pool.repositories) assert 1 == len(poetry.pool.repositories)
def test_poetry_with_two_default_sources(): def test_poetry_with_two_default_sources():
with pytest.raises(ValueError) as e: with pytest.raises(ValueError) as e:
Poetry.create(fixtures_dir / "with_two_default_sources") Factory().create_poetry(fixtures_dir / "with_two_default_sources")
assert "Only one repository can be the default" == str(e.value) assert "Only one repository can be the default" == str(e.value)
def test_check(): def test_validate():
complete = TomlFile(fixtures_dir / "complete.toml") complete = TomlFile(fixtures_dir / "complete.toml")
content = complete.read()["tool"]["poetry"] content = complete.read()["tool"]["poetry"]
assert Poetry.check(content) == {"errors": [], "warnings": []} assert Factory.validate(content) == {"errors": [], "warnings": []}
def test_check_fails(): def test_validate_fails():
complete = TomlFile(fixtures_dir / "complete.toml") complete = TomlFile(fixtures_dir / "complete.toml")
content = complete.read()["tool"]["poetry"] content = complete.read()["tool"]["poetry"]
content["this key is not in the schema"] = "" content["this key is not in the schema"] = ""
...@@ -177,12 +178,12 @@ def test_check_fails(): ...@@ -177,12 +178,12 @@ def test_check_fails():
"('this key is not in the schema' was unexpected)" "('this key is not in the schema' was unexpected)"
) )
assert Poetry.check(content) == {"errors": [expected], "warnings": []} assert Factory.validate(content) == {"errors": [expected], "warnings": []}
def test_create_fails_on_invalid_configuration(): def test_create_poetry_fails_on_invalid_configuration():
with pytest.raises(RuntimeError) as e: with pytest.raises(RuntimeError) as e:
Poetry.create( Factory().create_poetry(
Path(__file__).parent / "fixtures" / "invalid_pyproject" / "pyproject.toml" Path(__file__).parent / "fixtures" / "invalid_pyproject" / "pyproject.toml"
) )
...@@ -199,8 +200,8 @@ The Poetry configuration is invalid: ...@@ -199,8 +200,8 @@ The Poetry configuration is invalid:
assert expected == str(e.value) assert expected == str(e.value)
def test_poetry_with_local_config(fixture_dir): def test_create_poetry_with_local_config(fixture_dir):
poetry = Poetry.create(fixture_dir("with_local_config")) poetry = Factory().create_poetry(fixture_dir("with_local_config"))
assert not poetry.config.get("virtualenvs.in-project") assert not poetry.config.get("virtualenvs.in-project")
assert not poetry.config.get("virtualenvs.create") assert not poetry.config.get("virtualenvs.create")
...@@ -2,8 +2,8 @@ import sys ...@@ -2,8 +2,8 @@ import sys
import pytest import pytest
from poetry.factory import Factory
from poetry.packages import Locker as BaseLocker from poetry.packages import Locker as BaseLocker
from poetry.poetry import Poetry
from poetry.repositories.auth import Auth from poetry.repositories.auth import Auth
from poetry.repositories.legacy_repository import LegacyRepository from poetry.repositories.legacy_repository import LegacyRepository
from poetry.utils._compat import Path from poetry.utils._compat import Path
...@@ -40,7 +40,7 @@ def locker(): ...@@ -40,7 +40,7 @@ def locker():
@pytest.fixture @pytest.fixture
def poetry(fixture_dir, locker): def poetry(fixture_dir, locker):
p = Poetry.create(fixture_dir("sample_project")) p = Factory().create_poetry(fixture_dir("sample_project"))
p._locker = locker p._locker = locker
return p return p
......
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