FIX: correctly detect commit hashes under all cases

FIX: correctly detect commit hashes under all cases

In some cases commit hashes would get autolinked incorrectly if post contained markdown, this will skip elements that can not be transformed to a link (like code blocks). Hash detection runs now on all posts and wil automatically link them to the existing commit topic if there is one.

diff --git a/lib/discourse_code_review/importer.rb b/lib/discourse_code_review/importer.rb
index 4bffdc2..794a588 100644
--- a/lib/discourse_code_review/importer.rb
+++ b/lib/discourse_code_review/importer.rb
@@ -33,17 +33,21 @@ module DiscourseCodeReview
       end
     end
 
-    def auto_link_commits(text)
+    def auto_link_commits(text, doc = nil)
       linked_commits = find_linked_commits(text)
       if (linked_commits.length > 0)
+        doc ||= Nokogiri::HTML::fragment(PrettyText.cook(text))
+        skip_tags = ["a", "code"]
         linked_commits.each do |hash, topic|
-          # this is the ultra naive implementation
-          # the ultra correct one here is to convert to HTML, modify HTML
-          # convert back to Markdown, lets see what milege this gives
-          text.gsub!(hash, "[#{hash}](#{topic.url})")
+          doc.traverse do |node|
+            if node.text? && !skip_tags.include?(node.parent&.name)
+              node.replace node.content.gsub(hash, "<a href='#{topic.url}'>#{hash}</a>")
+            end
+          end
+          text = HtmlToMarkdown.new(doc.to_html).to_markdown
         end
       end
-      [text, linked_commits]
+      [text, linked_commits, doc]
     end
 
     def detect_shas(text)
diff --git a/plugin.rb b/plugin.rb
index c90a4f0..a7f7c75 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -129,7 +129,12 @@ after_initialize do
           end
         end
       end
+    end
+  end
 
+  on(:before_post_process_cooked) do |doc, post|
+    unless post.topic.custom_fields[DiscourseCodeReview::CommitHash].present? && post.post_number == 1
+      doc = DiscourseCodeReview::Importer.new(nil).auto_link_commits(post.raw, doc)[2]
     end
   end
 end
diff --git a/spec/discourse_code_review/lib/importer_spec.rb b/spec/discourse_code_review/lib/importer_spec.rb
index f83ebd1..741c6bb 100644
--- a/spec/discourse_code_review/lib/importer_spec.rb
+++ b/spec/discourse_code_review/lib/importer_spec.rb
@@ -91,5 +91,20 @@ module DiscourseCodeReview
       expect(post.cooked.scan("code").length).to eq(2)
       expect(post.excerpt).to eq("this is <a href=\"http://amaz.ing\">amazing</a>")
     end
+
+    it "#auto_link_commits" do
+      topic = Fabricate(:topic)
+      topic.custom_fields[DiscourseCodeReview::CommitHash] = "dbbadb5c357bc23daf1fa732f8670e55dc28b7cb"
+      topic.save
+      topic2 = Fabricate(:topic)
+      topic2.custom_fields[DiscourseCodeReview::CommitHash] = "a1db15feadc7951d8a2b4ae63384babd6c568ae0"
+      topic2.save
+
+      result = Importer.new(nil).auto_link_commits("a1db15feadc and another one dbbadb5c357")
+      markdown = "[a1db15feadc](#{topic2.url}) and another one [dbbadb5c357](#{topic.url})"
+      cooked = PrettyText.cook(markdown)
+      expect(result[0]).to eq(markdown)
+      expect(result[2].to_html).to eq(cooked)
+    end
   end
 end

GitHub sha: d8703fb1

1 Like