Re: [gedit-list] Navigating to a file/line from the Shell Output



Here is the patch that I made. It will parse links from Go stack traces and GoSpec's test reports. I hope you will include it in the next release.

The regexp is quite generic and it produced some overlap with a couple of the other regexps, so I had to add a uniqueness check for the links. It might be better (for performance and clearer intention) to collect the links to a set, but that would require refactoring the existing tests, because they rely on the links to be reported in the same order as they are found.

This patch is based on GEDIT_2_30_2 because I was not able to compile the master branch on Ubuntu 10.04, but I think those files were not modified in master, so the patch should apply cleanly.

--
Esko Luontola
www.orfjackal.net
>From 6faf5062211577a0eefe3ed559ded79193d06dfa Mon Sep 17 00:00:00 2001
From: Esko Luontola <esko luontola gmail com>
Date: Tue, 11 May 2010 21:20:51 +0300
Subject: [PATCH] Link parsing for Go stack traces

---
 plugins/externaltools/tools/linkparsing.py      |   22 +++++++++++++-
 plugins/externaltools/tools/linkparsing_test.py |   35 +++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletions(-)

diff --git a/plugins/externaltools/tools/linkparsing.py b/plugins/externaltools/tools/linkparsing.py
index 27b9ba8..6715dd4 100644
--- a/plugins/externaltools/tools/linkparsing.py
+++ b/plugins/externaltools/tools/linkparsing.py
@@ -42,6 +42,12 @@ class Link:
         return "%s[%s](%s:%s)" % (self.path, self.line_nr,
                                   self.start, self.end)
 
+    def __eq__(self, other):
+        return (self.path    == other.path and
+                self.line_nr == other.line_nr and
+                self.start   == other.start and
+                self.end     == other.end)
+
 class LinkParser:
     """
     Parses a text using different parsing providers with the goal of finding one
@@ -67,6 +73,7 @@ class LinkParser:
         self.add_regexp(REGEXP_RUBY)
         self.add_regexp(REGEXP_PERL)
         self.add_regexp(REGEXP_MCS)
+        self.add_regexp(REGEXP_GO)
 
     def add_parser(self, parser):
         self._providers.append(parser)
@@ -97,10 +104,15 @@ class LinkParser:
         links = []
 
         for provider in self._providers:
-            links.extend(provider.parse(text))
+            add_unique_links(provider.parse(text), links)
 
         return links
 
+def add_unique_links(source, target):
+    for link in source:
+        if link not in target:
+            target.append(link)
+
 class AbstractLinkParser(object):
     """The "abstract" base class for link parses"""
 
@@ -228,4 +240,12 @@ REGEXP_MCS = r"""
 \:\s
 """
 
+# Go stack trace 'pkg._func_040+0x243 /tmp/file.go:123'
+REGEXP_GO = r"""
+(?P<lnk>
+    (?P<pth> \/.+ )
+    \:
+    (?P<ln> \d+)
+)"""
+
 # ex:ts=4:et:
diff --git a/plugins/externaltools/tools/linkparsing_test.py b/plugins/externaltools/tools/linkparsing_test.py
index 609e3b2..c603b3f 100644
--- a/plugins/externaltools/tools/linkparsing_test.py
+++ b/plugins/externaltools/tools/linkparsing_test.py
@@ -155,6 +155,41 @@ test.rb:5: undefined method `fake_method' for main:Object (NoMethodError)
         self.assert_link(lnk, "test.go", 9)
         self.assert_link_text(line, lnk, 'test.go:9')
 
+    def test_parse_go_stack_trace_test_with_real_output(self):
+        output = """
+sigpanic+0x84 /tmp/go/src/pkg/runtime/linux/thread.c:285
+	sigpanic()
+gospec.*matcherAdapter·Expect+0x120 /tmp/gospec/matchers.go:32
+	gospec.*matcherAdapter·Expect(0x2b8b751f2d80, 0x2b8b751f05a0, 0x2b8b00000010, 0x4b2e28, 0x2b8b00000001, ...)
+gospec._func_040+0x243 /tmp/gospec/matchers_test.go:24
+	gospec._func_040(0x0, 0x4b2e28, 0x2b8b00000001, 0x414c16, 0x2b8b751efa90, ...)
+"""
+        links = self.p.parse(output)
+        self.assert_link_count(links, 3)
+        
+        # Go function
+        lnk = links[2]
+        self.assert_link(lnk, "/tmp/gospec/matchers_test.go", 24)
+        self.assert_link_text(output, lnk, '/tmp/gospec/matchers_test.go:24')
+        
+        # Go method; the same line contains a non-ASCII character "·"
+        lnk = links[1]
+        self.assert_link(lnk, "/tmp/gospec/matchers.go", 32)
+        self.assert_link_text(output, lnk, '/tmp/gospec/matchers.go:32')
+        
+        # C function; must not be restricted to *.go files
+        lnk = links[0]
+        self.assert_link(lnk, "/tmp/go/src/pkg/runtime/linux/thread.c", 285)
+        self.assert_link_text(output, lnk, '/tmp/go/src/pkg/runtime/linux/thread.c:285')
+
+    def test_parse_go_stack_trace_one_line(self):
+        line = 'pkg._func_040+0x243 /tmp/file.go:12'
+        links = self.p.parse(line)
+        self.assert_link_count(links, 1)
+        lnk = links[0]
+        self.assert_link(lnk, "/tmp/file.go", 12)
+        self.assert_link_text(line, lnk, '/tmp/file.go:12')
+
     def test_parse_perl_one_line(self):
         line = 'syntax error at test.pl line 889, near "$fake_var'
         links = self.p.parse(line)
-- 
1.7.0.4



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]