]> arthur.barton.de Git - bup.git/blobdiff - cmd/bup
test-web: mark as unresolved with respect to python 3
[bup.git] / cmd / bup
diff --git a/cmd/bup b/cmd/bup
index e442541bffb505572a9d0bc737b14eafa68a3970..c98d7e7eb62a368a6db7f826762dc9e903e50507 100755 (executable)
--- a/cmd/bup
+++ b/cmd/bup
@@ -16,43 +16,30 @@ exec "$script_home/bup-python" "$0" ${1+"$@"}
 # end of bup preamble
 
 from __future__ import absolute_import, print_function
-import errno, re, sys, os, subprocess, signal, getopt
+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 os.environ.get('BUP_ALLOW_UNEXPECTED_PYTHON_VERSION') == 'true':
+   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)
 
-from subprocess import PIPE
-from sys import stderr, stdout
-import select
-
-argv = sys.argv
-exe = os.path.realpath(argv[0])
-exepath = os.path.split(exe)[0] or '.'
-
-# fix the PYTHONPATH to include our lib dir
-if os.path.exists("%s/../bup/." % exepath):
-    # Everything is relative to exepath (i.e. LIBDIR/cmd/)
-    cmdpath = exepath
-    libpath = os.path.join(exepath, '..')
-    resourcepath = libpath
-else:
-    # running from the src directory without being installed first
-    cmdpath = exepath
-    libpath = os.path.join(exepath, '../lib')
-    resourcepath = libpath
-sys.path[:0] = [libpath]
-os.environ['PYTHONPATH'] = libpath + ':' + os.environ.get('PYTHONPATH', '')
-os.environ['BUP_MAIN_EXE'] = os.path.abspath(exe)
-os.environ['BUP_RESOURCE_PATH'] = resourcepath
-
-
-from bup import compat, helpers
-from bup.compat import add_ex_tb, add_ex_ctx, wrap_main
+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] '
@@ -77,9 +64,9 @@ def usage(msg=""):
     
     log('Other available commands:\n')
     cmds = []
-    for c in sorted(os.listdir(cmdpath) + os.listdir(exepath)):
-        if c.startswith('bup-') and c.find('.') < 0:
-            cname = c[4:]
+    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, '    '))
@@ -92,76 +79,79 @@ def usage(msg=""):
     sys.exit(99)
 
 
-if len(argv) < 2:
+if len(sys.argv) < 2:
     usage()
 
 # Handle global options.
 try:
     optspec = ['help', 'version', 'debug', 'profile', 'bup-dir=']
-    global_args, subcmd = getopt.getopt(argv[1:], '?VDd:', optspec)
+    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 = ['version']
+        subcmd = [b'version']
     elif opt[0] in ['-D', '--debug']:
         helpers.buglvl += 1
-        os.environ['BUP_DEBUG'] = str(helpers.buglvl)
+        environ[b'BUP_DEBUG'] = b'%d' % helpers.buglvl
     elif opt[0] in ['--profile']:
         do_profile = True
     elif opt[0] in ['-d', '--bup-dir']:
-        os.environ['BUP_DIR'] = opt[1]
+        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' in os.environ:
-    os.environ['BUP_DIR'] = os.path.abspath(os.environ['BUP_DIR'])
+if bup_dir:
+    environ[b'BUP_DIR'] = os.path.abspath(bup_dir)
 
 if len(subcmd) == 0:
     if help_requested:
-        subcmd = ['help']
+        subcmd = [b'help']
     else:
         usage()
 
-if help_requested and subcmd[0] != 'help':
-    subcmd = ['help'] + subcmd
+if help_requested and subcmd[0] != b'help':
+    subcmd = [b'help'] + subcmd
 
-if len(subcmd) > 1 and subcmd[1] == '--help' and subcmd[0] != 'help':
-    subcmd = ['help', subcmd[0]] + subcmd[2:]
+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(s):
-    sp = os.path.join(exepath, 'bup-%s' % s)
-    if not os.path.exists(sp):
-        sp = os.path.join(cmdpath, 'bup-%s' % s)
-    return sp
+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"' % subcmd_name)
+    usage('error: unknown command "%s"' % path_msg(subcmd_name))
 
-already_fixed = atoi(os.environ.get('BUP_FORCE_TTY'))
-if subcmd_name in ['mux', 'ftp', 'help']:
+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(os.environ,
-                         {'BUP_FORCE_TTY': str((fix_stdout and 1 or 0)
-                                               + (fix_stderr and 2 or 0))})
+    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 = os.environ
+    tty_env = environ
 
 
 sep_rx = re.compile(br'([\r\n])')
@@ -241,15 +231,19 @@ def filter_output(src_out, src_err, dest_out, dest_err):
 
 def run_subcmd(subcmd):
 
-    c = (do_profile and [sys.executable, '-m', 'cProfile'] or []) + 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 sys.stdout,
-                             stderr=PIPE if fix_stderr else sys.stderr,
+                             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.
@@ -258,8 +252,8 @@ def run_subcmd(subcmd):
 
         filter_output(fix_stdout and p.stdout.fileno() or None,
                       fix_stderr and p.stderr.fileno() or None,
-                      fix_stdout and sys.stdout.fileno() or None,
-                      fix_stderr and sys.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)