Raw File
distribution
#! /usr/bin/env python3

# --------------------------------------------------------------------
import sys, os, re, itertools as it, subprocess as sp
import glob, fnmatch

# --------------------------------------------------------------------
MYROOT  = os.path.dirname(__file__)
INSTALL = os.path.join(MYROOT, 'install-sh')

# --------------------------------------------------------------------
def _error(message):
    print("%s: %s" % (sys.argv[0], message), file=sys.stderr)
    exit(1)

# --------------------------------------------------------------------
def _exec(command):
    print(' '.join(command), file=sys.stderr)
    sp.check_call(command)

# --------------------------------------------------------------------
def install_dir(distdir, x):
    fulldir = os.path.join(distdir, x)
    command = [INSTALL, '-m', '0755', '-d', fulldir]

    _exec(command)

# --------------------------------------------------------------------
def install_files(distdir, x, files):
    fulldir  = os.path.join(distdir, x)
    filesR   = [os.path.join(x, f) for (f, b) in files if not b]
    filesX   = [os.path.join(x, f) for (f, b) in files if     b]

    command1 = [INSTALL, '-m', '0755', '-t', fulldir] + filesX
    command2 = [INSTALL, '-m', '0644', '-t', fulldir] + filesR

    if filesX: _exec(command1)
    if filesR: _exec(command2)

# --------------------------------------------------------------------
def _find(dirname, glob):
    for dirpath, dirnames, filenames in os.walk(dirname):
        for filename in fnmatch.filter(filenames, glob):
            yield os.path.join(dirpath, filename)

# --------------------------------------------------------------------
def _expand(x):
    if re.search('^.+:', x) is not None:
        findm = re.search(r'^find:(.*?):(.*$)$', x)
        if findm is not None:
            return list(_find(findm.group(1), findm.group(2)))
        return []

    if not hasattr(glob, 'has_magic') or glob.has_magic(x):
        return glob.glob(x)
    return [x]

# --------------------------------------------------------------------
def _exclude(x):
    exclm = re.search('^exclude:(.+)$', x)
    if exclm is not None:
        exclm = exclm.group(1)
        if not hasattr(glob, 'has_magic') or glob.has_magic(exclm):
            return glob.glob(exclm)
        return [exclm]

    return []

# --------------------------------------------------------------------
def _main():
    if len(sys.argv)-1 != 2:
        print("Usage: %s [dist-dir] [MANIFEST]" % (sys.argv[0]), file=sys.stderr)
        exit (1)

    distdir  = sys.argv[1]
    manifest = sys.argv[2]

    contents = open(manifest, 'r').readlines()
    contents = [re.sub('#.*$', '', x).strip() for x in contents]
    contents = [x for x in contents if x]

    exclude  = contents
    exclude  = list(it.chain(*[_exclude(x) for x in exclude]))
    exclude  = set([os.path.normpath(x) for x in exclude])

    manifest = contents
    manifest = list(it.chain(*[_expand(x) for x in manifest]))
    manifest = [os.path.normpath(x) for x in manifest]
    manifest = [x for x in manifest if x not in exclude]

    noaccess = [x for x in manifest if not os.access(x, os.F_OK)]

    if noaccess:
        msg = 'cannot access the following MANIFEST files: %s'
        _error(msg % ', '.join(noaccess))

    bygroup = dict()

    for x in manifest:
        if os.path.isdir(x):
            bygroup.setdefault(x, [])
        else:
            (xdir, xbase) = os.path.split(x)
            xexec = os.access(x, os.X_OK)
            bygroup.setdefault(xdir, []).append((xbase, xexec))

    for x, v in bygroup.items():
        install_dir(distdir, x)
        install_files(distdir, x, v)

# --------------------------------------------------------------------
if __name__ == '__main__':
    _main()
back to top