Skip to content
This repository has been archived by the owner on Jan 12, 2021. It is now read-only.

Commit

Permalink
Merge pull request #230 from dephell/poetry-path
Browse files Browse the repository at this point in the history
`path` support for poetry and pip specifiers
  • Loading branch information
orsinium committed Jul 17, 2019
2 parents 6078d31 + 68f9327 commit 9ce0dde
Show file tree
Hide file tree
Showing 24 changed files with 75 additions and 85 deletions.
5 changes: 1 addition & 4 deletions dephell/commands/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,7 @@ def _get_locked(self, default_envs: Set[str] = None):
path=loader_config['path'],
))
loader = CONVERTERS[loader_config['format']]
loader = loader.copy(
project_path=Path(self.config['project']),
resolve_path=Path(loader_config['path']).parent,
)
loader = loader.copy(project_path=Path(self.config['project']))
resolver = loader.load_resolver(path=loader_config['path'])
attach_deps(resolver=resolver, config=self.config, merge=False)
return self._resolve(resolver=resolver, default_envs=default_envs)
Expand Down
5 changes: 1 addition & 4 deletions dephell/commands/deps_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ def __call__(self) -> bool:
self.error('`--from` is required for this command')
return False
converter = CONVERTERS[self.config['from']['format']]
converter = converter.copy(
project_path=Path(self.config['project']),
resolve_path=Path(self.config['from']['path']).parent,
)
converter = converter.copy(project_path=Path(self.config['project']))
resolver = converter.load_resolver(path=self.config['from']['path'])

# get new deps
Expand Down
10 changes: 2 additions & 8 deletions dephell/commands/deps_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,9 @@ def __call__(self) -> bool:
self.error('`--to` is required for this command')
return False
loader = CONVERTERS[self.config['from']['format']]
loader = loader.copy(
project_path=Path(self.config['project']),
resolve_path=Path(self.config['from']['path']).parent,
)
loader = loader.copy(project_path=Path(self.config['project']))
dumper = CONVERTERS[self.config['to']['format']]
dumper = dumper.copy(
project_path=Path(self.config['project']),
resolve_path=Path(self.config['to']['path']).parent,
)
dumper = dumper.copy(project_path=Path(self.config['project']))

# load
self.logger.debug('load dependencies...', extra=dict(
Expand Down
5 changes: 1 addition & 4 deletions dephell/commands/generate_license.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@ def __call__(self) -> bool:
# get author from `from`
if not author and 'from' in self.config:
loader = CONVERTERS[self.config['from']['format']]
loader = loader.copy(
project_path=Path(self.config['project']),
resolve_path=Path(self.config['from']['path']).parent,
)
loader = loader.copy(project_path=Path(self.config['project']))
root = loader.load(self.config['from']['path'])
if root.authors:
author = root.authors[0]
Expand Down
10 changes: 2 additions & 8 deletions dephell/commands/project_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ def get_parser(cls) -> ArgumentParser:

def __call__(self) -> bool:
loader = CONVERTERS[self.config['from']['format']]
loader = loader.copy(
project_path=Path(self.config['project']),
resolve_path=Path(self.config['from']['path']).parent,
)
loader = loader.copy(project_path=Path(self.config['project']))
resolver = loader.load_resolver(path=self.config['from']['path'])
if loader.lock:
self.logger.warning('do not build project from lockfile!')
Expand All @@ -59,10 +56,7 @@ def __call__(self) -> bool:
continue
self.logger.info('dumping...', extra=dict(format=to_format))
dumper = CONVERTERS[to_format]
dumper = dumper.copy(
project_path=Path(self.config['project']),
resolve_path=Path(to_path).parent,
)
dumper = dumper.copy(project_path=Path(self.config['project']))
dumper.dump(
path=project_path.joinpath(to_path),
reqs=reqs,
Expand Down
5 changes: 1 addition & 4 deletions dephell/commands/project_bump.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ def __call__(self) -> bool:
if 'from' in self.config:
# get project metainfo
loader = CONVERTERS[self.config['from']['format']]
loader = loader.copy(
project_path=Path(self.config['project']),
resolve_path=Path(self.config['from']['path']).parent,
)
loader = loader.copy(project_path=Path(self.config['project']))
root = loader.load(path=self.config['from']['path'])
if root.version != '0.0.0':
package = root.package
Expand Down
5 changes: 1 addition & 4 deletions dephell/commands/project_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ def get_parser(cls) -> ArgumentParser:
def __call__(self) -> bool:
# load project
loader = CONVERTERS[self.config['from']['format']]
loader = loader.copy(
project_path=Path(self.config['project']),
resolve_path=Path(self.config['from']['path']).parent,
)
loader = loader.copy(project_path=Path(self.config['project']))
resolver = loader.load_resolver(path=self.config['from']['path'])
if loader.lock:
self.logger.warning('do not build project from lockfile!')
Expand Down
12 changes: 8 additions & 4 deletions dephell/controllers/_dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import List, Optional, Union

# external
from dephell_links import VCSLink, parse_link
from dephell_links import UnknownLink, VCSLink, parse_link
from dephell_markers import Markers
from dephell_specifier import GitSpecifier
from packaging.requirements import Requirement as PackagingRequirement
Expand Down Expand Up @@ -82,9 +82,13 @@ def from_params(cls, *, raw_name: str, constraint,
**kwargs) -> List[Union[Dependency, ExtraDependency]]:

# make link
link = parse_link(url)
if link and link.name and rex_hash.fullmatch(raw_name):
raw_name = link.name
if not url or isinstance(url, str):
link = parse_link(url)
else:
link = url
if link and not isinstance(link, UnknownLink):
if link.name and rex_hash.fullmatch(raw_name):
raw_name = link.name

# make constraint
if isinstance(constraint, str):
Expand Down
26 changes: 9 additions & 17 deletions dephell/converters/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class BaseConverter:
resolve_path = attr.ib(type=Optional[Path], default=None)
default_filename = attr.ib(type=Optional[str], default=None)

_resolve_path = None

# inspection

def can_parse(self, path: Path, content: Optional[str] = None) -> bool:
Expand Down Expand Up @@ -47,8 +49,11 @@ def load(self, path: Union[Path, str]) -> RootDependency:
if isinstance(path, str):
path = Path(path)
path = self._make_source_path_absolute(path)
self._resolve_path = path.parent
with path.open('r', encoding='utf8') as stream:
return self.loads(content=stream.read())
root = self.loads(content=stream.read())
self._resolve_path = None
return root

def dumps(self, reqs, *, project: RootDependency, content: str = None) -> str:
raise NotImplementedError
Expand Down Expand Up @@ -109,27 +114,14 @@ def _make_path_absolute(root: Path, path: Path) -> Path:
return (root / path).resolve()

def _make_source_path_absolute(self, path: Path) -> Path:
if self.project_path is not None:
root = self.project_path
else:
root = Path()
root = self.project_path or Path()
return self._make_path_absolute(root=root, path=path)

def _make_dependency_path_absolute(self, path: Path) -> Path:
if self.resolve_path is not None:
root = self.resolve_path
elif self.project_path is not None:
root = self.project_path
else:
root = Path()
root = self.resolve_path or self._resolve_path or self.project_path or Path()
return self._make_path_absolute(root=root, path=path)

def _make_dependency_path_relative(self, path: Path) -> Path:
if self.resolve_path is not None:
root = self.resolve_path
elif self.project_path is not None:
root = self.project_path
else:
root = Path()
root = self.resolve_path or self._resolve_path or self.project_path or Path()
root = root.resolve()
return path.relative_to(str(root))
2 changes: 2 additions & 0 deletions dephell/converters/pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ def load(self, path) -> RootDependency:
if isinstance(path, str):
path = Path(path)
path = self._make_source_path_absolute(path)
self._resolve_path = path.parent

root = RootDependency(
package=PackageRoot(path=self.project_path or path.parent),
)
Expand Down
9 changes: 6 additions & 3 deletions dephell/converters/pipfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,7 @@ def dumps(self, reqs, project: RootDependency, content=None) -> str:
return tomlkit.dumps(doc).rstrip() + '\n'

# https://github.com/pypa/pipfile/blob/master/examples/Pipfile
@staticmethod
def _make_deps(root, name: str, content) -> List[Dependency]:
def _make_deps(self, root, name: str, content) -> List[Dependency]:
if isinstance(content, str):
return [Dependency(
raw_name=name,
Expand All @@ -149,7 +148,11 @@ def _make_deps(root, name: str, content) -> List[Dependency]:
)]

# get link
url = content.get('file') or content.get('path') or content.get('vcs')
url = content.get('file') or content.get('path')
if url and not url.startswith('http'):
url = str(self._make_dependency_path_absolute(Path(url)))
if not url:
url = content.get('vcs')
if not url:
for vcs in VCS_LIST:
if vcs in content:
Expand Down
7 changes: 4 additions & 3 deletions dephell/converters/poetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,7 @@ def _add_repositories(section, root: RootDependency):
del section['source']

# https://github.com/sdispater/tomlkit/blob/master/pyproject.toml
@staticmethod
def _make_deps(root, name: str, content, envs: set) -> List[Dependency]:
def _make_deps(self, root, name: str, content, envs: set) -> List[Dependency]:
if isinstance(content, str):
deps = [Dependency(
raw_name=name,
Expand All @@ -309,6 +308,8 @@ def _make_deps(root, name: str, content, envs: set) -> List[Dependency]:

# get link
url = content.get('file') or content.get('path')
if url and not url.startswith('http'):
url = str(self._make_dependency_path_absolute(Path(url)))
if not url and 'git' in content:
url = 'git+' + content['git']
rev = content.get('rev') or content.get('branch') or content.get('tag')
Expand Down Expand Up @@ -346,7 +347,7 @@ def _format_req(self, req):
result[name] = value
if req.prereleases:
result['allows-prereleases'] = True
if 'version' not in result:
if 'version' not in result and 'git' not in result:
result['version'] = '*'
# if we have only version, return string instead of table
if tuple(result.value) == ('version', ):
Expand Down
5 changes: 4 additions & 1 deletion dephell/converters/setuppy.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ def can_parse(self, path: Path, content: Optional[str] = None) -> bool:
return ('setup(' in content)

def load(self, path) -> RootDependency:
path = Path(str(path))
if isinstance(path, str):
path = Path(path)
path = self._make_source_path_absolute(path)
self._resolve_path = path.parent

info = self._execute(path=path)
if info is None:
Expand Down
11 changes: 10 additions & 1 deletion dephell/models/requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
from collections import OrderedDict, defaultdict
from typing import Iterable, Optional, Set, Tuple

# external
from dephell_links import DirLink, FileLink

# app
from ..cached_property import cached_property


class Requirement:
_properties = (
'name', 'release', 'version', 'extras', 'markers',
'hashes', 'sources', 'editable', 'git', 'rev',
'hashes', 'sources', 'editable', 'git', 'rev', 'path',
'description', 'optional', 'platform', 'python',
)

Expand Down Expand Up @@ -84,6 +87,12 @@ def git(self) -> Optional[str]:
return self.dep.link.short
return None # mypy wants it

@property
def path(self) -> Optional[str]:
if isinstance(self.dep.link, (DirLink, FileLink)):
return self.dep.link.short
return None # mypy wants it

@property
def rev(self) -> Optional[str]:
return getattr(self.dep.link, 'rev', None) or None
Expand Down
2 changes: 1 addition & 1 deletion dephell/repositories/_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def get_releases(self, dep) -> Tuple[Release, ...]:
releases = []
dist_path = (self.path / 'dist')
if dist_path.exists():
repo = WarehouseLocalRepo(path=dist_path)
repo = WarehouseLocalRepo(name='tmp', path=dist_path)
releases = list(repo.get_releases(dep=dep))

root = self.get_root(name=dep.name, version='0.0.0')
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def temp_cache(temp_path):


@pytest.fixture
def requirements_dir() -> Path:
def requirements_path() -> Path:
""" Return the absolute Path to 'tests/requirements' """
return Path(__file__).parent / Path('requirements')

Expand Down
5 changes: 4 additions & 1 deletion tests/requirements/pipfile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ records = '>0.5.0'
django = { git = 'https://github.com/django/django.git', ref = '1.11.4', editable = true }
"e682b37" = {file = "https://github.com/divio/django-cms/archive/release/3.4.x.zip"}
"e1839a8" = {path = ".", editable = true}
pywinusb = { version = "*", os_name = "=='nt'", index="pypi"}
pywinusb = { version = "*", os_name = '=="nt"', index="pypi"}

egg-info = {path = "./egg-info/"}
setup = {path = "./setup.py"}

[dev-packages]
nose = '*'
Expand Down
4 changes: 4 additions & 0 deletions tests/requirements/poetry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ pendulum = { version = "^1.4", optional = true }
psycopg2 = { version = "^2.7", optional = true }
mysqlclient = { version = "^1.3", optional = true }

# local dependency
egg-info = { path = "./egg-info/" }
setup = { path = "./setup.py" }

[tool.poetry.extras]
mysql = ["mysqlclient"]
pgsql = ["psycopg2"]
Expand Down
6 changes: 2 additions & 4 deletions tests/test_commands/test_build.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
# built-in
import shutil
from pathlib import Path

# project
from dephell.commands import ProjectBuildCommand
from dephell.config import Config


def test_build_command(temp_path: Path):
def test_build_command(requirements_path, temp_path: Path):
(temp_path / 'project').mkdir()
(temp_path / 'project' / '__init__.py').touch()

metainfo_path = str(temp_path / 'pyproject.toml')
shutil.copy(str(Path('tests') / 'requirements' / 'poetry.toml'), metainfo_path)
metainfo_path = str(requirements_path / 'poetry.toml')
config = Config()
config.attach({
'from': dict(format='poetry', path=metainfo_path),
Expand Down
11 changes: 4 additions & 7 deletions tests/test_commands/test_deps_convert.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
# built-in
import shutil
from pathlib import Path

# project
from dephell.commands import DepsConvertCommand
from dephell.config import Config


def test_convert_poetry_to_setup(temp_path: Path, requirements_dir: Path):
from_path = str(temp_path / 'pyproject.toml')
def test_convert_poetry_to_setup(temp_path: Path, requirements_path: Path):
from_path = str(requirements_path / 'poetry.toml')
to_path = temp_path / 'setup.py'
shutil.copy(str(requirements_dir / 'poetry.toml'), from_path)
config = Config()
config.attach({
'from': dict(format='poetry', path=from_path),
Expand All @@ -25,9 +23,8 @@ def test_convert_poetry_to_setup(temp_path: Path, requirements_dir: Path):
assert 'The description of the package' in content


def test_convert_to_stdout(temp_path: Path, requirements_dir: Path, capsys):
from_path = str(temp_path / 'pyproject.toml')
shutil.copy(str(requirements_dir / 'poetry.toml'), from_path)
def test_convert_to_stdout(temp_path: Path, requirements_path: Path, capsys):
from_path = str(requirements_path / 'poetry.toml')
config = Config()
config.attach({
'from': {'format': 'poetry', 'path': from_path},
Expand Down
1 change: 1 addition & 0 deletions tests/test_commands/test_package_downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from dephell.config import Config


@pytest.mark.skipif(True, reason='disable while pypistat is down')
@pytest.mark.allow_hosts()
def test_package_downloads_command(capsys):
config = Config()
Expand Down

0 comments on commit 9ce0dde

Please sign in to comment.