From 379901bf8f2b4c177dc96e8728e2de30434ab706 Mon Sep 17 00:00:00 2001
From: david-sarah <david-sarah@jacaranda.org>
Date: Sat, 31 Mar 2012 22:41:22 +0000
Subject: [PATCH] Add 'tahoe debug flogtool' command, test for --help, and
 docs. This version gets the help synopses more correct, and changes the doc
 to say that this command is added in 1.10.0 rather than 1.9.2. fixes #1693

---
 docs/logging.rst               | 10 +++++--
 src/allmydata/scripts/debug.py | 51 ++++++++++++++++++++++++++++++++--
 src/allmydata/test/test_cli.py | 10 +++++++
 3 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/docs/logging.rst b/docs/logging.rst
index 9609de45..f3080bc0 100644
--- a/docs/logging.rst
+++ b/docs/logging.rst
@@ -29,9 +29,13 @@ The Foolscap logging system is documented at
 The Foolscap distribution includes a utility named "``flogtool``" that is
 used to get access to many Foolscap logging features. However, using this
 command directly on Tahoe log files may fail, due to use of an incorrect
-PYTHONPATH. Installing Foolscap v0.6.1 or later and then running
-``bin/tahoe @flogtool`` from the root of a Tahoe-LAFS source distribution
-may avoid this problem (but only on Unix, not Windows).
+PYTHONPATH. To avoid this problem, Tahoe-LAFS v1.10.0 and later include a
+``tahoe debug flogtool`` command; to use this, prefix all of the example
+commands below with ``tahoe debug``.
+
+For earlier versions since Tahoe-LAFS v1.8.2, installing Foolscap v0.6.1
+or later and then running ``bin/tahoe @flogtool`` from the root of a
+Tahoe-LAFS source distribution may work (but only on Unix, not Windows).
 
 
 Realtime Logging
diff --git a/src/allmydata/scripts/debug.py b/src/allmydata/scripts/debug.py
index b482fb9c..f7749cd4 100644
--- a/src/allmydata/scripts/debug.py
+++ b/src/allmydata/scripts/debug.py
@@ -5,6 +5,7 @@ import struct, time, os, sys
 from twisted.python import usage, failure
 from twisted.internet import defer
 from twisted.scripts import trial as twisted_trial
+from foolscap.logging import cli as foolscap_cli
 
 
 class DumpOptions(usage.Options):
@@ -998,6 +999,49 @@ def trial(config):
     twisted_trial.run()
 
 
+def fixOptionsClass( (subcmd, shortcut, OptionsClass, desc) ):
+    class FixedOptionsClass(OptionsClass):
+        def getSynopsis(self):
+            t = OptionsClass.getSynopsis(self)
+            i = t.find("Usage: flogtool ")
+            if i >= 0:
+                return "Usage: tahoe debug flogtool " + t[i+len("Usage: flogtool "):]
+            else:
+                return "Usage: tahoe debug flogtool %s [options]" % (subcmd,)
+    return (subcmd, shortcut, FixedOptionsClass, desc)
+
+class FlogtoolOptions(foolscap_cli.Options):
+    def __init__(self):
+        super(FlogtoolOptions, self).__init__()
+        self.subCommands = map(fixOptionsClass, self.subCommands)
+
+    def getSynopsis(self):
+        return "Usage: tahoe debug flogtool (%s) [command options]" % ("|".join([x[0] for x in self.subCommands]))
+
+    def parseOptions(self, all_subargs, *a, **kw):
+        self.flogtool_args = list(all_subargs)
+        return super(FlogtoolOptions, self).parseOptions(self.flogtool_args, *a, **kw)
+
+    def getUsage(self, width=None):
+        t = super(FlogtoolOptions, self).getUsage(width)
+        t += """
+The 'tahoe debug flogtool' command uses the correct imports for this instance
+of Tahoe-LAFS.
+
+Please run 'tahoe debug flogtool SUBCOMMAND --help' for more details on each
+subcommand.
+"""
+        return t
+
+    def opt_help(self):
+        print str(self)
+        sys.exit(0)
+
+def flogtool(config):
+    sys.argv = ['flogtool'] + config.flogtool_args
+    return foolscap_cli.run_flogtool()
+
+
 class DebugCommand(usage.Options):
     subCommands = [
         ["dump-share", None, DumpOptions,
@@ -1008,15 +1052,16 @@ class DebugCommand(usage.Options):
         ["corrupt-share", None, CorruptShareOptions, "Corrupt a share by flipping a bit."],
         ["repl", None, ReplOptions, "Open a Python interpreter."],
         ["trial", None, TrialOptions, "Run tests using Twisted Trial with the right imports."],
+        ["flogtool", None, FlogtoolOptions, "Utilities to access log files."],
         ]
     def postOptions(self):
         if not hasattr(self, 'subOptions'):
             raise usage.UsageError("must specify a subcommand")
     def getSynopsis(self):
-        return "Usage: tahoe debug SUBCOMMAND"
+        return ""
     def getUsage(self, width=None):
         #t = usage.Options.getUsage(self, width)
-        t = """
+        t = """Usage: tahoe debug SUBCOMMAND
 Subcommands:
     tahoe debug dump-share      Unpack and display the contents of a share.
     tahoe debug dump-cap        Unpack a read-cap or write-cap.
@@ -1025,6 +1070,7 @@ Subcommands:
     tahoe debug corrupt-share   Corrupt a share by flipping a bit.
     tahoe debug repl            Open a Python interpreter.
     tahoe debug trial           Run tests using Twisted Trial with the right imports.
+    tahoe debug flogtool        Utilities to access log files.
 
 Please run e.g. 'tahoe debug dump-share --help' for more details on each
 subcommand.
@@ -1065,6 +1111,7 @@ subDispatch = {
     "corrupt-share": corrupt_share,
     "repl": repl,
     "trial": trial,
+    "flogtool": flogtool,
     }
 
 
diff --git a/src/allmydata/test/test_cli.py b/src/allmydata/test/test_cli.py
index 59e2c6aa..485414b8 100644
--- a/src/allmydata/test/test_cli.py
+++ b/src/allmydata/test/test_cli.py
@@ -689,6 +689,16 @@ class Help(unittest.TestCase):
         self.failUnlessIn(" debug trial [options] [[file|package|module|TestCase|testmethod]...]", help)
         self.failUnlessIn("The 'tahoe debug trial' command uses the correct imports", help)
 
+    def test_debug_flogtool(self):
+        options = debug.FlogtoolOptions()
+        help = str(options)
+        self.failUnlessIn(" debug flogtool ", help)
+        self.failUnlessIn("The 'tahoe debug flogtool' command uses the correct imports", help)
+
+        for (option, shortcut, oClass, desc) in options.subCommands:
+            subhelp = str(oClass())
+            self.failUnlessIn(" debug flogtool %s " % (option,), subhelp)
+
 
 class CreateAlias(GridTestMixin, CLITestMixin, unittest.TestCase):
 
-- 
2.45.2