Skip to content

Instantly share code, notes, and snippets.

@etienned
Created September 21, 2018 04:23
Show Gist options
  • Save etienned/686d6743d66415eb39a715bb369fe2f6 to your computer and use it in GitHub Desktop.
Save etienned/686d6743d66415eb39a715bb369fe2f6 to your computer and use it in GitHub Desktop.
Function to export a requirements.txt from poetry
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