Created
September 21, 2018 04:23
-
-
Save etienned/686d6743d66415eb39a715bb369fe2f6 to your computer and use it in GitHub Desktop.
Function to export a requirements.txt from poetry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from poetry.console.application import Application | |
from poetry.semver import parse_constraint, VersionUnion | |
def export_requirements(tag=False): | |
app = Application() | |
installed_repo = app.poetry.locker.locked_repository(True) | |
output = [] | |
for package in installed_repo.packages: | |
if package.source_type: | |
name_version = '{}+{}@{}#egg={}'.format( | |
package.source_type, | |
package.source_url, | |
package.version | |
if (tag and package.version) | |
else package.source_reference, | |
package.pretty_name, | |
) | |
else: | |
name_version = '{}=={}'.format( | |
package.pretty_name, package.version | |
) | |
markers = [] | |
if 'platform' in package.requirements: | |
platform = package.requirements['platform'] | |
if platform.startswith('!='): | |
platform = platform[2:] | |
operator = '!=' | |
else: | |
operator = '==' | |
markers.append("sys_platform {} '{}'".format(operator, platform)) | |
if 'python' in package.requirements: | |
versions = parse_python_versions(package.requirements['python']) | |
markers.append(versions) | |
markers_delimiter = '; ' if markers else '' | |
output.append( | |
'{}{}{}'.format( | |
name_version, markers_delimiter, " and ".join(markers) | |
) | |
) | |
return '\n'.join(output) | |
def parse_python_versions(python): | |
_and = [] | |
versions = parse_constraint(python) | |
if isinstance(versions, VersionUnion): | |
_or = [] | |
for version_range in versions.ranges: | |
_or.append(range_to_requirements_text(version_range)) | |
if len(_or) > 1: | |
_and.append('(' + ') or ('.join(_or) + ')') | |
else: | |
_and.append(_or) | |
else: | |
_and.append(range_to_requirements_text(versions)) | |
return ' and '.join(_and) | |
def range_to_requirements_text(version_range): | |
if version_range.min: | |
if version_range.max: | |
text = "python_version >= '{}' and python_version < '{}'".format( | |
version_range.min, version_range.max | |
) | |
else: | |
text = "python_version > '{}'".format(version_range.min) | |
else: | |
text = "python_version < '{}'".format(version_range.max) | |
return text |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment