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

Commit

Permalink
Merge branch 'merging'
Browse files Browse the repository at this point in the history
  • Loading branch information
orsinium committed Nov 8, 2018
2 parents 89e0911 + b729c1b commit a5217f9
Show file tree
Hide file tree
Showing 22 changed files with 308 additions and 110 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,7 @@ dumper.dump(reqs=reqs, path='requirements.txt')

1. poetry
1. poetry lock
1. config
1. environments
1. Python version
1. Zero release (compatible with any constraints)
1. url defined release
1. git based dependency
1. Beautiful CLI
7 changes: 5 additions & 2 deletions dephell/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from argparse import ArgumentParser
from .commands import commands
from .constants import ReturnCodes


parser = ArgumentParser(
Expand All @@ -17,7 +18,9 @@ def main(argv):

is_valid = task.validate()
if not is_valid:
return 2
return ReturnCodes.INVALID_CONFIG.value

result = task()
return int(not result)
if not result:
return ReturnCodes.COMMAND_ERROR.value
return ReturnCodes.OK.value
34 changes: 26 additions & 8 deletions dephell/commands/convert.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from ..console import Progress, output
import huepy

from ..controllers import analize_conflict
from ..converters import CONVERTERS
from ..models import Requirement
Expand All @@ -13,19 +14,36 @@ def __call__(self):

# load
resolver = loader.load_resolver(path=self.config['from']['path'])
should_be_resolved = not loader.lock and dumper.lock

# attach
if self.config.get('and'):
for source in self.config['and']:
loader = CONVERTERS[source['format']]
root = loader.load(path=source['path'])
resolver.graph.add(root)

# merge (without full graph building)
if not should_be_resolved:
resolved = resolver.resolve(progress=True, level=1)
if not resolved:
conflict = analize_conflict(resolver=resolver)
print(huepy.bad('Conflict has found:'))
print(conflict)
return False
print(huepy.good('Merged!'))

# resolve
if not loader.lock and dumper.lock:
with Progress().auto():
resolved = resolver.resolve()
# resolve (and merge)
if should_be_resolved:
resolved = resolver.resolve(progress=True)
if not resolved:
conflict = analize_conflict(resolver=resolver)
output.writeln('<error>Conflict has found:</error> ')
output.writeln(conflict)
print(huepy.bad('Conflict has found:'))
print(conflict)
return False
print(huepy.good('Resolved!'))

# dump
output.writeln('<info>Resolved!</info>')
dumper.dump(
path=self.config['to']['path'],
reqs=Requirement.from_graph(resolver.graph, lock=dumper.lock),
Expand Down
10 changes: 8 additions & 2 deletions dephell/commands/init.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from collections import namedtuple
from pathlib import Path

import huepy
import tomlkit

from ..config import Config
Expand Down Expand Up @@ -32,7 +33,7 @@
from_path='pyproject.toml',
to_path='pyproject.lock',
from_format='poetry',
to_format='poetry.toml',
to_format='poetrylock',
),
)

Expand Down Expand Up @@ -71,7 +72,8 @@ def _make_env(rule):

def __call__(self):
config_path = Path(self.args.config)
if config_path.exists():
exists = config_path.exists()
if exists:
# read
with config_path.open('r', encoding='utf8') as stream:
doc = tomlkit.parse(stream.read())
Expand Down Expand Up @@ -105,4 +107,8 @@ def __call__(self):
with config_path.open('w', encoding='utf8') as stream:
stream.write(tomlkit.dumps(doc))

if exists:
print(huepy.good('pyproject.toml updated'))
else:
print(huepy.good('pyproject.toml created'))
return True
2 changes: 1 addition & 1 deletion dephell/config/parser.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from argparse import ArgumentParser
from .scheme import FORMATS, ENVS
from ..constants import FORMATS, ENVS


parser = ArgumentParser(
Expand Down
23 changes: 8 additions & 15 deletions dephell/config/scheme.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,4 @@


DEFAULTS = dict(
pip='requirements.in',
piplock='requirements.txt',

pipfile='Pipfile',
pipfilelock='Pipfile.lock',

poetry='pyproject.toml',
poetrylock='pyproject.lock',
)
FORMATS = tuple(DEFAULTS)
ENVS = ('main', 'dev', 'main-opt', 'dev-opt')
from ..constants import ENVS, FORMATS


_TARGET = dict(
Expand All @@ -33,13 +20,19 @@
default=('main', 'dev'),
allowed=ENVS,
),
}
},
)


SCHEME = {
'from': _TARGET,
'to': _TARGET,
'and': dict(
type='list',
schema=_TARGET,
required=False,
empty=True,
),
'silent': dict(
type='boolean',
required=False,
Expand Down
25 changes: 0 additions & 25 deletions dephell/console.py

This file was deleted.

24 changes: 24 additions & 0 deletions dephell/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from enum import Enum, unique


@unique
class ReturnCodes(Enum):
OK = 0
COMMAND_ERROR = 1
INVALID_CONFIG = 2
UNKNOWN_EXCEPTION = 3


FORMATS = (
'pip', 'piplock',
'pipfile', 'pipfilelock',
'poetry', 'poetrylock',
)

FILES = (
'requirements.in', 'requirements.txt',
'Pipfile', 'Pipfile.lock',
'pyproject.toml', 'pyproject.lock',
)

ENVS = ('main', 'dev', 'main-opt', 'dev-opt')
47 changes: 34 additions & 13 deletions dephell/controllers/graph.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from logging import getLogger
from collections import ChainMap
from typing import Optional

from graphviz import Digraph

from ..models.root import RootDependency


logger = getLogger(__name__)

Expand Down Expand Up @@ -41,14 +44,18 @@ def __repr__(self):


class Graph:
def __init__(self, root):
self.root = root
if not root.dependencies:
logger.warning('empty root passed')
def __init__(self, root=None):
if root is not None:
if not root.dependencies:
logger.warning('empty root passed')
self._roots = [root]
else:
self._roots = []
self._layers = []
self.reset()

def reset(self):
self._layers = [Layer(0, self.root)]
self._layers = [Layer(0, *self._roots)]
self._deps = ChainMap(*[layer._mapping for layer in self._layers])
self.conflict = None

Expand All @@ -58,7 +65,12 @@ def clear(self):
for layer in self._layers[1:]:
layer.clear()

def add(self, dep, *, level=None):
def add(self, dep, *, level=None) -> None:
if isinstance(dep, RootDependency):
self._layers[0].add(dep)
self._roots.append(dep)
return

if level is not None:
if level < len(self._layers):
self._layers[level].add(dep)
Expand All @@ -75,11 +87,15 @@ def add(self, dep, *, level=None):
return self.add(dep, level=layer.level + 1)
raise KeyError('Can\'t find any parent for dependency')

def get_leafs(self) -> tuple:
def get_leafs(self, level: Optional[int]=None) -> tuple:
"""Get deps that isn't applied yet
"""
layers = self._layers
if level is not None:
layers = layers[:level + 1]

result = []
for layer in self._layers:
for layer in layers:
for dep in layer:
if not dep.applied and dep.used:
result.append(dep)
Expand Down Expand Up @@ -135,20 +151,21 @@ def get_parents(self, *deps, avoid=None) -> dict:
if parents:
parents.update(self.get_parents(
*parents.values(),
avoid=avoid + [dep.name for dep in deps]
avoid=avoid + [dep.name for dep in deps],
))
return parents

def draw(self, path: str='.dephell_report', suffix: str=''):
dot = Digraph(
name=self.root.name + suffix,
name=self._roots[0].name + suffix,
directory=path,
format='png',
)
first_deps = self._layers[1]

# add root node
dot.node(self.root.name, self.root.raw_name, color='blue')
# add root nodes
for root in self._roots:
dot.node(root.name, root.raw_name, color='blue')

# add nodes
for dep in self:
Expand Down Expand Up @@ -177,7 +194,11 @@ def names(self) -> set:

@property
def deps(self) -> tuple:
return tuple(dep for dep in self._deps.values() if dep is not self.root)
return tuple(dep for dep in self._deps.values() if dep not in self._roots)

@property
def applied(self):
return all(root.applied for root in self._roots)

# magic

Expand Down

0 comments on commit a5217f9

Please sign in to comment.