Skip to content

Commit

Permalink
Merge pull request #58 from pyupio/feature/poetry-parse-support
Browse files Browse the repository at this point in the history
Poetry parse support
  • Loading branch information
yeisonvargasf authored Sep 9, 2022
2 parents 2bcf15b + 805f9a2 commit f281235
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 58 deletions.
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Supported Files
+------------------+------------+-----------+
| Pipfile.lock | yes | yes |
+------------------+------------+-----------+
| poetry.lock | yes | no |
+------------------+------------+-----------+
| setup.py | no (# 2_) | no (# 2_) |
+------------------+------------+-----------+
| zc.buildout | no (# 3_) | no (# 3_) |
Expand Down
48 changes: 41 additions & 7 deletions dparse/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import unicode_literals, absolute_import

import json
from json import JSONEncoder

from . import filetypes, errors

Expand All @@ -11,7 +12,9 @@ class Dependency(object):
"""

def __init__(self, name, specs, line, source="pypi", meta={}, extras=[], line_numbers=None, index_server=None, hashes=(), dependency_type=None, section=None):
def __init__(self, name, specs, line, source="pypi", meta={}, extras=[],
line_numbers=None, index_server=None, hashes=(),
dependency_type=None, section=None):
"""
:param name:
Expand Down Expand Up @@ -87,12 +90,25 @@ def full_name(self):
return self.name


class DparseJSONEncoder(JSONEncoder):
def default(self, o):
from packaging.specifiers import SpecifierSet

if isinstance(o, SpecifierSet):
return str(o)
if isinstance(o, set):
return list(o)

return JSONEncoder.default(self, o)


class DependencyFile(object):
"""
"""

def __init__(self, content, path=None, sha=None, file_type=None, marker=((), ()), parser=None):
def __init__(self, content, path=None, sha=None, file_type=None,
marker=((), ()), parser=None, resolve=False):
"""
:param content:
Expand Down Expand Up @@ -130,6 +146,8 @@ def __init__(self, content, path=None, sha=None, file_type=None, marker=((), ())
self.parser = parser_class.PipfileLockParser
elif file_type == filetypes.setup_cfg:
self.parser = parser_class.SetupCfgParser
elif file_type == filetypes.poetry_lock:
self.parser = parser_class.PoetryLockParser

elif path is not None:
if path.endswith((".txt", ".in")):
Expand All @@ -144,11 +162,23 @@ def __init__(self, content, path=None, sha=None, file_type=None, marker=((), ())
self.parser = parser_class.PipfileLockParser
elif path.endswith("setup.cfg"):
self.parser = parser_class.SetupCfgParser
elif path.endswith(filetypes.poetry_lock):
self.parser = parser_class.PoetryLockParser

if not hasattr(self, "parser"):
raise errors.UnknownDependencyFileError

self.parser = self.parser(self)
self.parser = self.parser(self, resolve=resolve)

@property
def resolved_dependencies(self):
deps = self.dependencies.copy()

for d in self.resolved_files:
if isinstance(d, DependencyFile):
deps.extend(d.resolved_dependencies)

return deps

def serialize(self):
"""
Expand All @@ -160,7 +190,9 @@ def serialize(self):
"content": self.content,
"path": self.path,
"sha": self.sha,
"dependencies": [dep.serialize() for dep in self.dependencies]
"dependencies": [dep.serialize() for dep in self.dependencies],
"resolved_dependencies": [dep.serialize() for dep in
self.resolved_dependencies]
}

@classmethod
Expand All @@ -170,7 +202,8 @@ def deserialize(cls, d):
:param d:
:return:
"""
dependencies = [Dependency.deserialize(dep) for dep in d.pop("dependencies", [])]
dependencies = [Dependency.deserialize(dep) for dep in
d.pop("dependencies", [])]
instance = cls(**d)
instance.dependencies = dependencies
return instance
Expand All @@ -180,7 +213,7 @@ def json(self): # pragma: no cover
:return:
"""
return json.dumps(self.serialize(), indent=2)
return json.dumps(self.serialize(), indent=2, cls=DparseJSONEncoder)

def parse(self):
"""
Expand All @@ -192,5 +225,6 @@ def parse(self):
return self
self.parser.parse()

self.is_valid = len(self.dependencies) > 0 or len(self.resolved_files) > 0
self.is_valid = len(self.dependencies) > 0 or len(
self.resolved_files) > 0
return self
13 changes: 12 additions & 1 deletion dparse/errors.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import


class UnknownDependencyFileError(Exception):
"""
"""
pass
def __init__(self, message="Unknown File type to parse"):
self.message = message
super().__init__(self.message)


class MalformedDependencyFileError(Exception):

def __init__(self, message="The dependency file is malformed. {info}",
info=""):
self.message = message.format(info=info)
super().__init__(self.message)
1 change: 1 addition & 0 deletions dparse/filetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
tox_ini = "tox.ini"
pipfile = "Pipfile"
pipfile_lock = "Pipfile.lock"
poetry_lock = "poetry.lock"
Loading

0 comments on commit f281235

Please sign in to comment.