Commits

Daniel Holth committed 1bbbd01

add experimental waf build script

  • Participants
  • Parent commits 12bbac6

Comments (0)

Files changed (3)

+Metadata-Version: 2.0
+Name: wheel
+Version: ${VERSION}
+Summary: A built-package format for Python.
+Home-page: http://bitbucket.org/pypa/wheel/
+Author: Daniel Holth
+Author-email: dholth@fastmail.fm
+License: MIT
+Keywords: wheel,packaging
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Provides-Extra: tool
+Provides-Extra: signatures
+Requires-Dist: keyring; extra == 'signatures'
+Provides-Extra: faster-signatures
+Requires-Dist: ed25519ll; extra == 'faster-signatures'
+Requires-Dist: argparse; python_version=="2.6"
+Provides-Extra: signatures
+Requires-Dist: pyxdg; sys_platform!="win32" and extra == 'signatures'
+
+${DESCRIPTION}
+[console_scripts]
+wheel = wheel.tool:main
+
+[distutils.commands]
+bdist_wheel = wheel.bdist_wheel:bdist_wheel
+APPNAME = 'wheel'
+WHEEL_TAG = 'py2.py3-none-any'
+VERSION = '0.24.0'
+
+top = '.'
+out = 'build'
+
+from waflib import Utils
+
+def options(opt):
+    opt.load('python')
+
+def configure(ctx):
+    ctx.load('python')
+
+def build(bld):
+    bld(features='py', 
+        source=bld.path.ant_glob('wheel/**/*.py', excl="wheel/test"), 
+        install_from='.')
+
+    # build the wheel:
+    
+    DIST_INFO = '%s-%s.dist-info' % (APPNAME, VERSION)
+
+    node = bld.path.get_bld().make_node(DIST_INFO)
+    if not os.path.exists(node.abspath()):
+        os.mkdir(node.abspath())
+
+    metadata = node.make_node('METADATA')
+
+    import codecs, string
+    README = codecs.open('README.txt', encoding='utf8').read()
+    CHANGES = codecs.open('CHANGES.txt', encoding='utf8').read()
+    METADATA = codecs.open('METADATA.in', encoding='utf8').read()
+    METADATA = string.Template(METADATA).substitute(
+            VERSION=VERSION, 
+            DESCRIPTION='\n\n'.join((README, CHANGES))
+            )
+
+    bld(source='METADATA.in',
+        target=metadata,
+        rule=lambda tsk: Utils.writef(tsk.outputs[0].abspath(), METADATA))
+
+    wheel = node.make_node('WHEEL')
+
+    WHEEL="""Wheel-Version: 1.0
+Generator: waf (0.0.1)
+Root-Is-Purelib: true
+Tag: py2-none-any
+Tag: py3-none-any
+"""
+    bld(target=wheel,
+       rule=lambda tsk: Utils.writef(tsk.outputs[0].abspath(), WHEEL))
+
+    # globs don't work, since here the files may not exist
+    bld.install_files('${PYTHONDIR}/'+DIST_INFO, [DIST_INFO+'/WHEEL', DIST_INFO+'/METADATA'])
+    bld.install_files('${PYTHONDIR}/'+DIST_INFO, ['entry_points.txt'])
+
+
+import shutil, os, base64
+
+def urlsafe_b64encode(data):
+    """urlsafe_b64encode without padding"""
+    return base64.urlsafe_b64encode(data).rstrip(b'=')
+
+from waflib import Scripting
+class WheelDist(Scripting.Dist):
+    def manifest(self):
+        """
+        Add the wheel manifest.
+        """
+        import hashlib
+        files = self.get_files()
+        lines = []
+        for f in files:
+            size = os.stat(f.abspath()).st_size
+            digest = hashlib.sha256(open(f.abspath(), 'rb').read()).digest()
+            digest = "sha256="+urlsafe_b64encode(digest)
+            lines.append("%s,%s,%s" % (f.path_from(self.base_path).replace(',', ',,'), digest, size))
+                    
+        record_path = '%s-%s.dist-info/RECORD' % (APPNAME, VERSION)
+        lines.append(record_path+',,')
+        RECORD = '\n'.join(lines)
+
+        import zipfile
+        zip = zipfile.ZipFile(self.get_arch_name(), 'a')
+        zip.writestr(record_path, RECORD, zipfile.ZIP_DEFLATED)
+        zip.close()
+
+from waflib import Build
+class package_cls(Build.InstallContext):
+    cmd = 'package'
+    fun = 'build'
+
+    def init_dirs(self, *k, **kw):
+        super(package_cls, self).init_dirs(*k, **kw)
+        self.tmp = self.bldnode.make_node('package_tmp_dir')
+        try:
+            shutil.rmtree(self.tmp.abspath())
+        except:
+            pass
+        if os.path.exists(self.tmp.abspath()):
+            self.fatal('Could not remove the temporary directory %r' % self.tmp)
+        self.tmp.mkdir()
+        self.options.destdir = self.tmp.abspath()
+
+    def execute(self, *k, **kw):
+        back = self.options.destdir
+        try:
+            super(package_cls, self).execute(*k, **kw)
+        finally:
+            self.options.destdir = back
+
+        files = self.tmp.ant_glob('**', excl=" **/*.pyc **/*.pyo")
+
+        # we could mess with multiple inheritance but this is probably unnecessary
+        ctx = WheelDist()
+        ctx.algo = 'zip'
+        ctx.arch_name = '%s-%s-%s.whl' % (APPNAME, VERSION, WHEEL_TAG)
+        ctx.files = files
+        ctx.tar_prefix = ''
+        ctx.base_path = self.tmp
+        ctx.base_name = ''
+        ctx.archive()
+
+        # add manifest...
+        ctx.manifest()
+
+        shutil.rmtree(self.tmp.abspath())
+
+# for variants, add command subclasses "package_release", "package_debug", etc
+def init(ctx):
+    for x in ('release', 'debug'):
+            class tmp(package_cls):
+                cmd = 'package_' + x
+                variant = x
+