Commits

Daniel Holth committed dccf30d

beginnings of new-draft metadata 2.0 support

Comments (0)

Files changed (2)

wheel/bdist_wheel.py

         self.add_requirements(metadata_path)
         
         # XXX to be specified
-        metadata_json_path = os.path.join(self.distinfo_dir, 'metadata.json')
+        metadata_json_path = os.path.join(self.distinfo_dir, 'pymeta.json')
         with open(metadata_json_path, "w") as metadata_json:
             json.dump(pkginfo_to_dict(metadata_path), metadata_json)
 

wheel/metadata.py

 # Convert egg-style metadata to Metadata 2.0, json version.
 # This is currently based on the pypi json API but with less UNKNOWN.
 
+from collections import defaultdict
 from .pkginfo import read_pkg_info
+import re
 
 METADATA_VERSION = "2.0"
 PLURAL_FIELDS = { "classifier" : "classifiers", 
                   "provides_extra" : "extras" }
 SKIP_FIELDS = set(["description"])
 
+# Will only support markers-as-extras here. Wheel itself is probably
+# the only program that uses non-extras markers in METADATA/PKG-INFO.
+EXTRA_RE = re.compile("extra == '(?P<extra>.+)'")
+KEYWORDS_RE = re.compile("[\0-,]+")
+
 def unique(iterable):
     seen = set()
     for value in iterable:
     pkg_info = read_pkg_info(path)
     for key in unique(k.lower() for k in pkg_info.keys()):
         low_key = key.replace('-', '_')
+
         if low_key in SKIP_FIELDS: 
             continue
+
         if low_key in PLURAL_FIELDS:
             metadata[PLURAL_FIELDS[low_key]] = pkg_info.get_all(key)
+
         elif low_key == "requires_dist":
-            requirements = {}
+            requirements = []
+            extra_requirements = defaultdict(list)
             for requirement, sep, marker in (value.partition(';') 
                                         for value in pkg_info.get_all(key)):
-                # XXX split out (version predicates) into their own list
                 marker = marker.strip()
-                if requirements.get(marker, None) == None:
-                    requirements[marker] = []
-                requirements[marker].append(requirement)
+                if marker:
+                    extra_match = EXTRA_RE.match(marker)
+                    if extra_match:
+                        extra_name = extra_match.group('extra')
+                        extra_requirements[extra_name].append(requirement)
+                else:
+                    requirements.append(requirement)
             metadata['requires'] = requirements
+            if extra_requirements:
+                metadata['may_require'] = [{'extra':key, 'dependencies':value} 
+                        for key, value in sorted(extra_requirements.items())]
+                metadata['extras'] = [key for key in sorted(extra_requirements.keys())]
+
+        elif low_key == 'provides-extra':
+            if not 'extras' in metadata:
+                metadata['extras'] = []
+            metadata['extras'].extend(pkg_info.get_all(key))
+
         else:
             metadata[low_key] = pkg_info[key]
+
     metadata['metadata_version'] = METADATA_VERSION
     return metadata