]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blobdiff - bin/tahoe-script.template
Merge pull request #236 from daira/2725.timezone-test.0
[tahoe-lafs/tahoe-lafs.git] / bin / tahoe-script.template
index 69d54c92bf1907da0e65435adf1f14f986bf676a..b088eaf6a32f736a232be60f9c420d4628d368dc 100644 (file)
@@ -1,27 +1,33 @@
 #!/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.
@@ -41,31 +47,84 @@ else:
     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)
-