Skip to content

Commit d0205c2

Browse files
committed
Merge branch 'master' of github.com:ali5h/rules_python
2 parents fdbb17a + 81aaec8 commit d0205c2

3 files changed

Lines changed: 45 additions & 4 deletions

File tree

rules_python/whl.py

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@
1414
"""The whl modules defines classes for interacting with Python packages."""
1515

1616
import argparse
17+
import collections
18+
import rfc822
1719
import json
1820
import os
1921
import pkg_resources
2022
import re
2123
import zipfile
2224

25+
EXTRA_RE = re.compile("""^(?P<package>.*?)(;\s*(?P<condition>.*?)(extra == '(?P<extra>.*?)')?)$""")
26+
MayRequiresKey = collections.namedtuple('MayRequiresKey', ('condition', 'extra'))
27+
2328

2429
class Wheel(object):
2530

@@ -66,7 +71,7 @@ def metadata(self):
6671
pass
6772
# fall back to METADATA file (https://www.python.org/dev/peps/pep-0427/)
6873
with whl.open(self._dist_info() + '/METADATA') as f:
69-
return self._parse_metadata(f.read().decode("utf-8"))
74+
return self._parse_metadata(f)
7075

7176
def name(self):
7277
return self.metadata().get('name')
@@ -107,9 +112,45 @@ def expand(self, directory):
107112

108113
# _parse_metadata parses METADATA files according to https://www.python.org/dev/peps/pep-0314/
109114
def _parse_metadata(self, content):
110-
# TODO: handle fields other than just name
111-
name_pattern = re.compile('Name: (.*)')
112-
return { 'name': name_pattern.search(content).group(1) }
115+
def get_header_value(header):
116+
return header.strip().split(':', 2)[1].strip()
117+
metadata = {}
118+
pkg_info = rfc822.Message(content)
119+
metadata['name'] = pkg_info.get('Name')
120+
extras = [get_header_value(h) for h in pkg_info.getallmatchingheaders('Provides-Extra')]
121+
if extras:
122+
metadata['extras'] = list(set(extras))
123+
124+
reqs_dist = [get_header_value(h) for h in pkg_info.getallmatchingheaders('Requires-Dist')]
125+
requires = collections.defaultdict(set)
126+
for value in sorted(reqs_dist):
127+
extra_match = EXTRA_RE.search(value)
128+
if extra_match:
129+
groupdict = extra_match.groupdict()
130+
condition = groupdict['condition']
131+
extra = groupdict['extra']
132+
package = groupdict['package']
133+
if condition.endswith(' and '):
134+
condition = condition[:-5]
135+
else:
136+
condition, extra = None, None
137+
package = value
138+
key = MayRequiresKey(condition, extra)
139+
requires[key].add(package)
140+
141+
if requires:
142+
metadata['run_requires'] = []
143+
for key, value in requires.items():
144+
requirement = {
145+
'requires': list(value)
146+
}
147+
if key.extra:
148+
requirement['extra'] = key.extra
149+
if key.condition:
150+
requirement['environment'] = key.condition
151+
metadata['run_requires'].append(requirement)
152+
153+
return metadata
113154

114155

115156
parser = argparse.ArgumentParser(

tools/piptool.par

2.36 KB
Binary file not shown.

tools/whltool.par

3.72 KB
Binary file not shown.

0 commit comments

Comments
 (0)