--- /dev/null
+Return-Path: <wking@tremily.us>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 9808D431FBF\r
+ for <notmuch@notmuchmail.org>; Sat, 10 May 2014 12:17:27 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References"\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0 tagged_above=-999 required=5\r
+ tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001]\r
+ autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id BGMCP752kGtw for <notmuch@notmuchmail.org>;\r
+ Sat, 10 May 2014 12:17:21 -0700 (PDT)\r
+Received: from QMTA11.westchester.pa.mail.comcast.net\r
+ (qmta11.westchester.pa.mail.comcast.net [76.96.59.211])\r
+ by olra.theworths.org (Postfix) with ESMTP id 4666B431FC0\r
+ for <notmuch@notmuchmail.org>; Sat, 10 May 2014 12:17:21 -0700 (PDT)\r
+Received: from omta12.westchester.pa.mail.comcast.net ([76.96.62.44])\r
+ by QMTA11.westchester.pa.mail.comcast.net with comcast\r
+ id 0K1n1o0030xGWP85BKHH7N; Sat, 10 May 2014 19:17:17 +0000\r
+Received: from odin.tremily.us ([24.18.63.50])\r
+ by omta12.westchester.pa.mail.comcast.net with comcast\r
+ id 0KHG1o008152l3L3YKHGXJ; Sat, 10 May 2014 19:17:17 +0000\r
+Received: from mjolnir.tremily.us (unknown [192.168.0.140])\r
+ by odin.tremily.us (Postfix) with ESMTPS id DD217119F4AD;\r
+ Sat, 10 May 2014 12:17:15 -0700 (PDT)\r
+Received: (nullmailer pid 7964 invoked by uid 1000);\r
+ Sat, 10 May 2014 19:16:43 -0000\r
+From: "W. Trevor King" <wking@tremily.us>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH 1/2] nmbug-status: Clarify errors for illegible configs\r
+Date: Sat, 10 May 2014 12:16:38 -0700\r
+Message-Id:\r
+ <1c786e115a812384a8b397583027cf89316253cb.1399749244.git.wking@tremily.us>\r
+X-Mailer: git-send-email 1.9.1.353.gc66d89d\r
+In-Reply-To: <cover.1399749244.git.wking@tremily.us>\r
+References: <cover.1399749244.git.wking@tremily.us>\r
+In-Reply-To: <cover.1399749244.git.wking@tremily.us>\r
+References: <cover.1399749244.git.wking@tremily.us>\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=comcast.net;\r
+ s=q20140121; t=1399749437;\r
+ bh=Y6e1Qnl8mwd0e87DRQAmuwxtsjiw5fDa2eESfCs8cMU=;\r
+ h=Received:Received:Received:Received:From:To:Subject:Date:\r
+ Message-Id;\r
+ b=R6menPQ+vS6Kjj8UwbryJvUT2aBeW7FPNW3e5Ae/RiK19MKujIKrws2W0cElEeA0b\r
+ 8rv75kp2vBJXqvYsLwTpn9OD6gdw0sbdWKe+a+Gwpe+YzKLNzk4P9Ir6z7FDfkhdxr\r
+ gkF2pWYEJEWu7eTYex1s8AImiiGkoqIhPnj7Rexgk5Xj168yt+7SedyltpFXZVxxr1\r
+ 0/bDs/Bjufhv7YtBcoivEzScwKSV0rP2sqwTsLoA6aXyAjGGHhw/Xt19EVIe5i4sSQ\r
+ LZ1+79OnvFrnfr1cA5dLsIdgLHPfpLdVqe/YdPVpMpL8VxAaPQUnthbZ1m0H78lP2A\r
+ RC4A62MAYOZAQ==\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sat, 10 May 2014 19:17:27 -0000\r
+\r
+Carl Worth pointed out that errors like:\r
+\r
+ $ ./nmbug-status\r
+ fatal: Not a git repository: '/home/cworth/.nmbug'\r
+ fatal: Not a git repository: '/home/cworth/.nmbug'\r
+ Traceback (most recent call last):\r
+ File "./nmbug-status", line 254, in <module>\r
+ config = read_config(path=args.config)\r
+ File "./nmbug-status", line 73, in read_config\r
+ return json.load(fp)\r
+ File "/usr/lib/python2.7/json/__init__.py", line 290, in load\r
+ **kw)\r
+ File "/usr/lib/python2.7/json/__init__.py", line 338, in loads\r
+ return _default_decoder.decode(s)\r
+ File "/usr/lib/python2.7/json/decoder.py", line 366, in decode\r
+ obj, end = self.raw_decode(s, idx=_w(s, 0).end())\r
+ File "/usr/lib/python2.7/json/decoder.py", line 384, in raw_decode\r
+ raise ValueError("No JSON object could be decoded")\r
+ ValueError: No JSON object could be decoded\r
+\r
+are not particularly clear. With this commit, we'll get output like:\r
+\r
+ $ ./nmbug-status\r
+ fatal: Not a git repository: '/home/wking/.nmbug'\r
+ No local branch 'config' in /home/wking/.nmbug. Checkout a local\r
+ config branch or explicitly set --config.\r
+\r
+which is much more accessible. I've also added user-friendly messages\r
+for a number of other config-parsing errors.\r
+---\r
+ devel/nmbug/nmbug-status | 54 ++++++++++++++++++++++++++++++++++++++++--------\r
+ 1 file changed, 45 insertions(+), 9 deletions(-)\r
+\r
+diff --git a/devel/nmbug/nmbug-status b/devel/nmbug/nmbug-status\r
+index 03621bd..75a6e47 100755\r
+--- a/devel/nmbug/nmbug-status\r
++++ b/devel/nmbug/nmbug-status\r
+@@ -49,28 +49,60 @@ if not hasattr(collections, 'OrderedDict'): # Python 2.6 or earlier\r
+ collections.OrderedDict = _OrderedDict\r
+ \r
+ \r
++class ConfigError (Exception):\r
++ """Errors with config file usage\r
++ """\r
++ pass\r
++\r
++\r
+ def read_config(path=None, encoding=None):\r
+ "Read config from json file"\r
+ if not encoding:\r
+ encoding = _ENCODING\r
+ if path:\r
+- fp = open(path)\r
++ try:\r
++ with open(path, 'rb') as f:\r
++ config_bytes = f.read()\r
++ except IOError as e:\r
++ raise ConfigError('Could not read config from {}'.format(path))\r
+ else:\r
+ nmbhome = os.getenv('NMBGIT', os.path.expanduser('~/.nmbug'))\r
++ branch = 'config'\r
++ filename = 'status-config.json'\r
+ \r
+ # read only the first line from the pipe\r
+ sha1_bytes = subprocess.Popen(\r
+- ['git', '--git-dir', nmbhome, 'show-ref', '-s', 'config'],\r
++ ['git', '--git-dir', nmbhome, 'show-ref', '-s', branch],\r
+ stdout=subprocess.PIPE).stdout.readline()\r
+ sha1 = sha1_bytes.decode(encoding).rstrip()\r
++ if not sha1:\r
++ raise ConfigError(\r
++ ("No local branch '{branch}' in {nmbgit}. "\r
++ 'Checkout a local {branch} branch or explicitly set --config.'\r
++ ).format(branch=branch, nmbgit=nmbhome))\r
+ \r
+- fp_byte_stream = subprocess.Popen(\r
++ p = subprocess.Popen(\r
+ ['git', '--git-dir', nmbhome, 'cat-file', 'blob',\r
+- sha1+':status-config.json'],\r
+- stdout=subprocess.PIPE).stdout\r
+- fp = codecs.getreader(encoding=encoding)(stream=fp_byte_stream)\r
+-\r
+- return json.load(fp)\r
++ '{}:{}'.format(sha1, filename)],\r
++ stdout=subprocess.PIPE)\r
++ config_bytes, err = p.communicate()\r
++ status = p.wait()\r
++ if status != 0:\r
++ raise ConfigError(\r
++ ("Missing status-config.json in branch '{branch}' of"\r
++ '{nmbgit}. Add the file or explicitly set --config.'\r
++ ).format(branch=branch, nmbgit=nmbhome))\r
++\r
++ config_json = config_bytes.decode(encoding)\r
++ try:\r
++ return json.loads(config_json)\r
++ except ValueError as e:\r
++ if not path:\r
++ path = "{} in branch '{}' of {}".format(\r
++ filename, branch, nmbhome)\r
++ raise ConfigError(\r
++ 'Could not parse JSON from the config file {}:\n{}'.format(\r
++ path, e))\r
+ \r
+ \r
+ class Thread (list):\r
+@@ -254,7 +286,11 @@ parser.add_argument('--get-query', help='get query for view',\r
+ \r
+ args = parser.parse_args()\r
+ \r
+-config = read_config(path=args.config)\r
++try:\r
++ config = read_config(path=args.config)\r
++except ConfigError as e:\r
++ print(e)\r
++ sys.exit(1)\r
+ \r
+ _PAGES['text'] = Page()\r
+ _PAGES['html'] = HtmlPage(\r
+-- \r
+1.9.1.353.gc66d89d\r
+\r