diff --git a/pom.xml b/pom.xml
index f3c0717..1c938f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -123,6 +123,18 @@
+
+
+ org.scalatest
+ scalatest_2.11
+ 3.0.7
+ test
+
org.specs2
specs2_${scala.version}
diff --git a/src/main/scala/ch/mibex/bitbucket/sonar/diff/GitDiffParser.scala b/src/main/scala/ch/mibex/bitbucket/sonar/diff/GitDiffParser.scala
index 9e82f07..32b02ec 100644
--- a/src/main/scala/ch/mibex/bitbucket/sonar/diff/GitDiffParser.scala
+++ b/src/main/scala/ch/mibex/bitbucket/sonar/diff/GitDiffParser.scala
@@ -24,6 +24,8 @@ object GitDiffParser extends RegexParsers {
case class FileChange(oldFile: String, newFile: String)
+ case class ExcludePattern(pattern: String)
+
sealed trait Diff
case class BinaryDiff() extends Diff
case class GitDiff(gitDiffHeader: FileChange, header: ExtendedDiffHeader, hunks: List[Hunk]) extends Diff {
@@ -57,10 +59,16 @@ object GitDiffParser extends RegexParsers {
def readUpToNextDiffOrEnd = """(?s).+?(?=((?:diff --git)|$))\n?""".r
- def binaryDiff: Parser[BinaryDiff] = gitDiffHeader ~ extendedDiffHeader ~ "GIT binary patch" ~ readUpToNextDiffOrEnd ^^ {
+ def binaryDiff: Parser[BinaryDiff] = gitDiffHeader ~ extendedDiffHeader ~ (("GIT binary patch" ~ readUpToNextDiffOrEnd) | binaryFilesDiff | excludedFile) ^^ {
_ => BinaryDiff()
}
+ def binaryFilesDiff: Parser[FileChange] = "Binary files " ~> ("""(?:a/)?""".r ~> binaryFilePath <~ " and ") ~ ("""(?:b/)?""".r ~> binaryFilePath <~ " differ") <~ nl ^^ {
+ case oldF ~ newF => FileChange(oldF, newF)
+ }
+
+ def excludedFile: Parser[ExcludePattern] = "File excluded by pattern " ~> """"(.+?)"""".r <~ nl ^^ { p => ExcludePattern(p) }
+
def gitDiff: Parser[GitDiff] = gitDiffHeader ~ extendedDiffHeader ~ hunks ^^ {
case fc ~ h ~ hs => GitDiff(fc, h, hs)
}
@@ -103,6 +111,9 @@ object GitDiffParser extends RegexParsers {
def filePath: Parser[String] = """.+?(?=(\sb/)|(\r?\n))""".r
+ // Match anything until " and " or " differ"
+ def binaryFilePath: Parser[String] = """.+?(?=(\sand\s)|(\sdiffer\r?\n))""".r
+
def similarity: Parser[Int] = """\d{1,3}""".r ^^ { _.toInt }
def hash: Parser[String] = """[0-9a-f]{7,}""".r
diff --git a/src/test/resources/diffs/diff-binary-files.txt b/src/test/resources/diffs/diff-binary-files.txt
new file mode 100644
index 0000000..f5aec5f
--- /dev/null
+++ b/src/test/resources/diffs/diff-binary-files.txt
@@ -0,0 +1,5 @@
+diff --git a/solutions/_templates/hybrid-solution/mvn/login/assets/finantix-logo.png b/solutions/_templates/hybrid/mvn/login/assets/finantix-logo.png
+similarity index 100%
+rename from solutions/_templates/hybrid-solution/mvn/login/assets/finantix-logo.png
+rename to solutions/_templates/hybrid/mvn/login/assets/finantix-logo.png
+Binary files a/solutions/_templates/hybrid-solution/mvn/login/assets/finantix-logo.png and b/solutions/_templates/hybrid/mvn/login/assets/finantix-logo.png differ
diff --git a/src/test/resources/diffs/diff-excluded-file.txt b/src/test/resources/diffs/diff-excluded-file.txt
new file mode 100644
index 0000000..5f0fa15
--- /dev/null
+++ b/src/test/resources/diffs/diff-excluded-file.txt
@@ -0,0 +1,3 @@
+diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml
+index d1549e0..06b7b7d 100644
+File excluded by pattern "pnpm-lock.yaml"
diff --git a/src/test/scala/ch/mibex/bitbucket/sonar/diff/GitDiffParserTest.scala b/src/test/scala/ch/mibex/bitbucket/sonar/diff/GitDiffParserTest.scala
new file mode 100644
index 0000000..8abec66
--- /dev/null
+++ b/src/test/scala/ch/mibex/bitbucket/sonar/diff/GitDiffParserTest.scala
@@ -0,0 +1,18 @@
+package ch.mibex.bitbucket.sonar.diff
+
+import org.scalatest.FunSuite
+
+class GitDiffParserTest extends FunSuite {
+ private def readFile(path: String) =
+ scala.io.Source.fromInputStream(getClass.getResourceAsStream(path)).mkString.replaceAll("\u0085", "")
+
+ test("The Binary files differ case should be correctly parsed") {
+ val response = GitDiffParser.parse(readFile("/diffs/diff-binary-files.txt"))
+ assert(response.isRight)
+ }
+
+ test("The File excluded by pattern case should be correctly parsed") {
+ val response = GitDiffParser.parse(readFile("/diffs/diff-excluded-file.txt"))
+ assert(response.isRight)
+ }
+}
\ No newline at end of file