Repository: mesonbuild/meson

Issue:
shutil.ReadError: Unknown archive format (tar.xz)
```
Dowloading enet from http://enet.bespin.org/download/enet-1.3.13.tar.gz
Downloading patch from https://github.com/ignatenkobrain/meson_wrap_example/raw/master/subprojects/enet-meson.tar.xz
Traceback (most recent call last):
  File "/home/brain/git/meson/meson.py", line 188, in run
    app.generate()
  File "/home/brain/git/meson/meson.py", line 129, in generate
    intr.run()
  File "/home/brain/git/meson/interpreter.py", line 871, in run
    self.evaluate_codeblock(self.ast)
  File "/home/brain/git/meson/interpreter.py", line 893, in evaluate_codeblock
    raise e
  File "/home/brain/git/meson/interpreter.py", line 887, in evaluate_codeblock
    self.evaluate_statement(cur)
  File "/home/brain/git/meson/interpreter.py", line 951, in evaluate_statement
    return self.evaluate_if(cur)
  File "/home/brain/git/meson/interpreter.py", line 1757, in evaluate_if
    self.evaluate_codeblock(node.elseblock)
  File "/home/brain/git/meson/interpreter.py", line 893, in evaluate_codeblock
    raise e
  File "/home/brain/git/meson/interpreter.py", line 887, in evaluate_codeblock
    self.evaluate_statement(cur)
  File "/home/brain/git/meson/interpreter.py", line 943, in evaluate_statement
    return self.assignment(cur)
  File "/home/brain/git/meson/interpreter.py", line 1637, in assignment
    value = self.evaluate_statement(node.value)
  File "/home/brain/git/meson/interpreter.py", line 941, in evaluate_statement
    return self.function_call(cur)
  File "/home/brain/git/meson/interpreter.py", line 1618, in function_call
    return self.funcs[func_name](node, self.flatten(posargs), kwargs)
  File "/home/brain/git/meson/interpreter.py", line 60, in wrapped
    return f(self, node, args, kwargs)
  File "/home/brain/git/meson/interpreter.py", line 52, in wrapped
    return f(self, node, args, kwargs)
  File "/home/brain/git/meson/interpreter.py", line 1071, in func_subproject
    resolved = r.resolve(dirname)
  File "/home/brain/git/meson/wrap.py", line 64, in resolve
    self.extract_package(p)
  File "/home/brain/git/meson/wrap.py", line 128, in extract_package
    shutil.unpack_archive(os.path.join(self.cachedir, package.get('patch_filename')), self.subdir_root)
  File "/usr/lib64/python3.4/shutil.py", line 953, in unpack_archive
    raise ReadError("Unknown archive format '{0}'".format(filename))
shutil.ReadError: Unknown archive format '/home/brain/meson_wrap/subprojects/packagecache/enet-meson.tar.xz'
```



Discussion:
This works for me on py3:

``` python
import tarfile

with tarfile.open('test.tar.xz') as f:
    f.extractall('.')
```

Looks like it's fixed in python 3.5: https://hg.python.org/cpython/rev/e57db221b6c4

I think we need workaround on python 3.4


Resolving patch:
diff --git a/wrap.py b/wrap.py
--- a/wrap.py
+++ b/wrap.py
@@ -15,6 +15,7 @@
 import mlog
 import urllib.request, os, hashlib, shutil
 import subprocess
+import sys
 
 class PackageDefinition:
     def __init__(self, fname):
@@ -121,6 +122,13 @@ def download(self, p, packagename):
         open(ofname, 'wb').write(srcdata)
 
     def extract_package(self, package):
+        if sys.version_info < (3, 5):
+            try:
+                import lzma
+                del lzma
+                shutil.register_unpack_format('xztar', ['.tar.xz', '.txz'], shutil._unpack_tarfile, [], "xz'ed tar-file")
+            except ImportError:
+                pass
         if os.path.isdir(os.path.join(self.subdir_root, package.get('directory'))):
             return
         shutil.unpack_archive(os.path.join(self.cachedir, package.get('source_filename')), self.subdir_root)


Test patch: