]> arthur.barton.de Git - bup.git/blobdiff - cmd/bup
Move cmd to lib/ and reverse symlink
[bup.git] / cmd / bup
diff --git a/cmd/bup b/cmd/bup
deleted file mode 100755 (executable)
index c98d7e7..0000000
--- a/cmd/bup
+++ /dev/null
@@ -1,268 +0,0 @@
-#!/bin/sh
-"""": # -*-python-*- # -*-python-*-
-set -e
-top="$(pwd)"
-cmdpath="$0"
-# loop because macos doesn't have recursive readlink/realpath utils
-while test -L "$cmdpath"; do
-    link="$(readlink "$cmdpath")"
-    cd "$(dirname "$cmdpath")"
-    cmdpath="$link"
-done
-script_home="$(cd "$(dirname "$cmdpath")" && pwd -P)"
-cd "$top"
-exec "$script_home/bup-python" "$0" ${1+"$@"}
-"""
-# end of bup preamble
-
-from __future__ import absolute_import, print_function
-import errno, getopt, os, re, select, signal, subprocess, sys
-from subprocess import PIPE
-
-from bup.compat import environ, restore_lc_env
-from bup.io import path_msg
-
-if sys.version_info[0] != 2 \
-   and not environ.get(b'BUP_ALLOW_UNEXPECTED_PYTHON_VERSION') == b'true':
-    print('error: bup may crash with python versions other than 2, or eat your data',
-          file=sys.stderr)
-    sys.exit(2)
-
-restore_lc_env()
-
-from bup import compat, path, helpers
-from bup.compat import add_ex_tb, add_ex_ctx, argv_bytes, wrap_main
-from bup.helpers import atoi, columnate, debug1, log, merge_dict, tty_width
-from bup.io import byte_stream, path_msg
-
-cmdpath = path.cmddir()
-
-# We manipulate the subcmds here as strings, but they must be ASCII
-# compatible, since we're going to be looking for exactly
-# b'bup-SUBCMD' to exec.
-
-def usage(msg=""):
-    log('Usage: bup [-?|--help] [-d BUP_DIR] [--debug] [--profile] '
-        '<command> [options...]\n\n')
-    common = dict(
-        ftp = 'Browse backup sets using an ftp-like client',
-        fsck = 'Check backup sets for damage and add redundancy information',
-        fuse = 'Mount your backup sets as a filesystem',
-        help = 'Print detailed help for the given command',
-        index = 'Create or display the index of files to back up',
-        on = 'Backup a remote machine to the local one',
-        restore = 'Extract files from a backup set',
-        save = 'Save files into a backup set (note: run "bup index" first)',
-        tag = 'Tag commits for easier access',
-        web = 'Launch a web server to examine backup sets',
-    )
-
-    log('Common commands:\n')
-    for cmd,synopsis in sorted(common.items()):
-        log('    %-10s %s\n' % (cmd, synopsis))
-    log('\n')
-    
-    log('Other available commands:\n')
-    cmds = []
-    for c in sorted(os.listdir(cmdpath)):
-        if c.startswith(b'bup-') and c.find(b'.') < 0:
-            cname = c[4:].decode('iso-8859-1')
-            if cname not in common:
-                cmds.append(c[4:])
-    log(columnate(cmds, '    '))
-    log('\n')
-    
-    log("See 'bup help COMMAND' for more information on " +
-        "a specific command.\n")
-    if msg:
-        log("\n%s\n" % msg)
-    sys.exit(99)
-
-
-if len(sys.argv) < 2:
-    usage()
-
-# Handle global options.
-try:
-    optspec = ['help', 'version', 'debug', 'profile', 'bup-dir=']
-    global_args, subcmd = getopt.getopt(sys.argv[1:], '?VDd:', optspec)
-except getopt.GetoptError as ex:
-    usage('error: %s' % ex.msg)
-
-subcmd = [argv_bytes(x) for x in subcmd]
-help_requested = None
-do_profile = False
-bup_dir = None
-
-for opt in global_args:
-    if opt[0] in ['-?', '--help']:
-        help_requested = True
-    elif opt[0] in ['-V', '--version']:
-        subcmd = [b'version']
-    elif opt[0] in ['-D', '--debug']:
-        helpers.buglvl += 1
-        environ[b'BUP_DEBUG'] = b'%d' % helpers.buglvl
-    elif opt[0] in ['--profile']:
-        do_profile = True
-    elif opt[0] in ['-d', '--bup-dir']:
-        bup_dir = argv_bytes(opt[1])
-    else:
-        usage('error: unexpected option "%s"' % opt[0])
-
-if bup_dir:
-    bup_dir = argv_bytes(bup_dir)
-
-# Make BUP_DIR absolute, so we aren't affected by chdir (i.e. save -C, etc.).
-if bup_dir:
-    environ[b'BUP_DIR'] = os.path.abspath(bup_dir)
-
-if len(subcmd) == 0:
-    if help_requested:
-        subcmd = [b'help']
-    else:
-        usage()
-
-if help_requested and subcmd[0] != b'help':
-    subcmd = [b'help'] + subcmd
-
-if len(subcmd) > 1 and subcmd[1] == b'--help' and subcmd[0] != b'help':
-    subcmd = [b'help', subcmd[0]] + subcmd[2:]
-
-subcmd_name = subcmd[0]
-if not subcmd_name:
-    usage()
-
-def subpath(subcmd):
-    return os.path.join(cmdpath, b'bup-' + subcmd)
-
-subcmd[0] = subpath(subcmd_name)
-if not os.path.exists(subcmd[0]):
-    usage('error: unknown command "%s"' % path_msg(subcmd_name))
-
-already_fixed = atoi(environ.get(b'BUP_FORCE_TTY'))
-if subcmd_name in [b'mux', b'ftp', b'help']:
-    already_fixed = True
-fix_stdout = not already_fixed and os.isatty(1)
-fix_stderr = not already_fixed and os.isatty(2)
-
-if fix_stdout or fix_stderr:
-    tty_env = merge_dict(environ,
-                         {b'BUP_FORCE_TTY': (b'%d'
-                                             % ((fix_stdout and 1 or 0)
-                                                + (fix_stderr and 2 or 0)))})
-else:
-    tty_env = environ
-
-
-sep_rx = re.compile(br'([\r\n])')
-
-def print_clean_line(dest, content, width, sep=None):
-    """Write some or all of content, followed by sep, to the dest fd after
-    padding the content with enough spaces to fill the current
-    terminal width or truncating it to the terminal width if sep is a
-    carriage return."""
-    global sep_rx
-    assert sep in (b'\r', b'\n', None)
-    if not content:
-        if sep:
-            os.write(dest, sep)
-        return
-    for x in content:
-        assert not sep_rx.match(x)
-    content = b''.join(content)
-    if sep == b'\r' and len(content) > width:
-        content = content[width:]
-    os.write(dest, content)
-    if len(content) < width:
-        os.write(dest, b' ' * (width - len(content)))
-    if sep:
-        os.write(dest, sep)
-
-def filter_output(src_out, src_err, dest_out, dest_err):
-    """Transfer data from src_out to dest_out and src_err to dest_err via
-    print_clean_line until src_out and src_err close."""
-    global sep_rx
-    assert not isinstance(src_out, bool)
-    assert not isinstance(src_err, bool)
-    assert not isinstance(dest_out, bool)
-    assert not isinstance(dest_err, bool)
-    assert src_out is not None or src_err is not None
-    assert (src_out is None) == (dest_out is None)
-    assert (src_err is None) == (dest_err is None)
-    pending = {}
-    pending_ex = None
-    try:
-        fds = tuple([x for x in (src_out, src_err) if x is not None])
-        while fds:
-            ready_fds, _, _ = select.select(fds, [], [])
-            width = tty_width()
-            for fd in ready_fds:
-                buf = os.read(fd, 4096)
-                dest = dest_out if fd == src_out else dest_err
-                if not buf:
-                    fds = tuple([x for x in fds if x is not fd])
-                    print_clean_line(dest, pending.pop(fd, []), width)
-                else:
-                    split = sep_rx.split(buf)
-                    while len(split) > 1:
-                        content, sep = split[:2]
-                        split = split[2:]
-                        print_clean_line(dest,
-                                         pending.pop(fd, []) + [content],
-                                         width,
-                                         sep)
-                    assert(len(split) == 1)
-                    if split[0]:
-                        pending.setdefault(fd, []).extend(split)
-    except BaseException as ex:
-        pending_ex = add_ex_ctx(add_ex_tb(ex), pending_ex)
-    try:
-        # Try to finish each of the streams
-        for fd, pending_items in compat.items(pending):
-            dest = dest_out if fd == src_out else dest_err
-            try:
-                print_clean_line(dest, pending_items, width)
-            except (EnvironmentError, EOFError) as ex:
-                pending_ex = add_ex_ctx(add_ex_tb(ex), pending_ex)
-    except BaseException as ex:
-        pending_ex = add_ex_ctx(add_ex_tb(ex), pending_ex)
-    if pending_ex:
-        raise pending_ex
-
-def run_subcmd(subcmd):
-
-    c = (do_profile and [sys.executable, b'-m', b'cProfile'] or []) + subcmd
-    if not (fix_stdout or fix_stderr):
-        os.execvp(c[0], c)
-
-    sys.stdout.flush()
-    sys.stderr.flush()
-    out = byte_stream(sys.stdout)
-    err = byte_stream(sys.stderr)
-    p = None
-    try:
-        p = subprocess.Popen(c,
-                             stdout=PIPE if fix_stdout else out,
-                             stderr=PIPE if fix_stderr else err,
-                             env=tty_env, bufsize=4096, close_fds=True)
-        # Assume p will receive these signals and quit, which will
-        # then cause us to quit.
-        for sig in (signal.SIGINT, signal.SIGTERM, signal.SIGQUIT):
-            signal.signal(sig, signal.SIG_IGN)
-
-        filter_output(fix_stdout and p.stdout.fileno() or None,
-                      fix_stderr and p.stderr.fileno() or None,
-                      fix_stdout and out.fileno() or None,
-                      fix_stderr and err.fileno() or None)
-        return p.wait()
-    except BaseException as ex:
-        add_ex_tb(ex)
-        try:
-            if p and p.poll() == None:
-                os.kill(p.pid, signal.SIGTERM)
-                p.wait()
-        except BaseException as kill_ex:
-            raise add_ex_ctx(add_ex_tb(kill_ex), ex)
-        raise ex
-        
-wrap_main(lambda : run_subcmd(subcmd))