summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Holth <dholth@fastmail.fm>2013-09-15 18:00:32 -0400
committerDaniel Holth <dholth@fastmail.fm>2013-09-15 18:00:32 -0400
commit7cb8691cd3bc34e10cb84b21274e101e9a68d07a (patch)
treee812edbe70941f91d344c01d56c37e7ff5c89ee7
parent4e3acc27e0face20cea92dac826977a739e6994b (diff)
downloadwheel-7cb8691cd3bc34e10cb84b21274e101e9a68d07a.tar.gz
improve test_requires parsing, add entry_points.txt to json
-rw-r--r--CHANGES.txt7
-rw-r--r--wheel/metadata.py58
-rw-r--r--wheel/test/complex-dist/setup.py2
-rw-r--r--wheel/test/pydist-schema.json112
4 files changed, 152 insertions, 27 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 34dd66c..9564047 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,10 @@
+0.22.0
+======
+- Include entry_points.txt, scripts a.k.a. commands, in experimental
+ pydist.json
+- Improved test_requires parsing
+- Python 2.6 fixes, "wheel version" command courtesy pombredanne
+
0.21.0
======
- Pregenerated scripts are the default again.
diff --git a/wheel/metadata.py b/wheel/metadata.py
index c0fdd63..5f2e5a3 100644
--- a/wheel/metadata.py
+++ b/wheel/metadata.py
@@ -6,7 +6,7 @@ from collections import defaultdict, namedtuple
from .pkginfo import read_pkg_info
import re
-import os
+import os.path
import textwrap
import pkg_resources
import email.parser
@@ -66,7 +66,7 @@ def handle_requires(metadata, pkg_info, key):
package = value
key = MayRequiresKey(condition, extra)
may_requires[key].append(package)
-
+
if may_requires:
metadata['run_requires'] = []
for key, value in may_requires.items():
@@ -76,7 +76,7 @@ def handle_requires(metadata, pkg_info, key):
if key.condition:
may_requirement['environment'] = key.condition
metadata['run_requires'].append(may_requirement)
-
+
if not 'extras' in metadata:
metadata['extras'] = []
metadata['extras'].extend([key.extra for key in may_requires.keys() if key.extra])
@@ -132,7 +132,7 @@ def pkginfo_to_dict(path, distribution=None):
if low_key in PLURAL_FIELDS:
metadata[PLURAL_FIELDS[low_key]] = pkg_info.get_all(key)
- elif low_key == "requires_dist":
+ elif low_key == "requires_dist":
handle_requires(metadata, pkg_info, key)
elif low_key == 'provides_extra':
@@ -156,8 +156,9 @@ def pkginfo_to_dict(path, distribution=None):
for requires, attr in (('test_requires', 'tests_require'),):
try:
requirements = getattr(distribution, attr)
- if requirements:
- metadata[requires] = [{'requires':requirements}]
+ if isinstance(requirements, list):
+ new_requirements = list(convert_requirements(requirements))
+ metadata[requires] = [{'requires':new_requirements}]
except AttributeError:
pass
@@ -174,8 +175,30 @@ def pkginfo_to_dict(path, distribution=None):
if contacts:
metadata['contacts'] = contacts
- return metadata
+ # convert entry points to exports
+ try:
+ with file(os.path.join(os.path.dirname(path), "entry_points.txt"), "r") as ep_file:
+ ep_map = pkg_resources.EntryPoint.parse_map(ep_file.read())
+ exports = {}
+ for group, items in ep_map.items():
+ exports[group] = {}
+ for item in items.values():
+ name, export = str(item).split(' = ', 1)
+ exports[group][name] = export
+ if exports:
+ metadata['exports'] = exports
+ except IOError:
+ pass
+
+ # copy console_scripts entry points to commands
+ if 'exports' in metadata:
+ for (ep_script, wrap_script) in (('console_scripts', 'wrap_console'),
+ ('gui_scripts', 'wrap_gui')):
+ if ep_script in metadata['exports']:
+ metadata['commands'] = metadata.get('commands', {})
+ metadata['commands'][wrap_script] = metadata['exports'][ep_script]
+ return metadata
def requires_to_requires_dist(requirement):
"""Compose the version predicates for requirement in PEP 345 fashion."""
@@ -186,6 +209,15 @@ def requires_to_requires_dist(requirement):
return ''
return " (%s)" % ','.join(requires_dist)
+def convert_requirements(requirements):
+ """Yield Requires-Dist: strings for parsed requirements strings."""
+ for req in requirements:
+ parsed_requirement = pkg_resources.Requirement.parse(req)
+ spec = requires_to_requires_dist(parsed_requirement)
+ extras = ",".join(parsed_requirement.extras)
+ if extras:
+ extras = "[%s]" % extras
+ yield (parsed_requirement.project_name + extras + spec)
def pkginfo_to_metadata(egg_info_path, pkginfo_path):
"""
@@ -202,16 +234,8 @@ def pkginfo_to_metadata(egg_info_path, pkginfo_path):
if extra:
pkg_info['Provides-Extra'] = extra
condition = '; extra == %s' % repr(extra)
- for req in reqs:
- parsed_requirement = pkg_resources.Requirement.parse(req)
- spec = requires_to_requires_dist(parsed_requirement)
- extras = ",".join(parsed_requirement.extras)
- if extras:
- extras = "[%s]" % extras
- pkg_info['Requires-Dist'] = (parsed_requirement.project_name
- + extras
- + spec
- + condition)
+ for new_req in convert_requirements(reqs):
+ pkg_info['Requires-Dist'] = new_req + condition
description = pkg_info['Description']
if description:
diff --git a/wheel/test/complex-dist/setup.py b/wheel/test/complex-dist/setup.py
index fd5ec9b..802dbaf 100644
--- a/wheel/test/complex-dist/setup.py
+++ b/wheel/test/complex-dist/setup.py
@@ -19,7 +19,7 @@ setup(name='complex-dist',
setup_requires=["wheel", "setuptools"],
install_requires=["quux", "splort"],
extras_require={'simple':['simple.dist']},
- tests_require=["foo", "bar"],
+ tests_require=["foo", "bar>=10.0.0"],
entry_points={'console_scripts':['complex-dist=complexdist:main']}
)
diff --git a/wheel/test/pydist-schema.json b/wheel/test/pydist-schema.json
index 41eb64a..fc350bf 100644
--- a/wheel/test/pydist-schema.json
+++ b/wheel/test/pydist-schema.json
@@ -17,7 +17,7 @@
"name": {
"description": "The name of the distribution.",
"type": "string",
- "$ref": "#/definitions/valid_name"
+ "$ref": "#/definitions/distribution_name"
},
"version": {
"description": "The distribution's public version identifier",
@@ -136,6 +136,32 @@
"$ref": "#/definitions/provides_declaration"
}
},
+ "modules": {
+ "description": "A list of modules and/or packages available for import after installing this distribution.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "$ref": "#/definitions/qualified_name"
+ }
+ },
+ "namespaces": {
+ "description": "A list of namespace packages this distribution contributes to",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "$ref": "#/definitions/qualified_name"
+ }
+ },
+ "commands": {
+ "description": "Command line interfaces provided by this distribution",
+ "type": "object",
+ "$ref": "#/definitions/commands"
+ },
+ "exports": {
+ "description": "Other exported interfaces provided by this distribution",
+ "type": "object",
+ "$ref": "#/definitions/exports"
+ },
"obsoleted_by": {
"description": "A string that indicates that this project is no longer being developed. The named project provides a substitute or replacement.",
"type": "string",
@@ -155,17 +181,18 @@
"properties": {
"postinstall": {
"type": "string",
- "$ref": "#/definitions/entry_point"
+ "$ref": "#/definitions/export_specifier"
},
"preuninstall": {
"type": "string",
- "$ref": "#/definitions/entry_point"
+ "$ref": "#/definitions/export_specifier"
}
}
},
"extensions": {
"description": "Extensions to the metadata may be present in a mapping under the 'extensions' key.",
- "type": "object"
+ "type": "object",
+ "$ref": "#/definitions/extensions"
}
},
@@ -204,7 +231,7 @@
"properties": {
"extra": {
"type": "string",
- "$ref": "#/definitions/valid_name"
+ "$ref": "#/definitions/extra_name"
},
"environment": {
"type": "string",
@@ -221,7 +248,61 @@
"required": ["requires"],
"additionalProperties": false
},
- "valid_name": {
+ "commands": {
+ "type": "object",
+ "properties": {
+ "wrap_console": {
+ "type": "object",
+ "$ref": "#/definitions/command_map"
+ },
+ "wrap_gui": {
+ "type": "object",
+ "$ref": "#/definitions/command_map"
+ },
+ "prebuilt": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "$ref": "#/definitions/relative_path"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "exports": {
+ "type": "object",
+ "patternProperties": {
+ "^[A-Za-z][0-9A-Za-z_]*([.][0-9A-Za-z_]*)*$": {
+ "type": "object",
+ "patternProperties": {
+ ".": {
+ "type": "string",
+ "$ref": "#/definitions/export_specifier"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ },
+ "extensions": {
+ "type": "object",
+ "patternProperties": {
+ "^[A-Za-z][0-9A-Za-z_]*([.][0-9A-Za-z_]*)*$": {}
+ },
+ "additionalProperties": false
+ },
+ "command_map": {
+ "type": "object",
+ "patternProperties": {
+ "^[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])?$": {
+ "type": "string",
+ "$ref": "#/definitions/export_specifier"
+ }
+ },
+ "additionalProperties": false
+ },
+ "distribution_name": {
"type": "string",
"pattern": "^[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])?$"
},
@@ -234,14 +315,27 @@
"environment_marker": {
"type": "string"
},
- "entry_point": {
- "type": "string"
- },
"document_name": {
"type": "string"
},
"extra_name" : {
+ "type": "string",
+ "pattern": "^[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])?$"
+ },
+ "relative_path" : {
"type": "string"
+ },
+ "export_specifier": {
+ "type": "string",
+ "pattern": "^([A-Za-z_][A-Za-z_0-9]*([.][A-Za-z_][A-Za-z_0-9]*)*)(:[A-Za-z_][A-Za-z_0-9]*([.][A-Za-z_][A-Za-z_0-9]*)*)?(\\[[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])?\\])?$"
+ },
+ "qualified_name" : {
+ "type": "string",
+ "pattern": "^[A-Za-z_][A-Za-z_0-9]*([.][A-Za-z_][A-Za-z_0-9]*)*$"
+ },
+ "prefixed_name" : {
+ "type": "string",
+ "pattern": "^[A-Za-z_][A-Za-z_0-9]*([.][A-Za-z_0-9]*)*$"
}
}
}