]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/main.py
main: fix output string truncation
[bup.git] / lib / bup / main.py
index e527977a2aa9214f391167b68ffeae163f9f7d05..dcab41b59eab18cf17b42df4d14a950c74f6e498 100755 (executable)
@@ -1,29 +1,36 @@
 
 from __future__ import absolute_import, print_function
+
+import bup_main, os, sys
+if bup_main.env_pythonpath:
+    if sys.version_info[0] < 3:
+        os.environ['PYTHONPATH'] = bup_main.env_pythonpath
+    else:
+        os.environb[b'PYTHONPATH'] = bup_main.env_pythonpath
+else:
+    del os.environ['PYTHONPATH']
+
 from importlib import import_module
 from pkgutil import iter_modules
 from subprocess import PIPE
 from threading import Thread
-import errno, getopt, os, re, select, signal, subprocess, sys
+import re, select, signal, subprocess
 
 from bup import compat, path, helpers
 from bup.compat import (
     ModuleNotFoundError,
     add_ex_ctx,
     add_ex_tb,
-    argv_bytes,
     environ,
     fsdecode,
     int_types,
     wrap_main
 )
-from bup.compat import add_ex_tb, add_ex_ctx, argv_bytes, wrap_main
+from bup.compat import add_ex_tb, add_ex_ctx, wrap_main
 from bup.helpers import (
     columnate,
-    debug1,
     handle_ctrl_c,
     log,
-    merge_dict,
     tty_width
 )
 from bup.git import close_catpipes
@@ -74,7 +81,7 @@ def usage(msg=""):
     for cmd,synopsis in sorted(common.items()):
         log('    %-10s %s\n' % (cmd, synopsis))
     log('\n')
-    
+
     log('Other available commands:\n')
     cmds = set()
     for c in sorted(os.listdir(cmdpath)):
@@ -90,46 +97,67 @@ def usage(msg=""):
 
     log(columnate(sorted(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)
 
-argv = compat.get_argv()
-if len(argv) < 2:
-    usage()
+def extract_argval(args):
+    """Assume args (all elements bytes) starts with a -x, --x, or --x=,
+argument that requires a value and return that value and the remaining
+args.  Exit with an errror if the value is missing.
 
-# Handle global options.
-try:
-    optspec = ['help', 'version', 'debug', 'profile', 'bup-dir=',
-               'import-py-module=']
-    global_args, subcmd = getopt.getopt(argv[1:], '?VDd:', optspec)
-except getopt.GetoptError as ex:
-    usage('error: %s' % ex.msg)
+    """
+    # Assumes that first arg is a valid arg
+    arg = args[0]
+    if b'=' in arg:
+        val = arg.split(b'=')[1]
+        if not val:
+            usage('error: no value provided for %s option' % arg)
+        return val, args[1:]
+    if len(args) < 2:
+        usage('error: no value provided for %s option' % arg)
+    return args[1], args[2:]
+
+
+args = compat.get_argvb()
+if len(args) < 2:
+    usage()
 
-subcmd = [argv_bytes(x) for x in subcmd]
+## Parse global options
 help_requested = None
 do_profile = False
 bup_dir = None
-
-for opt in global_args:
-    if opt[0] in ['-?', '--help']:
+args = args[1:]
+while args:
+    arg = args[0]
+    if arg in (b'-?', b'--help'):
         help_requested = True
-    elif opt[0] in ['-V', '--version']:
+        args = args[1:]
+    elif arg in (b'-V', b'--version'):
         subcmd = [b'version']
-    elif opt[0] in ['-D', '--debug']:
+        args = args[1:]
+    elif arg in (b'-D', b'--debug'):
         helpers.buglvl += 1
         environ[b'BUP_DEBUG'] = b'%d' % helpers.buglvl
-    elif opt[0] in ['--profile']:
+        args = args[1:]
+    elif arg == b'--profile':
         do_profile = True
-    elif opt[0] in ['-d', '--bup-dir']:
-        bup_dir = argv_bytes(opt[1])
-    elif opt[0] == '--import-py-module':
-        pass
+        args = args[1:]
+    elif arg in (b'-d', b'--bup-dir') or arg.startswith(b'--bup-dir='):
+        bup_dir, args = extract_argval(args)
+    elif arg == b'--import-py-module' or arg.startswith(b'--import-py-module='):
+        # Just need to skip it here
+        _, args = extract_argval(args)
+    elif arg.startswith(b'-'):
+        usage('error: unexpected option "%s"'
+              % arg.decode('ascii', 'backslashescape'))
     else:
-        usage('error: unexpected option "%s"' % opt[0])
+        break
+
+subcmd = args
 
 # Make BUP_DIR absolute, so we aren't affected by chdir (i.e. save -C, etc.).
 if bup_dir:
@@ -169,13 +197,9 @@ 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))),
-                          b'BUP_TTY_WIDTH': b'%d' % _tty_width(), })
-else:
-    tty_env = environ
+    _ttymask = (fix_stdout and 1 or 0) + (fix_stderr and 2 or 0)
+    environ[b'BUP_FORCE_TTY'] = b'%d' % _ttymask
+    environ[b'BUP_TTY_WIDTH'] = b'%d' % _tty_width()
 
 
 sep_rx = re.compile(br'([\r\n])')
@@ -195,7 +219,7 @@ def print_clean_line(dest, content, width, sep=None):
         assert not sep_rx.match(x)
     content = b''.join(content)
     if sep == b'\r' and len(content) > width:
-        content = content[width:]
+        content = content[:width]
     os.write(dest, content)
     if len(content) < width:
         os.write(dest, b' ' * (width - len(content)))
@@ -209,8 +233,7 @@ def filter_output(srcs, dests):
 
     """
     global sep_rx
-    assert all(type(x) in int_types for x in srcs)
-    assert all(type(x) in int_types for x in srcs)
+    assert all(isinstance(x, int_types) for x in srcs)
     assert len(srcs) == len(dests)
     srcs = tuple(srcs)
     dest_for = dict(zip(srcs, dests))
@@ -354,7 +377,7 @@ def run_subproc_cmd(args):
         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)
+                             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):