helpers.js

import _ from 'lodash'
import * as Diff from 'diff'

const getDiffsFromPatchText = (patchText) => {
  const lines = patchText.split("\n")
  const hunks = []
  let previousHunk = -1
  lines.forEach((line, index) => {
    if (line.startsWith("hunk") || index === lines.length - 1) {
      if (previousHunk === -1) {
        previousHunk = index
        return
      }
      // get diff from previous hunk to this next one
      const lastHunk = lines.slice(previousHunk, index + 1) // slice is non-inclusive for the end argument
      let lastHunkBefore = lastHunk.filter(line => line.startsWith("-")).map(str => str.replace("-", "")).join("\n")
      let lastHunkAfter = lastHunk.filter(line => line.startsWith("+")).map(str => str.replace("+", "")).join("\n")
      lastHunkBefore = _.escape(lastHunkBefore)
      lastHunkAfter = _.escape(lastHunkAfter)
      let filename = lines[previousHunk].replace("hunk ./", "")
      const changeObject = Diff.diffWords(lastHunkBefore, lastHunkAfter)
      let previousText = ""
      let afterText = ""

      changeObject.forEach((obj) => {
        if (!obj.added && !obj.removed) {
          previousText = previousText + obj.value
          afterText = afterText + obj.value
        }
        if (obj.added) {
          afterText = afterText + "<mark>" + obj.value + "</mark>"
        }
        if (obj.removed) {
          previousText = previousText + "<mark>" + obj.value + "</mark>"
        }
      })
      const regex = RegExp(/(.*) ([0-9]+)$/)
      const matches = filename.match(regex)
      const file = matches[1]
      const lineNumber = matches[2]

      hunks.push({
        file,
        lineNumber,
        previousText,
        afterText,
      })
      previousHunk = index
    }
  })
  return hunks
}

export {
  getDiffsFromPatchText,
}