Source code for arx.sources.tar

from sh import chmod, Command, mkdir, tar

from ..err import Err
from .core import twopaths, onepath


[docs]class Tar(object): """ With ``tar+...`` type URLs, passing fragment can give the source file nature; but by default it has directory nature. A fragment can reference a subdirectory or a particular file in the archive; in the latter case, the URL can be treated as a runnable program. There is a convention with release tarballs, to have a single top-level directory that is named something like ``<project>-<version>``. Tar offers ``--strip-components`` for this situation, where the archive is expanded as though only the top-level directory had been asked for. To access this functionality, use ``#/`` (this is the same as ``--strip-components 1``). Supplying ``#//`` would expand from all second-level directories (of which there is hopefully only one), &c. """ @twopaths def place(self, cache, path): data = self.cache(cache) opts = [] if self.url.fragment is not None: slashes = self.url.fragment.count('/') # If the fragment is `a/b/d/`, then we get three slashes and pass # three to `--strip-components`. The effect is similar to using # `rsync` or `cp -a` with trailing slashes. if slashes > 0: opts += ['--strip-components', str(slashes)] # Append fragment to arguments list, so only this file/dir is # extracted. opts += ['--', self.url.fragment] mkdir('-p', path.dirname) if self.url.fragment is None or self.url.fragment.endswith('/'): tar('-xf', str(data), '-C', str(path), *opts) else: tar('-xf', str(data), '--to-stdout', *opts, _out=str(path)) @onepath def run(self, cache, args=[]): if self.url.fragment is None: raise Invalid('Arx can not execute tarball URLs that have no ' 'fragment.') program = cache.join('program', self.url.fragment.split('/')[-1]) self.place(cache, program) chmod('a+rx', str(program)) cmd = Command(str(program)) cmd(*args) @onepath def dataname(self, cache): return cache.join('data.tar')
class Invalid(Err): pass