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

Commit b716f77

Browse files
committed
Merge branch 'command-tree'
2 parents d3a0e7c + f1b777b commit b716f77

File tree

7 files changed

+135
-2
lines changed

7 files changed

+135
-2
lines changed

dephell/commands/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from .deps_install import DepsInstallCommand
66
from .deps_licenses import DepsLicensesCommand
77
from .deps_outdated import DepsOutdatedCommand
8+
from .deps_tree import DepsTreeCommand
89
from .generate_authors import GenerateAuthorsCommand
910
from .generate_config import GenerateConfigCommand
1011
from .generate_editorconfig import GenerateEditorconfigCommand
@@ -34,6 +35,7 @@
3435
'DepsInstallCommand',
3536
'DepsLicensesCommand',
3637
'DepsOutdatedCommand',
38+
'DepsTreeCommand',
3739
'GenerateAuthorsCommand',
3840
'GenerateConfigCommand',
3941
'GenerateEditorconfigCommand',
@@ -63,6 +65,7 @@
6365
'deps install': DepsInstallCommand,
6466
'deps licenses': DepsLicensesCommand,
6567
'deps outdated': DepsOutdatedCommand,
68+
'deps tree': DepsTreeCommand,
6669
# 'deps remove': ...,
6770
# 'deps sync': ...,
6871
'generate authors': GenerateAuthorsCommand,

dephell/commands/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def validate(self):
4545
return is_valid
4646

4747
@classmethod
48-
def get_value(cls, data, key, sep: Optional[str] = '-'):
48+
def get_value(cls, data, key: str = None, sep: Optional[str] = '-'):
4949
json_params = dict(indent=2, sort_keys=True, ensure_ascii=False)
5050
# print all config
5151
if not key:

dephell/commands/deps_tree.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# built-in
2+
from argparse import ArgumentParser, REMAINDER
3+
from typing import List
4+
5+
# app
6+
from ..config import builders
7+
from ..controllers import analize_conflict
8+
from ..converters import CONVERTERS, PIPConverter
9+
from .base import BaseCommand
10+
11+
12+
class DepsTreeCommand(BaseCommand):
13+
"""Show dependencies tree.
14+
15+
https://dephell.readthedocs.io/en/latest/cmd-deps-tree.html
16+
"""
17+
@classmethod
18+
def get_parser(cls):
19+
parser = ArgumentParser(
20+
prog='dephell deps tree',
21+
description=cls.__doc__,
22+
)
23+
builders.build_config(parser)
24+
builders.build_from(parser)
25+
builders.build_resolver(parser)
26+
builders.build_api(parser)
27+
builders.build_output(parser)
28+
builders.build_other(parser)
29+
parser.add_argument(
30+
'--type',
31+
nargs='?',
32+
choices=('pretty', 'json', 'graph'),
33+
default='pretty',
34+
help='format for tree output.',
35+
)
36+
parser.add_argument('name', nargs=REMAINDER, help='package to get dependencies from')
37+
return parser
38+
39+
def __call__(self):
40+
if self.args.name:
41+
resolver = PIPConverter(lock=False).loads_resolver(' '.join(self.args.name))
42+
else:
43+
loader = CONVERTERS[self.config['from']['format']]
44+
resolver = loader.load_resolver(path=self.config['from']['path'])
45+
46+
# resolve
47+
self.logger.debug('resolving...')
48+
resolved = resolver.resolve()
49+
if not resolved:
50+
conflict = analize_conflict(resolver=resolver)
51+
self.logger.warning('conflict was found')
52+
print(conflict)
53+
return False
54+
self.logger.debug('resolved')
55+
56+
if self.args.type == 'pretty':
57+
for dep in sorted(resolver.graph.get_layer(1)):
58+
print('\n'.join(self._make_tree(dep)))
59+
return True
60+
61+
if self.args.type == 'json':
62+
result = []
63+
for dep in sorted(resolver.graph):
64+
result.append(dict(
65+
name=dep.name,
66+
constraint=str(dep.constraint) or '*',
67+
best=str(dep.group.best_release.version),
68+
latest=str(dep.groups.releases[0].version),
69+
dependencies=[subdep.name for subdep in dep.dependencies]
70+
))
71+
print(self.get_value(result, key=self.config.get('filter')))
72+
return True
73+
74+
if self.args.type == 'graph':
75+
resolver.graph.draw()
76+
self.logger.info('graph saved into .dephell_report/')
77+
return True
78+
79+
@classmethod
80+
def _make_tree(cls, dep, *, level: int = 0) -> List[str]:
81+
lines = ['{level}- {name} [required: {constraint}, locked: {best}, latest: {latest}]'.format(
82+
level=' ' * level,
83+
name=dep.name,
84+
constraint=str(dep.constraint) or '*',
85+
best=str(dep.group.best_release.version),
86+
latest=str(dep.groups.releases[0].version),
87+
)]
88+
for subdep in sorted(dep.dependencies):
89+
lines.extend(cls._make_tree(subdep, level=level + 1))
90+
return lines

dephell/config/manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
class Config:
2121
env = ''
22-
_skip = ('config', 'env', 'key', 'name')
22+
_skip = ('config', 'env', 'key', 'name', 'type')
2323

2424
def __init__(self, data: Optional[dict] = None):
2525
self._data = data or DEFAULT

docs/cmd-deps-convert.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ You can specify input and output in three different ways:
3232

3333
1. [dephell build](cmd-deps-install) to fast convert dependencies into setup.py, sdist and wheel.
3434
1. [dephell deps install](cmd-deps-install) to install project dependencies.
35+
1. [dephell deps tree](cmd-deps-tree) to show dependencies tree for project.

docs/cmd-deps-tree.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# dephell deps tree
2+
3+
Show dependencies tree for your dependencies from `from` section or given package.
4+
5+
Show project dependencies:
6+
7+
```bash
8+
$ dephell deps tree
9+
- aiofiles [required: *, locked: 0.4.0, latest: 0.4.0]
10+
- aiohttp [required: *, locked: 3.5.4, latest: 3.5.4]
11+
- async-timeout [required: <4.0,>=3.0, locked: 3.0.1, latest: 3.0.1]
12+
- attrs [required: >=17.3.0, locked: 19.1.0, latest: 19.1.0]
13+
- chardet [required: <4.0,>=2.0, locked: 3.0.4, latest: 3.0.4]
14+
- idna-ssl [required: >=1.0, locked: 1.1.0, latest: 1.1.0]
15+
- idna [required: >=2.0, locked: 2.8, latest: 2.8]
16+
...
17+
```
18+
19+
Field `locked` shows version that was resolved by this command, **not** the version that represented in any environment or lockfile.
20+
21+
Show dependencies for given package:
22+
23+
```bash
24+
$ dephell deps tree aiohttp==3.5.4
25+
- aiohttp [required: ==3.5.4, locked: 3.5.4, latest: 3.5.4]
26+
- async-timeout [required: <4.0,>=3.0, locked: 3.0.1, latest: 3.0.1]
27+
- attrs [required: >=17.3.0, locked: 19.1.0, latest: 19.1.0]
28+
- chardet [required: <4.0,>=2.0, locked: 3.0.4, latest: 3.0.4]
29+
- idna-ssl [required: >=1.0, locked: 1.1.0, latest: 1.1.0]
30+
- idna [required: >=2.0, locked: 2.8, latest: 2.8]
31+
...
32+
```
33+
34+
## See also
35+
36+
1. [dephell package outdated](cmd-package-list) to show outdated packages in a lockfile or project virtual environment.
37+
1. [dephell package list](cmd-package-list) to show information about installed packages.
38+
1. [dephell package show](cmd-package-show) to get information about single package.

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
cmd-deps-install
3030
cmd-deps-licenses
3131
cmd-deps-outdated
32+
cmd-deps-tree
3233
cmd-generate-authors
3334
cmd-generate-config
3435
cmd-generate-editorconfig

0 commit comments

Comments
 (0)