#!/bin/false # You must specify a python interpreter.
+import sys; assert sys.version_info < (3,), ur"Tahoe-LAFS does not run under Python 3. Please use a version of Python between 2.6 and 2.7.x inclusive."
-import errno, sys, os, subprocess
+import os, subprocess
where = os.path.realpath(sys.argv[0])
base = os.path.dirname(os.path.dirname(where))
+if sys.platform == "win32":
+ perhaps_installed_tahoe = os.path.join(os.path.dirname(sys.executable), 'Scripts', 'tahoe.pyscript')
+else:
+ perhaps_installed_tahoe = "/usr/bin/tahoe"
+
whoami = '''\
-I am a "bin/tahoe" executable who is only for the convenience of running
-Tahoe from its source distribution -- I work only when invoked as the "tahoe"
-script that lives in the "bin/" subdirectory of a Tahoe source code
-distribution, and only if you have already run "make".
-'''
+I am a "bin%stahoe" executable for the convenience of running Tahoe-LAFS
+from its source distribution -- I work only when invoked as the "tahoe"
+script that lives in the "bin" subdirectory of a Tahoe source code
+distribution, and only if you have already run "python setup.py build".
+''' % (os.path.sep,)
# look for Tahoe.home .
homemarker = os.path.join(base, "Tahoe.home")
if not os.path.exists(homemarker):
- print whoami
- print '''\
+ print(whoami)
+ print('''\
I just tried to run and found that I am not living in such a directory, so I
am stopping now. To run Tahoe after it has been is installed, please execute
-my brother, also named "tahoe", who gets installed into the appropriate place
-for executables when you run "make install" (perhaps as /usr/bin/tahoe).
-'''
+my brother, who gets installed into the appropriate place for executables
+when you run "make install" (perhaps as "%s").
+''' % (perhaps_installed_tahoe,))
sys.exit(1)
# we've found our home. Put the tahoe support/lib etc. in our PYTHONPATH.
pp = supportdir
os.environ["PYTHONPATH"] = pp
-# find the location of the tahoe executable.
-bin_dir = "bin"
+# find commandline args and the location of the tahoe executable.
if sys.platform == "win32":
- bin_dir = "Scripts"
-executable = os.path.join(base, "support", bin_dir, "tahoe")
+ import re
+ from ctypes import WINFUNCTYPE, POINTER, byref, c_wchar_p, c_int, windll
+
+ GetCommandLineW = WINFUNCTYPE(c_wchar_p)(("GetCommandLineW", windll.kernel32))
+ CommandLineToArgvW = WINFUNCTYPE(POINTER(c_wchar_p), c_wchar_p, POINTER(c_int)) \
+ (("CommandLineToArgvW", windll.shell32))
+
+ argc = c_int(0)
+ argv_unicode = CommandLineToArgvW(GetCommandLineW(), byref(argc))
+
+ # See src/allmydata/scripts/runner.py for the corresponding unmangler.
+ # Note that this doesn't escape \x7F. If it did, test_unicode_arguments_and_output
+ # in test_runner.py wouldn't work.
+ def mangle(s):
+ return str(re.sub(u'[^\\x20-\\x7F]', lambda m: u'\x7F%x;' % (ord(m.group(0)),), s))
+
+ argv = [mangle(argv_unicode[i]) for i in xrange(0, argc.value)]
+
+ # Take only the suffix with the same number of arguments as sys.argv.
+ # This accounts for anything that can cause initial arguments to be stripped,
+ # for example, the Python interpreter or any options passed to it, or runner
+ # scripts such as 'coverage run'. It works even if there are no such arguments,
+ # as in the case of a frozen executable created by bb-freeze or similar.
+
+ argv = argv[-len(sys.argv):]
+
+ # On Windows, the script is not directly executable and must be run via python.
+ prefix = [sys.executable]
+ script = os.path.join(base, "support", "Scripts", "tahoe.pyscript")
+ args = argv[1:]
+else:
+ # On non-Windows, invoke the script directly, so that 'top' for example shows 'tahoe'.
+ prefix = []
+ script = os.path.join(base, "support", "bin", "tahoe")
+ args = sys.argv[1:]
+
+# Support indirection via another "runner" script (e.g. coverage).
+# For example: bin/tahoe @RUNNER RUNNER_ARGS @tahoe TAHOE_ARGS
+
+if len(args) >= 1 and args[0].startswith('@'):
+ runner = args[0][1:]
+ if runner.endswith('.py') or runner.endswith('.pyscript'):
+ prefix = [sys.executable]
+ else:
+ prefix = []
+ if runner == "python":
+ runner = sys.executable
+
+ def _subst(a):
+ if a == '@tahoe': return script
+ return a
+ command = prefix + [runner] + map(_subst, args[1:])
+else:
+ runner = script
+ command = prefix + [script] + args
+
+ if not os.path.exists(script):
+ print(whoami)
+ print('''\
+I could not find the support script
+"%s".
+
+To run an installed version of Tahoe-LAFS, please execute the "tahoe"
+script that is installed into the appropriate place for executables
+when you run "python setup.py install" (perhaps as "%s").
+''' % (script, perhaps_installed_tahoe))
+ sys.exit(1)
try:
- res = subprocess.call([executable] + sys.argv[1:], env=os.environ)
-except (OSError, IOError), le:
- if le.args[0] == errno.ENOENT:
- print whoami
- print '''\
-I just tried to run and could not find my brother, named
-"../support/bin/tahoe". To run Tahoe when it is installed, please execute my
-brother, also named "tahoe", who gets installed into the appropriate place
-for executables when you run "make install" (perhaps as /usr/bin/tahoe).
-'''
- raise
-except Exception, le:
- print whoami
- print '''\
-I just tried to invoke my brother, named "../support/bin/tahoe" and got an
-exception.
-'''
+ res = subprocess.call(command, env=os.environ)
+except Exception as le:
+ print(whoami)
+ print('''\
+I just tried to invoke "%s"
+and got an exception.
+''' % (runner,))
raise
else:
sys.exit(res)